[
  {
    "path": ".devcontainer/Dockerfile",
    "content": "# Original Dockerfile by Sébastien HOUZÉ, https://github.com/shouze\n# Adapted for use as devcontainer\nFROM perl:slim AS base\n\nRUN export DEBIAN_FRONTEND=noninteractive \\\n && apt-get update \\\n && apt-get install -y --no-install-recommends \\\n    ca-certificates \\\n    git \\\n    unzip \\\n    locales \\\n    locales \\\n    exuberant-ctags \\\n    build-essential \\\n && rm -rf /var/lib/apt/lists/*\n\n# Generate locale\nRUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \\\n    locale-gen\nENV LANG en_US.UTF-8  \nENV LANGUAGE en_US:en  \nENV LC_ALL en_US.UTF-8     \n\n# Install all dependencies\nRUN cpanm \\\n      Algorithm::Diff \\\n      Digest::MD5 \\\n      Parallel::ForkManager \\\n      Regexp::Common \\\n      Perl::LanguageServer \\\n      Perl::Tidy \\\n && rm -rf $HOME/.cpanm\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n    \"build\": { \"dockerfile\": \"Dockerfile\" },\n    \"extensions\": [\n        \"mhutchie.git-graph\",\n        \"eamodio.gitlens\",\n        \"richterger.perl\",\n        \"cfgweb.vscode-perl\",\n        \"gruntfuggly.todo-tree\"\n    ]\n}\n"
  },
  {
    "path": ".dockerignore",
    "content": ".github\nLICENSE\nREADME.md\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [AlDanial] \n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/report-a-bug.md",
    "content": "---\nname: report a bug\nabout: report a bug\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA concise description of the problem you found with cloc.\n\n**cloc; OS; OS version**\n - cloc version:\n - If running the cloc source, Perl version:\n - OS (eg Linux, Windows, macOS, etc):\n - OS version:\n\n**To Reproduce**\nSteps one can follow reproduce the behavior you're seeing.\n\n**Expected result**\nA concise description of what you expected to happen.\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/request-an-enhancement.md",
    "content": "---\nname: request an enhancement\nabout: request support for additional languages or new capabilities\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**If you want an unsupported language added, provide:**\n - language name:\n - file extension(s):\n - method(s) of commenting text:\n - location of sample code:\n\n**For other enhancements:**\nGive a concise description of what you want cloc to be able to do.\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "# This workflow will build a container image,\n# to run all tests (syntax checking + integration tests) on each PR and git push.\n\non: [push, pull_request]\n\nname: Run all tests\n\njobs:\n  deploy:\n    name: Deploy\n    runs-on: ubuntu-latest\n    timeout-minutes: 4\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v1\n\n    - name: Run tests\n      id: run-tests\n      env:\n        IMAGE_TAG: ${{ github.sha }}\n      run: |\n        # Build a docker container to run tests\n        docker build . --target test\n"
  },
  {
    "path": ".github/workflows/release-ready.yml",
    "content": "name: Create release\n\non:\n  pull_request:\n    types: [closed]\n\njobs:\n  create_release:\n    if: ${{ github.event.pull_request.merged == true && startsWith(github.head_ref, 'release-v') }}\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          ref: \"master\"\n\n      - name: Extract version from branch name\n        id: get_version\n        run: |\n          BRANCH=\"${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}\"\n          if [[ \"$BRANCH\" =~ release-v([0-9]+\\.[0-9]+) ]]; then\n            VERSION=\"${BASH_REMATCH[1]}\"\n            echo \"VERSION=$VERSION\" >> $GITHUB_OUTPUT\n            echo \"DISPLAY_VERSION=v$VERSION\" >> $GITHUB_OUTPUT\n          else\n            echo \"Branch name does not match expected format (release-vX.XX)!\" && exit 1\n          fi\n\n      - name: Package repository as tar.gz\n        run: |\n          VER=\"${{ steps.get_version.outputs.VERSION }}\"\n          git archive --format=tar.gz -o cloc-$VER.tar.gz HEAD\n\n      - name: Get artifact url\n        id: get_artifact_url\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          ARTIFACT_COMMENT=$(gh pr view ${{ github.event.pull_request.number }} --json comments -q '\n            .comments \n            | sort_by(.createdAt) \n            | reverse \n            | map(select(.body | contains(\"**Built executable artifact:**\"))) \n            | .[0].body\n          ')\n          if [ -z \"$ARTIFACT_COMMENT\" ]; then\n            echo \"No matching comment found.\"\n            exit 1\n          fi\n          MATCHING_URLS=$(echo \"$ARTIFACT_COMMENT\" | grep -oP 'https:\\/\\/[^\\s\\)]+')\n          if [ -z \"$MATCHING_URLS\" ]; then\n            echo \"No URL found in the comment.\"\n            exit 1\n          fi\n          ARTIFACT_URL=$(echo \"$MATCHING_URLS\" | head -n 1)\n          RUN_ID=$(echo \"$ARTIFACT_URL\" | grep -oP '/actions/runs/\\K[0-9]+')\n          echo \"RUN_ID=$RUN_ID\" >> $GITHUB_OUTPUT\n          echo \"Artifact URL: $ARTIFACT_URL\"\n      \n      - name: Download artifact\n        uses: actions/download-artifact@v4\n        with:\n          name: cloc-${{ steps.get_version.outputs.VERSION }}-executable\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          run-id: ${{ steps.get_artifact_url.outputs.RUN_ID }}\n\n      - name: Prepare renamed release assets\n        run: |\n          VER=\"${{ steps.get_version.outputs.VERSION }}\"\n          cp cloc cloc-$VER.pl\n          cp Unix/NEWS release_notes-$VER.txt\n\n      - name: Create GitHub release with assets\n        uses: softprops/action-gh-release@v2\n        with:\n          tag_name: \"${{ steps.get_version.outputs.DISPLAY_VERSION }}\"\n          name: \"${{ steps.get_version.outputs.DISPLAY_VERSION }}\"\n          body: \"${{ github.event.pull_request.body }}\"\n          token: ${{ secrets.GITHUB_TOKEN }}\n          files: |\n            cloc-${{ steps.get_version.outputs.VERSION }}.tar.gz\n            README.md\n            cloc-${{ steps.get_version.outputs.VERSION }}.pl\n            cloc-${{ steps.get_version.outputs.VERSION }}.exe\n            release_notes-${{ steps.get_version.outputs.VERSION }}.txt\n"
  },
  {
    "path": ".github/workflows/release-staging.yml",
    "content": "name: Build Windows executable\n\non:\n  pull_request:\n    types: [labeled]\n\njobs:\n  staging_build:\n    if: ${{ github.event.label.name == 'release-ready' }}\n    runs-on: windows-latest\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n        with:\n          ref: ${{ github.head_ref }}\n\n      # Branch name must be in the format \"release-vX.XX\"\n      - name: Extract version from branch name\n        id: get_version\n        shell: pwsh\n        run: |\n          $branch = \"${{ github.head_ref }}\"\n          if (-not $branch) { $branch = \"${{ github.ref }}\" }\n          if ($branch -match 'release-v(?<ver>[0-9]+\\.[0-9]+)') {\n            $ver = $Matches[\"ver\"]\n            echo \"VERSION_NUM=$ver\" >> $env:GITHUB_OUTPUT\n            echo \"DISPLAY_VERSION=v$ver\" >> $env:GITHUB_OUTPUT\n            Write-Host \"Extracted version: $ver\"\n          }\n          else {\n            Write-Error \"Branch name does not match expected format (release-vX.XX).\"\n          }\n\n      - name: Update version in cloc files\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          Write-Host \"Updating version in cloc and Unix/cloc to '$ver'\"\n          $replaceVer = 'my $VERSION = \"' + $ver + '\";'\n          (Get-Content cloc) -replace 'my \\$VERSION = \".*\";', $replaceVer | Set-Content cloc\n          (Get-Content Unix/cloc) -replace 'my \\$VERSION = \".*\";', $replaceVer | Set-Content Unix/cloc\n\n      - name: Update README.md with version and date\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          $disp = \"${{ steps.get_version.outputs.DISPLAY_VERSION }}\"\n          $currentDate = (Get-Date).ToString(\"MMM. d, yyyy\")\n          Write-Host \"Updating README.md with version $disp and date $currentDate\"\n          (Get-Content README.md) `\n            -replace 'Latest release:\\s+v\\d+\\.\\d+\\s+\\(.*\\)', \"Latest release:  $disp ($currentDate)\" `\n            -replace 'badge/version-\\d+\\.\\d+', \"badge/version-$ver\" `\n            -replace 'cloc-\\d+\\.\\d+\\.pl', \"cloc-$ver.pl\" `\n            -replace 'cloc-\\d+\\.\\d+\\.exe(?!:)', \"cloc-$ver.exe\" `\n            -replace 'pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o cloc-\\d+\\.\\d+\\.exe', \"pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o cloc-$ver.exe\" `\n            -replace '<tt>cloc-\\d+\\.\\d+\\.exe</tt>', \"<tt>cloc-$ver.exe</tt>\" | Set-Content README.md\n      \n      - name: Install or upgrade Strawberry Perl\n        shell: pwsh\n        run: |\n          if (Get-Command perl -ErrorAction SilentlyContinue) {\n            # see https://github.com/StrawberryPerl/Perl-Dist-Strawberry/issues/19#issuecomment-2401043349\n            choco uninstall strawberryperl -y\n          }\n          choco install strawberryperl --no-progress -y\n          perl -V\n          cpan -v\n\n      - name: Install CPAN dependencies\n        shell: pwsh\n        run: |\n          cpan -i App::cpanminus\n          cpanm Digest::MD5\n          cpanm Regexp::Common\n          cpanm Algorithm::Diff\n          cpanm PAR::Packer\n          cpanm Win32::LongPath || cpanm -n Win32::LongPath\n      \n      - name: Build executable\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o \"cloc-$ver.exe\" cloc\n\n      - name: Upload executable to VirusTotal and get analysis URL\n        id: vt_upload\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          $apiKey = \"${{ secrets.VIRUSTOTAL_API_KEY }}\"\n          $exeFile = \"cloc-$ver.exe\"\n          $absoluteFilePath = (Get-Location).Path + \"\\\" + $exeFile\n          Write-Host \"Uploading $absoluteFilePath to VirusTotal...\"\n          $headers=@{}\n          $headers.Add(\"accept\", \"application/json\")\n          $headers.Add(\"content-type\", \"multipart/form-data\")\n          $headers.Add(\"x-apikey\", $apiKey)\n          $response = Invoke-RestMethod -Uri \"https://www.virustotal.com/api/v3/files\" `\n                                     -Method POST `\n                                     -Headers $headers `\n                                     -Form @{ file = Get-Item -Path $absoluteFilePath }\n          $vtAnalysisId = $response.data.id\n          $response2 = Invoke-WebRequest -Uri \"https://www.virustotal.com/api/v3/analyses/$vtAnalysisId\" -Method GET -Headers $headers\n          $vtId = ($response2.Content | ConvertFrom-Json).data.links.item.Split(\"/\")[-1]\n          $vtUrl = \"https://www.virustotal.com/gui/file/$vtId\"\n          echo \"VT_URL=$vtUrl\" >> $env:GITHUB_OUTPUT\n          Write-Host \"VirusTotal analysis available at $vtUrl\"\n      \n      - name: Upload artifact\n        uses: actions/upload-artifact@v4\n        id: upload-artifact\n        with:\n          name: cloc-${{ steps.get_version.outputs.VERSION_NUM }}-executable\n          path: cloc-${{ steps.get_version.outputs.VERSION_NUM }}.exe\n\n      - name: Post comment with artifact and VirusTotal URL\n        uses: peter-evans/create-or-update-comment@v4\n        with:\n          issue-number: ${{ github.event.pull_request.number }}\n          body: |\n            **Built executable artifact:**\n            [Download the executable artifact from this workflow run](${{ steps.upload-artifact.outputs.artifact-url }})\n\n            **VirusTotal Analysis:** ${{ steps.vt_upload.outputs.VT_URL }}\n\n      - name: Clean up local exe\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          Remove-Item \"cloc-$ver.exe\"\n\n      - name: Update README recent versions entry\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          $vtUrl = \"${{ steps.vt_upload.outputs.VT_URL }}\"\n          $readme = Get-Content README.md -Raw\n          $pattern = 'The entries for recent versions are:\\s*\\r?\\n\\s*\\r?\\n'\n          $replacement = \"The entries for recent versions are:`n`ncloc-$ver.exe:`n$vtUrl`n`n\"\n          $newReadme = [regex]::Replace($readme, $pattern, $replacement)\n          Set-Content -Path README.md -Value $newReadme\n          (Get-Content README.md -Raw) -replace '\\r?\\n\\s*\\r?\\n$', \"\" | Set-Content README.md\n\n      - name: Update Unix/NEWS with release notes\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          $currentDate = (Get-Date).ToString(\"MMM. d, yyyy\")\n          $event = Get-Content $env:GITHUB_EVENT_PATH -Raw | ConvertFrom-Json\n          $prBody = $event.pull_request.body -replace '\"', '`\"'\n          $processedNotes = $prBody -replace '- ', '    o ' -replace '[\\*\\`_]', ''\n          $newsContent = Get-Content Unix/NEWS -Raw -Encoding UTF8\n          $header = @(\n            \"                Release Notes for cloc version $ver\",\n            \"                   https://github.com/AlDanial/cloc\",\n            \"                             $currentDate\"\n          )\n          $newNews = $header + \"\" + $processedNotes + \"\" + (\"=\" * 76) + $newsContent\n          Set-Content -Path Unix/NEWS -Value $newNews -Encoding UTF8\n          (Get-Content Unix/NEWS -Raw) -replace '\\r?\\n\\s*\\r?\\n$', \"\" | Set-Content Unix/NEWS -Encoding UTF8\n\n      - name: Commit changes\n        shell: pwsh\n        run: |\n          $ver = \"${{ steps.get_version.outputs.VERSION_NUM }}\"\n          git config user.name \"github-actions\"\n          git config user.email \"actions@github.com\"\n          git add cloc README.md Unix/NEWS Unix/cloc\n          git commit -m \"chore: prepare release version $ver\"\n          git push\n"
  },
  {
    "path": ".gitignore",
    "content": "cloc-?.??.*\nrelease_notes-?.??.txt\n\n# Visual Studio Code and extensions\n.vstags\n.vscode/perl-lang\n.gitmodules\nUnix/cloc_submodule_test\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    // Further information: https://go.microsoft.com/fwlink/?linkid=830387\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"type\": \"perl\",\n            \"request\": \"launch\",\n            \"name\": \"Perl-Debug\",\n            \"program\": \"${workspaceFolder}/${relativeFile}\",\n            \"stopOnEntry\": true,\n            \"reloadModules\": true\n        }\n    ]\n}"
  },
  {
    "path": "Dockerfile",
    "content": "# Dockerfile by Sébastien HOUZÉ, https://github.com/shouze\nFROM perl:slim AS builder\n\nRUN export DEBIAN_FRONTEND=noninteractive \\\n && apt-get update \\\n && apt-get install -y --no-install-recommends \\\n    dos2unix \\\n    gcc\n\n#Install all dependencies\nRUN cpanm \\\n      Algorithm::Diff \\\n      Digest::MD5 \\\n      Parallel::ForkManager \\\n      Regexp::Common\n\n#Copy source code\nCOPY cloc /usr/src/\nRUN find /usr/src/ -type f -exec dos2unix {} \\;\n\nFROM perl:slim AS base\n\nRUN export DEBIAN_FRONTEND=noninteractive \\\n && apt-get update \\\n && apt-get install -y --no-install-recommends \\\n    git \\\n    unzip \\\n && rm -rf /var/lib/apt/lists/*\n\n#Copy dependencies and source prepared in base image\nCOPY --from=builder /usr/local/lib/perl5 /usr/local/lib/perl5\nCOPY --from=builder /usr/src/ /usr/src/\n\n####################\nFROM base AS test\n\nRUN export DEBIAN_FRONTEND=noninteractive \\\n && apt-get update \\\n && apt-get install -y --no-install-recommends \\\n    ca-certificates\n\n#Copy test code\nCOPY .git /usr/src/.git\nCOPY tests /usr/src/tests\nCOPY Unix /usr/src/Unix\n\nWORKDIR /usr/src/Unix\n\n#Checkout of cloc_submodule_test for t/02_git.t tests\nRUN git clone https://github.com/AlDanial/cloc_submodule_test.git\n\n#Run tests\nRUN make test\n\n####################\nFROM base AS final\n\nWORKDIR /tmp\n\nENTRYPOINT [\"/usr/src/cloc\"]\nCMD [\"--help\"]\n"
  },
  {
    "path": "Dockerfile.build",
    "content": "FROM alpine:3.11\n\nRUN apk add --no-cache cloc\nENTRYPOINT [\"cloc\"]"
  },
  {
    "path": "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\n"
  },
  {
    "path": "README.md",
    "content": "# cloc\n*Count Lines of Code*\n\n* * *\ncloc counts blank lines, comment lines, and physical lines of source code in many programming languages.\n\nLatest release:  v2.08 (Jan. 24, 2026)\n\n[![Version](https://img.shields.io/badge/version-2.08-blue.svg)](https://github.com/AlDanial/cloc)\n[![Contributors](https://img.shields.io/github/contributors/AlDanial/cloc.svg)](https://github.com/AlDanial/cloc/graphs/contributors)\n[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.42029482.svg)](https://doi.org/10.5281/zenodo.42029482)\n[![Forks](https://img.shields.io/github/forks/AlDanial/cloc.svg)](https://github.com/AlDanial/cloc/network/members)\n[![Downloads](https://img.shields.io/github/downloads/AlDanial/cloc/total.svg)]()\n\ncloc moved to GitHub in September 2015 after being hosted\nat http://cloc.sourceforge.net/ since August 2006.\n\n# Quick Start\n\n\n\nStep 1:  Install cloc (see [Install from Github Releases](#install-from-github-releases)\nand [Install via package manager](#install-via-package-manager)) or run cloc's\n[docker image](#run-via-docker).  The Windows executable has no requirements.\nThe source version of cloc requires a Perl interpreter, and the\nDocker version of cloc requires a Docker installation.\n\nStep 2:  Open a terminal (`cmd.exe` on Windows).\n\nStep 3:  Invoke cloc to count your source files, directories, archives,\nor git commits.\nThe executable name differs depending on whether you use the\ndevelopment source version (`cloc`), source for a\nreleased version (`cloc-2.08.pl`) or a Windows executable\n(`cloc-2.08.exe`).\n\nOn this page, `cloc` is the generic term\nused to refer to any of these.\n\n[Include Security](https://www.youtube.com/user/IncludeSecurity) has a\n[YouTube video](https://www.youtube.com/watch?v=eRLTkDMsCqs)\nshowing the steps in action.\n\n**a file**\n```\nprompt> cloc hello.c\n       1 text file.\n       1 unique file.\n       0 files ignored.\n\nhttps://github.com/AlDanial/cloc v 1.65  T=0.04 s (28.3 files/s, 340.0 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nC                                1              0              7              5\n-------------------------------------------------------------------------------\n```\n\n**a directory**\n```\nprompt> cloc gcc-5.2.0/gcc/c\n      16 text files.\n      15 unique files.\n       3 files ignored.\n\nhttps://github.com/AlDanial/cloc v 1.65  T=0.23 s (57.1 files/s, 188914.0 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nC                               10           4680           6621          30812\nC/C++ Header                     3             99            286            496\n-------------------------------------------------------------------------------\nSUM:                            13           4779           6907          31308\n-------------------------------------------------------------------------------\n```\n\n**an archive**\n\nWe'll pull cloc's source zip file from GitHub, then count the contents:\n```\nprompt> wget https://github.com/AlDanial/cloc/archive/master.zip\n\nprompt> cloc master.zip\nhttps://github.com/AlDanial/cloc v 1.65  T=0.07 s (26.8 files/s, 141370.3 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nPerl                             2            725           1103           8713\n-------------------------------------------------------------------------------\nSUM:                             2            725           1103           8713\n-------------------------------------------------------------------------------\n```\n\n**a git repository, using a specific commit**\n\nThis example uses code from\n<a href=https://pypi.python.org/pypi/pudb>PuDB</a>, a fantastic Python debugger.\n\n```\nprompt> git clone https://github.com/inducer/pudb.git\n\nprompt> cd pudb\n\nprompt> cloc 6be804e07a5db\n      48 text files.\n      41 unique files.                              \n       8 files ignored.\n\ngithub.com/AlDanial/cloc v 1.99  T=0.04 s (1054.9 files/s, 189646.8 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nPython                          28           1519            728           4659\nreStructuredText                 6            102             20            203\nYAML                             2              9              2             75\nBourne Shell                     3              6              0             17\nText                             1              0              0             11\nmake                             1              4              6             10\n-------------------------------------------------------------------------------\nSUM:                            41           1640            756           4975\n-------------------------------------------------------------------------------\n```\n\n**each subdirectory of a particular directory**\n\nSay you have a directory with three different git-managed projects,\nProject0, Project1, and Project2.  You can use your shell's looping\ncapability to count the code in each.  This example uses bash (scroll down for cmd.exe example):\n```\nprompt> for d in ./*/ ; do (cd \"$d\" && echo \"$d\" && cloc --vcs git); done\n./Project0/\n7 text files.\n       7 unique files.\n       1 file ignored.\n\ngithub.com/AlDanial/cloc v 1.71  T=0.02 s (390.2 files/s, 25687.6 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nD                                4             61             32            251\nMarkdown                         1              9              0             38\nmake                             1              0              0              4\n-------------------------------------------------------------------------------\nSUM:                             6             70             32            293\n-------------------------------------------------------------------------------\n./Project1/\n       7 text files.\n       7 unique files.\n       0 files ignored.\n\ngithub.com/AlDanial/cloc v 1.71  T=0.02 s (293.0 files/s, 52107.1 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nGo                               7            165            282            798\n-------------------------------------------------------------------------------\nSUM:                             7            165            282            798\n-------------------------------------------------------------------------------\n./Project2/\n      49 text files.\n      47 unique files.\n      13 files ignored.\n\ngithub.com/AlDanial/cloc v 1.71  T=0.10 s (399.5 files/s, 70409.4 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nPython                          33           1226           1026           3017\nC                                4            327            337            888\nMarkdown                         1             11              0             28\nYAML                             1              0              2             12\n-------------------------------------------------------------------------------\nSUM:                            39           1564           1365           3945\n-------------------------------------------------------------------------------\n```\n\n**each subdirectory of a particular directory (Windows/cmd.exe)**\n```\nfor /D %I in (.\\*) do cd %I && cloc --vcs git && cd ..\n```\n\n# Overview\n\ncloc counts blank lines, comment lines, and physical lines of source\ncode in [many programming languages](#recognized-languages). Given two versions of\na code base, cloc can compute differences in blank, comment, and source\nlines. It is written entirely in Perl with no dependencies outside the\nstandard distribution of Perl v5.6 and higher (code from some external\nmodules is [embedded within\ncloc](https://github.com/AlDanial/cloc#regexp_common)) and so is\nquite portable. cloc is known to run on many flavors of Linux, FreeBSD,\nNetBSD, OpenBSD, macOS, AIX, HP-UX, Solaris, IRIX, z/OS, and Windows.\n(To run the Perl source version of cloc on Windows one needs\n[ActiveState Perl](http://www.activestate.com/activeperl) 5.6.1 or\nhigher, [Strawberry Perl](http://strawberryperl.com/),\nWindows Subsystem for Linux,\n[Cygwin](http://www.cygwin.com/),\n[MobaXTerm](http://mobaxterm.mobatek.net/) with the Perl plug-in\ninstalled,\nor\na mingw environment and terminal such as provided by\n[Git for Windows](https://gitforwindows.org/).\nAlternatively one can use the Windows binary of cloc\ngenerated with [PAR::Packer](http://search.cpan.org/~rschupp/PAR-Packer-1.019/lib/pp.pm)\nto run on Windows computers that have neither Perl nor Cygwin.)\n\nIn addition to counting code in individual text files, directories,\nand git repositories, cloc can also count code in archive files such\nas ``.tar`` (including compressed versions), ``.zip``, Python\nwheel ``.whl``, Jupyter notebook ``.ipynb``, source RPMs ``.rpm``\nor ``.src`` (requires ``rpm2cpio``),\nand Debian ``.deb`` files (requires ``dpkg-deb``).\n\ncloc contains code from David Wheeler's\n[SLOCCount](http://www.dwheeler.com/sloccount/),\nDamian Conway and Abigail's Perl module\n[Regexp::Common](http://search.cpan.org/%7Eabigail/Regexp-Common-2.120/lib/Regexp/Common.pm),\nSean M. Burke's Perl module\n[Win32::Autoglob](http://search.cpan.org/%7Esburke/Win32-Autoglob-1.01/Autoglob.pm),\nand Tye McQueen's Perl module\n[Algorithm::Diff](http://search.cpan.org/%7Etyemq/Algorithm-Diff-1.1902/lib/Algorithm/Diff.pm).\nLanguage scale factors were derived from Mayes Consulting, LLC web site\nhttp://softwareestimator.com/IndustryData2.htm.\n\nNew releases nominally appear every six months.\n\n## Install from Github Releases\n\nGrab the latest release of cloc from the [Releases section of this repository](https://github.com/AlDanial/cloc/releases).\n\n### Source version on Linux/macOS\n\nSave the latest source file, for example `cloc-2.08.pl`,\nas `cloc` (if you prefer the shorter command name) somewhere on your `PATH`.\nAfter downloading, make the file executable:\n\n```shell\ncd ~/Downloads\nmv cloc-2.08.pl cloc\nchmod a+rx cloc\n./cloc --version     # make sure it runs\nmv cloc ~/bin        # for example, if ~/bin is in $PATH\n```\n\n### Source version on Windows\n\nYou'll need a Perl interpreter such as [Strawberry Perl](http://strawberryperl.com/)\ninstalled to run the source version of cloc.\nAfter downloading the cloc source file, open a command prompt or PowerShell window,\nnavigate to the download directory (`C:\\TEMP` in the example below), then test cloc with:\n\n```dos\ncd C:\\TEMP>\nC:TEMP\\> perl cloc-2.08.pl --version\n```\n\n### Binary version on Windows\n\nDownload the latest released Windows executable, for example `cloc-2.08.exe`\nand save it as `cloc.exe` (if desired) in a directory on your `PATH`.\n\nThere is no binary version for Linux or macOS.\n\n## Install via package manager\nDepending your operating system, one of these installation methods may\nwork for you (all but the last two entries for Windows require\na Perl interpreter):\n\n    npm install -g cloc              # https://www.npmjs.com/package/cloc\n    sudo apt install cloc            # Debian, Ubuntu\n    sudo yum install cloc            # Red Hat, Fedora\n    sudo dnf install cloc            # Fedora 22 or later\n    sudo pacman -S cloc              # Arch\n    yay -S cloc-git                  # Arch AUR (latest git version)\n    sudo emerge -av dev-util/cloc    # Gentoo https://packages.gentoo.org/packages/dev-util/cloc\n    sudo apk add cloc                # Alpine Linux\n    doas pkg_add cloc                # OpenBSD\n    sudo pkg install cloc            # FreeBSD\n    sudo port install cloc           # macOS with MacPorts\n    brew install cloc                # macOS with Homebrew\n    winget install AlDanial.Cloc     # Windows with winget (might not work, ref https://github.com/AlDanial/cloc/issues/849)\n    choco install cloc               # Windows with Chocolatey\n    scoop install cloc               # Windows with Scoop\n\n**Note**: I don't control any of these packages.\nIf you encounter a bug in cloc using one of the above\npackages, try with cloc pulled from the latest stable release here\non GitHub (link follows below) before submitting a problem report.\n\n## Run via docker\n\nThese docker commands count lines of code in and below\nthe current directory:\n\n```shell\ndocker run --rm -v $PWD:/tmp aldanial/cloc .\n```\n\n### Run via docker on git-bash\n```shell\ndocker run --rm -v \"/$(pwd -W)\":/tmp aldanial/cloc .\n```\n\n## Development version\n\nDownload the cloc source code at https://github.com/AlDanial/cloc/raw/master/cloc and\nsave it as the file `cloc` (or `cloc.pl`, or whatever executable name you wish).\nThe next step depends on the operating system you're using.\n\n# License\n\ncloc is licensed under the\n[GNU General Public License, v 2](http://www.gnu.org/licenses/gpl-2.0.html),\nexcluding portions which\nare copied from other sources. Code\ncopied from the Regexp::Common, Win32::Autoglob, and Algorithm::Diff\nPerl modules is subject to the\n[Artistic License](https://opensource.org/license/artistic-2-0).\n\n# Why Use cloc?\n\ncloc has many features that make it easy to use, thorough, extensible, and portable:\n\n1.  Exists as a single, self-contained file that requires minimal installation effort---just download the file and run it.\n2.  Can read language comment definitions from a file and thus potentially work with computer languages that do not yet exist.\n3.  Allows results from multiple runs to be summed together by language and by project.\n4.  Can produce results in a variety of formats: plain text, Markdown, SQL, JSON, XML, YAML, comma separated values.\n5.  Can count code within compressed archives (tar balls, Zip files, Java .ear files).\n6.  Has numerous troubleshooting options.\n7.  Handles file and directory names with spaces and other unusual characters.\n8.  Has no dependencies outside the standard Perl distribution.\n9.  Runs on Linux, FreeBSD, NetBSD, OpenBSD, macOS, AIX, HP-UX, Solaris, IRIX, and z/OS systems that have Perl 5.6 or higher. The source version runs on Windows with either ActiveState Perl, Strawberry Perl, Cygwin, or MobaXTerm+Perl plugin. Alternatively on Windows one can run the Windows binary which has no dependencies.\n\n# Other Counters\n\nIf cloc does not suit your needs here are other freely available counters to consider:\n\n*   [loc](https://github.com/cgag/loc/)\n*   [gcloc](https://github.com/JoaoDanielRufino/gcloc)\n*   [gocloc](https://github.com/hhatto/gocloc/)\n*   [Ohcount](https://github.com/blackducksoftware/ohcount/)\n*   [scc](https://github.com/boyter/scc/)\n*   [sclc](https://code.google.com/archive/p/sclc/)\n*   [SLOCCount](http://www.dwheeler.com/sloccount/)\n*   [Sonar](http://www.sonarsource.org/)\n*   [tokei](https://github.com/Aaronepower/tokei/)\n*   [Unified Code Count](http://csse.usc.edu/ucc_new/wordpress/)\n\nOther references:\n\n*   QSM's [directory](http://www.qsm.com/CodeCounters.html) of code counting tools.\n*   The [Wikipedia entry](http://en.wikipedia.org/wiki/Source_lines_of_code) for source code line counts.\n\n# Regexp::Common, Digest::MD5, Win32::Autoglob, Algorithm::Diff\n\nAlthough cloc does not need Perl modules outside those found in the\nstandard distribution, cloc does rely on a few external modules. Code\nfrom three of these external modules--Regexp::Common, Win32::Autoglob,\nand Algorithm::Diff--is embedded within cloc. A fourth module,\nDigest::MD5, is used only if it is available. If cloc finds\nRegexp::Common or Algorithm::Diff installed locally it will use those\ninstallation. If it doesn't, cloc will install the parts of\nRegexp::Common and/or Algorithm:Diff it needs to temporary directories\nthat are created at the start of a cloc run then removed when the run is\ncomplete. The necessary code from Regexp::Common v2.120 and\nAlgorithm::Diff v1.1902 are embedded within the cloc source code (see\nsubroutines `Install_Regexp_Common()` and `Install_Algorithm_Diff()` ).\nOnly three lines are needed from Win32::Autoglob and these are included\ndirectly in cloc.\n\nAdditionally, cloc will use Digest::MD5 to validate uniqueness among\nequally-sized input files if Digest::MD5 is installed locally.\n\nA parallel processing option, `--processes=*N*`, was introduced with\ncloc version 1.76 to enable faster runs on multi-core machines.  However,\nto use it, one must have the module Parallel::ForkManager installed.\nThis module does not work reliably on Windows so parallel processing\nwill only work on Unix-like operating systems.\n\nThe Windows binary is built on a computer that has both Regexp::Common\nand Digest::MD5 installed locally.\n\n# Building a Windows Executable\n\n#### Create your own executable\nThe most robust option for creating a Windows executable of\ncloc is to use [ActiveState's Perl Development Kit](http://www.activestate.com/perl-dev-kit).\nIt includes a utility, `perlapp`, which can build stand-alone\nWindows, Mac, and Linux binaries of Perl source code.\n\n[perl2exe](http://www.indigostar.com/perl2exe/)\nwill also do the trick.  If you do have `perl2exe`, modify lines\n84-87 in the cloc source code for a minor code\nmodification that is necessary to make a cloc Windows executable.\n\nOtherwise, to build a Windows executable with `pp` from\n`PAR::Packer`, first install a Windows-based Perl distribution\n(for example Strawberry Perl or ActivePerl) following their\ninstructions. Next, open a command prompt, aka a DOS window and install\nthe PAR::Packer module. Finally, invoke the newly installed `pp`\ncommand with the cloc source code to create an `.exe` file:\n\n```\nC:> cpan -i Digest::MD5\nC:> cpan -i Regexp::Common\nC:> cpan -i Algorithm::Diff\nC:> cpan -i PAR::Packer\nC:> cpan -i Win32::LongPath\nC:> pp -M Win32::LongPath -M Encode::Unicode -M Digest::MD5 -c -x -o cloc-2.08.exe cloc-2.08.pl\n```\n\nA variation on the instructions above is if you installed the portable\nversion of Strawberry Perl, you will need to run `portableshell.bat` first\nto properly set up your environment.\n\nThe Windows executable in the Releases section, `cloc-2.08.exe`,\nwas built on a 64 bit Windows 11 computer using\n[Strawberry Perl](http://strawberryperl.com/)\n5.32.1 and\n[PAR::Packer](http://search.cpan.org/~rschupp/PAR-Packer-1.064/lib/pp.pm)\nto build the `.exe`.\n\n#### Is the Windows executable safe to run?  Does it have malware?\n\nIdeally, no one would need the Windows executable because they\nhave a Perl interpreter installed on their machines and can\nrun the cloc source file.\nOn centrally-managed corporate Windows machines, however, this\nthis may be difficult or impossible.\n\nThe Windows executable distributed with cloc is provided as\na best-effort of a virus and malware-free `.exe`.\nYou are encouraged to run your own virus scanners against the\nexecutable and also check sites such\nhttps://www.virustotal.com/ .\nThe entries for recent versions are:\n\ncloc-2.08.exe:\nhttps://www.virustotal.com/gui/file/4529557d957ade0dd45746eae10e9c51ee01061bb617eeeab256672faf6e42c6?nocache=1\n\ncloc-2.06.exe:\nhttps://www.virustotal.com/gui/file/bbe48de9102d0f2520d292d65897001c1d068340eb7cd74dd1ee30c1a9091c4a?nocache=1\n\ncloc-2.04.exe:\nhttps://www.virustotal.com/gui/file/89cda0038bf4e13c6c13ebc1e60bec4dfad362e69ac8a5b8e2d5ebe3020359e1\n\ncloc-2.02-winget.exe:  (includes [PR 850](https://github.com/AlDanial/cloc/pull/850) to allow\n[running from a symlink on Windows](https://github.com/AlDanial/cloc/issues/849))\nhttps://www.virustotal.com/gui/file/be033061e091fea48a5bc9e8964cee0416ddd5b34bd5226a1c9aa4b30bdba66a?nocache=1\n\ncloc-2.02.exe:\nhttps://www.virustotal.com/gui/file/369ed76125f7399cd582d169adf39a2e08ae5066031fea0cc8b2836ea50e7ce2?nocache=1\n\ncloc-2.00.exe:\nhttps://www.virustotal.com/gui/file/7a234ef0cb495de1b5776acf88c5554e2bab1fb02725a5fb85756a6db3121c1f\n\n#### Why is the Windows executable so large?\n\nWindows executables of cloc versions 1.60 and earlier, created with\nperl2exe as noted above, are about 1.6 MB, while versions 1.62 and 1.54, created\nwith `PAR::Packer`, are 11 MB.\nVersion 1.66, built with a newer version of `PAR::Packer`, is about 5.5 MB.\nWhy are the `PAR::Packer`, executables so\nmuch larger than those built with perl2exe? My theory is that perl2exe\nuses smarter tree pruning logic\nthan `PAR::Packer`, but that's pure speculation.\n\n# Basic Use\n\ncloc is a command line program that takes file, directory, and/or\narchive names as inputs. Here's an example of running cloc against the\nPerl v5.22.0 source distribution:\n\n```\nprompt> cloc perl-5.22.0.tar.gz\n    5605 text files.\n    5386 unique files.\n    2176 files ignored.\n\nhttps://github.com/AlDanial/cloc v 1.65  T=25.49 s (134.7 files/s, 51980.3 lines/s)\n-----------------------------------------------------------------------------------\nLanguage                         files          blank        comment           code\n-----------------------------------------------------------------------------------\nPerl                              2892         136396         184362         536445\nC                                  130          24676          33684         155648\nC/C++ Header                       148           9766          16569         147858\nBourne Shell                       112           4044           6796          42668\nPascal                               8            458           1603           8592\nXML                                 33            142              0           2410\nYAML                                49             20             15           2078\nC++                                 10            313            277           2033\nmake                                 4            426            488           1986\nProlog                              12            438              2           1146\nJSON                                14              1              0           1037\nyacc                                 1             85             76            998\nWindows Message File                 1            102             11            489\nDOS Batch                           14             92             41            389\nWindows Resource File                3             10              0             85\nD                                    1              5              7              8\nLisp                                 2              0              3              4\n-----------------------------------------------------------------------------------\nSUM:                              3434         176974         243934         903874\n-----------------------------------------------------------------------------------\n\n```\n\nTo run cloc on Windows computers, open up a command (aka DOS) window\nand invoke cloc.exe from the command line there.\nAlternatively, try ClocViewer, the GUI wrapper around cloc found at\nhttps://github.com/Roemer/ClocViewer.\n\nSee also https://github.com/jmensch1/codeflower for a\ngraphical rendering of cloc results.\n\n# GUI Frontends\n\nSeveral GUI frontends to cloc are available:\n\n* [cloctui](https://github.com/edward-jazzhands/cloctui)\n* [ClocViewer](https://github.com/Roemer/ClocViewer)\n* [codeflower](https://github.com/jmensch1/codeflower)\n\n# Options\n\n<details>\n<summary>Full options list (<code>cloc --help</code>) (click the triangle to see all option)</summary>\n\n```\nprompt> cloc --help\n\nUsage: cloc [options] <file(s)/dir(s)/git hash(es)> | <set 1> <set 2> | <report files>\n\n Count, or compute differences of, physical lines of source code in the\n given files (may be archives such as compressed tarballs or zip files,\n or git commit hashes or branch names) and/or recursively below the\n given directories.\n\n Input Options\n   --extract-with=<cmd>      This option is only needed if cloc is unable\n                             to figure out how to extract the contents of\n                             the input file(s) by itself.\n                             Use <cmd> to extract binary archive files (e.g.:\n                             .tar.gz, .zip, .Z).  Use the literal '>FILE<' as\n                             a stand-in for the actual file(s) to be\n                             extracted.  For example, to count lines of code\n                             in the input files\n                                gcc-4.2.tar.gz  perl-5.8.8.tar.gz\n                             on Unix use\n                               --extract-with='gzip -dc >FILE< | tar xf -'\n                             or, if you have GNU tar,\n                               --extract-with='tar zxf >FILE<'\n                             and on Windows use, for example:\n                               --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE< .\"\n                             (if WinZip is installed there).\n   --list-file=<file>        Take the list of file and/or directory names to\n                             process from <file>, which has one file/directory\n                             name per line.  Only exact matches are counted;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.  Set <file>\n                             to - to read file names from a STDIN pipe.\n                             See also --exclude-list-file.\n   --diff-list-file=<file>   Take the pairs of file names to be diff'ed from\n                             <file>, whose format matches the output of\n                             --diff-alignment.  (Run with that option to\n                             see a sample.)  The language identifier at the\n                             end of each line is ignored.  This enables --diff\n                             mode and bypasses file pair alignment logic.\n   --vcs=<VCS>               Invoke a system call to <VCS> to obtain a list of\n                             files to work on.  If <VCS> is 'git', then will\n                             invoke 'git ls-files' to get a file list and\n                             'git submodule status' to get a list of submodules\n                             whose contents will be ignored.  See also --git\n                             which accepts git commit hashes and branch names.\n                             If <VCS> is 'svn' then will invoke 'svn list -R'.\n                             The primary benefit is that cloc will then skip\n                             files explicitly excluded by the versioning tool\n                             in question, ie, those in .gitignore or have the\n                             svn:ignore property.\n                             Alternatively <VCS> may be any system command\n                             that generates a list of files.\n                             Note:  cloc must be in a directory which can read\n                             the files as they are returned by <VCS>.  cloc will\n                             not download files from remote repositories.\n                             'svn list -R' may refer to a remote repository\n                             to obtain file names (and therefore may require\n                             authentication to the remote repository), but\n                             the files themselves must be local.\n                             Setting <VCS> to 'auto' selects between 'git'\n                             and 'svn' (or neither) depending on the presence\n                             of a .git or .svn subdirectory below the directory\n                             where cloc is invoked.  --files-from is a synonym\n                             for --vcs.\n   --unicode                 Check binary files to see if they contain Unicode\n                             expanded ASCII text.  This causes performance to\n                             drop noticeably.\n\n Processing Options\n   --autoconf                Count .in files (as processed by GNU autoconf) of\n                             recognized languages.  See also --no-autogen.\n   --by-file                 Report results for every source file encountered.\n   --by-file-by-lang         Report results for every source file encountered\n                             in addition to reporting by language.\n   --config <file>           Read command line switches from <file> instead of\n                             the default location of /home/al/.config/cloc/options.txt.\n                             The file should contain one switch, along with\n                             arguments (if any), per line.  Blank lines and lines\n                             beginning with '#' are skipped.  Options given on\n                             the command line take priority over entries read from\n                             the file.\n   --count-and-diff <set1> <set2>\n                             First perform direct code counts of source file(s)\n                             of <set1> and <set2> separately, then perform a diff\n                             of these.  Inputs may be pairs of files, directories,\n                             or archives.  If --out or --report-file is given,\n                             three output files will be created, one for each\n                             of the two counts and one for the diff.  See also\n                             --diff, --diff-alignment, --diff-timeout,\n                             --ignore-case, --ignore-whitespace.\n   --diff <set1> <set2>      Compute differences in code and comments between\n                             source file(s) of <set1> and <set2>.  The inputs\n                             may be any mix of files, directories, archives,\n                             or git commit hashes.  Use --diff-alignment to\n                             generate a list showing which file pairs where\n                             compared.  When comparing git branches, only files\n                             which have changed in either commit are compared.\n                             See also --git, --count-and-diff, --diff-alignment,\n                             --diff-list-file, --diff-timeout, --ignore-case,\n                             --ignore-whitespace.\n   --diff-timeout <N>        Ignore files which take more than <N> seconds\n                             to process.  Default is 10 seconds.  Setting <N>\n                             to 0 allows unlimited time.  (Large files with many\n                             repeated lines can cause Algorithm::Diff::sdiff()\n                             to take hours.) See also --timeout.\n   --docstring-as-code       cloc considers docstrings to be comments, but this is\n                             not always correct as docstrings represent regular\n                             strings when they appear on the right hand side of an\n                             assignment or as function arguments.  This switch\n                             forces docstrings to be counted as code.\n   --follow-links            [Unix only] Follow symbolic links to directories\n                             (sym links to files are always followed).\n                             See also --stat.\n   --force-lang=<lang>[,<ext>]\n                             Process all files that have a <ext> extension\n                             with the counter for language <lang>.  For\n                             example, to count all .f files with the\n                             Fortran 90 counter (which expects files to\n                             end with .f90) instead of the default Fortran 77\n                             counter, use\n                               --force-lang=\"Fortran 90,f\"\n                             If <ext> is omitted, every file will be counted\n                             with the <lang> counter.  This option can be\n                             specified multiple times (but that is only\n                             useful when <ext> is given each time).\n                             See also --script-lang, --lang-no-ext.\n   --force-lang-def=<file>   Load language processing filters from <file>,\n                             then use these filters instead of the built-in\n                             filters.  Note:  languages which map to the same\n                             file extension (for example:\n                             MATLAB/Mathematica/Objective-C/MUMPS/Mercury;\n                             Pascal/PHP; Lisp/OpenCL; Lisp/Julia; Perl/Prolog)\n                             will be ignored as these require additional\n                             processing that is not expressed in language\n                             definition files.  Use --read-lang-def to define\n                             new language filters without replacing built-in\n                             filters (see also --write-lang-def,\n                             --write-lang-def-incl-dup).\n   --git                     Forces the inputs to be interpreted as git targets\n                             (commit hashes, branch names, et cetera) if these\n                             are not first identified as file or directory\n                             names.  This option overrides the --vcs=git logic\n                             if this is given; in other words, --git gets its\n                             list of files to work on directly from git using\n                             the hash or branch name rather than from\n                             'git ls-files'.  This option can be used with\n                             --diff to perform line count diffs between git\n                             commits, or between a git commit and a file,\n                             directory, or archive.  Use -v/--verbose to see\n                             the git system commands cloc issues.\n   --git-diff-rel            Same as --git --diff, or just --diff if the inputs\n                             are recognized as git targets.  Only files which\n                             have changed in either commit are compared.\n   --git-diff-all            Git diff strategy #2:  compare all files in the\n                             repository between the two commits.\n   --ignore-whitespace       Ignore horizontal white space when comparing files\n                             with --diff.  See also --ignore-case.\n   --ignore-case             Ignore changes in case within file contents;\n                             consider upper- and lowercase letters equivalent\n                             when comparing files with --diff.  See also\n                             --ignore-whitespace.\n   --ignore-case-ext         Ignore case of file name extensions.  This will\n                             cause problems counting some languages\n                             (specifically, .c and .C are associated with C and\n                             C++; this switch would count .C files as C rather\n                             than C++ on *nix operating systems).  File name\n                             case insensitivity is always true on Windows.\n   --lang-no-ext=<lang>      Count files without extensions using the <lang>\n                             counter.  This option overrides internal logic\n                             for files without extensions (where such files\n                             are checked against known scripting languages\n                             by examining the first line for #!).  See also\n                             --force-lang, --script-lang.\n   --max-file-size=<MB>      Skip files larger than <MB> megabytes when\n                             traversing directories.  By default, <MB>=100.\n                             cloc's memory requirement is roughly twenty times\n                             larger than the largest file so running with\n                             files larger than 100 MB on a computer with less\n                             than 2 GB of memory will cause problems.\n                             Note:  this check does not apply to files\n                             explicitly passed as command line arguments.\n   --no-autogen[=list]       Ignore files generated by code-production systems\n                             such as GNU autoconf.  To see a list of these files\n                             (then exit), run with --no-autogen list\n                             See also --autoconf.\n   --original-dir            [Only effective in combination with\n                             --strip-comments]  Write the stripped files\n                             to the same directory as the original files.\n   --read-binary-files       Process binary files in addition to text files.\n                             This is usually a bad idea and should only be\n                             attempted with text files that have embedded\n                             binary data.\n   --read-lang-def=<file>    Load new language processing filters from <file>\n                             and merge them with those already known to cloc.\n                             If <file> defines a language cloc already knows\n                             about, cloc's definition will take precedence.\n                             Use --force-lang-def to over-ride cloc's\n                             definitions (see also --write-lang-def,\n                             --write-lang-def-incl-dup).\n   --script-lang=<lang>,<s>  Process all files that invoke <s> as a #!\n                             scripting language with the counter for language\n                             <lang>.  For example, files that begin with\n                                #!/usr/local/bin/perl5.8.8\n                             will be counted with the Perl counter by using\n                                --script-lang=Perl,perl5.8.8\n                             The language name is case insensitive but the\n                             name of the script language executable, <s>,\n                             must have the right case.  This option can be\n                             specified multiple times.  See also --force-lang,\n                             --lang-no-ext.\n   --sdir=<dir>              Use <dir> as the scratch directory instead of\n                             letting File::Temp chose the location.  Files\n                             written to this location are not removed at\n                             the end of the run (as they are with File::Temp).\n   --skip-uniqueness         Skip the file uniqueness check.  This will give\n                             a performance boost at the expense of counting\n                             files with identical contents multiple times\n                             (if such duplicates exist).\n   --stat                    Some file systems (AFS, CD-ROM, FAT, HPFS, SMB)\n                             do not have directory 'nlink' counts that match\n                             the number of its subdirectories.  Consequently\n                             cloc may undercount or completely skip the\n                             contents of such file systems.  This switch forces\n                             File::Find to stat directories to obtain the\n                             correct count.  File search speed will decrease.\n                             See also --follow-links.\n   --stdin-name=<file>       Give a file name to use to determine the language\n                             for standard input.  (Use - as the input name to\n                             receive source code via STDIN.)\n   --strip-comments=<ext>    For each file processed, write to the current\n                             directory a version of the file which has blank\n                             and commented lines removed (in-line comments\n                             persist).  The name of each stripped file is the\n                             original file name with .<ext> appended to it.\n                             It is written to the current directory unless\n                             --original-dir is on.\n   --strip-str-comments      Replace comment markers embedded in strings with\n                             'xx'.  This attempts to work around a limitation\n                             in Regexp::Common::Comment where comment markers\n                             embedded in strings are seen as actual comment\n                             markers and not strings, often resulting in a\n                             'Complex regular subexpression recursion limit'\n                             warning and incorrect counts.  There are two\n                             disadvantages to using this switch:  1/code count\n                             performance drops, and 2/code generated with\n                             --strip-comments will contain different strings\n                             where ever embedded comments are found.\n   --sum-reports             Input arguments are report files previously\n                             created with the --report-file option in plain\n                             format (eg. not JSON, YAML, XML, or SQL).\n                             Makes a cumulative set of results containing the\n                             sum of data from the individual report files.\n   --timeout <N>             Ignore files which take more than <N> seconds\n                             to process at any of the language's filter stages.\n                             The default maximum number of seconds spent on a\n                             filter stage is the number of lines in the file\n                             divided by one thousand.  Setting <N> to 0 allows\n                             unlimited time.  See also --diff-timeout.\n   --processes=NUM           [Available only on systems with a recent version\n                             of the Parallel::ForkManager module.  Not\n                             available on Windows.] Sets the maximum number of\n                             cores that cloc uses.  The default value of 0\n                             disables multiprocessing.\n   --unix                    Override the operating system autodetection\n                             logic and run in UNIX mode.  See also\n                             --windows, --show-os.\n   --use-sloccount           If SLOCCount is installed, use its compiled\n                             executables c_count, java_count, pascal_count,\n                             php_count, and xml_count instead of cloc's\n                             counters.  SLOCCount's compiled counters are\n                             substantially faster than cloc's and may give\n                             a performance improvement when counting projects\n                             with large files.  However, these cloc-specific\n                             features will not be available: --diff,\n                             --count-and-diff, --strip-comments, --unicode.\n   --windows                 Override the operating system autodetection\n                             logic and run in Microsoft Windows mode.\n                             See also --unix, --show-os.\n\n Filter Options\n   --include-content=<regex> Only count files containing text that matches the\n                             given regular expression.\n   --exclude-content=<regex> Exclude files containing text that matches the given\n                             regular expression.\n   --exclude-dir=<D1>[,D2,]  Exclude the given comma separated directories\n                             D1, D2, D3, et cetera, from being scanned.  For\n                             example  --exclude-dir=.cache,test  will skip\n                             all files and subdirectories that have /.cache/\n                             or /test/ as their parent directory.\n                             Directories named .bzr, .cvs, .hg, .git, .svn,\n                             and .snapshot are always excluded.\n                             This option only works with individual directory\n                             names so including file path separators is not\n                             allowed.  Use --fullpath and --not-match-d=<regex>\n                             to supply a regex matching multiple subdirectories.\n   --exclude-ext=<ext1>[,<ext2>[...]]\n                             Do not count files having the given file name\n                             extensions.\n   --exclude-lang=<L1>[,L2[...]]\n                             Exclude the given comma separated languages\n                             L1, L2, L3, et cetera, from being counted.\n   --exclude-list-file=<file>  Ignore files and/or directories whose names\n                             appear in <file>.  <file> should have one file\n                             name per line.  Only exact matches are ignored;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.\n                             See also --list-file.\n   --fullpath                Modifies the behavior of --match-f, --not-match-f,\n                             and --not-match-d to include the file's path\n                             in the regex, not just the file's basename.\n                             (This does not expand each file to include its\n                             absolute path, instead it uses as much of\n                             the path as is passed in to cloc.)\n                             Note:  --match-d always looks at the full\n                             path and therefore is unaffected by --fullpath.\n   --include-ext=<ext1>[,ext2[...]]\n                             Count only languages having the given comma\n                             separated file extensions.  Use --show-ext to\n                             see the recognized extensions.\n   --include-lang=<L1>[,L2[...]]\n                             Count only the given comma separated languages\n                             L1, L2, L3, et cetera.  Use --show-lang to see\n                             the list of recognized languages.\n   --match-d=<regex>         Only count files in directories matching the Perl\n                             regex.  For example\n                               --match-d='/(src|include)/'\n                             only counts files in directories containing\n                             /src/ or /include/.  Unlike --not-match-d,\n                             --match-f, and --not-match-f, --match-d always\n                             compares the fully qualified path against the\n                             regex.\n   --not-match-d=<regex>     Count all files except those in directories\n                             matching the Perl regex.  Only the trailing\n                             directory name is compared, for example, when\n                             counting in /usr/local/lib, only 'lib' is\n                             compared to the regex.\n                             Add --fullpath to compare parent directories to\n                             the regex.\n                             Do not include file path separators at the\n                             beginning or end of the regex.\n   --match-f=<regex>         Only count files whose basenames match the Perl\n                             regex.  For example\n                               --match-f='^[Ww]idget'\n                             only counts files that start with Widget or widget.\n                             Add --fullpath to include parent directories\n                             in the regex instead of just the basename.\n   --not-match-f=<regex>     Count all files except those whose basenames\n                             match the Perl regex.  Add --fullpath to include\n                             parent directories in the regex instead of just\n                             the basename.\n   --skip-archive=<regex>    Ignore files that end with the given Perl regular\n                             expression.  For example, if given\n                               --skip-archive='(zip|tar(.(gz|Z|bz2|xz|7z))?)'\n                             the code will skip files that end with .zip,\n                             .tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and\n                             .tar.7z.\n   --skip-win-hidden         On Windows, ignore hidden files.\n\n Debug Options\n   --categorized=<file>      Save file sizes in bytes, identified languages\n                             and names of categorized files to <file>.\n   --counted=<file>          Save names of processed source files to <file>.\n   --diff-alignment=<file>   Write to <file> a list of files and file pairs\n                             showing which files were added, removed, and/or\n                             compared during a run with --diff.  This switch\n                             forces the --diff mode on.\n   --explain=<lang>          Print the filters used to remove comments for\n                             language <lang> and exit.  In some cases the\n                             filters refer to Perl subroutines rather than\n                             regular expressions.  An examination of the\n                             source code may be needed for further explanation.\n   --help                    Print this usage information and exit.\n   --found=<file>            Save names of every file found to <file>.\n   --ignored=<file>          Save names of ignored files and the reason they\n                             were ignored to <file>.\n   --print-filter-stages     Print processed source code before and after\n                             each filter is applied.\n   --show-ext[=<ext>]        Print information about all known (or just the\n                             given) file extensions and exit.\n   --show-lang[=<lang>]      Print information about all known (or just the\n                             given) languages and exit.\n   --show-os                 Print the value of the operating system mode\n                             and exit.  See also --unix, --windows.\n   -v[=<n>]                  Verbose switch (optional numeric value).\n   -verbose[=<n>]            Long form of -v.\n   --version                 Print the version of this program and exit.\n   --write-lang-def=<file>   Writes to <file> the language processing filters\n                             then exits.  Useful as a first step to creating\n                             custom language definitions. Note: languages which\n                             map to the same file extension will be excluded.\n                             (See also --force-lang-def, --read-lang-def).\n   --write-lang-def-incl-dup=<file>\n                             Same as --write-lang-def, but includes duplicated\n                             extensions.  This generates a problematic language\n                             definition file because cloc will refuse to use\n                             it until duplicates are removed.\n\n Output Options\n   --3                       Print third-generation language output.\n                             (This option can cause report summation to fail\n                             if some reports were produced with this option\n                             while others were produced without it.)\n   --by-percent  X           Instead of comment and blank line counts, show\n                             these values as percentages based on the value\n                             of X in the denominator:\n                                X = 'c'   -> # lines of code\n                                X = 'cm'  -> # lines of code + comments\n                                X = 'cb'  -> # lines of code + blanks\n                                X = 'cmb' -> # lines of code + comments + blanks\n                             For example, if using method 'c' and your code\n                             has twice as many lines of comments as lines\n                             of code, the value in the comment column will\n                             be 200%.  The code column remains a line count.\n   --csv                     Write the results as comma separated values.\n   --csv-delimiter=<C>       Use the character <C> as the delimiter for comma\n                             separated files instead of ,.  This switch forces --csv to be on.\n   --file-encoding=<E>       Write output files using the <E> encoding instead of\n                             the default ASCII (<E> = 'UTF-7').  Examples: 'UTF-16',\n                             'euc-kr', 'iso-8859-16'.  Known encodings can be\n                             printed with\n                               perl -MEncode -e 'print join(\"\\n\", Encode->encodings(\":all\")), \"\\n\"'\n   --hide-rate               Do not show line and file processing rates in the\n                             output header. This makes output deterministic.\n   --json                    Write the results as JavaScript Object Notation\n                             (JSON) formatted output.\n   --md                      Write the results as Markdown-formatted text.\n   --out=<file>              Synonym for --report-file=<file>.\n   --percent                 Show counts as percentages of sums for each column.\n                             Same as '--by-percent t'.\n   --progress-rate=<n>       Show progress update after every <n> files are\n                             processed (default <n>=100).  Set <n> to 0 to\n                             suppress progress output (useful when redirecting\n                             output to STDOUT).\n   --quiet                   Suppress all information messages except for\n                             the final report.\n   --report-file=<file>      Write the results to <file> instead of STDOUT.\n   --sql=<file>              Write results as SQL create and insert statements\n                             which can be read by a database program such as\n                             SQLite.  If <file> is -, output is sent to STDOUT.\n   --sql-append              Append SQL insert statements to the file specified\n                             by --sql and do not generate table creation\n                             statements.  Only valid with the --sql option.\n   --sql-project=<name>      Use <name> as the project identifier for the\n                             current run.  Only valid with the --sql option.\n   --sql-style=<style>       Write SQL statements in the given style instead\n                             of the default SQLite format.  Styles include\n                             'Oracle' and 'Named_Columns'.\n   --sum-one                 For plain text reports, show the SUM: output line\n                             even if only one input file is processed.\n   --thousands-delimiter=<C> Divides numbers with many digits (i.e. numbers\n                             over 999) into groups using the character <C> as\n                             delimiter (e.g. for <C> = '.': 12345 -> 12.345).\n                             Only works with the '--fmt' option.\n                             Sample values: '.', ',', '_', ' '\n                             Synonym:  --ksep\n   --xml                     Write the results in XML.\n   --xsl=<file>              Reference <file> as an XSL stylesheet within\n                             the XML output.  If <file> is 1 (numeric one),\n                             writes a default stylesheet, cloc.xsl (or\n                             cloc-diff.xsl if --diff is also given).\n                             This switch forces --xml on.\n   --yaml                    Write the results in YAML.\n```\n\n</details>\n\n# Recognized Languages\n\n<details>\n<summary>Full language list (<code>cloc --show-lang</code>) (click the triangle to see all languages)</summary>\n\n```\nprompt> cloc --show-lang\n\nLanguage                   Extension(s)\n--------------------       ----------------------------------------\nABAP                       (abap)\nActionScript               (as)\nActiviti Business Process  (bpmn)\nAda                        (ada, adb, ads, pad)\nADSO/IDSM                  (adso)\nAgda                       (agda, lagda)\nAMPLE                      (ample, dofile, startup)\nAnsProlog                  (lp)\nAnt                        (build.xml, build.xml)\nANTLR Grammar              (g, g4)\nApex Class                 (cls)\nApex Trigger               (trigger)\nAPL                        (apl, apla, aplc, aplf, apli, apln, aplo, dyalog, dyapp, mipage)\nAppleScript                (applescript)\nArduino Sketch             (ino)\nAria                       (aria)\nArkTs                      (ets)\nArturo                     (art)\nAsciiDoc                   (adoc, asciidoc)\nASP                        (asa, ashx, asp, axd)\nASP.NET                    (asax, ascx, asmx, aspx, master, sitemap, webinfo)\nAspectJ                    (aj)\nAssembly                   (a51, asm, nasm, S, s)\nAstro                      (astro)\nAsymptote                  (asy)\nAutoHotkey                 (ahk, ahkl)\nawk                        (auk, awk, gawk, mawk, nawk)\nAXAML                      (axaml)\nBazel                      (BUILD)\nBeluga                     (bel)\nBicep                      (bicep, bicepparam)\nBitBake                    (bb, bbappend, bbclass)\nBizTalk Orchestration      (odx)\nBizTalk Pipeline           (btp)\nBlade                      (blade, blade.php)\nBlueprint                  (blp)\nBourne Again Shell         (bash)\nBourne Shell               (sh)\nBrightScript               (brs)\nbuilder                    (xml.builder)\nC                          (c, cats, ec, idc, pgc)\nC Shell                    (csh, tcsh)\nC#                         (cs)\nC# Designer                (designer.cs)\nC++                        (C, c++, c++m, cc, ccm, CPP, cpp, cppm, cxx, cxxm, h++, inl, ipp,\n                            ixx, pcc, tcc, tpp)\nC/C++ Header               (H, h, hh, hpp, hxx)\nCadence                    (cdc)\nCairo                      (cairo)\nCake Build Script          (cake)\nCangjie                    (cj)\nCarbon                     (carbon)\nCCS                        (ccs)\nChapel                     (chpl)\nCircom                     (circom)\nCivet                      (civet, cvt, cvtx)\nClarity                    (clar)\nClean                      (dcl, icl)\nClojure                    (boot, cl2, clj, cljs.hl, cljscm, cljx, hic, riemann.config, cj)\nClojureC                   (cljc)\nClojureScript              (cljs)\nCMake                      (cmake, cmake.in, CMakeLists.txt)\nCOBOL                      (CBL, cbl, ccp, COB, cob, cobol, cpy)\nCoCoA 5                    (c5, cocoa5, cocoa5server, cpkg5)\nCodeQL                     (ql, qll)\nCoffeeScript               (_coffee, cakefile, cjsx, coffee, iced)\nColdFusion                 (cfm, cfml)\nColdFusion CFScript        (cfc)\nConstraint Grammar         (cg3, rlx)\nContainerfile              (Containerfile)\nCoq                        (v)\nCrystal                    (cr)\nCSON                       (cson)\nCSS                        (css)\nCSV                        (csv)\nCucumber                   (feature)\nCUDA                       (cu, cuh)\nCython                     (pxd, pxi, pyx)\nD                          (d)\nDafny                      (dfy)\nDAL                        (da)\nDart                       (dart)\nDelphi Form                (dfm)\nDenizenScript              (dsc)\nDerw                       (derw)\ndhall                      (dhall)\nDIET                       (dt)\ndiff                       (diff, patch)\nDITA                       (dita)\nDockerfile                 (Dockerfile, dockerfile)\nDOORS Extension Language   (dxl)\nDOS Batch                  (BAT, bat, BTM, btm, CMD, cmd)\nDrools                     (drl)\nDTD                        (dtd)\ndtrace                     (d)\nECPP                       (ecpp)\nEEx                        (eex)\nEJS                        (ejs)\nElixir                     (ex)\nElixir Script              (exs)\nElm                        (elm)\nEmbedded Crystal           (ecr)\nERB                        (ERB, erb)\nErlang                     (app.src, emakefile, erl, hrl, rebar.config, rebar.config.lock,\n                            rebar.lock, xrl, yrl)\nExpect                     (exp)\nF#                         (fsi, fs, fs)\nF# Script                  (fsx)\nFennel                     (fnl)\nFinite State Language      (fsl, jssm)\nFish Shell                 (fish)\nFlatbuffers                (fbs)\nFocus                      (focexec)\nForth                      (4th, e4, f83, fb, forth, fpm, fr, frt, ft, fth, rx, fs, f, for)\nFortran 2003               (F03, f03)\nFortran 77                 (F, F77, f77, FOR, FTN, ftn, pfo, f, for)\nFortran 90                 (F90, f90)\nFortran 95                 (F95, f95)\nFreemarker Template        (ftl)\nFuthark                    (fut)\nFXML                       (fxml)\nGDScript                   (gd)\nGencat NLS                 (msg)\nGlade                      (glade, ui)\nGleam                      (gleam)\nGlimmer JavaScript         (gjs)\nGlimmer TypeScript         (gts)\nGLSL                       (comp, fp, frag, frg, fsh, fshader, geo, geom, glsl, glslv, gshader,\n                            tesc, tese, vert, vrx, vsh, vshader)\nGo                         (go, ʕ◔ϖ◔ʔ)\nGodot Resource             (tres)\nGodot Scene                (tscn)\nGodot Shaders              (gdshader)\nGradle                     (gradle, gradle.kts)\nGrails                     (gsp)\nGraphQL                    (gql, graphql, graphqls)\nGroovy                     (gant, groovy, grt, gtpl, gvy, jenkinsfile)\nHaml                       (haml, haml.deface)\nHandlebars                 (handlebars, hbs)\nHarbour                    (hb)\nHare                       (ha)\nHaskell                    (hs, hsc, lhs)\nHaskell Boot               (hs-boot, lhs-boot)\nHaxe                       (hx, hxsl)\nHCL                        (hcl, nomad, tf, tfvars)\nHibernate                  (hbm.xml)\nHLSL                       (cg, cginc, fxh, hlsl, hlsli, shader)\nHolyC                      (HC)\nHoon                       (hoon)\nHTML                       (htm, html, html.hl, xht)\nHTML EEx                   (heex)\nIDL                        (dlm, idl, pro)\nIdris                      (idr)\nIgor Pro                   (ipf)\nImba                       (imba)\nINI                        (buildozer.spec, editorconfig, ini, lektorproject, prefs)\nInstallShield              (ism)\nIPL                        (ipl)\nJai                        (jai)\nJanet                      (janet)\nJasper Report XML/Template (jrxml)\nJava                       (java)\nJavaScript                 (_js, bones, cjs, es6, jake, jakefile, js, jsb, jscad, jsfl, jsm,\n                            jss, mjs, njs, pac, sjs, ssjs, xsjs, xsjslib)\nJavaServer Faces           (jsf)\nJCL                        (jcl)\nJinja Template             (j2, jinja, jinja2)\nJSON                       (arcconfig, avsc, composer.lock, geojson, gltf, har, htmlhintrc,\n                            json, json-tmlanguage, jsonl, mcmeta, mcmod.info, tern-config,\n                            tern-project, tfstate, tfstate.backup, topojson, watchmanconfig,\n                            webapp, webmanifest, yyp)\nJSON5                      (json5)\nJsonnet                    (jsonnet)\nJSP                        (jsp, jspf)\nJSP Tag Library Definition (tld)\nJSX                        (jsx)\nJulia                      (jl)\nJuniper Junos              (junos)\nJupyter Notebook           (ipynb)\nJustfile                   (just)\nKermit                     (ksc)\nKorn Shell                 (ksh)\nKotlin                     (kt, ktm, kts)\nkvlang                     (kv)\nLean                       (hlean, lean)\nLem                        (lem)\nLESS                       (less)\nlex                        (l, lex)\nLFE                        (lfe)\nLinker Script              (ld)\nLiquibase                  (lb.xml)\nliquid                     (liquid)\nLisp                       (asd, el, lisp, lsp, cl, jl)\nLiterate Idris             (lidr)\nLiveLink OScript           (oscript)\nLLVM IR                    (ll)\nLogos                      (x, xm)\nLogtalk                    (lgt, logtalk)\nLua                        (lua, nse, p8, pd_lua, rbxs, wlua)\nLuau                       (luau)\nm4                         (ac, m4)\nMagik                      (magik)\nmake                       (am, Gnumakefile, gnumakefile, Makefile, makefile, mk)\nMako                       (mako, mao)\nMarkdown                   (contents.lr, markdown, md, mdown, mdwn, mdx, mkd, mkdn, mkdown,\n                            ronn, workbook)\nMathematica                (cdf, ma, mathematica, mt, nbp, wl, wlt, m)\nMATLAB                     (m)\nMaven                      (pom, pom.xml)\nMeson                      (meson.build)\nMetal                      (metal)\nModelica                   (mo)\nModula3                    (i3, ig, m3, mg)\nMojo                       (mojo, 🔥)\nMojom                      (mojom)\nMoonBit                    (mbt, mbti, mbtx, mbty)\nMSBuild script             (btproj, csproj, msbuild, vcproj, wdproj, wixproj)\nMUMPS                      (mps, m)\nMustache                   (mustache)\nMXML                       (mxml)\nNAnt script                (build)\nNASTRAN DMAP               (dmap)\nNemerle                    (n)\nNetLogo                    (nlogo, nls)\nNextflow                   (nf)\nNickel                     (ncl)\nNim                        (nim, nim.cfg, nimble, nimrod, nims)\nNix                        (nix)\nNunjucks                   (njk)\nNushell                    (nu)\nNushell Object Notation    (nuon)\nObjective-C                (m)\nObjective-C++              (mm)\nOCaml                      (eliom, eliomi, ml, ml4, mli, mll, mly)\nOdin                       (odin)\nOpenCL                     (cl)\nOpenSCAD                   (scad)\nOracle Forms               (fmt)\nOracle PL/SQL              (bdy, bod, fnc, prc, spc, trg)\nOracle Reports             (rex)\nOrg Mode                   (org)\nP4                         (p4)\nPascal                     (dpr, lpr, pas, pascal)\nPascal/Pawn                (p)\nPascal/Puppet              (pp)\nPatran Command Language    (pcl, ses)\nPawn                       (pawn, pwn)\nPEG                        (peg)\npeg.js                     (pegjs)\npeggy                      (peggy)\nPek                        (pek)\nPerl                       (ack, al, cpanfile, makefile.pl, perl, ph, plh, plx, pm, psgi,\n                            rexfile, pl, p6)\nPest                       (pest)\nPHP                        (aw, ctp, phakefile, php, php3, php4, php5, php_cs, php_cs.dist, phps,\n                            phpt, phtml)\nPHP/Pascal/Fortran/Pawn/BitBake (inc)\nPig Latin                  (pig)\nPkl                        (pkl)\nPL/I                       (pl1)\nPL/M                       (lit, plm)\nPlantUML                   (iuml, plantuml, pu, puml, wsd)\nPO File                    (po)\nPony                       (pony)\nPowerBuilder               (pbt, sra, srf, srm, srs, sru, srw)\nPowerShell                 (ps1, psd1, psm1)\nPrisma Schema              (prisma)\nProcessing                 (pde)\nProGuard                   (pro)\nProlog                     (P, prolog, yap, pl, p6, pro)\nProperties                 (properties)\nProtocol Buffers           (proto)\nPRQL                       (prql)\nPug                        (jade, pug)\nPureScript                 (purs)\nPython                     (buck, build.bazel, gclient, gyp, gypi, lmi, py, py3, pyde, pyi, pyp,\n                            pyt, pyw, sconscript, sconstruct, snakefile, tac, workspace, wscript,\n                            wsgi, xpy)\nQML                        (qbs, qml)\nQt Linguist                (ts)\nQt Project                 (pro)\nR                          (expr-dist, R, r, rd, rprofile, rsx)\nRacket                     (rkt, rktd, rktl, scrbl)\nRaku                       (pm6, raku, rakumod)\nRaku/Prolog                (P6, p6)\nRAML                       (raml)\nRapydScript                (pyj)\nRazor                      (cshtml, razor)\nReasonML                   (re, rei)\nRego                       (rego)\nReScript                   (res, resi)\nreStructuredText           (rest, rest.txt, rst, rst.txt)\nRexx                       (pprx, rexx)\nRing                       (rform, rh, ring)\nRmd                        (Rmd)\nRobotFramework             (robot)\nRuby                       (appraisals, berksfile, brewfile, builder, buildfile, capfile,\n                            dangerfile, deliverfile, eye, fastfile, gemfile, gemfile.lock,\n                            gemspec, god, guardfile, irbrc, jarfile, jbuilder, mavenfile,\n                            mspec, podfile, podspec, pryrc, puppetfile, rabl, rake, rb,\n                            rbuild, rbw, rbx, ru, snapfile, thor, thorfile, vagrantfile, watchr)\nRuby HTML                  (rhtml)\nRust                       (rs, rs.in)\nSaltStack                  (sls)\nSAS                        (sas)\nSass                       (sass)\nScala                      (kojo, sbt, scala)\nScheme                     (sc, sch, scm, sld, sps, ss, sls)\nSCSS                       (scss)\nsed                        (sed)\nSKILL++                    (ils)\nSKILL/.NET IL              (il)\nSlice                      (ice)\nSlim                       (slim)\nSlint                      (slint)\nSmalltalk                  (st, cs)\nSmarty                     (smarty, tpl)\nSnakemake                  (rules, smk)\nSoftbridge Basic           (SBL, sbl)\nSolidity                   (sol)\nSparForte                  (sp)\nSpecman e                  (e)\nSQL                        (cql, mysql, psql, SQL, sql, tab, udf, viw)\nSQL Data                   (data.sql)\nSQL Stored Procedure       (spc.sql, spoc.sql, sproc.sql, udf.sql)\nSquirrel                   (nut)\nStandard ML                (fun, sig, sml)\nStarlark                   (bazel, bzl)\nStata                      (ado, DO, do, doh, ihlp, mata, matah, sthlp)\nStylus                     (styl)\nSugarSS                    (sss)\nSurrealQL                  (surql)\nSvelte                     (svelte)\nSVG                        (SVG, svg)\nSwift                      (swift)\nSWIG                       (i)\nTableGen                   (td)\nTcl/Tk                     (itk, tcl, tk)\nTEAL                       (teal)\nTeamcenter met             (met)\nTeamcenter mth             (mth)\nTempl                      (templ)\nTeX                        (aux, bbx, bib, bst, cbx, dtx, ins, lbx, ltx, mkii, mkiv, mkvi,\n                            sty, tex, cls)\nText                       (text, txt)\nThrift                     (thrift)\nTITAN Project File Information (tpd)\nTitanium Style Sheet       (tss)\nTLA+                       (tla)\nTNSDL                      (cii, cin, in1, in2, in3, in4, inf, interface, rou, sdl, sdt,\n                            spd, ssc, sst)\nTOML                       (toml)\ntspeg                      (jspeg, tspeg)\nTTCN                       (ttcn, ttcn2, ttcn3, ttcnpp)\nTwig                       (twig)\nTypeScript                 (cts, mts, tsx, ts)\nTypst                      (typ)\nUmka                       (um)\nUnity-Prefab               (mat, prefab)\nUnknown/BitBake            (conf)\nUSS                        (uss)\nUXML                       (uxml)\nVala                       (vala)\nVala Header                (vapi)\nVBA                        (VBA, vba)\nVBScript                   (VBS, vbs)\nVelocity Template Language (vm)\nVerilog-SystemVerilog      (sv, svh, v)\nVHDL                       (VHD, vhd, VHDL, vhdl, vhf, vhi, vho, vhs, vht, vhw)\nvim script                 (vim)\nVisual Basic               (BAS, bas, ctl, Dsr, dsr, frm, FRX, frx, vbp, vbw, cls)\nVisual Basic .NET          (VB, vb, VBHTML, vbhtml, vbproj)\nVisual Fox Pro             (SCA, sca)\nVisual Studio Solution     (sln)\nVisualforce Component      (component)\nVisualforce Page           (page)\nVSCode Workspace           (code-workspace)\nVuejs Component            (vue)\nVyper                      (vy)\nWeb Services Description   (wsdl)\nWebAssembly                (wast, wat)\nWGSL                       (wgsl)\nWindows Message File       (mc)\nWindows Module Definition  (def)\nWindows Resource File      (rc, rc2)\nWiX include                (wxi)\nWiX source                 (wxs)\nWiX string localization    (wxl)\nWXML                       (wxml)\nWXSS                       (wxss)\nX++                        (xpo)\nXAML                       (xaml)\nxBase                      (prg, prw)\nxBase Header               (ch)\nXHTML                      (xhtml)\nXMI                        (XMI, xmi)\nXML                        (adml, admx, ant, app.config, axml, builds, ccproj, ccxml,\n                            classpath, clixml, cproject, cscfg, csdef, csl, ct, depproj,\n                            ditamap, ditaval, dll.config, dotsettings, filters, fsproj,\n                            gmx, grxml, iml, ivy, jelly, jsproj, kml, launch, mdpolicy,\n                            mjml, natvis, ndproj, nproj, nuget.config, nuspec, odd, osm,\n                            packages.config, pkgproj, plist, proj, project, props, ps1xml,\n                            psc1, pt, rdf, resx, rss, scxml, settings.stylecop, sfproj,\n                            shproj, srdf, storyboard, sttheme, sublime-snippet, targets,\n                            tmcommand, tml, tmlanguage, tmpreferences, tmsnippet, tmtheme,\n                            urdf, ux, vcxproj, vsixmanifest, vssettings, vstemplate, vxml,\n                            web.config, web.debug.config, web.release.config, wsf, x3d,\n                            xacro, xib, xlf, xliff, XML, xml, xml.dist, xproj, xspec, xul,\n                            zcml)\nXML-Qt-GTK                 (ui)\nXQuery                     (xq, xql, xqm, xquery, xqy)\nXSD                        (XSD, xsd)\nXSLT                       (XSL, xsl, XSLT, xslt)\nXtend                      (xtend)\nyacc                       (y, yacc)\nYAML                       (clang-format, clang-tidy, gemrc, glide.lock, mir, reek, rviz,\n                            sublime-syntax, syntax, yaml, yaml-tmlanguage, yml, yml.mysql)\nYang                       (yang)\nYarn                       (yarn)\nZig                        (zig)\nzsh                        (zsh)\n```\n\n</details>\n\nThe above list can be customized by reading language definitions from a\nfile with the `--read-lang-def` or `--force-lang-def` options.\n\nThese file extensions map to multiple languages:\n\n*   `cj`  files could be Clojure or Cangjie\n*   `cl`  files could be Lisp or OpenCL\n*   `cls` files could be Visual Basic, TeX or Apex Class\n*   `conf` files could be BitBake or plain text\n*   `cs`  files could be C# or Smalltalk\n*   `d`   files could be D or dtrace\n*   `f`   files could be Fortran 77 or Forth\n*   `fnc` files could be Oracle PL or SQL\n*   `for` files could be Fortran 77 or Forth\n*   `fs`  files could be F# or Forth\n*   `inc` files could be PHP, Pascal or BitBake\n*   `itk` files could be Tcl or Tk\n*   `jl`  files could be Lisp or Julia\n*   `lit` files could be PL or M\n*   `m`   files could be MATLAB, Mathematica, Objective-C, MUMPS or Mercury\n*   `p6`  files could be Perl or Prolog\n*   `pl`  files could be Perl or Prolog\n*   `PL`  files could be Perl or Prolog\n*   `pp`  files could be Pascal or Puppet\n*   `pro` files could be IDL, Qt Project, Prolog or ProGuard\n*   `ts`  files could be TypeScript or Qt Linguist\n*   `ui`  files could be Qt or Glade\n*   `v`   files could be Verilog-SystemVerilog or Coq\n\ncloc has subroutines that attempt to identify the correct language based\non the file's contents for these special cases. Language identification\naccuracy is a function of how much code the file contains; .m files with\njust one or two lines for example, seldom have enough information to\ncorrectly distinguish between MATLAB, Mercury, MUMPS, or Objective-C.\n\nLanguages with file extension collisions are difficult to customize with\n`--read-lang-def` or `--force-lang-def` as they have no mechanism to\nidentify languages with common extensions. In this situation one must\nmodify the cloc source code.\n\n# How It Works\n\ncloc's method of operation resembles SLOCCount's: First, create a list\nof files to consider. Next, attempt to determine whether or not found\nfiles contain recognized computer language source code. Finally, for\nfiles identified as source files, invoke language-specific routines to\ncount the number of source lines.\n\nA more detailed description:\n\n1.  If the input file is an archive (such as a .tar.gz or .zip file),\n    create a temporary directory and expand the archive there using a\n    system call to an appropriate underlying utility (tar, bzip2, unzip,\n    etc) then add this temporary directory as one of the inputs. (This\n    works more reliably on Unix than on Windows.)\n2.  Use File::Find to recursively descend the input directories and make\n    a list of candidate file names. Ignore binary and zero-sized files.\n3.  Make sure the files in the candidate list have unique contents\n    (first by comparing file sizes, then, for similarly sized files,\n    compare MD5 hashes of the file contents with Digest::MD5). For each\n    set of identical files, remove all but the first copy, as determined\n    by a lexical sort, of identical files from the set. The removed\n    files are not included in the report. (The `--skip-uniqueness` switch\n    disables the uniqueness tests and forces all copies of files to be\n    included in the report.) See also the `--ignored=` switch to see which\n    files were ignored and why.\n4.  Scan the candidate file list for file extensions which cloc\n    associates with programming languages (see the `--show-lang` and\n    `--show-ext` options). Files which match are classified as\n    containing source\n    code for that language. Each file without an extension is opened\n    and its first line read to see if it is a Unix shell script\n    (anything that begins with #!). If it is shell script, the file is\n    classified by that scripting language (if the language is\n    recognized). If the file does not have a recognized extension or is\n    not a recognized scripting language, the file is ignored.\n5.  All remaining files in the candidate list should now be source files\n    for known programming languages. For each of these files:\n\n    1.  Read the entire file into memory.\n    2.  Count the number of lines (= L<sub>original</sub>).\n    3.  Remove blank lines, then count again (= L<sub>non_blank</sub>).\n    4.  Loop over the comment filters defined for this language. (For\n        example, C++ has two filters: (1) remove lines that start with\n        optional whitespace followed by // and (2) remove text between\n        /* and */) Apply each filter to the code to remove comments.\n        Count the left over lines (= L<sub>code</sub>).\n    5.  Save the counts for this language:\n        * blank lines = L<sub>original</sub> - L<sub>non_blank</sub>\n        * comment lines = L<sub>non_blank</sub> - L<sub>code</sub>\n        * code lines = L<sub>code</sub>\n\nThe options modify the algorithm slightly. The `--read-lang-def` option\nfor example allows the user to read definitions of comment filters,\nknown file extensions, and known scripting languages from a file. The\ncode for this option is processed between Steps 2 and 3.\n\n# Advanced Use\n\n## Remove Comments from Source Code\n\nHow can you tell if cloc correctly identifies comments? One way to\nconvince yourself cloc is doing the right thing is to use its\n`--strip-comments` option to remove comments and blank lines from files, then\ncompare the stripped-down files to originals.\n\nLet's try this out with the SQLite amalgamation, a C file containing all\ncode needed to build the SQLite library along with a header file:\n\n```\nprompt> tar zxf sqlite-amalgamation-3.5.6.tar.gz\nprompt> cd sqlite-3.5.6/\nprompt> cloc --strip-comments=nc sqlite.c\n       1 text file.\n       1 unique file.\nWrote sqlite3.c.nc\n       0 files ignored.\n\nhttp://cloc.sourceforge.net v 1.03  T=1.0 s (1.0 files/s, 82895.0 lines/s)\n-------------------------------------------------------------------------------\nLanguage          files     blank   comment      code    scale   3rd gen. equiv\n-------------------------------------------------------------------------------\nC                     1      5167     26827     50901 x   0.77 =       39193.77\n-------------------------------------------------------------------------------\n```\n\nThe extension argument given to --strip-comments is arbitrary; here nc was used as an abbreviation for \"no comments\".\n\ncloc removed over 31,000 lines from the file:\n\n```\nprompt> wc -l sqlite3.c sqlite3.c.nc\n  82895 sqlite3.c\n  50901 sqlite3.c.nc\n 133796 total\nprompt> echo \"82895 - 50901\" | bc\n31994\n```\n\nWe can now compare the original file, sqlite3.c and the one stripped of\ncomments, sqlite3.c.nc with tools like diff or vimdiff and see what\nexactly cloc considered comments and blank lines. A rigorous proof that\nthe stripped-down file contains the same C code as the original is to\ncompile these files and compare checksums of the resulting object files.\n\nFirst, the original source file:\n\n```\nprompt> gcc -c sqlite3.c\nprompt> md5sum sqlite3.o\ncce5f1a2ea27c7e44b2e1047e2588b49  sqlite3.o\n```\n\nNext, the version without comments:\n\n```\nprompt> mv sqlite3.c.nc sqlite3.c\nprompt> gcc -c sqlite3.c\nprompt> md5sum sqlite3.o\ncce5f1a2ea27c7e44b2e1047e2588b49  sqlite3.o\n```\n\ncloc removed over 31,000 lines of comments and blanks but did not modify the source code in any significant way since the resulting object file matches the original.\n\n## Work with Compressed Archives\nVersions of cloc before v1.07 required an\n `--extract-with=CMD` option to tell cloc how\nto expand an archive file.  Beginning with v1.07 this is extraction is\nattempted automatically.  At the moment the automatic extraction method works\nreasonably well on Unix-type OS's for the following file types:\n`.tar.gz`,\n`.tar.bz2`,\n`.tar.xz`,\n`.tgz`,\n`.zip`,\n`.ear`,\n`.deb`.\nSome of these extensions work on Windows if one has WinZip installed\nin the default location (`C:\\Program Files\\WinZip\\WinZip32.exe`).\nAdditionally, with newer versions of WinZip, the\n[http://www.winzip.com/downcl.htm](command line add-on)\nis needed for correct operation; in this case one would invoke cloc with\nsomething like \n```\n --extract-with=\"\\\"c:\\Program Files\\WinZip\\wzunzip\\\" -e -o >FILE< .\"\n </code>\n```\nRef. http://sourceforge.net/projects/cloc/forums/forum/600963/topic/4021070?message=8938196\n\nIn situations where the automatic extraction fails, one can try the\n`--extract-with=CMD`\noption to count lines of code within tar files, Zip files, or\nother compressed archives for which one has an extraction tool.\ncloc takes the user-provided extraction command and expands the archive\nto a temporary directory (created with File::Temp),\ncounts the lines of code in the temporary directory,\nthen removes that directory.  While not especially helpful when dealing\nwith a single compressed archive (after all, if you're going to type\nthe extraction command anyway why not just manually expand the archive?)\nthis option is handy for working with several archives at once.\n\nFor example, say you have the following source tarballs on a Unix machine\n\n    perl-5.8.5.tar.gz\n    Python-2.4.2.tar.gz\n\nand you want to count all the code within them.  The command would be\n```\ncloc --extract-with='gzip -dc >FILE< | tar xf -' perl-5.8.5.tar.gz Python-2.4.2.tar.gz\n```\nIf that Unix machine has GNU tar (which can uncompress and extract in\none step) the command can be shortened to\n```\ncloc --extract-with='tar zxf >FILE<' perl-5.8.5.tar.gz Python-2.4.2.tar.gz\n```\nOn a Windows computer with WinZip installed in\n`c:\\Program Files\\WinZip` the command would look like\n```\ncloc.exe --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE< .\" perl-5.8.5.tar.gz Python-2.4.2.tar.gz\n```\nJava `.ear` files are Zip files that contain additional Zip\nfiles.  cloc can handle nested compressed archives without\ndifficulty--provided all such files are compressed and archived in the\nsame way.  Examples of counting a\nJava `.ear` file in Unix and Windows:\n```\nUnix> cloc --extract-with=\"unzip -d . >FILE< \" Project.ear\nDOS> cloc.exe --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE< .\" Project.ear\n```\n\n## Differences\nThe `--diff` switch allows one to measure the relative change in\nsource code and comments between two versions of a file, directory,\nor archive.  Differences reveal much more than absolute code\ncounts of two file versions.  For example, say a source file\nhas 100 lines and its developer delivers a newer version with\n102 lines.  Did the developer add two comment lines,\nor delete seventeen source\nlines and add fourteen source lines and five comment lines, or did\nthe developer\ndo a complete rewrite, discarding all 100 original lines and\nadding 102 lines of all new source?  The diff option tells how\nmany lines of source were added, removed, modified or stayed\nthe same, and how many lines of comments were added, removed,\nmodified or stayed the same.\n\nDifferences in blank lines are handled much more coarsely\nbecause these are stripped by cloc early on.  Unless a\nfile pair is identical, cloc will report only differences\nin absolute counts of blank lines.  In other words, one\ncan expect to see only entries for 'added' if the second\nfile has more blanks than the first, and 'removed' if the\nsituation is reversed.  The entry for 'same' will be non-zero\nonly when the two files are identical.\n\nIn addition to file pairs, one can give cloc pairs of\ndirectories, or pairs of file archives, or a file archive\nand a directory.  cloc will try to align\nfile pairs within the directories or archives and compare diffs\nfor each pair.  For example, to see what changed between\nGCC 4.4.0 and 4.5.0 one could do\n```\ncloc --diff gcc-4.4.0.tar.bz2  gcc-4.5.0.tar.bz2\n```\n\nBe prepared to wait a while for the results though; the `--diff`\noption runs much more slowly than an absolute code count.\n\nTo see how cloc aligns files between the two archives, use the\n`--diff-alignment` option\n```\ncloc --diff-alignment=align.txt gcc-4.4.0.tar.bz2  gcc-4.5.0.tar.bz2\n```\nto produce the file `align.txt` which shows the file pairs as well\nas files added and deleted.  The symbols `==` and `!=` before each\nfile pair indicate if the files are identical (`==`)\nor if they have different content (`!=`).\n\nHere's sample output showing the difference between the Python 2.6.6 and 2.7\nreleases:\n```\nprompt> cloc --diff Python-2.7.9.tgz Python-2.7.10.tar.xz\n    4315 text files.\n    4313 text files.s\n    2173 files ignored.\n\n4 errors:\nDiff error, exceeded timeout:  /tmp/8ToGAnB9Y1/Python-2.7.9/Mac/Modules/qt/_Qtmodule.c\nDiff error, exceeded timeout:  /tmp/M6ldvsGaoq/Python-2.7.10/Mac/Modules/qt/_Qtmodule.c\nDiff error (quoted comments?):  /tmp/8ToGAnB9Y1/Python-2.7.9/Mac/Modules/qd/qdsupport.py\nDiff error (quoted comments?):  /tmp/M6ldvsGaoq/Python-2.7.10/Mac/Modules/qd/qdsupport.py\n\nhttps://github.com/AlDanial/cloc v 1.65  T=298.59 s (0.0 files/s, 0.0 lines/s)\n-----------------------------------------------------------------------------\nLanguage                   files          blank        comment           code\n-----------------------------------------------------------------------------\nVisual Basic\n same                          2              0              1             12\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nmake\n same                         11              0            340           2952\n modified                      1              0              0              1\n added                         0              0              0              0\n removed                       0              0              0              0\ndiff\n same                          1              0             87            105\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nCSS\n same                          0              0             19            327\n modified                      1              0              0              1\n added                         0              0              0              0\n removed                       0              0              0              0\nObjective-C\n same                          7              0             61            635\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nNAnt script\n same                          2              0              0             30\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nXML\n same                          3              0              2             72\n modified                      1              0              0              1\n added                         0              0              0              1\n removed                       0              1              0              0\nWindows Resource File\n same                          3              0             56            206\n modified                      1              0              0              1\n added                         0              0              0              0\n removed                       0              0              0              0\nExpect\n same                          6              0            161            565\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nHTML\n same                         14              0             11           2344\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nvim script\n same                          1              0              7            106\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nC++\n same                          2              0             18            128\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nWindows Module Definition\n same                          7              0            187           2080\n modified                      2              0              0              0\n added                         0              0              0              1\n removed                       0              1              0              2\nProlog\n same                          1              0              0             24\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nJavascript\n same                          3              0             49            229\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nAssembly\n same                         51              0           6794          12298\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nBourne Shell\n same                         41              0           7698          45024\n modified                      1              0              0              3\n added                         0             13              2             64\n removed                       0              0              0              0\nDOS Batch\n same                         29              0            107            494\n modified                      1              0              0              9\n added                         0              1              0              3\n removed                       0              0              0              0\nMSBuild script\n same                         77              0              3          38910\n modified                      0              0              0              0\n added                         0              0              0              0\n removed                       0              0              0              0\nPython\n same                       1947              0         109012         430335\n modified                    192              0             94            950\n added                         2            323            283           2532\n removed                       2             55             58            646\nm4\n same                         18              0            191          15352\n modified                      1              0              0              2\n added                         1             31              0            205\n removed                       0              0              0              0\nC\n same                        505              0          37439         347837\n modified                     45              0             13            218\n added                         0             90             33            795\n removed                       0              9              2            148\nC/C++ Header\n same                        255              0          10361          66635\n modified                      5              0              5              7\n added                         0              1              3            300\n removed                       0              0              0              0\n---------------------------------------------------------------------\nSUM:\n same                       2986              0         172604         966700\n modified                    251              0            112           1193\n added                         3            459            321           3901\n removed                       2             66             60            796\n---------------------------------------------------------------------\n```\nA pair of errors occurred.\nThe first pair was caused by timing out when computing diffs of the file\n`Python-X/Mac/Modules/qt/_Qtmodule.c` in each Python version.\nThis file has > 26,000 lines of C code and takes more than\n10 seconds--the default maximum duration for diff'ing a\nsingle file--on my slow computer.  (Note:  this refers to\nperforming differences with\nthe `sdiff()` function in the Perl `Algorithm::Diff` module,\nnot the command line `diff` utility.)  This error can be\novercome by raising the time to, say, 20 seconds\nwith `--diff-timeout 20`.\n\nThe second error is more problematic.  The files\n`Python-X/Mac/Modules/qd/qdsupport.py`\ninclude Python docstring (text between pairs of triple quotes)\ncontaining C comments.  cloc treats docstrings as comments and handles them\nby first converting them to C comments, then using the C comment removing\nregular expression.  Nested C comments yield erroneous results however.\n\n## Create Custom Language Definitions\ncloc can write its language comment definitions to a file or can read\ncomment definitions from a file, overriding the built-in definitions.\nThis can be useful when you want to use cloc to count lines of a\nlanguage not yet included, to change association of file extensions\nto languages, or to modify the way existing languages are counted.\n\nThe easiest way to create a custom language definition file is to\nmake cloc write its definitions to a file, then modify that file:\n```\nUnix> cloc --write-lang-def=my_definitions.txt\n```\ncreates the file `my_definitions.txt` which can be modified\nthen read back in with either the `--read-lang-def` or\n`--force-lang-def` option.  The difference between the options is\nformer merges language definitions from the given file in with\ncloc's internal definitions with cloc's taking precedence\nif there are overlaps.  The `--force-lang-def` option, on the\nother hand, replaces cloc's definitions completely.\nThis option has a disadvantage in preventing cloc from counting\n<a class=\"u\" href=\"#extcollision\" name=\"extcollision\">\nlanguages whose extensions map to multiple languages\n</a> as these languages require additional logic that is not easily\nexpressed in a definitions file.\n```\nUnix> cloc --read-lang-def=my_definitions.txt  file1 file2 dir1 ...\n```\n\nEach language entry has four parts:\n* The language name starting in column 1.\n* One or more comment *filters* starting in column 5.\n* One or more filename extensions starting in column 5.\n* A 3rd generation scale factor starting in column 5.\n  This entry must be provided\n  but its value is not important\n  unless you want to compare your language to a hypothetical\n  third generation programming language.\n\nA filter defines a method to remove comment text from the source file.\nFor example the entry for C++ looks like this\n```\nC++\n    filter call_regexp_common C++\n    filter remove_inline //.*$\n    extension C\n    extension c++\n    extension cc\n    extension cpp\n    extension cxx\n    extension pcc\n    3rd_gen_scale 1.51\n    end_of_line_continuation \\\\$\n```\nC++ has two filters:  first, remove lines matching\nRegexp::Common's C++ comment regex.\nThe second filter using remove_inline is currently\nunused.  Its intent is to identify lines with both\ncode and comments and it may be implemented in the future.\n\nA more complete discussion of the different filter options may appear\nhere in the future.  The output of cloc's\n`--write-lang-def` option should provide enough examples\nfor motivated individuals to modify or extend cloc's language definitions.\n\n## Combine Reports\n\nIf you manage multiple software projects you might be interested in\nseeing line counts by project, not just by language.\nSay you manage three software projects called MariaDB, PostgreSQL, and SQLite.\nThe teams responsible for each of these projects run cloc on their\nsource code and provide you with the output.\nFor example, the MariaDB team does\n\n```\ncloc --out mariadb-10.1.txt mariadb-server-10.1.zip\n```\n\nand provides you with the file `mariadb-10.1.txt`.\nThe contents of the three files you get are\n\n```\nUnix> cat mariadb-10.1.txt\nhttps://github.com/AlDanial/cloc v 1.65  T=45.36 s (110.5 files/s, 66411.4 lines/s)\n-----------------------------------------------------------------------------------\nLanguage                         files          blank        comment           code\n-----------------------------------------------------------------------------------\nC++                               1613         225338         290077         983026\nC                                  853          62442          73017         715018\nC/C++ Header                      1327          48300         114577         209394\nBourne Shell                       256          10224          10810          61943\nPerl                               147          10342           8305          35562\nPascal                             107           4907           5237          32541\nHTML                                56            195              6          16489\nJavascript                           5           3309           3019          15540\nm4                                  30           1599            359          14215\nCMake                              190           1919           4097          12206\nXML                                 35            648             56           5210\nRuby                                59            619            184           4998\nPuppet                              10              0              1           3848\nmake                               134            724            360           3631\nSQL                                 23            306            377           3405\nPython                              34            371            122           2545\nBourne Again Shell                  27            299            380           1604\nWindows Module Definition           37             27             13           1211\nlex                                  4            394            166            991\nyacc                                 2            152             64            810\nDOS Batch                           19             89             82            700\nProlog                               1              9             40            448\nRobotFramework                       1              0              0            441\nCSS                                  2             33            155            393\nJSON                                 5              0              0            359\ndtrace                               9             59            179            306\nWindows Resource File               10             61             89            250\nAssembly                             2             70            284            237\nWiX source                           1             18             10            155\nVisual Basic                         6              0              0             88\nYAML                                 2              4              4             65\nPHP                                  1             11              2             24\nSKILL                                1              8             15             16\nsed                                  2              0              0             16\nWindows Message File                 1              2              8              6\ndiff                                 1              1              4              4\nD                                    1              4             11              4\n-----------------------------------------------------------------------------------\nSUM:                              5014         372484         512110        2127699\n-----------------------------------------------------------------------------------\n\nUnix> cat sqlite-3081101.txt\nhttps://github.com/AlDanial/cloc v 1.65  T=1.22 s (3.3 files/s, 143783.6 lines/s)\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nC                                2          11059          53924         101454\nC/C++ Header                     2            211           6630           1546\n-------------------------------------------------------------------------------\nSUM:                             4          11270          60554         103000\n-------------------------------------------------------------------------------\n\nUnix> cat postgresql-9.4.4.txt\nhttps://github.com/AlDanial/cloc v 1.65  T=22.46 s (172.0 files/s, 96721.6 lines/s)\n-----------------------------------------------------------------------------------\nLanguage                         files          blank        comment           code\n-----------------------------------------------------------------------------------\nHTML                              1254           3725              0         785991\nC                                 1139         139289         244045         736519\nC/C++ Header                       667          12277          32488          57014\nSQL                                410          13400           8745          51926\nyacc                                 8           3163           2669          28491\nBourne Shell                        41           2647           2440          17170\nPerl                                81           1702           1308           9456\nlex                                  9            792           1631           4285\nmake                               205           1525           1554           4114\nm4                                  12            218             25           1642\nWindows Module Definition           13              4             17           1152\nXSLT                                 5             76             55            294\nDOS Batch                            7             29             30             92\nCSS                                  1             20              7             69\nAssembly                             3             17             38             69\nD                                    1             14             14             66\nWindows Resource File                3              4              0             62\nLisp                                 1              1              1             16\nsed                                  1              1              7             15\nPython                               1              5              0             13\nBourne Again Shell                   1              8              6             10\nWindows Message File                 1              0              0              5\n-----------------------------------------------------------------------------------\nSUM:                              3864         178917         295080        1698471\n-----------------------------------------------------------------------------------\n```\n\nWhile these three files are interesting, you also want to see\nthe combined counts from all projects.\nThat can be done with cloc's `--sum_reports`\noption:\n\n```\nUnix> cloc --sum-reports --out=databases mariadb-10.1.txt  sqlite-3081101.txt  postgresql-9.4.4.txt\nWrote databases.lang\nWrote databases.file\n```\n\nThe report combination produces two output files, one for sums by\nprogramming language (`databases.lang`) and one by project\n(`databases.file`).\nTheir contents are\n```\nUnix> cat databases.lang\nhttps://github.com/AlDanial/cloc v 1.65\n--------------------------------------------------------------------------------\nLanguage                      files          blank        comment           code\n--------------------------------------------------------------------------------\nC                              1994         212790         370986        1552991\nC++                            1613         225338         290077         983026\nHTML                           1310           3920              6         802480\nC/C++ Header                   1996          60788         153695         267954\nBourne Shell                    297          12871          13250          79113\nSQL                             433          13706           9122          55331\nPerl                            228          12044           9613          45018\nPascal                          107           4907           5237          32541\nyacc                             10           3315           2733          29301\nm4                               42           1817            384          15857\nJavascript                        5           3309           3019          15540\nCMake                           190           1919           4097          12206\nmake                            339           2249           1914           7745\nlex                              13           1186           1797           5276\nXML                              35            648             56           5210\nRuby                             59            619            184           4998\nPuppet                           10              0              1           3848\nPython                           35            376            122           2558\nWindows Module Definition        50             31             30           2363\nBourne Again Shell               28            307            386           1614\nDOS Batch                        26            118            112            792\nCSS                               3             53            162            462\nProlog                            1              9             40            448\nRobotFramework                    1              0              0            441\nJSON                              5              0              0            359\nWindows Resource File            13             65             89            312\nAssembly                          5             87            322            306\ndtrace                            9             59            179            306\nXSLT                              5             76             55            294\nWiX source                        1             18             10            155\nVisual Basic                      6              0              0             88\nD                                 2             18             25             70\nYAML                              2              4              4             65\nsed                               3              1              7             31\nPHP                               1             11              2             24\nSKILL                             1              8             15             16\nLisp                              1              1              1             16\nWindows Message File              2              2              8             11\ndiff                              1              1              4              4\n--------------------------------------------------------------------------------\nSUM:                           8882         562671         867744        3929170\n--------------------------------------------------------------------------------\n\nUnix> cat databases.file\n----------------------------------------------------------------------------------\nFile                            files          blank        comment           code\n----------------------------------------------------------------------------------\nmariadb-10.1.txt                 5014         372484         512110        2127699\npostgresql-9.4.4.txt             3864         178917         295080        1698471\nsqlite-3081101.txt                  4          11270          60554         103000\n----------------------------------------------------------------------------------\nSUM:                             8882         562671         867744        3929170\n----------------------------------------------------------------------------------\n```\n\nReport files themselves can be summed together.  Say you also manage\ndevelopment of Perl and Python and you want to keep track\nof those line counts separately from your database projects.  First\ncreate reports for Perl and Python separately:\n\n```\ncloc --out perl-5.22.0.txt   perl-5.22.0.tar.gz\ncloc --out python-2.7.10.txt Python-2.7.10.tar.xz\n```\n\nthen sum these together with\n\n```\nUnix> cloc --sum-reports --out script_lang perl-5.22.0.txt python-2.7.10.txt\nWrote script_lang.lang\nWrote script_lang.file\n\nUnix> cat script_lang.lang\nhttps://github.com/AlDanial/cloc v 1.65\n-------------------------------------------------------------------------------\nLanguage                     files          blank        comment           code\n-------------------------------------------------------------------------------\nPerl                          2892         136396         184362         536445\nC                              680          75566          71211         531203\nPython                        2141          89642         109524         434015\nC/C++ Header                   408          16433          26938         214800\nBourne Shell                   154          11088          14496          87759\nMSBuild script                  77              0              3          38910\nm4                              20           1604            191          15559\nAssembly                        51           3775           6794          12298\nPascal                           8            458           1603           8592\nmake                            16            897            828           4939\nXML                             37            198              2           2484\nHTML                            14            393             11           2344\nC++                             12            338            295           2161\nWindows Module Definition        9            171            187           2081\nYAML                            49             20             15           2078\nProlog                          12            438              2           1146\nJSON                            14              1              0           1037\nyacc                             1             85             76            998\nDOS Batch                       44            199            148            895\nObjective-C                      7             98             61            635\nExpect                           6            104            161            565\nWindows Message File             1            102             11            489\nCSS                              1             98             19            328\nWindows Resource File            7             55             56            292\nJavascript                       3             31             49            229\nvim script                       1             36              7            106\ndiff                             1             17             87            105\nNAnt script                      2              1              0             30\nIDL                              1              0              0             24\nVisual Basic                     2              1              1             12\nD                                1              5              7              8\nLisp                             2              0              3              4\n-------------------------------------------------------------------------------\nSUM:                          6674         338250         417148        1902571\n-------------------------------------------------------------------------------\n\nUnix> cat script_lang.file\n-------------------------------------------------------------------------------\nFile                         files          blank        comment           code\n-------------------------------------------------------------------------------\npython-2.7.10.txt             3240         161276         173214         998697\nperl-5.22.0.txt               3434         176974         243934         903874\n-------------------------------------------------------------------------------\nSUM:                          6674         338250         417148        1902571\n-------------------------------------------------------------------------------\n```\n\nFinally, combine the combination files:\n\n```\nUnix> cloc --sum-reports --report_file=everything databases.lang script_lang.lang\nWrote everything.lang\nWrote everything.file\n\nUnix> cat everything.lang\nhttps://github.com/AlDanial/cloc v 1.65\n---------------------------------------------------------------------------------\nLanguage                       files          blank        comment           code\n---------------------------------------------------------------------------------\nC                               2674         288356         442197        2084194\nC++                             1625         225676         290372         985187\nHTML                            1324           4313             17         804824\nPerl                            3120         148440         193975         581463\nC/C++ Header                    2404          77221         180633         482754\nPython                          2176          90018         109646         436573\nBourne Shell                     451          23959          27746         166872\nSQL                              433          13706           9122          55331\nPascal                           115           5365           6840          41133\nMSBuild script                    77              0              3          38910\nm4                                62           3421            575          31416\nyacc                              11           3400           2809          30299\nJavascript                         8           3340           3068          15769\nmake                             355           3146           2742          12684\nAssembly                          56           3862           7116          12604\nCMake                            190           1919           4097          12206\nXML                               72            846             58           7694\nlex                               13           1186           1797           5276\nRuby                              59            619            184           4998\nWindows Module Definition         59            202            217           4444\nPuppet                            10              0              1           3848\nYAML                              51             24             19           2143\nDOS Batch                         70            317            260           1687\nBourne Again Shell                28            307            386           1614\nProlog                            13            447             42           1594\nJSON                              19              1              0           1396\nCSS                                4            151            181            790\nObjective-C                        7             98             61            635\nWindows Resource File             20            120            145            604\nExpect                             6            104            161            565\nWindows Message File               3            104             19            500\nRobotFramework                     1              0              0            441\ndtrace                             9             59            179            306\nXSLT                               5             76             55            294\nWiX source                         1             18             10            155\ndiff                               2             18             91            109\nvim script                         1             36              7            106\nVisual Basic                       8              1              1            100\nD                                  3             23             32             78\nsed                                3              1              7             31\nNAnt script                        2              1              0             30\nIDL                                1              0              0             24\nPHP                                1             11              2             24\nLisp                               3              1              4             20\nSKILL                              1              8             15             16\n---------------------------------------------------------------------------------\nSUM:                           15556         900921        1284892        5831741\n---------------------------------------------------------------------------------\n\nUnix> cat everything.file\n-------------------------------------------------------------------------------\nFile                         files          blank        comment           code\n-------------------------------------------------------------------------------\ndatabases.lang                8882         562671         867744        3929170\nscript_lang.lang              6674         338250         417148        1902571\n-------------------------------------------------------------------------------\nSUM:                         15556         900921        1284892        5831741\n-------------------------------------------------------------------------------\n```\n\nOne limitation of the `--sum-reports` feature is that the individual counts must\nbe saved in the plain text format.  Counts saved as\nXML, JSON, YAML, or SQL will produce errors if used in a summation.\n\n## SQL\nCloc can write results in the form of SQL table create and insert\nstatements for use\nwith relational database programs such as SQLite, MySQL,\nPostgreSQL, Oracle, or Microsoft SQL.\nOnce the code count information is in a database,\nthe information can be interrogated and displayed in interesting ways.\n\nA database created from cloc SQL output has two tables,\n**metadata** and **t**:\n\nTable **metadata**:\n\n|Field     | Type                |\n|----------|---------------------|\n|id        | integer primary key |\n|timestamp | text                |\n|project   | text                |\n|elapsed_s | text                |\n\nTable **t**:\n\n|Field             | Type                     |\n|------------------|--------------------------|\n| project          |text                      |\n| language         |text                      |\n| file             |text                      |\n| nBlank           |integer                   |\n| nComment         |integer                   |\n| nCode            |integer                   |\n| nScaled          |real                      |\n| foreign key (id) | references metadata (id) |\n\nThe **metadata** table contains information about when the cloc run\nwas made.  Run time is stored two ways: as Unix epoch\nseconds in `id` and as an ISO 8601 formatted text string\nin the local time zone\n(for example `2024-03-01 14:19:41`) in `timestamp`.\nThe `--sql-append` switch allows one to combine\nmany runs in a single database; each run adds a\nrow to the metadata table.\nThe code count information resides in table **t**.\nThe `id` key makes it easy to associate a run's code count with\nits metadata.\n\nLet's repeat the code count examples of Perl, Python, SQLite, MySQL and\nPostgreSQL tarballs shown in the\n[Combine Reports](#combine_reports)\nexample above, this time\nusing the SQL output options and the\n[SQLite](http://www.sqlite.org/)\ndatabase engine.\n\nThe `--sql` switch tells cloc to generate output in the form\nof SQL table `create` and `insert` commands.  The switch takes\nan argument of a file name to write these SQL statements into, or,\nif the argument is 1 (numeric one), streams output to STDOUT.\nSince the SQLite command line program, `sqlite3`, can read\ncommands from STDIN, we can dispense with storing SQL statements to\na file and use `--sql 1` to pipe data directly into the\nSQLite executable:\n\n```\ncloc --sql 1 --sql-project mariadb mariadb-server-10.1.zip | sqlite3 code.db\n```\n\nThe `--sql-project mariadb` part is optional; there's no need\nto specify a project name when working with just one code base.  However,\nsince we'll be adding code counts from four other tarballs, we'll only\nbe able to identify data by input source if we supply a\nproject name for each run.\n\nNow that we have a database we will need to pass in the `--sql-append`\nswitch to tell cloc not to wipe out this database but instead add more data:\n\n```\ncloc --sql 1 --sql-project postgresql --sql-append postgresql-9.4.4.tar.bz2        | sqlite3 code.db\ncloc --sql 1 --sql-project sqlite     --sql-append sqlite-amalgamation-3081101.zip | sqlite3 code.db\ncloc --sql 1 --sql-project python     --sql-append Python-2.7.10.tar.xz            | sqlite3 code.db\ncloc --sql 1 --sql-project perl       --sql-append perl-5.22.0.tar.gz              | sqlite3 code.db\n```\n\nNow the fun begins--we have a database, `code.db`, with lots of\ninformation about the five projects and can query it\nfor all manner of interesting facts.\n\n**Which is the longest file over all projects?**\n\n```\nprompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t\n                                 where nL = (select max(nBlank+nComment+nCode) from t)'\n\nsqlite|sqlite-amalgamation-3081101/sqlite3.c|161623\n```\n\n`sqlite3`'s default output format leaves a bit to be desired.\nWe can add an option to the program's rc file,\n`~/.sqliterc`, to show column headers:\n```\n  .header on\n```\nOne might be tempted to also include\n```\n  .mode column\n```\nin `~/.sqliterc` but this causes problems when the output has more than\none row since the widths of entries in the first row govern the maximum\nwidth for all subsequent rows. Often this leads to truncated output--not\nat all desirable. One option is to write a custom SQLite output\nformatter such as `sqlite_formatter`, included with cloc.\n\nTo use it, simply pass `sqlite3`'s STDOUT into `sqlite_formatter`\nvia a pipe:\n\n```\nprompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t\n                         where nL = (select max(nBlank+nComment+nCode) from t)' | ./sqlite_formatter\n  <font color=\"darkgreen\">\n  -- Loading resources from ~/.sqliterc\n  Project File                                  nL\n  _______ _____________________________________ ______\n  sqlite  sqlite-amalgamation-3081101/sqlite3.c 161623\n  </font>\n```\n\nIf the \"Project File\" line doesn't appear, add `.header on` to your\n`~/.sqliterc` file as explained above.\n\n\n**What is the longest file over all projects?**\n\n```\nprompt> sqlite3 code.db 'select project,file,nBlank+nComment+nCode as nL from t\n                         where nL = (select max(nBlank+nComment+nCode) from t)' | sqlite_formatter\n\nProject File                                  nL\n_______ _____________________________________ ______\nsqlite  sqlite-amalgamation-3081101/sqlite3.c 161623\n```\n\n**What is the longest file in each project?**\n\n```\nprompt> sqlite3 code.db 'select project,file,max(nBlank+nComment+nCode) as nL from t\n                          group by project order by nL;' | sqlite_formatter\n\nProject    File                                                             nL\n__________ ________________________________________________________________ ______\npython     Python-2.7.10/Mac/Modules/qt/_Qtmodule.c                          28091\npostgresql postgresql-9.4.4/src/interfaces/ecpg/preproc/preproc.c            54623\nmariadb    server-10.1/storage/mroonga/vendor/groonga/lib/nfkc.c             80246\nperl       perl-5.22.0/cpan/Locale-Codes/lib/Locale/Codes/Language_Codes.pm 100747\nsqlite     sqlite-amalgamation-3081101/sqlite3.c                            161623\n```\n\n**Which files in each project have the most code lines?**\n\n```\nprompt> sqlite3 code.db 'select project,file,max(nCode) as nL from t\n                         group by project order by nL desc;' | sqlite_formatter\n\nProject    File                                                             nL\n__________ ________________________________________________________________ ______\nperl       perl-5.22.0/cpan/Locale-Codes/lib/Locale/Codes/Language_Codes.pm 100735\nsqlite     sqlite-amalgamation-3081101/sqlite3.c                             97469\nmariadb    server-10.1/storage/mroonga/vendor/groonga/lib/nfkc.c             80221\npostgresql postgresql-9.4.4/src/interfaces/ecpg/preproc/preproc.c            45297\npython     Python-2.7.10/Mac/Modules/qt/_Qtmodule.c                          26705\n```\n\n**Which C source files with more than 300 lines have a comment ratio below 1%?**\n\n```\nprompt> sqlite3 code.db 'select project, file, nCode, nComment,\n                         (100.0*nComment)/(nComment+nCode) as comment_ratio from t\n                         where language=\"C\" and nCode > 300 and\n                         comment_ratio < 1 order by comment_ratio;' | sqlite_formatter\n\nProject    File                                                                                            nCode nComment comment_ratio\n__________ _______________________________________________________________________________________________ _____ ________ __________________\nmariadb    server-10.1/storage/mroonga/vendor/groonga/lib/nfkc.c                                           80221       14 0.0174487443135789\npython     Python-2.7.10/Python/graminit.c                                                                  2175        1 0.0459558823529412\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c                            2095        1 0.0477099236641221\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_french.c                             1211        1 0.0825082508250825\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c                        1201        1 0.0831946755407654\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c                          1182        1 0.084530853761623\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c                     1178        1 0.0848176420695505\nmariadb    server-10.1/strings/ctype-eucjpms.c                                                             67466       60 0.0888546633889169\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_english.c                            1072        1 0.0931966449207828\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c                       1064        1 0.0938967136150235\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c                            1053        1 0.094876660341556\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c                       1049        1 0.0952380952380952\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_italian.c                            1031        1 0.0968992248062016\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c                       1023        1 0.09765625\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c                          981        1 0.10183299389002\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c                     975        1 0.102459016393443\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c                            967        1 0.103305785123967\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c                       961        1 0.103950103950104\nmariadb    server-10.1/strings/ctype-ujis.c                                                                67177       79 0.117461639110265\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c                             720        1 0.13869625520111\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_porter.c                              717        1 0.139275766016713\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c                        714        1 0.13986013986014\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c                         711        1 0.140449438202247\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c                            660        1 0.151285930408472\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_russian.c                             654        1 0.152671755725191\npython     Python-2.7.10/Mac/Modules/qt/_Qtmodule.c                                                        26705       42 0.157026956294164\npython     Python-2.7.10/Mac/Modules/icn/_Icnmodule.c                                                       1521        3 0.196850393700787\nmariadb    server-10.1/strings/ctype-extra.c                                                                8282       18 0.216867469879518\npostgresql postgresql-9.4.4/src/bin/psql/sql_help.c                                                         3576        8 0.223214285714286\nmariadb    server-10.1/strings/ctype-sjis.c                                                                34006       86 0.252258594391646\npython     Python-2.7.10/Python/Python-ast.c                                                                6554       17 0.258712524729874\nmariadb    server-10.1/strings/ctype-cp932.c                                                               34609       92 0.265122042592432\nperl       perl-5.22.0/keywords.c                                                                           2815        8 0.283386468296139\npython     Python-2.7.10/Mac/Modules/menu/_Menumodule.c                                                     3263       10 0.305530094714329\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c                               596        2 0.334448160535117\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c                          586        2 0.340136054421769\nmariadb    server-10.1/strings/ctype-gbk.c                                                                 10684       38 0.354411490393583\npython     Python-2.7.10/Mac/Modules/qd/_Qdmodule.c                                                         6694       24 0.357249181303959\npython     Python-2.7.10/Mac/Modules/win/_Winmodule.c                                                       3056       11 0.358656667753505\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_german.c                              476        2 0.418410041841004\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c                         470        2 0.423728813559322\nmariadb    server-10.1/strings/ctype-euc_kr.c                                                               9956       44 0.44\npostgresql postgresql-9.4.4/src/backend/utils/fmgrtab.c                                                     4815       23 0.475403059115337\npython     Python-2.7.10/Mac/Modules/ctl/_Ctlmodule.c                                                       5442       28 0.511882998171846\npython     Python-2.7.10/Mac/Modules/ae/_AEmodule.c                                                         1347        7 0.51698670605613\npython     Python-2.7.10/Mac/Modules/app/_Appmodule.c                                                       1712        9 0.52295177222545\nmariadb    server-10.1/strings/ctype-gb2312.c                                                               6377       35 0.54585152838428\nmariadb    server-10.1/storage/tokudb/ft-index/third_party/xz-4.999.9beta/src/liblzma/lzma/fastpos_table.c   516        3 0.578034682080925\npython     Python-2.7.10/Mac/Modules/evt/_Evtmodule.c                                                        504        3 0.591715976331361\npython     Python-2.7.10/Modules/expat/xmlrole.c                                                            1256        8 0.632911392405063\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_UTF_8_danish.c                              312        2 0.636942675159236\npostgresql postgresql-9.4.4/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c                         310        2 0.641025641025641\npython     Python-2.7.10/Mac/Modules/res/_Resmodule.c                                                       1621       12 0.734843845682792\npython     Python-2.7.10/Mac/Modules/drag/_Dragmodule.c                                                     1046        8 0.759013282732448\npython     Python-2.7.10/Mac/Modules/list/_Listmodule.c                                                     1021        8 0.777453838678329\npython     Python-2.7.10/Mac/Modules/te/_TEmodule.c                                                         1198       10 0.827814569536424\npython     Python-2.7.10/Mac/Modules/cg/_CGmodule.c                                                         1190       10 0.833333333333333\npython     Python-2.7.10/Modules/clmodule.c                                                                 2379       23 0.957535387177352\npython     Python-2.7.10/Mac/Modules/folder/_Foldermodule.c                                                  306        3 0.970873786407767\n```\n\n**What are the ten longest files (based on code lines) that have no comments at all?  Exclude header, .html, and YAML files.**\n\n```\nprompt> sqlite3 code.db 'select project, file, nCode from t\n                         where nComment = 0 and\n                         language not in (\"C/C++ Header\", \"YAML\", \"HTML\")\n                         order by nCode desc limit 10;' | sqlite_formatter\n\nProject File                                                                 nCode\n_______ ____________________________________________________________________ _____\nperl    perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/ja.pl                 1938\npython  Python-2.7.10/PCbuild/pythoncore.vcproj                               1889\npython  Python-2.7.10/PC/VS8.0/pythoncore.vcproj                              1889\nmariadb server-10.1/mysql-test/extra/binlog_tests/mysqlbinlog_row_engine.inc  1862\nperl    perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_strk.pl            1589\nperl    perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_zhu.pl             1563\nmariadb server-10.1/storage/mroonga/vendor/groonga/configure.ac               1526\nperl    perl-5.22.0/cpan/Unicode-Collate/Collate/Locale/zh_pin.pl             1505\nmariadb server-10.1/mysql-test/suite/funcs_1/storedproc/storedproc_02.inc     1465\npython  Python-2.7.10/PC/VS8.0/_bsddb.vcproj                                  1463\n```\n\n**What are the most popular languages (in terms of lines\nof code) in each project?**\n\n```\nprompt> sqlite3 code.db 'select project, language, sum(nCode) as SumCode from t\n                         group by project,language\n                         order by project,SumCode desc;' | sqlite_formatter\nProject    Language                  SumCode\n__________ _________________________ _______\nmariadb    C++                        983026\nmariadb    C                          715018\nmariadb    C/C++ Header               209394\nmariadb    Bourne Shell                61943\nmariadb    Perl                        35562\nmariadb    Pascal                      32541\nmariadb    HTML                        16489\nmariadb    Javascript                  15540\nmariadb    m4                          14215\nmariadb    CMake                       12206\nmariadb    XML                          5210\nmariadb    Ruby                         4998\nmariadb    Puppet                       3848\nmariadb    make                         3631\nmariadb    SQL                          3405\nmariadb    Python                       2545\nmariadb    Bourne Again Shell           1604\nmariadb    Windows Module Definition    1211\nmariadb    lex                           991\nmariadb    yacc                          810\nmariadb    DOS Batch                     700\nmariadb    Prolog                        448\nmariadb    RobotFramework                441\nmariadb    CSS                           393\nmariadb    JSON                          359\nmariadb    dtrace                        306\nmariadb    Windows Resource File         250\nmariadb    Assembly                      237\nmariadb    WiX source                    155\nmariadb    Visual Basic                   88\nmariadb    YAML                           65\nmariadb    PHP                            24\nmariadb    SKILL                          16\nmariadb    sed                            16\nmariadb    Windows Message File            6\nmariadb    D                               4\nmariadb    diff                            4\nperl       Perl                       536445\nperl       C                          155648\nperl       C/C++ Header               147858\nperl       Bourne Shell                42668\nperl       Pascal                       8592\nperl       XML                          2410\nperl       YAML                         2078\nperl       C++                          2033\nperl       make                         1986\nperl       Prolog                       1146\nperl       JSON                         1037\nperl       yacc                          998\nperl       Windows Message File          489\nperl       DOS Batch                     389\nperl       Windows Resource File          85\nperl       D                               8\nperl       Lisp                            4\npostgresql HTML                       785991\npostgresql C                          736519\npostgresql C/C++ Header                57014\npostgresql SQL                         51926\npostgresql yacc                        28491\npostgresql Bourne Shell                17170\npostgresql Perl                         9456\npostgresql lex                          4285\npostgresql make                         4114\npostgresql m4                           1642\npostgresql Windows Module Definition    1152\npostgresql XSLT                          294\npostgresql DOS Batch                      92\npostgresql Assembly                       69\npostgresql CSS                            69\npostgresql D                              66\npostgresql Windows Resource File          62\npostgresql Lisp                           16\npostgresql sed                            15\npostgresql Python                         13\npostgresql Bourne Again Shell             10\npostgresql Windows Message File            5\npython     Python                     434015\npython     C                          375555\npython     C/C++ Header                66942\npython     Bourne Shell                45091\npython     MSBuild script              38910\npython     m4                          15559\npython     Assembly                    12298\npython     make                         2953\npython     HTML                         2344\npython     Windows Module Definition    2081\npython     Objective-C                   635\npython     Expect                        565\npython     DOS Batch                     506\npython     CSS                           328\npython     Javascript                    229\npython     Windows Resource File         207\npython     C++                           128\npython     vim script                    106\npython     diff                          105\npython     XML                            74\npython     NAnt script                    30\npython     Prolog                         24\npython     Visual Basic                   12\nsqlite     C                          101454\nsqlite     C/C++ Header                 1546\n```\n\n## Custom Column Output\nCloc's default output is a text table with five columns:\nlanguage, file count, number of blank lines, number of comment\nlines and number of code lines.  The switches `--by-file`,\n`--3`, and `--by-percent` generate additional information but\nsometimes even those are insufficient.\n\nThe `--sql` option described in the previous section offers the\nability to create custom output.  This section has a pair of examples\nthat show how to create custom columns.\nThe first example includes an extra column, **Total**, which is the\nsum of the numbers of blank, comment, and code lines.\nThe second shows how to include the language name when running\nwith `--by-file`.\n\n**Example 1:  Add a \"Totals\" column.**\n\nThe first step is to run cloc and save the output to a relational database,\nSQLite in this case:\n```\ncloc --sql 1 --sql-project x yaml-cpp-yaml-cpp-0.5.3.tar.gz | sqlite3 counts.db\n```\n(the tar file comes from the\n[YAML-C++](https://github.com/jbeder/yaml-cpp) project).\n\nSecond, we craft an SQL query that returns the regular cloc output\nplus an extra column for totals, then save the SQL statement to\na file, `query_with_totals.sql`:\n```\n-- file query_with_totals.sql\nselect Language, count(File)   as files                       ,\n                 sum(nBlank)   as blank                       ,\n                 sum(nComment) as comment                     ,\n                 sum(nCode)    as code                        ,\n                 sum(nBlank)+sum(nComment)+sum(nCode) as Total\n    from t group by Language order by code desc;\n```\n\nThird, we run this query through SQLite using the `counts.db` database.\nWe'll include the `-header` switch so that SQLite prints the\ncolumn names:\n\n```\n> cat query_with_totals.sql | sqlite3 -header counts.db\nLanguage|files|blank|comment|code|Total\nC++|141|12786|17359|60378|90523\nC/C++ Header|110|8566|17420|51502|77488\nBourne Shell|10|6351|6779|38264|51394\nm4|11|2037|260|17980|20277\nPython|30|1613|2486|4602|8701\nMSBuild script|11|0|0|1711|1711\nCMake|7|155|285|606|1046\nmake|5|127|173|464|764\nMarkdown|2|30|0|39|69\n```\n\nThe extra column for **Total** is there but the format is unappealing.\nRunning the output through `sqlite_formatter` yields the desired result:\n\n```\n> cat query_with_totals.sql | sqlite3 -header counts.db | sqlite_formatter\nLanguage       files blank comment code  Total\n______________ _____ _____ _______ _____ _____\nC++              141 12786   17359 60378 90523\nC/C++ Header     110  8566   17420 51502 77488\nBourne Shell      10  6351    6779 38264 51394\nm4                11  2037     260 17980 20277\nPython            30  1613    2486  4602  8701\nMSBuild script    11     0       0  1711  1711\nCMake              7   155     285   606  1046\nmake               5   127     173   464   764\nMarkdown           2    30       0    39    69\n```\n\nThe next section,\n[Wrapping cloc in other scripts](#wrapping-cloc-in-other-scripts-),\nshows one way these commands can be combined\ninto a new utility program.\n\n**Example 2:  Include a column for \"Language\" when running with `--by-file`.**\n\nOutput from `--by-file` omits each file's language to save screen real estate;\nfile paths for large projects can be long and including an extra 20 or so\ncharacters for a Language column can be excessive.\n\nAs an example, here are the first few lines of output using the same\ncode base as in Example 1:\n\n```\n> cloc --by-file yaml-cpp-yaml-cpp-0.5.3.tar.gz\ngithub.com/AlDanial/cloc v 1.81  T=1.14 s (287.9 files/s, 221854.9 lines/s)\n--------------------------------------------------------------------------------------------------------------------------------------------\nFile                                                                                                     blank        comment           code\n--------------------------------------------------------------------------------------------------------------------------------------------\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/configure                                                        2580           2264          13691\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/configure                                                  2541           2235          13446\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/fused-src/gtest/gtest.h                                    1972           4681          13408\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/fused-src/gmock/gmock.h                                          1585           3397           9216\nyaml-cpp-yaml-cpp-0.5.3/test/integration/gen_emitter_test.cpp                                              999              0           8760\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/aclocal.m4                                                        987            100           8712\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/m4/libtool.m4                                               760             65           7176\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/build-aux/ltmain.sh                                         959           1533           7169\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/fused-src/gmock-gtest-all.cc                                     1514           3539           6390\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/fused-src/gtest/gtest-all.cc                               1312           2896           5384\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/test/gtest_unittest.cc                                     1226           1091           5098\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/include/gtest/internal/gtest-param-util-generated.h         349            235           4559\n```\n\nThe absence of language identification for each file\nis a bit disappointing, but\nthis can be remedied with a custom column solution.\n\nThe first step, creating a database, matches that from Example 1 so\nwe'll go straight to the second step of creating the desired\nSQL query.  We'll store this one in the file `by_file_with_language.sql`:\n\n```\n-- file by_file_with_language.sql\nselect File, Language, nBlank   as blank  ,\n                       nComment as comment,\n                       nCode    as code\n    from t order by code desc;\n```\n\nOur desired extra column appears when we pass this custom SQL query\nthrough our database:\n\n```\n> cat by_file_with_language.sql | sqlite3 -header counts.db | sqlite_formatter\nFile                                                                                               Language       blank comment code\n__________________________________________________________________________________________________ ______________ _____ _______ _____\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/configure                                                 Bourne Shell    2580    2264 13691\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/configure                                           Bourne Shell    2541    2235 13446\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/fused-src/gtest/gtest.h                             C/C++ Header    1972    4681 13408\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/fused-src/gmock/gmock.h                                   C/C++ Header    1585    3397  9216\nyaml-cpp-yaml-cpp-0.5.3/test/integration/gen_emitter_test.cpp                                      C++              999       0  8760\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/aclocal.m4                                                m4               987     100  8712\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/m4/libtool.m4                                       m4               760      65  7176\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/build-aux/ltmain.sh                                 Bourne Shell     959    1533  7169\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/fused-src/gmock-gtest-all.cc                              C++             1514    3539  6390\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/fused-src/gtest/gtest-all.cc                        C++             1312    2896  5384\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/test/gtest_unittest.cc                              C++             1226    1091  5098\nyaml-cpp-yaml-cpp-0.5.3/test/gmock-1.7.0/gtest/include/gtest/internal/gtest-param-util-generated.h C/C++ Header     349     235  4559\n```\n\n## Wrapping cloc in other scripts\n\nMore complex code counting solutions are possible by wrapping\ncloc in scripts or programs.  The \"total lines\" column from\nexample 1 of [Custom Column Output](#custom-column-output-)\ncould be simplified to a single command with this shell script (on Linux):\n\n```\n#!/bin/sh\n#\n# These commands must be in the user's $PATH:\n#   cloc\n#   sqlite3\n#   sqlite_formatter\n#\nif test $# -eq 0 ; then\n    echo \"Usage: $0  [cloc arguments]\"\n    echo \"       Run cloc to count lines of code with an additional\"\n    echo \"       output column for total lines (code+comment+blank).\"\n    exit\nfi\nDBFILE=`tempfile`\ncloc --sql 1 --sql-project x $@ | sqlite3 ${DBFILE}\nSQL=\"select Language, count(File)   as files                       ,\n                      sum(nBlank)   as blank                       ,\n                      sum(nComment) as comment                     ,\n                      sum(nCode)    as code                        ,\n                      sum(nBlank)+sum(nComment)+sum(nCode) as Total\n         from t group by Language order by code desc;\n\"\necho ${SQL} | sqlite3 -header ${DBFILE} | sqlite_formatter\nrm ${DBFILE}\n```\n\nSaving the lines above to ``total_columns.sh`` and making it\nexecutable (``chmod +x total_columns.sh``) would let us do\n```\n./total_columns.sh yaml-cpp-yaml-cpp-0.5.3.tar.gz\n```\nto directly get\n```\nLanguage       files blank comment code  Total\n______________ _____ _____ _______ _____ _____\nC++              141 12786   17359 60378 90523\nC/C++ Header     110  8566   17420 51502 77488\nBourne Shell      10  6351    6779 38264 51394\nm4                11  2037     260 17980 20277\nPython            30  1613    2486  4602  8701\nMSBuild script    11     0       0  1711  1711\nCMake              7   155     285   606  1046\nmake               5   127     173   464   764\nMarkdown           2    30       0    39    69\n```\n\nOther examples:\n* Count code from a specific branch of a web-hosted\ngit repository and send the results as a .csv email attachment:\nhttps://github.com/dannyloweatx/checkmarx\n\n\n## git and UTF8 pathnames\n\ncloc's ``--git`` option may fail if you work with directory or\nfile names with UTF-8 characters (for example, see\n<a href=https://github.com/AlDanial/cloc/issues/457>issue 457</a>).\nThe solution,\nhttps://stackoverflow.com/questions/22827239/how-to-make-git-properly-display-utf-8-encoded-pathnames-in-the-console-window,\nis to apply this git configuration command:\n\n```\ngit config --global core.quotepath off\n```\n\nYour console's font will need to be capable of displaying\nUnicode characters.\n\n## Third Generation Language Scale Factors\n\ncloc versions before 1.50 by default computed, for the provided inputs, a\nrough estimate of how many lines of code would be needed to write the\nsame code in a hypothetical third-generation computer language.\nTo produce this output one must now use the `--3` switch.\n\nScale factors were derived from the 2006 version of language gearing ratios\nlisted at Mayes Consulting web site,\n[http://softwareestimator.com/IndustryData2.htm](http://softwareestimator.com/IndustryData2.htm), using this equation:\n\ncloc scale factor for language X = 3rd generation default gearing ratio / language X gearing ratio\n\nFor example, cloc 3rd generation scale factor for DOS Batch = 80 / 128 = 0.625.\n\nThe biggest flaw with this approach is that gearing ratios are defined\nfor logical lines of source code not physical lines (which cloc counts).\nThe values in cloc's 'scale' and '3rd gen. equiv.' columns should be\ntaken with a large grain of salt.\n\n## options.txt configuration file\n\nIf you find yourself using the same command line switches every\ntime you invoke cloc, you can save some typing by adding those\nswitches to the ``options.txt`` runtime configuration file.\ncloc will look for this file in the following default locations:\n```\n# Linux, NetBSD, FreeBSD, macOS:\n/home/USERNAME/.config/cloc/options.txt\n\n# Windows\nC:\\Users\\USERNAME\\AppData\\Roaming\\cloc\n```\n\nIf you run cloc with ``--help``, cloc will tell you\nwhere it expects to find this config file file.  The information\nappears by the explanation of the ``--config`` switch after\nthe text ``the default location of``.\nOn Unix-like operating systems, this can be simplified to\n\n```\n> cloc --help | grep \"default location\"\n             the default location of /home/al/.config/cloc/options.txt.\n```\n\nand in a Windows ``cmd`` terminal with\n\n```\n> cloc --help | findstr default | findstr location\n             the default location of C:\\Users\\al\\AppData\\Roaming\\cloc\n```\n\nPlace each switch and arguments, if any, on a line by itself.\nLines prefixed with ``#`` symbol are ignored as comments and\nblank lines are skipped.  Leading hyphens on the switches are\noptional.  Here's a sample file:\n```\n# options.txt\n--vcs git\nv      # verbose level 1\nexclude-ext svg,html\n```\n\nThe path to the ``options.txt`` file can also be specified\nwith the ``--config FILE`` switch.\n\nFinally, if cloc finds an ``options.txt`` file in the same\ndirectory as files given by any of these switches (in the\nlisted priority), it will use that configuration file\nfrom that location:\n\n1. ``--list-file``\n1. ``--exclude-list-file``\n1. ``--read-lang-def``\n1. ``--force-lang-def``\n1. ``--diff-list-file``\n\nRun with ``--verbose`` to have cloc tell you which, if\nany, ``options.txt`` file it uses.\n\n## Python Programmatic Interface\n\n[Stefano Campanella](https://github.com/StefanoStone)\ncreated a Python programmatic interface to cloc.\nIt is available at https://github.com/pycloc/pycloc\n\n## Java Programmatic Interface\n\n[Ozren Dabić](https://github.com/seart-group/jcloc/commits?author=dabico)\ncreated a Java programmatic interface to cloc.\nIt is available at https://github.com/seart-group/jcloc\n\n# Complex regular subexpression recursion limit\ncloc relies on the Regexp::Common module's regular expressions to remove\ncomments from source code.  If comments are malformed, for example the\n``/*`` start comment marker appears in a C program without a corresponding ``*/``\nmarker, the regular expression engine could enter a recursive\nloop, eventually triggering the warning\n``Complex regular subexpression recursion limit``.\n\nThe most common cause for this warning is the existence of comment markers\nin string literals.  While language compilers and interpreters are smart\nenough to recognize that ``\"/*\"`` (for example) is a string and not a comment,\ncloc is fooled.  File path globs, as in this line of JavaScript\n```\nvar paths = globArray(\"**/*.js\", {cwd: srcPath});\n```\nare frequent culprits.\n\nIn an attempt to overcome this problem, a different\nalgorithm which removes comment markers in strings can be enabled\nwith the ``--strip-str-comments`` switch.  Doing so, however,\nhas drawbacks:  cloc\nwill run more slowly and the output of ``--strip-comments``\nwill contain strings that no longer match the input source.\n\n# Limitations\nIdentifying comments within source code is trickier than one might expect.\nMany languages would need a complete parser to be counted correctly.\ncloc does not attempt to parse any of\nthe languages it aims to count and therefore is an imperfect tool.\nThe following are known problems:\n\n<ol>\n<li>  Lines containing both source code and comments are counted as lines of code.\n</li>\n<li>  Comment markers within strings or\n<a href=\"http://www.faqs.org/docs/abs/HTML/here-docs.html\">here-documents</a>\nare treated as actual comment markers and not string literals.\nFor example the following lines of C code\n```\nprintf(\" /* \");\nfor (i = 0; i < 100; i++) {\n    a += i;\n}\nprintf(\" */ \");\n```\nlook to cloc like this:\n```\nprintf(\" xxxxxxx\nxxxxxxx\nxxxxxxx\nxxxxxxx\nxxxxxxx     \");\n```\nwhere `xxxxxxx` represents cloc's view of commented text.\nTherefore cloc counts the five lines as two lines of C code and three\nlines of comments (lines with both code and comment are counted as code).\n\nIf you suspect your code has such strings, use the switch\n``--strip-str-comments`` to switch to the algorithm which removes\nembedded comment markers.  Its use will render the five lines above as\n```\nprintf(\"  \");\nfor (i = 0; i < 100; i++) {\n    a += i;\n}\nprintf(\"  \");\n```\nand therefore return a count of five lines of code.\nSee the\n[previous section](#complex-regular-subexpression-recursion-limit-)\non drawbacks to using ``--strip-str-comments``.\n</li>\n<li> Embedded languages are not recognized.  For example, an HTML file containing\nJavaScript will be counted entirely as HTML.\n</li>\n<li> Python docstrings can serve several purposes.  They may\ncontain documentation,\ncomment out blocks of code, or they can be regular strings (when\nthey appear on the right hand side of an assignment or as a function argument).\ncloc is unable to infer the meaning of docstrings by context; by default\ncloc treats all docstrings as comments.  The switch\n`--docstring-as-code`\ntreats all docstrings as code.\n</li>\n<li> Language definition files read with `--read-lang-def` or\n`--force-lang-def` must be plain ASCII text files.\n</li>\n<li> cloc treats compiler pragma's, for example `#if` / `#endif`, as code\neven if these are used to block lines of source from being compiled;\nthe blocked lines still contribute to the code count.\n</li>\n<li> On Windows, cloc  will fail with <tt>Can't cd to ... No such file or\ndirectory at <embedded>/File/Find.pm</tt> if the code being scanned has\nfile paths longer than 255 characters.  A work-around is to run cloc\nfrom the Windows Subsystem for Linux (WSL).\n</li>\n<li> cloc's comment match code uses regular expressions\nwhich cannot properly account for nested comments using\nthe same comment markers (such as `/*  /*  */  */`).\n</li>\n<li> XML comments embedded within `CDATA` blocks are counted as\ncomments rather than code.\n</li>\n</ol>\n\n# Support for Additional Languages\n\nIf cloc does not recognize a language you are interested in counting,\nyou can either \n\n1. [implement it yourself](#implement-it-yourself),\n2. [request it to be implemented](#request-to-implement).\n\n## Implement an Additional Language\n\nIn short, you will need to:\n\n- edit the `cloc` file:\n\n  - look for `%{$rh_Language_by_Extension} = (             # {{{1` and add, respecting the alphabetical order,\n\n    ```\n    '<ext>' => '<Language Name>'           ,\n    ```\n    \n    where `<ext>` is the extension used by your language, and `<Language Name>` is its name. Repeat for each extension used by your language.\n    \n  - look for `%{$rhaa_Filters_by_Language} = (            # {{{1`, and add, respecting the alphabetical order,\n  \n  ```\n   '<Language Name>'     => [\n                                <list>\n                            ],\n    ```\n    \n    where `<Language Name>` is the name of the language you are implementing, and `<list>` is a list of filter options (whose documentation remains to be written -- take inspiration from existing languages).\n    \n  - look for `%{$rh_Scale_Factor}          = (             # {{{1`, and add, respecting the alphabetical order,\n  \n    ```\n    '<Language Name>'             =>   <factor>,\n    ```\n    \n      where `<Language Name>` is the name of the language you are implementing, and `<factor>` is a [third generation language scale factor](#third-generation-language-scale-factors-).\n    \n- edit the `Readme.md` file, adding under [\"Recognized Languages\"](#recognized-languages-) \n\n  ```\n  <Language Name>                    (<list of extensions>)\n  ```\n\n  for `<Language Name>` the name of the language you are implementing, and `<list of extensions>` the list of extensions you declared in `rh_Language_by_Extension`.\n  \n- (optional, but recommended) Add a test case:\n  \n    - Create a `tests/inputs/<Language name>.<extension>` file, containing some code written in `<Language name>`,\n    - Generate a `‎tests/outputs/<Language name>.<extension>.yaml` file, using \n    \n      ```\n      cloc --yaml tests/inputs/<Language name>.<extension> --out ‎tests/outputs/<Language name>.<extension>.yaml\n      ```\n    - Add your case in `Unix/t/00_C.t`: under `my @Tests = (`, add \n    \n      ```\n      {\n        'name' => '<Language name>',\n        'ref'  => '../tests/outputs/<Language name>.<extension>.yaml',\n        'args' => '../tests/inputs/<Language name>.<extension>',\n      },\n      ```\n\n    - Make sure you examine the output of `‎tests/outputs/<Language name>.<extension>.yaml` and that it is correct, then run `make test` from the `Unix` folder to make sure your test was successful.\n\nYou can use [this pull request](https://github.com/AlDanial/cloc/pull/962) or [this one](https://github.com/AlDanial/cloc/pull/947) as guidelines.\n\n## Request an Additional Language\n\nCreate a [GitHub issue](https://github.com/AlDanial/cloc/issues)\nrequesting support for your language.  Include this information:\n<ol>\n<li> File extensions associated with the language.  If the language does\nnot rely on file extensions and instead works with fixed file names or\nwith `#!` style program invocations, explain what those are.</li>\n<li> A description of how comments are defined.</li>\n<li> Links to sample code.</li>\n</ol>\n\n# Reporting Problems\n\nIf you encounter a problem with cloc, first check to see if\nyou're running with the latest version of the tool:\n```\n  cloc --version\n```\nIf the version is older than the most recent release\nat https://github.com/AlDanial/cloc/releases, download the\nlatest version and see if it solves your problem.\n\nIf the problem happens with the latest release, submit\na new issue at https://github.com/AlDanial/cloc/issues *only*\nif you can supply enough information for anyone reading the\nissue report to reproduce the problem.\nThat means providing\n<ol>\n<li> the operating system you're running on</li>\n<li> the cloc command with all options</li>\n<li> the code you are counting (URL to a public git repo or zip file or\ntar file, et cetera)</li>\n</ol>\nThe last item is generally problematic.  If the code base is\nproprietary or amounts to more than a few dozen kilobytes,\nyou'll need to try to reconstruct similar inputs or demonstrate\nthe problem with an existing public code base.\n\nProblem reports that cannot be reproduced will be ignored and\neventually closed.\n\n# Citation\n\nPlease use the following bibtex entry to cite cloc in a publication:\n\n```\n@software{adanial_cloc,\n  author       = {Albert Danial},\n  title        = {cloc: v2.08},\n  month        = dec,\n  year         = 2026,\n  publisher    = {Zenodo},\n  version      = {v2.08},\n  doi          = {10.5281/zenodo.5760077},\n  url          = {https://doi.org/10.5281/zenodo.5760077}\n}\n```\n\n(Update the version number and corresponding year if this\nentry is outdated.)\n\n# Acknowledgments\n[Wolfram Rösler](https://github.com/wolframroesler) provided most of the code examples in the test suite.\nThese examples come from his [Hello World collection](http://helloworldcollection.de/).\n\nIsmet Kursunoglu found errors with the MUMPS counter and provided\naccess to a computer with a large body of MUMPS code to test cloc.\n\nTod Huggins gave helpful suggestions for the Visual Basic filters.\n\nAnton Demichev found a flaw with the JSP counter in cloc v0.76\nand wrote the XML output generator for the `--xml` option.\n\nReuben Thomas pointed out that ISO C99 allows `//` as a comment\nmarker, provided code for the `--no3` and `--stdin-name`\noptions, counting the m4 language,\nand suggested several user-interface enhancements.\n\nMichael Bello provided code for the `--opt-match-f`,\n`--opt-not-match-f`,\n`--opt-match-d`, and `--opt-not-match-d`\noptions.\n\nMahboob Hussain inspired the `--original-dir` and\n`--skip-uniqueness` options, found a\nbug in the duplicate file detection logic and improved the JSP filter.\n\nRandy Sharo found and fixed an uninitialized variable bug for shell\nscripts having only one line.\n\nSteven Baker found and fixed a problem with the YAML output generator.\n\nGreg Toth provided code to improve blank line detection in COBOL.\n\nJoel Oliveira provided code to let `--exclude-list-file` handle\ndirectory name exclusion.\n\nBlazej Kroll provided code to produce an XSLT file, `cloc-diff.xsl`,\nwhen producing XML output for the `--diff` option.\n\nDenis Silakov enhanced the code which generates `cloc.xsl` when\nusing `--by-file` and `--by-file-by-lang` options, and\nprovided an XSL file that works with `--diff` output.\n\nAndy (awalshe@sf.net) provided code to fix several bugs:\ncorrect output of `--counted`\nso that only files that are used in the code count appear and\nthat results are shown by language rather than file name;\nallow `--diff` output from multiple runs to be summed\ntogether with `--sum-reports`.\n\nJari Aalto created the initial version of `cloc.1.pod` and\nmaintains the Debian package for cloc.\n\nMikkel Christiansen (mikkels@gmail.com) provided counter definitions\nfor Clojure and ClojureScript.\n\nVera Djuraskovic from [Webhostinggeeks.com](http://webhostinggeeks.com/)\nprovided the\n[Serbo-Croatian](http://science.webhostinggeeks.com/cloc)\ntranslation.\n\nGill Ajoft of [Ajoft Software](http://www.ajoft.com)\nprovided the\n[Bulgarian](http://www.ajoft.com/wpaper/aj-cloc.html)\ntranslation.\n\nThe\n[Knowledge Team](http://newknowledgez.com/)\nprovided the\n[Slovakian](http://newknowledgez.com/cloc.html) translation.\n\nErik Gooven Arellano Casillas provided an update to the MXML counter to\nrecognize ActionScript comments.\n\n[Gianluca Casati](http://g14n.info) created the\n[cloc CPAN package](https://metacpan.org/pod/App::cloc).\n\n<!--- broken link\nMary Stefanova provided the\n[Polish](http://www.trevister.com/blog/cloc.html)\ntranslation. --->\n\nRyan Lindeman implemented the `--by-percent` feature.\n\nKent C. Dodds, [@kentcdodds](https://twitter.com/kentcdodd),\ncreated and maintains the npm package of cloc.\n\n[Viktoria Parnak](http://kudoybook.com)\nprovided the\n[Ukrainian](http://blog.kudoybook.com/cloc/)\ntranslation.\n\nNatalie Harmann provided the\n[Belarussian](http://www.besteonderdelen.nl/blog/?p=5426)\ntranslation.\n\nNithyal at [Healthcare Administration Portal](http://healthcareadministrationdegree.co/)\nprovided the\n[Tamil](http://healthcareadministrationdegree.co/socialwork/aldanial-cloc/)\ntranslation.\n\nPatricia Motosan\nprovided the\n[Romanian](http://www.bildelestore.dk/blog/cloc-contele-de-linii-de-cod/)\ntranslation.\n\n<!--- broken link\nThe [Garcinia Cambogia Review Team](http://www.garciniacambogiareviews.ca/)\nprovided the\n[Arabic translation](http://www.garciniacambogiareviews.ca/translations/aldanial-cloc/). --->\n\nGajk Melikyan provided the\nprovided the\n[Armenian translation](http://students.studybay.com/?p=34)\nfor http://studybay.com.\n\n<a href=\"http://www.forallworld.com/cloc-grof-sornyi-kodot/\">Hungarian translation</a>\ncourtesy of <a href=\"http://www.forallworld.com/\">Zsolt Boros</a>.\n\n<a href=https://github.com/stsnel>Sietse Snel</a> implemented the parallel\nprocessing capability available with the `--processes=*N*`\nswitch.\n\nThe development of cloc was partially funded by the Northrop Grumman\nCorporation.\n\n# Copyright\nCopyright (c) 2006-2026, [Al Danial](https://github.com/AlDanial)\n\n"
  },
  {
    "path": "Unix/AUTHORS",
    "content": "Al Danial <al.danial@gmail.com>, https://github.com/AlDanial\nhttps://github.com/stsnel\nhttps://github.com/MichaelDimmitt\nhttps://github.com/jolkdarr\nhttps://github.com/jwilk\nhttps://github.com/asrmchq\nhttps://github.com/ljdursi\nhttps://github.com/ymahnovskyy\nhttps://github.com/codyebberson\nhttps://github.com/dulrich\nhttps://github.com/erkmos\nhttps://github.com/larsbrinkhoff\nhttps://github.com/toirl\nhttps://github.com/ialexryan\nhttps://github.com/ashinn\nhttps://github.com/AnthonyMastrean\nhttps://github.com/mafagafogigante\nhttps://github.com/brandon93s\nhttps://github.com/cansin\nhttps://github.com/charlax\nhttps://github.com/eduardosm\nhttps://github.com/ers35\nhttps://github.com/gleb\nhttps://github.com/soundasleep\nhttps://github.com/jongalloway\nhttps://github.com/jonasstein\nhttps://github.com/kaelig\nhttps://github.com/mwiley\nhttps://github.com/michalmuskala\nhttps://github.com/Inventitech\nhttps://github.com/zhangzqs\nhttps://github.com/drkameleon\nhttps://github.com/jackos\nhttps://github.com/Aerek-Yasa\nhttps://github.com/EDM115\nhttps://github.com/aionescu\n"
  },
  {
    "path": "Unix/COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\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    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <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 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": "Unix/INSTALL",
    "content": "Adjust prefix variables to install to other than system default:\n\n\tmake [-n] [prefix=/usr/local] install\n\nFor more information, use:\n\n\tmake help\n\n\nDependencies:\n\n  Algorithm::Diff\n  Regexp::Common\n  Digest::MD5\n  Parallel::ForkManager\n"
  },
  {
    "path": "Unix/Makefile",
    "content": "#!/usr/bin/make -f\n#\n#   Copyright information\n#\n#\tCopyright (C) 2012 Jari Aalto\n#\n#   License\n#\n#\tThis program is free software; you can redistribute it and/or modify\n#\tit under the terms of the GNU General Public License as published by\n#\tthe Free Software Foundation; either version 2 of the License, or\n#\t(at your option) any later version.\n#\n#\tThis program is distributed in the hope that it will be useful,\n#\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n#\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n#\tGNU General Public License for more details.\n#\n#\tYou should have received a copy of the GNU General Public License\n#\talong with this program. If not, see <http://www.gnu.org/licenses/>.\n\nifneq (,)\nThis makefile requires GNU Make.\nendif\n\nPACKAGE\t\t= cloc\n\nDESTDIR\t\t=\nprefix\t\t= /usr\nexec_prefix\t= $(prefix)\nman_prefix\t= $(prefix)/share\nmandir\t\t= $(man_prefix)/man\nbindir\t\t= $(exec_prefix)/bin\nsharedir\t= $(prefix)/share\n\nBINDIR\t\t= $(DESTDIR)$(bindir)\nDOCDIR\t\t= $(DESTDIR)$(sharedir)/doc\nLOCALEDIR\t= $(DESTDIR)$(sharedir)/locale\nSHAREDIR\t= $(DESTDIR)$(sharedir)/$(PACKAGE)\nLIBDIR\t\t= $(DESTDIR)$(prefix)/lib/$(PACKAGE)\nSBINDIR\t\t= $(DESTDIR)$(exec_prefix)/sbin\nETCDIR\t\t= $(DESTDIR)/etc/$(PACKAGE)\n\n# 1 = regular, 5 = conf, 6 = games, 8 = daemons\nMANDIR\t\t= $(DESTDIR)$(mandir)\nMANDIR1\t\t= $(MANDIR)/man1\nMANDIR5\t\t= $(MANDIR)/man5\nMANDIR6\t\t= $(MANDIR)/man6\nMANDIR8\t\t= $(MANDIR)/man8\n\nBIN\t\t= $(PACKAGE)\nPL_SCRIPT\t= $(BIN)\n\nINSTALL_OBJS_BIN = $(PL_SCRIPT)\nINSTALL_OBJS_MAN = *.1\n\nINSTALL\t\t= /usr/bin/install\nINSTALL_BIN\t= $(INSTALL) -m 755\nINSTALL_DATA\t= $(INSTALL) -m 644\n\nall: man\n\t@echo \"Nothing to compile for a Perl script.\"\n\t@echo \"Try 'make help' or 'make -n DESTDIR= prefix=/usr/local install'\"\n\n# Rule: help - display Makefile rules\nhelp:\n\t@grep \"^# Rule:\" Makefile | sort\n\n# Rule: clean - remove temporary files\nclean:\n\t# clean\n\trm -f *[#~] *.\\#* *.x~~ pod*.tmp *.1\n\trm -rf tmp\n\ndistclean: clean\n\nrealclean: clean\n\n# Rule: man - Generate or update manual page\nman:\n\t$(MAKE) -f pod2man.mk PACKAGE=$(PACKAGE) makeman\n\n# Rule: doc - Generate or update all documentation\ndoc: man\n\n# Rule: test-perl - Check program syntax\ntest-perl:\n\t# perl-test - Check syntax\n\tperl -cw $(PL_SCRIPT)\n\n# Rule: test-pod - Check POD syntax\ntest-pod:\n\tpodchecker *.pod\n\n# Rule: test-code - Check that the counter works\ntest-code:\n\tt/00_C.t\n\tt/02_git.t\n\tt/01_opts.t\n\n# Rule: test-unix - Check that the Unix version works\ntest-unix:\n\tt/00_C.t -u\n\tt/02_git.t -u\n\tt/01_opts.t -u\n\n# Rule: test - Run tests (exclude test-unix)\ntest: test-perl test-pod test-code\n\ninstall-man: test-pod man\n\t# install-man\n\t$(INSTALL_BIN) -d $(MANDIR1)\n\t$(INSTALL_DATA) $(INSTALL_OBJS_MAN) $(MANDIR1)\n\ninstall-bin: test-perl\n\t# install-bin - Install programs\n\t$(INSTALL_BIN) -d $(BINDIR)\n\tfor f in $(INSTALL_OBJS_BIN); \\\n\tdo \\\n\t\tdest=$${f%.pl}; \\\n\t\t$(INSTALL_BIN) $$f $(BINDIR)/$$dest; \\\n\tdone\n\n# Rule: install - Standard install\ninstall: install-bin install-man\n\n# Rule: install-test - for Maintainer only\ninstall-test:\n\trm -rf tmp\n\t$(MAKE) DESTDIR=$$(pwd)/tmp prefix=/usr install\n\tfind tmp | sort\n\n# Rule: dist - for Maintainer only, make distribution\ndist: clean\n\t[ -f version ] || fail-version-file-is-missing\n\n\trelease=$(PACKAGE)-$$(cat version); \\\n\trm -rf /tmp/$$release ; \\\n\tmkdir -vp /tmp/$$release ; \\\n\tcp -rav . /tmp/$$release/ ; \\\n    find /tmp/$$release/ -type d \\\n      \\( -name .svn -o -name .git -o -name .hg \\) | xargs -r rm -r; \\\n\ttar -C /tmp -zvcf /tmp/$$release.tar.gz $$release ; \\\n\techo \"DONE: /tmp/$$release.tag.gz\"\n\n.PHONY: clean distclean realclean install install-bin install-man\n\n# End of file\n"
  },
  {
    "path": "Unix/NEWS",
    "content": "                Release Notes for cloc version 2.08\n                   https://github.com/AlDanial/cloc\n                             Jan. 24, 2026\n\nNew Languages and File Types:\n    o Activiti Business Process\n    o Aria\n    o AXAML\n    o Bicep\n    o BitBake\n    o Clarity\n    o Haskell Boot\n    o Hibernate\n    o JSP Tag Library Definition\n    o Jasper Report XML/Template\n    o Justfile\n    o Liquibase\n    o Magik\n    o VSCode Workspace\n    o Yarn\n\nUpdates:\n    o Support input through process substitution on Unix-like\n      operating systems (example:  cloc <(git diff HEAD~1 HEAD --name-only) )\n    o Improve Perl filter for POD (plain old documentation) handling.\n    o --quiet now suppresses all output including error messages unless\n      --show-errors is also given.\n    o Add .cts extension for TypeScript.\n    o Renamed \"VB for Applications\" to \"VBA\"\n    o Add .vbhtml extension for Visual Basic .NET\n    o Renamed \"Visual Basic Script\" to \"VBScript\"\n    o New switch --include-submodules (applies to --vcs=git) to include\n      git submodule files in the count.\n    o Revert back to manual build of Windows executable to avoid\n      issues with symlinks seen with winget on executables created\n      in Github Actions.\n\nBug fixes:\n    o Handle empty files when using --git --diff.\n    o Replace \"Nothing to count.\" output with valid formatted output\n      (JSON, etc) when no files are found to count.\n    o Fix language definition parse errors with --read-lang-def, --force-lang-def\n      (specifically, update matching regex to allow leading '.' as in .NET)\n\n============================================================================\n                Release Notes for cloc version 2.06\n                   https://github.com/AlDanial/cloc\n                             June 24, 2025\n\nNew Languages and File Types:\n    o Cangjie\n    o Elixir Script\n    o Fortran 2003\n    o Jsonnet\n    o Nextflow\n    o Nushell\n    o Org Mode\n    o Rego\n    o UXML, USS (Unity)\n\nUpdates:\n    o First attempt at using Github Actions to package a release\n      including making a Windows executable that works with\n      symlinks as used by winget\n    o Add column headers for --show-lang and --show-ext output\n    o Remove '->' separator in --show-ext output\n    o Remove leading blank space for --fmt output written to STDOUT\n    o New switch --files-from as a synonym for --vcs\n    o New switch --ksep/--thousands-delimiter to show a separator (default\n      is a comma) between thousands in output counts\n    o Change sequence of Python language filters so that docstrings are\n      handled before #\n    o Jenkinsfile now recognized as Groovy\n    o Improve Windows/Unix path conflicts when using --git --diff in\n      git-bash terminal\n    o New switch --percent as a shortcut to '--by-percent t' to show\n      percentage of totals in blank, comment, code columns\n    o Add backtick and C++ style comment support for Svelte\n    o Write results in multiple formats if multiple output format\n      switches are given (for example --json --yaml --xml)\n\nBug fixes:\n    o Remove file 'irregular\"file2.md' from the test suite as filenames\n      with embedded double quotes are illegal in Windows and cause git\n      pull problems (among other issues).  This file is created dynamically\n      during testing on non-Windows operating systems.\n    o On Windows use zip format instead of tar for the 'git archive' command\n      used when running with --git --diff\n    o Remove duplicate \"percent\" entry in options handling\n    o Support --exclude-lang in --diff mode\n    o Fix --exclude-lang option when used in diff mode and when all files\n      are additions or deletions\n    o On Windows, remove temporary \"SCALAR(0x..)\" files created when\n      using --fmt\n    o Handle --by-file for JSON and YAML outputs with single and double\n      quotes in file names\n\n============================================================================\n                Release Notes for cloc version 2.04\n                   https://github.com/AlDanial/cloc\n                             Jan. 31, 2025\n\nNew Languages and File Types:\n    o Blueprint\n    o MoonBit\n    o SurrealQL\n    o Pkl\n    o Civet\n    o Cadence\n    o Pek\n\nUpdates:\n    o Follow file renames when pairing files for --git --diff.\n    o Arch Linux now has an AUR package for cloc.\n    o New switch --ignore-regex to exclude files whose content matches a regex.\n    o New switch --unique to identify unique files found.\n    o Descriptive message at the end of a run if timeouts were encountered.\n    o Slight performance improvement for --help by installing temporary\n      modules later.\n\nBug fixes:\n    o Better handling of Vuejs.\n    o Better handling of Oracle PL/SQL.\n    o Better error message on failure to count .src.rpm files if external\n      tools are not installed.\n    o Identify non-Glade .ui files as 'XML (Qt/GTK)' instead of 'Qt'.\n    o Apply file filter rules with --no-recurse.\n\n============================================================================\n                Release Notes for cloc version 2.02\n                   https://github.com/AlDanial/cloc\n                             Aug. 2, 2024\n\nNew Languages and File Types:\n    o Arturo\n    o Glimmer JavaScript\n    o Glimmer TypeScript\n    o Luau\n    o Modelica\n    o Mojo\n    o Nickel\n    o Pawn\n    o Processing\n    o Templ\n    o Yang\n\nUpdates:\n    o Support SQL output with --diff\n    o Support counting in .git repo directories not owned by the user.\n    o Eliminate the need to write temporary files when using --fmt.\n    o Restore Dockerfile CI by fixing CPAN module setup that somehow stopped\n      installing Parallel::ForkManager.\n    o Improve handling of C comments in Go strings.\n\nBug fixes:\n    o Improve --fmt output column alignments.\n    o Handle --no-match when combined with --fullpath and --vcs.\n\n============================================================================\n                Release Notes for cloc version 2.00\n                   https://github.com/AlDanial/cloc\n                             Feb. 17, 2024\n\n\n       **  Note:  There are no breaking changes between the   **\n       **         1.xx versions and this 2.00 release.        **\n\n\nNew Languages and File Types:\n    o AnsProlog\n    o AppleScript\n    o ArkTs\n    o Astro\n    o Dafny\n    o PlusCal\n    o Prisma Schema\n    o PRQL\n    o Slint\n    o Snakemake\n    o TLA+\n    o vyper\n\nUpdates:\n    o Five new output formats with the new --fmt switch.  Includes the often-\n      requested addition of language name with --by-file counts.\n    o *.o.d files are ignored\n    o Added .j2 as a Jinja Template extension.\n    o Added .mts as a TypeScript extension.\n    o Added .iuml, .pu. .plantuml, .wsd as as PlantUML extensions.\n    o Support Java block comments.\n    o More consistent and accurate results from --diff.\n    o Disambiguate .inc files among PHP, Pascal, and Fortran.\n    o Ignore .gitattribute files.\n    o Improved support for --exclude-list-file.\n    o Fix JSON output generator which inserted a superfluous comma.\n    o Recognize autogenerated C# SpecFlow files and ignore them with\n      --no-autogen.\n    o Support --list-file with --git-diff-*.\n    o SQL output:  add foreign key 'id' to table t referencing 'id'\n      in the metadata table.  The key value is Unix epoch seconds when\n      cloc was invoked.\n    o Support // comments in ReasonML.\n    o Support directories in exclusion list files; all files below the\n      named directories are excluded.\n    o Support --exclude-file-list with --git --diff.\n    o New switch, --strip-code, which attempts to only leave comments in\n      the output file.\n\nBug fixes:\n    o More accurate counts of XML with block comments.\n    o More accurate counts of Java with block comments and comment markers\n      within strings.\n    o Fix improper handling of --match-d and --not-match-d.\n\n============================================================================\n                Release Notes for cloc version 1.98\n                   https://github.com/AlDanial/cloc\n                             Aug. 19, 2023\n\nNew Languages and File Types:\n    o Asymptote\n    o CoCoA 5\n    o Constraint Grammar\n    o Hare\n    o Jai\n    o Linker Script\n    o NetLogo\n    o Typst\n\nUpdates:\n    o Added .editorconfig as an INI extension.\n    o Added .cppm, .ixx, .ccm, .cxxm, .c++m as C++ extensions.\n    o Improved handling of trailing slash with --match-d\n    o --exclude-list-file with --git now works as expected.\n    o --not-match-d, --not-match-f can now be repeated.\n    o --quiet mode is now enabled when STDOUT is not a terminal.\n      This makes for cleaner output when piping to other programs.\n    o New switch --include-content=regex to only count files whose\n      content matches the given regex.\n    o New switch --only-count-files to only count files.  Counts for\n      blank, comment, and code lines will be zero.\n\nBug fixes:\n    o --no-recurse on Windows\n    o Improved exclusion of autogenerated files on Windows.\n    o Improved handling of path separators with git in PowerShell.\n    o Resolve nondeterministic --diff output.\n    o --hide-rate supports all output file types\n    o Fixed --diff-list-file with unknown listed file.\n    o Fixed parsing of verbose option in the cloc configuration file.\n\nNOTE:  The next release of cloc will be 2.00.  Despite the major version\n       number bump, there will be no breaking changes.\n\n============================================================================\n                Release Notes for cloc version 1.96\n                   https://github.com/AlDanial/cloc\n                             Dec. 18, 2022\n\nNew Languages and File Types:\n    o Cairo\n    o Carbon\n    o Circom\n    o Containerfile\n    o HolyC\n    o kvlang\n    o Nunjucks\n    o OpenSCAD\n    o P4\n    o Pest\n    o Pony\n    o TEAL\n    o WGSL\n\nUpdates:\n    o New switch --diff-list-files to run diff given two list\n      files.\n    o Handle comments embedded in OCaml strings.\n    o Write empty JSON and XML structures if the inputs yield zero\n      counts.\n    o Including Win32::LongPath to support long paths on Windows.\n    o Better support for building and running Docker image on Windows\n    o Better output file names when running with --count-and-diff\n      and --out.\n    o Resolve internal file handle conflict when running --diff with\n      --sdir or --categorized.\n\n============================================================================\n                Release Notes for cloc version 1.94\n                   https://github.com/AlDanial/cloc\n                             July 4, 2022\n\nNew Languages and File Types:\n    o Derw\n    o Finite State Language\n    o Flatbuffers\n    o Futhark\n    o Godot Shaders\n    o HTML EEx\n    o Lem\n    o PEG, peg.js, peggy, tspeg\n    o Text (.txt and .text)\n    o Visual Studio Module\n    o X++\n\nUpdates:\n    o Handle empty Unicode files which contain only a BOM (byte\n      order mark).\n    o The arguments to --include-lang are now case insensitive.\n    o .cjs added as JavaScript extension.\n    o Switches --git and --xml together now include additional git\n      metadata (origin, branch, commit hash) in the XML output.  Future\n      releases will include these additions in YAML, JSON, SQL, and\n      Markdown output as well.\n    o New switch --no-recurse prevents recursive directory traversal.\n\n============================================================================\n                Release Notes for cloc version 1.92\n                   https://github.com/AlDanial/cloc\n                             Dec. 5, 2021\n\nNew Languages and File Types:\n    o GraphQL\n    o Metal Shading Language\n    o PlantUML\n    o Properties\n    o Umka\n\nUpdates:\n    o The .bzl and .bazel extensions are now associated with Starlark.\n    o Added support for Puppet functions and type aliases.\n    o Removed reliance on XML definition with --force-lang-def\n    o Fixed broken --csv-delimiter handling.\n    o Fixed broken interaction of --vcs=git with --max-file-size;\n      support floating point value for --max-file-size.\n    o Improved support for uniform handling of uppercase and\n      lowercase filenames and extensions on Windows.\n    o Recognize CMakeLists.txt on Windows.\n    o Fixed handling of --unicode for small files.\n    o Updated Dockerfile to produce a smaller image.\n    o Improved contents of --ignored file (now includes skipped\n      binary files and does not include directory names).\n    o Identify SCSS separately from Sass.\n    o Updated Sass filters to handle C++ style comments.\n    o Improved support for Assembly.\n    o Recognize :: comments in DOS batch files.\n    o Properly handle explicitly-excluded files (for example,\n      .gitignore) with --diff.\n\n\n============================================================================\n                Release Notes for cloc version 1.90\n                   https://github.com/AlDanial/cloc\n                             May 1, 2021\n\nNew Languages and File Types:\n    o BizTalk Orchestration\n    o BizTalk Pipeline\n    o Cake Build Script\n    o C# Designer\n    o CSV\n    o Delphi Form\n    o Gleam\n    o Godot Resource\n    o Godot Scene\n    o Juniper Junos\n    o ReScript\n    o Ring\n    o Visual Studio Solution\n    o Web Services Description\n    o Zig\n\nUpdates:\n    o Dockerfile:  add .[dD]ockerfile as an extension; treat\n      files named Dockerfile.ext as Dockerfile unless ext\n      maps to a recognized language other than cmake or m4.\n    o Identify autogenerated C# files.\n    o If getting input from a list file or using a language\n      definition file, also check for (and use, if it exists)\n      an options.txt file in the same directory.\n    o Use --csv-delimiter for --ignored, --categorized output.\n    o Support diff summation in csv format.\n    o Update cloc's Unix Makefile to support macOS\n    o Rename Junos to Juniper Junos\n    o Stratify Visual Basic to for Applications, .NET, Script\n    o Use tar on Windows 10 instead of zip with --git --diff\n    o Track upper/lowercase file names on Windows to permit\n      consistent diffs.\n    o Support nested Elm comments.\n    o Update to Regexp::Common 2017060201.\n    o Minimum Perl version is now 5.10.0\n    o New options --skip-leading, --summary-cutoff\n    o Refine comment definitions for ASP.NET, Razor\n    o Handle Julia docstrings.\n    o Adjust timeout and diff_timeout values to avoid alarm\n      overflows.\n    o Add extensions .btproj, .msbuild for MSBuild script\n\nBug Fixes:\n    o Add missing Raku_or_Prolog() subroutine.\n    o Handle UTF encoded list files (file given to --list-file).\n    o Improved support for options parsing from config file.\n    o Catch unidentified files via --diff-list-file.\n    o Don't insert extra newlines when stripping with --unicode.\n    o Strip literal '\\x' from JSON output strings.\n    o Improve logic for detecting Unicode files less than\n      90 bytes in size.\n    o Fix divide by zero classifying nonreadable .b files.\n    o Escape backslash for 'report_file' entry in JSON, YAML on\n      Windows.\n\n============================================================================\n                Release Notes for cloc version 1.88\n                   https://github.com/AlDanial/cloc\n                            Sept. 12, 2020\n\nNew Languages and File Types:\n    o LLVM IR\n    o Logos\n    o Meson\n    o Mojo\n    o Odin\n    o Jinja Templates\n    o WXML\n    o WXSS\n\nUpdates:\n    o Support MATLAB block comments.\n    o More flexible matching of git hashes.\n    o Case insensitive diff file alignment on Windows.\n    o Add .BAS as a Visual Basic extension\n    o Rename Objective C to Objective-C\n\nBug Fixes:\n    o Add missing Raku_or_Prolog() subroutine.\n    o Handle UTF encoded list files (file given to --list-file).\n    o Improved support for options parsing from config file.\n    o Catch unidentified files via --diff-list-file.\n    o Don't insert extra newlines when stripping with --unicode.\n\n============================================================================\n                Release Notes for cloc version 1.86\n                   https://github.com/AlDanial/cloc\n                             May 17, 2020\n\nNew Languages and File Types:\n    o ASP.NET Core Blazor WASM (*.razor)\n    o Bazel\n    o dhall\n    o Raku (renamed from Perl6)\n    o Squirrel\n    o SugarSS\n    o Svelte\n    o TNSDL\n    o Remove .tsv as a RobotFramework extension\n    o Add .inl as a C++ extension.\n    o Add #_ as a Closure comment marker.\n\nUpdates:\n    o Provide alternate algorithms for --git --diff:\n      --git-diff-rel computes differences of only files that have changed\n                     between the two git commits (this is now the default\n                     action with \"--git --diff\")\n      --git-diff-all computes differences between all files in the repo\n                     between the two git commits (this was the default\n                     action with \"--git --diff\" behavior in 1.84)\n    o New cloc releases will be accompanied by Docker instances on\n      Dockerhub.\n    o Support reading file names from a STDIN pipe.\n    o Check unrecognized files to see if they contain XML.\n    o Switch --vcs supports an 'auto' option to automatically determine\n      if one is counting in a subversion or git repository.\n    o Expand git archives in user-provided scratch directory with --sdir.\n    o Mask comment markers in Kotlin raw strings.\n    o Make output more deterministic with secondary sort of results.\n    o Avoid computation of log(0).\n    o Improve --strip-str-comments logic.\n    o Improve handling of triple quotes (Python, Groovy, Gradle).\n    o New switch --diff-list-file, to perform diff's using a provided\n      list file containing file pairs to compare.\n    o New switch --ignore-case-ext to ignore upper/lowercase of\n      file extension.\n\nBug Fixes:\n    o Fix --exclude-list-file with --diff.\n    o Fix creation of empty tar file if this happens during --git --diff.\n    o Restore --exclude-lang functionality with --diff.\n\n============================================================================\n                Release Notes for cloc version 1.84\n                   https://github.com/AlDanial/cloc\n                         September 22, 2019\n\nNew Languages and File Types:\n    o APL\n    o Apache Thrift\n    o Imba\n    o IPL\n    o SaltStack\n\nUpdates:\n    o Improved handling of --git --diff\n    o Add .podspec as a Ruby file extension.\n    o New switch, --stat, to force a stat check of\n      directories. This enables traversal of directory\n      types whose nlink count does not match the count\n      of subdirectories (examples: CD-ROM, FAT, AFS).\n    o Force stat on top level directories.  This is\n      companion logic to the new --stat switch.\n    o Add file extensions defined by the Linguist project.\n    o New switch, --exclude-content, to exclude files if\n      any of their lines match a regex.\n    o New switch, --timeout, to give control over timeouts\n      on direct counts (as opposed to diff timeouts).\n    o On Windows, lower batch size on git archive\n      commands to 100 files (the value is 1,000 on *nix).\n    o Better identification of Smarty .tpl template files.\n\nBug Fixes:\n    o On Windows, use double quotes for git archive entries.\n    o On Windows, double slash path separators with --by-file\n      and JSON output.\n    o On Windows, replace / with \\\\ in results only when\n      running with --by-file.\n    o Fix header line metrics for files/sec and lines/sec\n      when doing --diff.\n    o Python:  handle cases of /* or */ embedded in strings\n      (this conflicted with internal logic which replaced\n      docstring triple quotes with C comments).\n    o Fix mishandling of --exclude-dir with --follow-link.\n    o Fix doubly-counted #! line\n    o Support --hide-rate with csv output.\n\n============================================================================\n                Release Notes for cloc version 1.82\n                   https://github.com/AlDanial/cloc\n                           May  3, 2019\n\nNew Languages and File Types:\n    o Apex Class\n    o DIET\n    o Fennel\n    o FXML\n    o Jupyter notebook files (.ipynb)\n    o Python wheel files (.whl)\n    o SVG\n    o reStructuredText\n\nUpdates:\n    o Handle backslashed quotes in strings to improve --strip-str-comments\n      logic.\n    o Improve Perl v. Prolog identification.\n    o New switch --docstring-as-code to count Python docstrings as code.\n    o Partial support for Lua nested comments.\n    o Renamed Skylark to Starlark.\n    o Modified Java filter to try to handle embedded comments better.\n    o Recognize groovy as one of the #! languages.\n    o Add .pyw as a file extension for Python.\n    o Update comment definitions for Velocity Template Language.\n    o Override file alignment logic with --diff when only two files are\n      given.\n    o Identify TeX v. Visual Basic for .cls file extension.\n    o Include result summation line with --csv output.\n    o Support --csv, --json, --md, --xml, --yaml output types for the\n      --ignored debug file.\n    o Force IO encoding to allow wider Unicode characters for creating\n      Windows exe's with PAR::Packer\n\n============================================================================\n                Release Notes for cloc version 1.80\n                   https://github.com/AlDanial/cloc\n                           Oct. 5, 2018\n\nThis is a bug-fix release to solve mishandling of git inputs for\nstraight counts in 1.78 (--git --diff works ok in 1.78),\nhttps://github.com/AlDanial/cloc/issues/328.\n\nNew Languages:\n    o ReasonML\n\nUpdates:\n    o New SQL output style option with \"--sql-style Named_Columns\".  This\n      includes the table \"t\" column names in each insert statement.\n    o New option --file-encoding to create all output files using the\n      given file encoding (for example \"--file-encoding\n    o Add escript as script language for Erlang.\n    o Improved handling of custom Smarty definitions through\n      --read-lang-def.\n    o Better diff logic when comparing two files.\n    o Faster program start on the Unix-tuned version of cloc when\n      multiple processors are not used.\n\n============================================================================\n\n                Release Notes for cloc version 1.78\n                   https://github.com/AlDanial/cloc\n                           Sept. 7, 2018\n\nNew Languages:\n    o EJS\n    o Gradle\n    o Igor Pro\n    o JSON5\n    o Nix\n    o R Markdown\n    o SparForte\n    o Xtend\n\nUpdates:\n    o Interpret \"--diff-timeout 0\" as allowing unlimited time to compute\n      diffs.\n    o Add .inl extension for C++\n    o Improve language rules for Assembly and JCL.\n    o Better handling of OCaml comments (don't just use Pascal rules).\n    o Handle unusual file names with --use-sloccount.\n    o Remove GNU grep specific -P option with --use-sloccount (fall back\n      to simpler BSD grep options).\n    o Handle OCaml nested comments.\n    o Remove debug print statement for counts of Rmd (R markdown) files.\n    o New switch --include-ext to only count files with the given extension.\n    o New switch --config to load command line switches from a file.\n    o New switch --hide-rate to suppress header line (makes the output\n      deterministic).\n    o Skip header line when combining diff reports.\n    o Allow any number (including just one) of diff reports to be summed.\n    o Exit early if --diff arguments are the same.\n    o New switch --strip-str-comments to (try to) avoid 'Complex regular\n      subexpression recursion limit' warning.\n    o Run cleanly under Perl 5.28 and 5.32 by backslashing braces in regex.\n    o Suppord Idris block comments.\n    o Set UTF-8 encoding on XML and XSL files generated by cloc.\n    o New switch --write-lang-def-incl-dup to include files with extension \n      collisions (but should be used with care because the resulting language\n      definition file will be rejected by cloc until all collisions have been\n      resolved).\n\nBug Fixes:\n    o Correctly handle --not-match-d and --follow-links together.\n    o Fix --git --diff handling of large file sets.\n    o Remove \\$ from git pathspec filename-cleansing regex as git already\n      handles such filename mangling\n    o Remove debug die() invocation in make_file_list().\n    o Fix improperly formatted JSON emitted with --by-file-by-lang.\n    o Improve accuracy of C#/Smalltalk disambuguator (was biased toward\n      counting .cs files as Smalltalk).\n    o Improve accuracy of TypeScript/Qt Linguist disambuguator.\n    o More robust YAML output by quoting file and language names.\n    o Handle more unusual file names with --git --diff\n\n============================================================================\n                Release Notes for cloc version 1.76\n                   https://github.com/AlDanial/cloc\n                          February 9, 2018\n\nNew Languages:\n    o Agda\n    o AsciiDoc\n    o Chapel\n    o Fish Shell\n    o Gencat NLS\n    o Lean\n    o HCL\n    o Oracle PL/SQL\n    o PL/M\n    o ProGuard\n    o RAML\n    o Skylark\n    o SWIG\n\nUpdates:\n    o Performance improvement by using multiple cores for both\n      straight counts and --diff via the new --processes option\n      added by Sietse Snel, https://github.com/stsnel.\n    o Support --git on Windows.\n    o Improve identification of Qt Project files (instead of IDL).\n    o Fix language determination logic so that languages that map\n      to the same file extension and have ties in the number of\n      accumulated points always return the same result.\n    o Add support for replace_between_regex in --write_lang_def and\n      --read_lang_def.\n    o Add SUM section to JSON, YAML output with --diff.\n    o Make numeric values in JSON output numbers instead of strings.\n    o Optionally exclude autogenerated files with new --no-autogen\n      (currently only supports the Go language).\n\nBug Fixes:\n    o Remove temp directory prefix for YAML and JSON output when\n      counting git archives with --by-file.\n    o Properly handle git files with spaces embedded in the file name.\n    o Remove a debug regex inadvertently included in v1.74.\n\n============================================================================\n                Release Notes for cloc version 1.74\n                   https://github.com/AlDanial/cloc\n                          September 8, 2017\n\nNew Languages:\n    o BrightScript\n    o Cucumber\n    o Drools\n    o F# Script\n    o GraphQL\n    o Idris\n    o Literate Idris\n    o Smalltalk\n    o Solidity\n    o Stata\n    o TOML\n\nUpdates:\n    o New option, --git, to allow git commit hashes and branch\n      names as inputs (issue 205).\n    o Add .asd extension for Lisp.\n    o Add .snapshot to the list of excluded directories.\n    o New option --no-autogen to ignore files generated\n      by code production systems like GNU autoconf.\n    o Rename \"ASP.Net\" to \"ASP.NET\".\n    o Improvements to Specman e parsing (issue 175).\n    o Support uppercase CPP extension (issue 177).\n    o Support triple extensions.\n    o Improve language distinction between C# and Smalltalk (issue 160).\n    o Consider Elixir docs as comments.\n    o Handle Python docstrings made with single quotes.\n    o Replace built-in \"is it a file?\" and \"is it a directory?\"\n      with native Perl -f and -d operators (these were unreliable\n      on older versions of Perl on Windows).\n    o Put timeout around Regexp::Common regex evaluation to prevent\n      hangs on unbalanced comment markers within huge strings (issue 206).\n    o Fix Pascal regex with '{' for Perl version >= 5.26 (issue 209)\n      and '(*', '*)' comment matching (issue 212).\n    o Rename Antlr to ANTLR Grammar.\n    o Add .g4 extension for ANTLR Grammar.\n    o Replace soon-to-be deprecated File::Glob::glob() with\n      File::Glob::bsd_glob() (issue 214).\n    o Revert from charset=iso-8859-1 to charset=utf-8 on undocumented\n      --html option.\n    o For Assembly, process # comments before C++ comments.\n\nBug Fixes:\n    o Correct handling of remove_between_general and\n      remove_between_regex when running with --read-lang-def (issue 166)\n    o Fix bug handling balanced parentheses in Forth (issue 183)\n    o Force legal output filenames with --count-and-diff and --out\n      (issue #220).\n\n============================================================================\n                Release Notes for cloc version 1.72\n                   https://github.com/AlDanial/cloc\n                          January 14, 2017\n\nNew Languages:\n    o Antlr\n    o Dockerfile\n    o Glade\n    o GLSL\n    o Lisp Flavored Erlang\n    o Mako\n    o PO files (used for translations in GTK programming)\n    o RapydScript\n    o Slice interface specification language\n    o Specman e\n    o Vue.js Component\n\nUpdates:\n    o Support for Lua --[[ ]] block comments.\n    o Improve --not-match-d support.\n    o Add extension .tsx for TypeScript.\n    o Renamed SASS to Sass.\n    o '--vcs git' now ignores code in git submodules.\n    o Add .p6 and .pm6 extensions for Perl 6.\n    o Add .phtml extension for PHP.\n    o Add .psm1 and .psd1 extensions for PowerShell.\n    o Only print a small usage summary when running cloc without\n      arguments.  Now have to run 'cloc --help' to get the huge\n      output.\n\nBug Fixes:\n    o Filter updates for Assembly, Groovy to prevent infinite recursion in\n      regex.\n    o Correct handling of Julia block comments.\n    o Correct output when running with '--diff --json' or '--diff --yaml'.\n    o Fix logic error in code that handled --exclude-dir.\n    o Fix error in handling of '--vcs X' where X is a user-provided\n      command to generate a list of files.\n\n============================================================================\n                Release Notes for cloc version 1.70\n                   https://github.com/AlDanial/cloc\n                             July 1, 2016\n\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *   v1.70 is a bugfix release to correct the \"which: no abc in\"   *\n *   problem seen on non-Debian based Linux distributions; ref.    *\n *   https://github.com/AlDanial/cloc/issues/105                   *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\nNew Languages:\n    o Freemarker Template\n    o Haxe\n    o Nim\n    o TeX\n\nUpdates:\n    o Improved handling for Forth comments.\n\nBug Fixes:\n    o Fixed \"which: no abc in\" bug; issue 105\n      https://github.com/AlDanial/cloc/issues/105\n\n============================================================================\n                Release Notes for cloc version 1.68\n                   https://github.com/AlDanial/cloc\n                             June 3, 2016\n\nNew Languages:\n    o Blade\n    o Brainfuck\n    o builder\n    o Clean\n    o INI\n    o JSX\n    o liquid\n    o Logtalk\n    o Markdown\n    o Mathematica\n    o Pug\n    o Qt Linguist\n    o Slim\n    o TTCN\n\nUpdates:\n    o --help output now goes to STDOUT instead of STDERR.\n    o Shortened cloc's output header line by removing \"https:\" from the\n      github repository URL.\n    o Add block comment support to CoffeeScript.\n    o Improve Coq/Verilog disambiguator by recognizing more Coq keywords.\n    o Improve handling of HAML block comments.\n    o Improve Pascal/Puppet disambiguator.\n    o Improve Perl/Prolog disambiguator by recognizing Perl HERE documents.\n    o Add .cuh extension for CUDA.\n    o Add .hxx extension for C/C++ header files.\n    o Associate .mk extension with make.\n\nNew options and features:\n\n    --use-sloccount           If SLOCCount is installed, use its compiled\n                              executables c_count, java_count, pascal_count,\n                              php_count, and xml_count instead of cloc's\n                              counters.  SLOCCount's compiled counters are\n                              substantially faster than cloc's and may give\n                              a performance improvement when counting projects\n                              with large files.  However, these cloc-specific\n                              features will not be available: --diff,\n                              --count-and-diff, --strip-comments, --unicode.\n     --vcs=<VCS>              Invoke a system call to <VCS> to obtain a list of\n                              files to work on.  If <VCS> is 'git', then will\n                              invoke 'git ls-files'.  If <VCS> is 'svn' then\n                              will invoke 'svn list -R'.  The primary benefit\n                              is that cloc will then skip files explicitly\n                              excluded by the versioning tool in question,\n                              ie, those in .gitignore or have the svn:ignore\n                              property.\n                              Alternatively <VCS> may be any system command\n                              that generates a list of files.\n                              Note:  cloc must be in a directory which can read\n                              the files as they are returned by <VCS>.  cloc\n                              will not download files from remote repositories.\n                              'svn list -R' may refer to a remote repository\n                              to obtain file names (and therefore may require\n                              authentication to the remote repository), but\n                              the files themselves must be local.\n \n\n    o Handle .deb archive files on Unix-like operating systems that have\n      the Debian 'dpkg-deb' command.  This is only useful for counting\n      lines in Debian packages that contain source code--most contain\n      only compiled executables.\n\nBug Fixes:\n    o Updated documentation for --exclude-dir to prohibit path separators.\n    o Correct file path normalization problem when directory contains\n      trailing slash.\n    o --list-file:  Return an empty list if the file cannot be read.\n    o --exclude-dir:  correctly handle command line input consisting of a \n      file with leading directory names, eg abc/def/hello.c, by first\n      checking that parent directories aren't in exclusion list.\n    o Expand behavior of --fullpath to also work with --not-match-d.\n    o Split into two statements expressions like \"scalar(split(..))\"\n      which are deprecated in Perl 5.22.\n    o --sum-reports: Give a useful error message when encountering an unknown \n      language during report summation.\n\n============================================================================\n                Release Notes for cloc version 1.66\n                   https://github.com/AlDanial/cloc\n                          January 23, 2016\n\nNew Languages:\n    o AspectJ\n    o Coq\n    o CSON (CoffeeScript Object Notation)\n    o Crystal\n    o DOORS Extension Language\n    o EEx (Embedded Elixir)\n    o Elm\n    o Forth\n    o GDScript\n    o Jam\n    o Nemerle\n    o PowerBuilder\n    o Stylus\n    o Twig\n    o XHTML\n    o XMI (XML Metadata Interchange)\n    o zsh\n\nUpdates:\n    o Add block comment support to CoffeeScript.\n    o .xhtml is no longer associated with JavaServer Faces; instead\n      it is counted as XHTML\n    o Remove association of .config to ASP.Net (.config is too\n      general to be appropriated by one language).\n    o Support .hlsl extension for HLSL.\n    o Changes to support Perl v5.22:\n      * Remove references to deprecated \"defined(@array)\".\n      * Remove \"no warnings 'deprecated'\" as it is no longer needed.\n    o Greater reliance on Regexp::Common's C++ regex instead of\n      using internal // filter.\n    o Update code pulled from Regexp::Common 2.120 to 2013031301.\n    o Support .f and .for extensions for Forth and disambiguate\n      between Fortran and Forth.\n    o Better output with --explain for languages that share file\n      extensions.\n    o Ignore .o.cmd files as they are Linux kernel compilation\n      optimization files.\n    o Add .kts extension for Kotlin.\n    o Add .cljc extension for ClojureC.\n    o Add .ui extension for Qt.\n    o Support php and php5 as #! scripting languages.\n\nNew options and features:\n\n   --json                    Write the results as JavaScript Object Notation\n                             (JSON) formatted output.\n   --fullpath                Modifies the behavior of --match-f or\n                             --not-match-f to include the file's path\n                             in the regex, not just the file's basename.\n                             (This does not expand each file to include its\n                             absolute path, instead it uses as much of\n                             the path as is passed in to cloc.)\n   --md                      Write the results as Markdown-formatted text.\n   --verbose                 Synonym for -v.\n\n\nBug Fixes:\n    o Don't write language definition for \"(unknown)\" (via --write-lang-def).\n    o Fix length of hyphen line with --sum-reports. \n    o Fix uninitialized variable bug when --explain is given an unknown\n      language.\n    o Force files ending with .smarty to be counted as Smarty (unless over-\n      ridden by --force-lang=X).\n    o Fix hash reference bug triggered with '--csv --by-percent' combination .\n    o Correctly recognize R files on Windows.\n\n============================================================================\n                Release Notes for cloc version 1.64\n                   http://cloc.sourceforge.net\n                           June 27, 2015\n\nNew Languages:\n    o DITA\n    o dtrace\n    o Elixir\n    o Embedded Ruby\n    o Julia\n    o Mercury\n    o Prolog\n    o Protocol Buffers\n    o PureScript\n    o Qt Project\n    o Racket\n    o SAS\n    o Standard ML\n    o Titanium Style Sheet\n    o Visual FoxPro\n    o Windows Module Definition\n\nUpdates:\n    o Add support for sharpsign vertical bar block comments in Lisp.\n    o Added python, python2.6, python2.7, python3, python3.3, python3.4\n      as script executables to identify Python files that don't end in .py.\n    o Added rexx and regina as script executables for Rexx.\n    o Extend Assembly filters to include !, |, @, --.\n    o Add for, FOR, ftn, FTN extensions for Fortran 77.\n    o Improve --show-lang so that it exactly matches a language instead of\n      finding the language in a regex (eg 'C' matched nearly everything).\n    o Update --explain to also print language extensions.\n    o Change --sql schema by adding fields File_dirname, File_basename to \n      table 't' of SQL output to simplify obtaining per-directory metrics\n    o Escape embedded single quotes in file names (bug #127) for SQL output.\n    o Improved language detection for Objective C (earlier misidentified\n      as MATLAB or other .m languages).\n    o Sort duplicate file lists by full path instead of basename to give\n      repeatable output.\n    o Change SQL schema 'text' type to more standard 'varchar(500)'.\n    o Added .gradle extension for Groovy.\n    o Better handling of files ending with .d (could be Linux init scripts).\n    o Added .robot extension for RobotFramework.\n    o Support Python unicode docstrings, patch by <clemens@kaposi.name>.\n    o Ignore line ending styles when diff'ing Windows and Unix files.\n\n\nNew options and features:\n\n   --count-and-diff <set1> <set2>\n                            First perform direct code counts of source file(s)\n                            of <set1> and <set2> separately, then perform a \n                            diff of these.  Inputs may be pairs of files, \n                            directories, or archives.  See also --diff, \n                            --diff-alignment, --diff-timeout, --ignore-case, \n                            --ignore-whitespace.\n\n   --include-lang=<L1>[,L2,]\n                           Count only the given comma separated languages\n                           L1, L2, L3, et cetera.\n                           Patch by Ryan Lindeman.\n\n   --by-percent  X         Instead of comment and blank line counts, show\n                           these values as percentages based on the value\n                           of X in the denominator:\n                              X = 'c'   -> # lines of code\n                              X = 'cm'  -> # lines of code + comments\n                              X = 'cb'  -> # lines of code + blanks\n                              X = 'cmb' -> # lines of code + comments + blanks\n                           For example, if using method 'c' and your code\n                           has twice as many lines of comments as lines\n                           of code, the value in the comment column will\n                           be 200%.  The code column remains a line count.\n                           Patch by Ryan Lindeman.\n\n   --sql-style=<style>     Write SQL statements in the given style instead\n                           of the default SQLite format.  Currently, the\n                           only style option is Oracle.\n\n\nBug Fixes:\n    o Added a more sophisticated method to align top level directories\n      for --diff.\n    o Fixes XML output when running with --sum-reports and --xml so the\n      .lang file ends with <languages/> and the .file file ends with\n      <files/> (previously both ended with <languages/>).\n    o Fix logig error when handling HAML block comments.\n    o Fix language filter for Groovy.\n    o Fix some forward and backslash issues with file name parsing\n      in Windows filenames during --diff.\n    o Handle --exclude-file-list when running with --diff.\n    o Fix regex error for detecting double extensions (eg .sproc.sql)\n      provided by Super Dave <faygo@users.sf.net>\n\n============================================================================\n                Release Notes for cloc version 1.62\n                   http://cloc.sourceforge.net\n                           July 29 2014\n\nNew Languages:\n    o CUDA\n    o ECPP\n    o F#\n    o Grails\n    o Haml\n    o Handlebars\n    o Harbour\n    o HLSL\n    o JSON\n    o Kotlin\n    o Mustache\n    o PL/I\n    o Puppet manifest\n    o R\n    o Racket\n    o Rake\n    o RobotFramework\n    o Swift\n    o TypeScript\n    o Unity-Prefab\n    o Velocity Template Language\n    o Windows Message\n    o Windows Module Definition\n    o Windows Resource\n    o WiX include\n    o WiX source\n    o WiX string localization\n    o xBase\n    o xBase Header\n    o XQuery\n\nUpdates:\n    o JSP             Added extension  .jspf\n    o MSBuild script  Added extensions .vcproj, .wixproj, .vbproj\n    o DOS Batch       Added extensions .cmd, .btm\n    o C++             Added extension  .c++\n    o Pascal          Lines that begin with {! are counted as code as\n                      some compilers treat these as a compiler directives.\n    o Lisp            Treat text between #| and |# as a block comment.\n    o Suppress progress rate display if --quiet is set.\n    o --exclude-dir directories are pruned before the file search \n      descends into those directories instead of just ignoring\n      files there\n    o The logic that aligns file pairs between --diff sets was \n      rewritten.  Corner cases such as diff between one file and\n      a set of files are handled much more precisely.\n\nNew options and features:\n\n   --explain=LANG            Print the filters used to remove comments for\n                             language LANG and exit.  In some cases the \n                             filters refer to Perl subroutines rather than\n                             regular expressions.  An examination of the\n                             source code may be needed for further explanation.\n\n   Added new filter macros:\n      o remove_between_general, which accepts start and end comment marker.\n      o remove_between_regex, which accepts start and end comment regexes.\n\n   Properly handle text files that begin with Unicode Byte Order Marks.\n\nBug Fixes:\n\n    Remove spurious newlines produced by bad comment removal regexes\n    which could cause incorrect diff's.\n    Correctly handle file extensions with non-alphanumeric characters.\n    Show file count with --sum-reports.\n    Properly encode characters &,<,>,\",' in XML output.\n    Properly read and write entries for the 'remove_between_general'\n    macro in language definition text files.\n\n============================================================================\n                Release Notes for cloc version 1.60\n                   http://cloc.sourceforge.net\n                           August 16, 2013\n\nNew Languages:\n    o LESS\n    o Razor\n    o JavaServer Faces\n    o SASS\n    o Apex Trigger\n    o Visualforce Component\n    o Visualforce Page\n    o Verilog-SystemVerilog\n    o Pig Latin\n\nUpdates:\n    o Improved handling of UTF-16 (both little and big endian).\n    o use Time::HiRes if available.\n    o Improved logic that distinguishes between Objective C,\n      MUMPS and MATLAB files.\n    o Added information about duplicate files to output created\n      by --ignored.\n    o Added support for .tar.xz compressed archives.\n    o CMake                Added .cmake file extension.\n    o MXML                 Added support for Actionscript\n    o Groovy               Added .gant file extension.\n    o Vala                 Recognize Vala header files.\n\nNew options and features:\n\n   --max-file-size=<MB>      Skip files larger than <MB> megabytes when\n                             traversing directories.  By default, <MB>=100.\n                             cloc's memory requirement is roughly twenty times \n                             larger than the largest file so running with \n                             files larger than 100 MB on a computer with less \n                             than 2 GB of memory will cause problems.  \n                             Note:  this check does not apply to files \n                             explicitly passed as command line arguments.\n\nBug Fixes:\n\n    Suppress \"Wrote <file>\" messages when running with --quiet.\n    Fixed an error that caused cloc to fail with \"Can't use an \n    undefined value as an ARRAY reference\" when running with \n    Perl 5.16 or newer when it encounters certain file types.\n\n============================================================================\n                Release Notes for cloc version 1.58\n                   http://cloc.sourceforge.net\n                           March 3, 2013\n\nVersion 1.58 introduces a new version numbering scheme:  odd numbers \nrepresent development versions while even numbers represent stable,\nreleased versions.  There was no release 1.57 as it was the development\nversion leading to this release.\n\nNew Languages:\n    o Ant\n    o Arduino Sketch\n    o InstallShield\n    o Maven\n    o PowerShell\n    o Rust\n    o Vala\n\nUpdates:\n    o OCaml                Added extensions .mli, .mly, .mll\n    o --read-lang-def      See the section --read-lang-def v. \n                           --force-lang-def below.\n\nNew options and features:\n\n  --diff-timeout N\n      o Running diff on large files with many repeated lines may\n        cause Algorithm::Diff::sdiff() to run for hours.  This\n        option sets the upper time limit on the duration of this\n        operation for a single file pair.  Default is 10 seconds.\n\n  --force-lang-def FILE\n      o See the section --read-lang-def v. --force-lang-def below.\n\n  --skip-archive REGEX\n      o Ignore files that end with the given Perl regular expression.  \n        For example, if given --skip-archive='(zip|tar(.(gz|Z|bz2|xz|7z))?)'\n        the code will skip files that end with .zip, .tar, .tar.gz, \n        .tar.Z, .tar.bz2, .tar.xz, and .tar.7z (feature req. 32).\n\n    Prevent \"defined(@array) is deprecated\" warnings with Perl 5.16.1.\n\n    Show an example of alternation in the documentation for the --match-d\n    switch.\n\n\n--read-lang-def v. --force-lang-def\n      \n    The --read-lang-def option allows one to replace cloc's language\n    processing filters with custom settings.  The problem with this\n    option is that it overwrites internal logic that handles languages\n    which map to the same file extension.  Currently these are\n        MATLAB/Objective C/MUMPS   -> .m\n        Pascal/PHP                 -> .inc\n        Lisp/OpenCL                -> .cl\n    The logic needed to handle these extension collisions is not\n    easily expressed in an input text file.  In any event, in most\n    instances one merely wishes to augment cloc's language definitions\n    with entries for new languages rather than replace definitions\n    for known languages.\n\n    For this reason, the behavior of --read-lang-def has been changed\n    to merge new language definitions found in the given file with\n    cloc's existing languages.  Where there are conflicts, cloc's\n    built-in definitions take precedence.  This new behavior allows\n    one to add new language definitions without sacrificing cloc's\n    ability to count files languages ending with .m, .inc, or .cl.\n\n    The new option --force-lang-def behaves exactly like --read-lang-def\n    did in cloc versions 1.56 and earlier--it completely ignores\n    cloc's internal language definitions and replaces them with definitions\n    in the given file.  However, one will no longer be able to count\n    files with the extensions .m, .inc, or .cl.\n\nBug Fixes:\n\n    Suppress \"Wrote <file>\" messages when running with --quiet.\n\n    Create .file output when running with --sum-reports (id 3571353).\n\n    Correct output for languages starting with a lower case letter when \n    running with --diff --sum-reports.\n\n    Show correct count of files added/deleted with --diff (id 78).\n\n    Handle special case of --diff between one file and a set of files (id 82).\n\n    Prevent cloc from inadvertently counting lines from temporary\n    installations of Algorithm::Diff and/or Regexp::Common.  This happens\n    on faulty Perl installations (eg. MinGW MSYS Perl) which cause \n    File::Temp::tempdir() to return the current working directory.\n\n============================================================================\n                Release Notes for cloc version 1.56\n                   http://cloc.sourceforge.net\n                           April 3, 2012   \n\nVersion 1.56 introduces an additional documentation file, cloc.1.pod, which\ncan be used to produce cloc's documentation in the style of a Unix man page,\nplain text, HTML, or LaTeX.\n\nNew Languages:\n    o Clojure\n    o ClojureScript\n    o AutoHotkey\n    o QML\n    o CFScript\n    o OpenCL\n\nNew options and features:\n\n  --unix\n      o Override the operating system autodetection logic and run in \n        UNIX mode.\n\n  --windows\n      o Override the operating system autodetection logic and run in \n        Microsoft Windows mode.\n\n  --show-os\n      o Print the name of the of the operating system mode and exit.\n\n  --csv-delimiter\n      o Use the provided delimiter instead of a comma when generating \n        csv output.\n\n  --stdin-name\n      o On UNIX systems, enables cloc to count code piped in via STDIN.\n        This switch provides a filename for to use to infer the language.\n\n  .git subdirectories are now ignored.\n\n  Updated yacc counter to recognize C99 comments.\n\n  Improved detection and reporting of ignored zero sized files.\n\n  Removed spurious <languages> from YAML output.\n\n  Fixed handling of multi-line Ruby comments surrounded by =begin/=end.\n\n  Associated .ctl and .dsr extensions with Visual Basic\n\nBug Fixes:\n\n  Produce correct diff results when comparing empty files with populated \n  files.\n\n  Remove temporary directory names from --by-file output when working\n  with archive files.\n\n  Honor user's requested scratch directory if given --sdir.\n\n============================================================================\n                Release Notes for cloc version 1.55\n                   http://cloc.sourceforge.net\n                          October 14, 2011\n\nVersion 1.55 is a bugfix release to correct malformed XML output \nthat was introduced in the 1.54 release.  Two minor enhancements\nwere added:\n\nNew Languages:\n    o Dart\n\nNew options and features:\n\n  --sum-one\n      o Force printing of the SUM: line even if only one source\n        file is counted.\n\n============================================================================\n                Release Notes for cloc version 1.54\n                   http://cloc.sourceforge.net\n                          October 1, 2011\n\n\nNew Languages:\n    o CMake\n    o Cython\n    o Objective C++\n    o Ocaml\n    o Smarty\n\nNew options and features:\n\n  --autoconf\n      o Count files of recognized languages that end with \".in\"\n        (for example, code.h.in, Makefile.in) as used by GNU\n        automake/autoconf.\n\n  --match-d, --not-match-d\n      o Include, or skip over, directories whose names match\n        provided regular expressions.\n\n  --follow-links\n      o Follow symbolic links (on Unix-like OS's).\n\n  YAML and XML output:  header lines now include the cloc URL,\n  version, # lines and files counted, etc.\n\n  YAML and XML output:  if writing to a file (rather than STDOUT),\n  save the file name as an element inside the file.\n\n  Include support for languages with double extensions.  First\n  implementation of these uses .spc.sql for SQL Stored Procedures \n  and .data.sql as SQL Data as distinct from just SQL.\n\n  Handle archive files (tar files, zip files, etc) with spaces\n  in their names.\n\nBug Fixes:\n\n  Lisp:  Include .lisp as a valid file extension.\n\n  Correctly identify operating system as Windows if MKS Toolkit is \n  installed.\n\n  Fix incorrectly handled .inc files (could be PHP or Pascal).\n\n  --counted\n      o Correct output to show only files which were actually\n        used to produce the code count.  Also show the output\n        by language rather than by filename.\n\n  --diff\n      o Fixed null output when one input has a single file while\n        the comparison input has multiple files.\n      o Fixed null output when no lines of code are modified in\n        common files (only entire files were added or removed).\n      o Handle cases where one of the two inputs is an empty\n        file or directory.\n\n  --diff + --exclude-file-list\n      o --diff now skips files defined by --exclude-file-list\n\n  --diff + --exclude-lang\n      o --diff now skips languages defined by --exclude-lang\n\n  --diff + --xml   \n      o Include user-provided xsl file name in XML --diff output.\n      o XML output for --by-file and --by-file-by-lang.\n  \n  --diff + --csv\n      o Added comma separated value output for --diff.\n  \n  --diff + --sum-reports\n      o Can now use the --sum-reports option with --diff.\n\n  --exclude-dir\n      o Quote metacharacters when comparing directory names against \n      --exclude-dir value.\n\n  --strip-comments\n      o Do not remove blank lines if they follow lines with\n        (language-dependent) continuation markers.\n\n  --sum-reports + --list-file\n      o Allow the --sum-reports option to take its inputs from\n        files defined by --list-file\n\nOutstanding issues:\n  --sql output formats remain unimplemented for --diff.\n\n============================================================================\n                Release Notes for cloc version 1.53\n                   http://cloc.sourceforge.net\n\nNew Languages:\n    o Go\n    o MXML\n\nNew options:\n\n  --lang-no-ext\n      o Alternate method to count files without file\n        extension.\n  --ignore-case  \n      o Works with --diff; treat uppercase and lowercase text\n        as equivalent.\n\nBug Fixes:\n\n  Pascal:  Add // as a comment marker.\n  IDL:     Include .pro as a recognized file extension.\n\n  --3:   \n      o Correct XSLT style when running with --3.\n  \n  --diff:   \n      o Implemented YAML output option.\n      o Implemented XML output option.  Includes an optional\n        default XSLT style file.\n      o Include code/comment/blank counts of added files to  \n        total added material and include code/comment/blank\n        counts of removed files to total removed material.\n      o Ignore unrecognized languages.\n  \n  --exclude-ext\n      o Was inadvertently disabled in v1.52; works now.\n\nOutstanding issues:\n  --csv, --sql output formats remain unimplemented for --diff.\n\n============================================================================\n                Release Notes for cloc version 1.52\n                   http://cloc.sourceforge.net\n\nNew Languages:\n    o Groovy\n    o Scala\n    o XAML\n\nNew options:\n\n  --exclude-ext \n      o Ignore files with the given file extension.\n  \n  --ignore-whitespace  \n      o Works with --diff; ignore whitespace in code and comments\n        when computing differences.\n\nBug Fixes:\n\n  Fortran:  Treat line starting with an exclamation mark as a comment.\n  Cobol:    Treat page eject directive and any line with characters\n            in columns 1-6 as a blank line.\n  \n  --diff:   \n      o Fix negative value of removed blank lines.\n      o Better output column alignment when running with --by-file.\n      o Bug fixes when dealing with fully qualified Windows paths.\n  \n  --exclude-list-file  \n      o Can now also include directories to ignore in the supplied \n        input file.\n\nOther Improvements:\n    o Better logic to select the file whose name identifies it as\n      containing source code when the file is one of several having \n      identical contents (for example, if main.c and main.c.bak have\n      identical contents, choose main.c for counting instead of \n      main.c.bak, which would be rejected because the filename\n      does not match any recognized language).\n    o Contents of .hg/ (Mercurial) directories are ignored.\n    o On Windows: Ignore case in file name extensions.\n"
  },
  {
    "path": "Unix/README",
    "content": "README: cloc - statistics utility to count lines of code\n----------------------------------------------------------------\n\nCount physical lines of source code in the given files (may be\narchives such as compressed tarballs or zip files) and/or recursively\nbelow the given directories.  Given two directories or archive\nfiles, it can compute differences of source code and comments\nbetween the code bases.\n\nImportant files\n\n    COPYING         GPL v2 or later Licence\n    INSTALL         Install instructions\n    NEWS       \t    Project change records\n\nProject details\n\n    Homepage\n      https://github.com/AlDanial/cloc\n\n    To report bugs\n      See Devel site\n\n    Source code repository\n      See Devel site\n\n    Depends\n      Perl (version 5.006 or newer). Uses only standard Perl libraries.\n      CPAN Algorithm::Diff\n      CPAN Regexp::Common\n      CPAN Parallel::ForkManager\n      CPAN Digest::MD5\n\nEnd of file\n"
  },
  {
    "path": "Unix/cloc",
    "content": "#!/usr/bin/env perl\n# cloc -- Count Lines of Code                  {{{1\n# Copyright (C) 2006-2026 Al Danial <al.danial@gmail.com>\n# First release August 2006\n#\n# Includes code from:\n#   - SLOCCount v2.26\n#     http://www.dwheeler.com/sloccount/\n#     by David Wheeler.\n#   - Regexp::Common v2017060201\n#     https://metacpan.org/pod/Regexp::Common\n#     by Damian Conway and Abigail.\n#   - Win32::Autoglob 1.01\n#     https://metacpan.org/pod/Win32::Autoglob\n#     by Sean M. Burke.\n#   - Algorithm::Diff 1.1902\n#     https://metacpan.org/pod/Algorithm::Diff\n#     by Tye McQueen.\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# <http://www.gnu.org/licenses/gpl.txt>.\n#\n# 1}}}\nmy $VERSION = \"2.09\";  # odd number == beta; even number == stable\nmy $URL     = \"github.com/AlDanial/cloc\";  # 'https://' pushes header too wide\nrequire 5.10.0;\n# use modules                                  {{{1\nuse warnings;\nuse strict;\n\nuse Getopt::Long;\nuse File::Basename;\nuse File::Temp qw { tempfile tempdir };\nuse File::Find;\nuse File::Path;\nuse File::Spec;\nuse IO::File;\nuse List::Util qw( min max );\nuse Cwd;\nuse Encode qw( encode );\nuse POSIX qw { strftime ceil};\n\n# Digest::MD5 isn't in the standard distribution. Use it only if installed.\nmy $HAVE_Digest_MD5 = 1;\nuse Digest::MD5;\n#eval \"use Digest::MD5;\";\n#if (defined $Digest::MD5::VERSION) {\n#    $HAVE_Digest_MD5 = 1;\n#} else {\n#    warn \"Digest::MD5 not installed; will skip file uniqueness checks.\\n\";\n#}\n\n# Time::HiRes became standard with Perl 5.8\nmy $HAVE_Time_HiRes = 1;\nuse Time::HiRes;\n\nmy $HAVE_Rexexp_Common = 1;\n# Regexp::Common isn't in the standard distribution.  It will\n# be installed in a temp directory if necessary.\nuse Regexp::Common qw ( comment );\neval \"use Regexp::Common qw ( comment ) \";\n#if (defined $Regexp::Common::VERSION) {\n#    $HAVE_Rexexp_Common = 1;\n#} else {\n#    $HAVE_Rexexp_Common = 0;\n#}\n\n# Uncomment next two lines when building Windows executable with perl2exe\n# or if running on a system that already has Regexp::Common.\n#use Regexp::Common;\n#$HAVE_Rexexp_Common = 1;\n\n#perl2exe_include \"Regexp/Common/whitespace.pm\"\n#perl2exe_include \"Regexp/Common/URI.pm\"\n#perl2exe_include \"Regexp/Common/URI/fax.pm\"\n#perl2exe_include \"Regexp/Common/URI/file.pm\"\n#perl2exe_include \"Regexp/Common/URI/ftp.pm\"\n#perl2exe_include \"Regexp/Common/URI/gopher.pm\"\n#perl2exe_include \"Regexp/Common/URI/http.pm\"\n#perl2exe_include \"Regexp/Common/URI/pop.pm\"\n#perl2exe_include \"Regexp/Common/URI/prospero.pm\"\n#perl2exe_include \"Regexp/Common/URI/news.pm\"\n#perl2exe_include \"Regexp/Common/URI/tel.pm\"\n#perl2exe_include \"Regexp/Common/URI/telnet.pm\"\n#perl2exe_include \"Regexp/Common/URI/tv.pm\"\n#perl2exe_include \"Regexp/Common/URI/wais.pm\"\n#perl2exe_include \"Regexp/Common/CC.pm\"\n#perl2exe_include \"Regexp/Common/SEN.pm\"\n#perl2exe_include \"Regexp/Common/number.pm\"\n#perl2exe_include \"Regexp/Common/delimited.pm\"\n#perl2exe_include \"Regexp/Common/profanity.pm\"\n#perl2exe_include \"Regexp/Common/net.pm\"\n#perl2exe_include \"Regexp/Common/zip.pm\"\n#perl2exe_include \"Regexp/Common/comment.pm\"\n#perl2exe_include \"Regexp/Common/balanced.pm\"\n#perl2exe_include \"Regexp/Common/lingua.pm\"\n#perl2exe_include \"Regexp/Common/list.pm\"\n#perl2exe_include \"File/Glob.pm\"\n\nuse Text::Tabs qw { expand };\nuse Cwd qw { cwd };\nuse File::Glob;\n# 1}}}\n# Usage information, options processing.       {{{1\nmy $ON_WINDOWS = 0;\n   $ON_WINDOWS = 1 if ($^O =~ /^MSWin/) or ($^O eq \"Windows_NT\");\nif ($ON_WINDOWS and $ENV{'SHELL'}) {\n    if ($ENV{'SHELL'} =~ m{^/}) {\n        $ON_WINDOWS = 0;  # make Cygwin look like Unix\n    } else {\n        $ON_WINDOWS = 1;  # MKS defines $SHELL but still acts like Windows\n    }\n}\nmy $ON_MINGW64 = 0; # git-bash on Windows has special needs\nif (!$ON_WINDOWS and defined $ENV{'SSH_ASKPASS'} and $ENV{'SSH_ASKPASS'} =~ m{^/mingw64/}) {\n    $ON_MINGW64 = 1;\n}\n\nuse Cwd \"abs_path\";\nuse File::Spec;\n# Fix for issues when runing cloc through a symlink on Windows\n# e.g. : it have been installed with Winget\n# See https://github.com/AlDanial/cloc/issues/849\nif ($ON_WINDOWS) {\n    my $exec_path = abs_path($0);\n    if (-l $0) {\n        $exec_path = abs_path(readlink($0));\n    }\n    $0 = $exec_path;\n}\n\nmy $HAVE_Win32_Long_Path = 0;\n# Win32::LongPath is an optional dependency that when available on\n# Windows will be used to support reading files past the 255 char\n# path length limit.\nif ($ON_WINDOWS) {\n    eval \"use Win32::LongPath;\";\n    if (defined $Win32::LongPath::VERSION) {\n        $HAVE_Win32_Long_Path = 1;\n    }\n}\nmy $config_file = '';\nif ( $ENV{'HOME'} ) {\n    $config_file = File::Spec->catfile( $ENV{'HOME'}, '.config', 'cloc', 'options.txt');\n} elsif ( $ENV{'APPDATA'} and $ON_WINDOWS ) {\n    $config_file = File::Spec->catfile( $ENV{'APPDATA'}, 'cloc');\n}\n# $config_file may be updated by check_alternate_config_files()\n\nmy $NN     = chr(27) . \"[0m\";  # normal\n   $NN     = \"\" if $ON_WINDOWS or !(-t STDOUT); # -t STDOUT:  is it a terminal?\nmy $BB     = chr(27) . \"[1m\";  # bold\n   $BB     = \"\" if $ON_WINDOWS or !(-t STDOUT);\nmy $script = basename $0;\n\n#  Intended for v1.88:\n#  --git-diff-simindex       Git diff strategy #3:  use git's similarity index\n#                            (git diff -M --name-status) to identify file pairs\n#                            to compare.  This is especially useful to compare\n#                            files that were renamed between the commits.\n\nmy $brief_usage = brief_usage();\nmy $usage  = long_usage();\n\n$| = 1;  # flush STDOUT\nmy $start_time = get_time();\nmy (\n    $opt_categorized          ,\n    $opt_found                ,\n    @opt_force_lang           ,\n    $opt_lang_no_ext          ,\n    @opt_script_lang          ,\n    $opt_count_diff           ,\n    $opt_diff                 ,\n    $opt_diff_alignment       ,\n    $opt_diff_list_file       ,\n    $opt_diff_list_files      ,\n    $opt_diff_timeout         ,\n    $opt_timeout              ,\n    $opt_html                 ,\n    $opt_ignored              ,\n    $opt_unique               ,\n    $opt_counted              ,\n    $opt_show_ext             ,\n    $opt_show_lang            ,\n    $opt_progress_rate        ,\n    $opt_print_filter_stages  ,\n    $opt_v                    ,\n    $opt_vcs                  ,\n    $opt_version              ,\n    $opt_include_submodules   ,\n    $opt_include_content      ,\n    $opt_exclude_content      ,\n    $opt_exclude_lang         ,\n    $opt_exclude_list_file    ,\n    $opt_exclude_dir          ,\n    $opt_explain              ,\n    $opt_include_ext          ,\n    $opt_include_lang         ,\n    $opt_force_lang_def       ,\n    $opt_read_lang_def        ,\n    $opt_write_lang_def       ,\n    $opt_write_lang_def_incl_dup,\n    $opt_strip_code           ,\n    $opt_strip_comments       ,\n    $opt_original_dir         ,\n    $opt_quiet                ,\n    $opt_report_file          ,\n    $opt_sdir                 ,\n    $opt_sum_reports          ,\n    $opt_hide_rate            ,\n    $opt_processes            ,\n    $opt_unicode              ,\n    $opt_no3                  ,   # accept it but don't use it\n    $opt_3                    ,\n    $opt_extract_with         ,\n    $opt_by_file              ,\n    $opt_by_file_by_lang      ,\n    $opt_by_percent           ,\n    $opt_percent              ,\n    $opt_xml                  ,\n    $opt_xsl                  ,\n    $opt_yaml                 ,\n    $opt_csv                  ,\n    $opt_csv_delimiter        ,\n    $opt_fullpath             ,\n    $opt_json                 ,\n    $opt_md                   ,\n    $opt_match_f              ,\n    @opt_not_match_f          ,\n    $opt_match_d              ,\n    @opt_not_match_d          ,\n    $opt_skip_uniqueness      ,\n    $opt_list_file            ,\n    $opt_help                 ,\n    $opt_skip_win_hidden      ,\n    $opt_read_binary_files    ,\n    $opt_sql                  ,\n    $opt_sql_append           ,\n    $opt_sql_project          ,\n    $opt_sql_style            ,\n    $opt_inline               ,\n    $opt_exclude_ext          ,\n    $opt_ignore_whitespace    ,\n    $opt_ignore_case          ,\n    $opt_ignore_case_ext      ,\n    @opt_ignore_regex         ,\n    $opt_follow_links         ,\n    $opt_autoconf             ,\n    $opt_sum_one              ,\n    $opt_stdin_name           ,\n    $opt_force_on_windows     ,\n    $opt_force_on_unix        ,   # actually forces !$ON_WINDOWS\n    $opt_show_os              ,\n    $opt_skip_archive         ,\n    $opt_max_file_size        ,   # in MB\n    $opt_use_sloccount        ,\n    $opt_no_autogen           ,\n    $opt_force_git            ,\n    $opt_git_diff_rel         ,\n    $opt_git_diff_all         ,\n    $opt_git_diff_simindex    ,\n    $opt_config_file          ,\n    $opt_strip_str_comments   ,\n    $opt_file_encoding        ,\n    $opt_docstring_as_code    ,\n    $opt_stat                 ,\n    $opt_summary_cutoff       ,\n    $opt_skip_leading         ,\n    $opt_no_recurse           ,\n    $opt_only_count_files     ,\n    $opt_fmt                  ,\n    $opt_encoding             ,\n    $opt_txt                  ,  # not associated with a command line option\n    $opt_thousands_delimiter  ,\n    $opt_show_errors          ,\n   );\n\nmy $getopt_success = GetOptions(             # {{{1\n   \"by_file|by-file\"                         => \\$opt_by_file             ,\n   \"by_file_by_lang|by-file-by-lang\"         => \\$opt_by_file_by_lang     ,\n   \"categorized=s\"                           => \\$opt_categorized         ,\n   \"counted=s\"                               => \\$opt_counted             ,\n   \"include_ext|include-ext=s\"               => \\$opt_include_ext         ,\n   \"include_lang|include-lang=s\"             => \\$opt_include_lang        ,\n   \"include_content|include-content=s\"       => \\$opt_include_content     ,\n   \"exclude_content|exclude-content=s\"       => \\$opt_exclude_content     ,\n   \"exclude_lang|exclude-lang=s\"             => \\$opt_exclude_lang        ,\n   \"exclude_dir|exclude-dir=s\"               => \\$opt_exclude_dir         ,\n   \"exclude_list_file|exclude-list-file=s\"   => \\$opt_exclude_list_file   ,\n   \"explain=s\"                               => \\$opt_explain             ,\n   \"extract_with|extract-with=s\"             => \\$opt_extract_with        ,\n   \"found=s\"                                 => \\$opt_found               ,\n   \"count_and_diff|count-and-diff\"           => \\$opt_count_diff          ,\n   \"diff\"                                    => \\$opt_diff                ,\n   \"diff-alignment|diff_alignment=s\"         => \\$opt_diff_alignment      ,\n   \"diff-timeout|diff_timeout=i\"             => \\$opt_diff_timeout        ,\n   \"diff-list-file|diff_list_file=s\"         => \\$opt_diff_list_file      ,\n   \"diff-list-files|diff_list_files\"         => \\$opt_diff_list_files     ,\n   \"timeout=i\"                               => \\$opt_timeout             ,\n   \"html\"                                    => \\$opt_html                ,\n   \"ignored=s\"                               => \\$opt_ignored             ,\n   \"unique=s\"                                => \\$opt_unique             ,\n   \"quiet\"                                   => \\$opt_quiet               ,\n   \"force_lang_def|force-lang-def=s\"         => \\$opt_force_lang_def      ,\n   \"read_lang_def|read-lang-def=s\"           => \\$opt_read_lang_def       ,\n   \"show_ext|show-ext:s\"                     => \\$opt_show_ext            ,\n   \"show_lang|show-lang:s\"                   => \\$opt_show_lang           ,\n   \"progress_rate|progress-rate=i\"           => \\$opt_progress_rate       ,\n   \"print_filter_stages|print-filter-stages\" => \\$opt_print_filter_stages ,\n   \"report_file|report-file=s\"               => \\$opt_report_file         ,\n   \"out=s\"                                   => \\$opt_report_file         ,\n   \"script_lang|script-lang=s\"               => \\@opt_script_lang         ,\n   \"sdir=s\"                                  => \\$opt_sdir                ,\n   \"skip_uniqueness|skip-uniqueness\"         => \\$opt_skip_uniqueness     ,\n   \"strip_code|strip-code=s\"                 => \\$opt_strip_code          ,\n   \"strip_comments|strip-comments=s\"         => \\$opt_strip_comments      ,\n   \"original_dir|original-dir\"               => \\$opt_original_dir        ,\n   \"sum_reports|sum-reports\"                 => \\$opt_sum_reports         ,\n   \"hide_rate|hide-rate\"                     => \\$opt_hide_rate           ,\n   \"processes=n\"                             => \\$opt_processes           ,\n   \"unicode\"                                 => \\$opt_unicode             ,\n   \"no3\"                                     => \\$opt_no3                 ,  # ignored\n   \"3\"                                       => \\$opt_3                   ,\n   \"v|verbose:i\"                             => \\$opt_v                   ,\n   \"vcs=s\"                                   => \\$opt_vcs                 ,\n   \"files-from=s\"                            => \\$opt_vcs                 ,  # synonym\n   \"include-submodules\"                      => \\$opt_include_submodules  ,\n   \"version\"                                 => \\$opt_version             ,\n   \"write_lang_def|write-lang-def=s\"         => \\$opt_write_lang_def      ,\n   \"write_lang_def_incl_dup|write-lang-def-incl-dup=s\" => \\$opt_write_lang_def_incl_dup,\n   \"xml\"                                     => \\$opt_xml                 ,\n   \"xsl=s\"                                   => \\$opt_xsl                 ,\n   \"force_lang|force-lang=s\"                 => \\@opt_force_lang          ,\n   \"lang_no_ext|lang-no-ext=s\"               => \\$opt_lang_no_ext         ,\n   \"yaml\"                                    => \\$opt_yaml                ,\n   \"csv\"                                     => \\$opt_csv                 ,\n   \"csv_delimiter|csv-delimiter=s\"           => \\$opt_csv_delimiter       ,\n   \"json\"                                    => \\$opt_json                ,\n   \"md\"                                      => \\$opt_md                  ,\n   \"fullpath\"                                => \\$opt_fullpath            ,\n   \"match_f|match-f=s\"                       => \\$opt_match_f             ,\n   \"not_match_f|not-match-f=s\"               => \\@opt_not_match_f         ,\n   \"match_d|match-d=s\"                       => \\$opt_match_d             ,\n   \"not_match_d|not-match-d=s\"               => \\@opt_not_match_d         ,\n   \"list_file|list-file=s\"                   => \\$opt_list_file           ,\n   \"help\"                                    => \\$opt_help                ,\n   \"skip_win_hidden|skip-win-hidden\"         => \\$opt_skip_win_hidden     ,\n   \"read_binary_files|read-binary-files\"     => \\$opt_read_binary_files   ,\n   \"sql=s\"                                   => \\$opt_sql                 ,\n   \"sql_project|sql-project=s\"               => \\$opt_sql_project         ,\n   \"sql_append|sql-append\"                   => \\$opt_sql_append          ,\n   \"sql_style|sql-style=s\"                   => \\$opt_sql_style           ,\n   \"inline\"                                  => \\$opt_inline              ,\n   \"exclude_ext|exclude-ext=s\"               => \\$opt_exclude_ext         ,\n   \"ignore_whitespace|ignore-whitespace\"     => \\$opt_ignore_whitespace   ,\n   \"ignore_case|ignore-case\"                 => \\$opt_ignore_case         ,\n   \"ignore_case_ext|ignore-case-ext\"         => \\$opt_ignore_case_ext     ,\n   \"ignore_regex|ignore-regex=s\"             => \\@opt_ignore_regex        ,\n   \"follow_links|follow-links\"               => \\$opt_follow_links        ,\n   \"autoconf\"                                => \\$opt_autoconf            ,\n   \"sum_one|sum-one\"                         => \\$opt_sum_one             ,\n   \"percent\"                                 => \\$opt_percent             ,\n   \"by_percent|by-percent=s\"                 => \\$opt_by_percent          ,\n   \"stdin_name|stdin-name=s\"                 => \\$opt_stdin_name          ,\n   \"windows\"                                 => \\$opt_force_on_windows    ,\n   \"unix\"                                    => \\$opt_force_on_unix       ,\n   \"show_os|show-os\"                         => \\$opt_show_os             ,\n   \"skip_archive|skip-archive=s\"             => \\$opt_skip_archive        ,\n   \"max_file_size|max-file-size=f\"           => \\$opt_max_file_size       ,\n   \"use_sloccount|use-sloccount\"             => \\$opt_use_sloccount       ,\n   \"no_autogen|no-autogen\"                   => \\$opt_no_autogen          ,\n   \"git\"                                     => \\$opt_force_git           ,\n   \"git_diff_rel|git-diff-rel\"               => \\$opt_git_diff_rel        ,\n   \"git_diff_all|git-diff-all\"               => \\$opt_git_diff_all        ,\n#  \"git_diff_simindex|git-diff-simindex\"     => \\$opt_git_diff_simindex   ,\n   \"config=s\"                                => \\$opt_config_file         ,\n   \"strip_str_comments|strip-str-comments\"   => \\$opt_strip_str_comments  ,\n   \"file_encoding|file-encoding=s\"           => \\$opt_file_encoding       ,\n   \"docstring_as_code|docstring-as-code\"     => \\$opt_docstring_as_code   ,\n   \"stat\"                                    => \\$opt_stat                ,\n   \"summary_cutoff|summary-cutoff=s\"         => \\$opt_summary_cutoff      ,\n   \"skip_leading|skip-leading:s\"             => \\$opt_skip_leading        ,\n   \"no_recurse|no-recurse\"                   => \\$opt_no_recurse          ,\n   \"only_count_files|only-count-files\"       => \\$opt_only_count_files    ,\n   \"fmt=i\"                                   => \\$opt_fmt                 ,\n   \"encoding=s\"                              => \\$opt_encoding            , # not production ready #880\n   \"ksep|thousands-delimiter=s\"              => \\$opt_thousands_delimiter ,\n   \"show-errors\"                             => \\$opt_show_errors         ,\n  );\n$opt_txt = 0;\nmy $tmp_file_to_delete = \"\";\n# 1}}}\n$config_file = $opt_config_file if defined $opt_config_file;\nload_from_config_file($config_file,          # {{{2\n                                                \\$opt_by_file             ,\n                                                \\$opt_by_file_by_lang     ,\n                                                \\$opt_categorized         ,\n                                                \\$opt_counted             ,\n                                                \\$opt_include_ext         ,\n                                                \\$opt_include_lang        ,\n                                                \\$opt_include_content     ,\n                                                \\$opt_exclude_content     ,\n                                                \\$opt_exclude_lang        ,\n                                                \\$opt_exclude_dir         ,\n                                                \\$opt_exclude_list_file   ,\n                                                \\$opt_explain             ,\n                                                \\$opt_extract_with        ,\n                                                \\$opt_found               ,\n                                                \\$opt_count_diff          ,\n                                                \\$opt_diff_list_files     ,\n                                                \\$opt_diff                ,\n                                                \\$opt_diff_alignment      ,\n                                                \\$opt_diff_timeout        ,\n                                                \\$opt_timeout             ,\n                                                \\$opt_html                ,\n                                                \\$opt_ignored             ,\n                                                \\$opt_unique              ,\n                                                \\$opt_quiet               ,\n                                                \\$opt_force_lang_def      ,\n                                                \\$opt_read_lang_def       ,\n                                                \\$opt_show_ext            ,\n                                                \\$opt_show_lang           ,\n                                                \\$opt_progress_rate       ,\n                                                \\$opt_print_filter_stages ,\n                                                \\$opt_report_file         ,\n                                                \\@opt_script_lang         ,\n                                                \\$opt_sdir                ,\n                                                \\$opt_skip_uniqueness     ,\n                                                \\$opt_strip_code          ,\n                                                \\$opt_strip_comments      ,\n                                                \\$opt_original_dir        ,\n                                                \\$opt_sum_reports         ,\n                                                \\$opt_hide_rate           ,\n                                                \\$opt_processes           ,\n                                                \\$opt_unicode             ,\n                                                \\$opt_3                   ,\n                                                \\$opt_v                   ,\n                                                \\$opt_vcs                 ,\n                                                \\$opt_include_submodules  ,\n                                                \\$opt_version             ,\n                                                \\$opt_write_lang_def      ,\n                                                \\$opt_write_lang_def_incl_dup,\n                                                \\$opt_xml                 ,\n                                                \\$opt_xsl                 ,\n                                                \\@opt_force_lang          ,\n                                                \\$opt_lang_no_ext         ,\n                                                \\$opt_yaml                ,\n                                                \\$opt_csv                 ,\n                                                \\$opt_csv_delimiter       ,\n                                                \\$opt_json                ,\n                                                \\$opt_md                  ,\n                                                \\$opt_fullpath            ,\n                                                \\$opt_match_f             ,\n                                                \\@opt_not_match_f         ,\n                                                \\$opt_match_d             ,\n                                                \\@opt_not_match_d         ,\n                                                \\$opt_list_file           ,\n                                                \\$opt_help                ,\n                                                \\$opt_skip_win_hidden     ,\n                                                \\$opt_read_binary_files   ,\n                                                \\$opt_sql                 ,\n                                                \\$opt_sql_project         ,\n                                                \\$opt_sql_append          ,\n                                                \\$opt_sql_style           ,\n                                                \\$opt_inline              ,\n                                                \\$opt_exclude_ext         ,\n                                                \\$opt_ignore_whitespace   ,\n                                                \\$opt_ignore_case         ,\n                                                \\$opt_ignore_case_ext     ,\n                                                \\@opt_ignore_regex        ,\n                                                \\$opt_follow_links        ,\n                                                \\$opt_autoconf            ,\n                                                \\$opt_sum_one             ,\n                                                \\$opt_by_percent          ,\n                                                \\$opt_stdin_name          ,\n                                                \\$opt_force_on_windows    ,\n                                                \\$opt_force_on_unix       ,\n                                                \\$opt_show_os             ,\n                                                \\$opt_skip_archive        ,\n                                                \\$opt_max_file_size       ,\n                                                \\$opt_use_sloccount       ,\n                                                \\$opt_no_autogen          ,\n                                                \\$opt_force_git           ,\n                                                \\$opt_strip_str_comments  ,\n                                                \\$opt_file_encoding       ,\n                                                \\$opt_docstring_as_code   ,\n                                                \\$opt_stat                ,\n                                                \\$opt_thousands_delimiter ,\n                                                \\$opt_show_errors         ,\n);  # 2}}} Not pretty.  Not at all.\nmy $HAVE_Parallel_ForkManager = undef;\nif ($opt_processes and $opt_processes > 1) {\n    # Parallel::ForkManager isn't in the standard distribution.\n    # Use it only if installed, and only if --processes=N is given.\n    # The module load is slow so only use it if called for.\n    use Parallel::ForkManager;\n    $HAVE_Parallel_ForkManager = 1;\n} else {\n    $HAVE_Parallel_ForkManager = 0;\n}\nif ($opt_version) {\n    printf \"$VERSION\\n\";\n    exit;\n}\nmy $opt_git = 0;\n$opt_git = 1 if defined($opt_git_diff_all) or\n                defined($opt_git_diff_rel) or\n                (defined($opt_vcs) and ($opt_vcs eq \"git\"));\n$opt_by_file  = 1 if defined  $opt_by_file_by_lang;\n$opt_fmt = 0 unless defined $opt_fmt;\nif ($opt_fmt) {\n    $opt_by_file = 1;\n    $opt_json = 1;\n}\nmy $CLOC_XSL = \"cloc.xsl\"; # created with --xsl\n   $CLOC_XSL = \"cloc-diff.xsl\" if $opt_diff;\ndie \"\\n\" unless $getopt_success;\nprint $usage and exit if $opt_help;\nmy %Exclude_Language = ();\n   %Exclude_Language = map { $_ => 1 } split(/,/, $opt_exclude_lang)\n        if $opt_exclude_lang;\nmy %Exclude_Dir      = ();\n   %Exclude_Dir      = map { $_ => 1 } split(/,/, $opt_exclude_dir )\n        if $opt_exclude_dir ;\ndie unless exclude_dir_validates(\\%Exclude_Dir);\nmy %Include_Ext = ();\n   %Include_Ext = map { $_ => 1 } split(/,/, $opt_include_ext)\n        if $opt_include_ext;\nmy %Include_Language = (); # keys are lower case language names\n   %Include_Language = map { lc($_) => 1 } split(/,/, $opt_include_lang)\n        if $opt_include_lang;\n# Forcibly exclude .svn, .cvs, .hg, .git, .bzr directories.  The contents of these\n# directories often conflict with files of interest.\n$opt_exclude_dir       = 1;\n$Exclude_Dir{\".svn\"}   = 1;\n$Exclude_Dir{\".cvs\"}   = 1;\n$Exclude_Dir{\".hg\"}    = 1;\n$Exclude_Dir{\".git\"}   = 1;\n$Exclude_Dir{\".bzr\"}   = 1;\n$Exclude_Dir{\".snapshot\"} = 1;  # NetApp backups\n$Exclude_Dir{\".config\"} = 1;\n$Exclude_Dir{\".venv\"}  = 1; # Python virtual environment\n$opt_count_diff        = defined $opt_count_diff ? 1 : 0;\n$opt_diff              = 1  if $opt_diff_alignment    or\n                               $opt_diff_list_file    or\n                               $opt_diff_list_files   or\n                               $opt_git_diff_rel      or\n                               $opt_git_diff_all      or\n                               $opt_git_diff_simindex;\n$opt_force_git         = 1  if $opt_git_diff_rel      or\n                               $opt_git_diff_all      or\n                               $opt_git_diff_simindex;\n$opt_diff_alignment    = 0  if $opt_diff_list_file;\n$opt_exclude_ext       = \"\" unless $opt_exclude_ext;\n$opt_ignore_whitespace = 0  unless $opt_ignore_whitespace;\n$opt_ignore_case       = 0  unless $opt_ignore_case;\n$opt_ignore_case_ext   = 0  unless $opt_ignore_case_ext;\nmy %ignore_regex       = ();\n$opt_lang_no_ext       = 0  unless $opt_lang_no_ext;\n$opt_follow_links      = 0  unless $opt_follow_links;\nif (defined $opt_diff_timeout) {\n    # if defined but with a value of <= 0, set to 2^31-1 seconds = 68 years\n    $opt_diff_timeout = 2**31-1 unless $opt_diff_timeout > 0;\n} else {\n    $opt_diff_timeout  =10; # seconds\n}\n$opt_thousands_delimiter = 0 unless defined $opt_thousands_delimiter;\nif (defined $opt_timeout) {\n    # if defined but with a value of <= 0, set to 2^31-1 seconds = 68 years\n    $opt_timeout = 2**31-1 unless $opt_timeout > 0;\n    # else is computed dynamically, ref $max_duration_sec\n}\n$opt_csv               = 0  unless defined $opt_csv;\n$opt_csv               = 1  if $opt_csv_delimiter;\n$ON_WINDOWS            = 1  if $opt_force_on_windows;\n$ON_WINDOWS            = 0  if $opt_force_on_unix;\n$opt_max_file_size     = 100 unless $opt_max_file_size;\nmy $HAVE_SLOCCOUNT_c_count = 0;\nif (!$ON_WINDOWS and $opt_use_sloccount) {\n    # Only bother doing this kludgey test is user explicitly wants\n    # to use SLOCCount.  Debian based systems will hang if just doing\n    #  external_utility_exists(\"c_count\")\n    # if c_count is in $PATH; c_count expects to have input.\n    $HAVE_SLOCCOUNT_c_count = external_utility_exists(\"c_count /bin/sh\");\n}\nif ($opt_use_sloccount) {\n    if (!$HAVE_SLOCCOUNT_c_count) {\n        warn \"c_count could not be found; ignoring --use-sloccount\\n\";\n        $opt_use_sloccount = 0;\n    } else {\n        warn \"Using c_count, php_count, xml_count, pascal_count from SLOCCount\\n\";\n        warn \"--diff is disabled with --use-sloccount\\n\" if $opt_diff;\n        warn \"--count-and-diff is disabled with --use-sloccount\\n\" if $opt_count_diff;\n        warn \"--unicode is disabled with --use-sloccount\\n\" if $opt_unicode;\n        warn \"--strip-comments is disabled with --use-sloccount\\n\" if $opt_strip_comments;\n        warn \"--strip-code is disabled with --use-sloccount\\n\" if $opt_strip_code;\n        $opt_diff           = 0;\n        $opt_count_diff     = undef;\n        $opt_unicode        = 0;\n        $opt_strip_comments = 0;\n        $opt_strip_code     = 0;\n    }\n}\ndie \"--strip-comments and --strip-code are mutually exclusive\\n\" if\n    $opt_strip_comments and $opt_strip_code;\n$opt_vcs = 0 if $opt_force_git;\n\n# replace Windows path separators with /\nif ($ON_WINDOWS) {\n    map { s{\\\\}{/}g } @ARGV;\n    if ($opt_git) {\n        # PowerShell tab expansion automatically prefixes local directories\n        # with \".\\\" (now mapped to \"./\").   git ls-files output does not\n        # include this.  Strip this prefix to permit clean matches.\n        map { s{^\\./}{} } @ARGV;\n    }\n}\n\nmy @COUNT_DIFF_ARGV        = undef;\nmy $COUNT_DIFF_report_file = undef;\nif ($opt_count_diff and !$opt_diff_list_file) {\n    die \"--count-and-diff requires two arguments; got \", scalar @ARGV, \"\\n\"\n        if scalar @ARGV != 2;\n    # prefix with a dummy term so that $opt_count_diff is the\n    # index into @COUNT_DIFF_ARGV to work on at each pass\n    @COUNT_DIFF_ARGV = (undef, $ARGV[0],\n                               $ARGV[1],\n                              [$ARGV[0], $ARGV[1]]);  # 3rd pass: diff them\n    $COUNT_DIFF_report_file = $opt_report_file if $opt_report_file;\n}\n\n# Options defaults:\n$opt_quiet         =   1 if ($opt_md or $opt_json or !(-t STDOUT))\n                            and !defined $opt_report_file;\n$opt_progress_rate = 100 unless defined $opt_progress_rate;\n$opt_progress_rate =   0 if     defined $opt_quiet;\nif (!defined $opt_v) {\n    $opt_v  = 0;\n} elsif (!$opt_v) {\n    $opt_v  = 1;\n}\nif (defined $opt_xsl) {\n    $opt_xsl = $CLOC_XSL if $opt_xsl eq \"1\";\n    $opt_xml = 1;\n}\nmy $skip_generate_report = 0;\n$opt_sql_style = 0 unless defined $opt_sql_style;\n$opt_sql = 0 unless $opt_sql_style or defined $opt_sql;\nif ($opt_sql eq \"-\" || $opt_sql eq \"1\") { # stream SQL output to STDOUT\n    $opt_quiet            = 1;\n    $skip_generate_report = 1;\n    $opt_by_file          = 1;\n    $opt_sum_reports      = 0;\n    $opt_progress_rate    = 0;\n} elsif ($opt_sql)  { # write SQL output to a file\n    $opt_by_file          = 1;\n    $skip_generate_report = 1;\n    $opt_sum_reports      = 0;\n}\nif ($opt_sql_style) {\n    $opt_sql_style = lc $opt_sql_style;\n    if (!grep { lc $_ eq $opt_sql_style } qw ( Oracle Named_Columns )) {\n        die \"'$opt_sql_style' is not a recognized SQL style.\\n\";\n    }\n}\n$opt_by_percent = '' unless defined $opt_by_percent;\nif ($opt_by_percent and $opt_by_percent !~ m/^(c|cm|cb|cmb|t)$/i) {\n    die \"--by-percent must be either 'c', 'cm', 'cb', 'cmb', or 't'\\n\";\n}\n$opt_by_percent = lc $opt_by_percent;\n$opt_by_percent = 't' if $opt_percent;\n\n$opt_txt = 1 if $opt_report_file;\nmy $N_OUTPUT_FORMATS = 0;\nmy %OUTFILE_EXT      = (\n    \"txt\"  => $opt_txt ,\n    \"csv\"  => $opt_csv ,\n    \"xml\"  => 0        ,\n    \"yaml\" => 0        ,\n    \"json\" => 0        ,\n    \"md\"   => 0        ,\n);\n$OUTFILE_EXT{\"xml\" } = 1 if defined($opt_xml );\n$OUTFILE_EXT{\"yaml\"} = 1 if defined($opt_yaml);\n$OUTFILE_EXT{\"json\"} = 1 if defined($opt_json);\n$OUTFILE_EXT{\"md\"  } = 1 if defined($opt_md  );\n# $OUTFILE_EXT{\"sql\" } = 1 if defined($opt_sql ); # doesn't work; --sql needs an argument\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    ++$N_OUTPUT_FORMATS if $OUTFILE_EXT{$out_style};\n}\nif ($N_OUTPUT_FORMATS >= 2 and $OUTFILE_EXT{\"txt\"}) {\n    --$N_OUTPUT_FORMATS;\n    $OUTFILE_EXT{\"txt\"} = 0;\n}\nif (!$N_OUTPUT_FORMATS) {\n    $N_OUTPUT_FORMATS = 1;\n    $OUTFILE_EXT{\"txt\"} = 1;\n    $opt_txt = 1;\n}\n\nif (defined $opt_vcs) {\n    if ($opt_vcs eq \"auto\") {\n        if      (is_dir(\".git\")) {\n            $opt_vcs = \"git\";\n        } elsif (is_dir(\".svn\")) {\n            $opt_vcs = \"svn\";\n        } else {\n            warn \"--vcs auto:  unable to determine versioning system\\n\";\n        }\n    }\n    if      ($opt_vcs eq \"git\") {\n        $opt_vcs = \"git -c \\\"safe.directory=*\\\" ls-files\";\n        $opt_vcs .= \" --recurse-submodules\" if $opt_include_submodules;\n        my @submodules = invoke_generator(\"git -c \\\"safe.directory=*\\\" submodule status\", \\@ARGV);\n        foreach my $SM (@submodules) {\n            $SM =~ s/^\\s+//;        # may have leading space\n            $SM =~ s/\\(\\S+\\)\\s*$//; # may end with something like (heads/master)\n            my ($checksum, $dir) = split(' ', $SM, 2);\n            $dir =~ s/\\s+$//;\n            $Exclude_Dir{$dir} = 1;\n        }\n    } elsif ($opt_vcs eq \"svn\") {\n        $opt_vcs = \"svn list -R\";\n    }\n}\n\nmy $list_no_autogen = 0;\nif (defined $opt_no_autogen and scalar @ARGV == 1 and $ARGV[0] eq \"list\") {\n    $list_no_autogen = 1;\n}\nif ($opt_summary_cutoff) {\n    my $error = summary_cutoff_error($opt_summary_cutoff);\n    die \"$error\\n\" if $error;\n}\n\nif (!$opt_config_file) {\n    # if not explicitly given, look for a config file in other\n    # possible locations\n    my $other_loc = check_alternate_config_files($opt_list_file,\n        $opt_exclude_list_file, $opt_read_lang_def, $opt_force_lang_def,\n        $opt_diff_list_file);\n    $opt_config_file = $other_loc if $other_loc;\n}\n\n# --match-d and --not-match-d: if end with a trailing slash, update the\n# regex to be either slash or end of line since File::Find::find() will\n# not see the trailing slash in leaf directories (#732, #833).\nif ($opt_match_d and $opt_match_d =~ m{/$}) {\n    $opt_match_d =~ s{/$}{(/|\\$)};\n}\nforeach my $nmd (@opt_not_match_d) {\n    if ($nmd =~ m{/$}) {\n        $nmd =~ s{/$}{(/|\\$)};\n    }\n}\n\ndie $brief_usage unless defined $opt_version         or\n                        defined $opt_show_lang       or\n                        defined $opt_show_ext        or\n                        defined $opt_show_os         or\n                        defined $opt_write_lang_def  or\n                        defined $opt_write_lang_def_incl_dup  or\n                        defined $opt_list_file       or\n                        defined $opt_diff_list_file  or\n                        defined $opt_vcs             or\n                        defined $opt_xsl             or\n                        defined $opt_explain         or\n                        $list_no_autogen             or\n                        scalar @ARGV >= 1;\nif (!$opt_diff_list_file) {\n    die \"--diff requires two arguments; got \", scalar @ARGV, \"\\n\"\n        if $opt_diff and !$opt_sum_reports and scalar @ARGV != 2;\n    die \"--diff arguments are identical; nothing done\", \"\\n\"\n        if $opt_diff and !$opt_sum_reports and scalar @ARGV == 2\n                                           and $ARGV[0] eq $ARGV[1];\n}\n\nmy $HAVE_Algorithm_Diff = 1;\n# Algorithm::Diff isn't in the standard distribution.  It will\n# be installed in a temp directory if necessary.\nuse Algorithm::Diff qw ( sdiff );\n#eval \"use Algorithm::Diff qw ( sdiff ) \";\n#if (defined $Algorithm::Diff::VERSION) {\n#    $HAVE_Algorithm_Diff = 1;\n#} else {\n#    Install_Algorithm_Diff();\n#}\n\ntrick_pp_packer_encode() if $ON_WINDOWS and $opt_file_encoding;\n$File::Find::dont_use_nlink = 1 if $opt_stat or top_level_SMB_dir(\\@ARGV);\nmy @git_similarity = (); # only populated with --git-diff-simindex\nmy %git_metadata   = (); # key is hash, tag, or other git reference;\n                         # this has two keys if doing git diff and\n                         # both L and R are git references\nget_git_metadata(\\@ARGV, \\%git_metadata) if $opt_force_git;\n#use Data::Dumper;\n#print Dumper(\\%git_metadata);\nreplace_git_hash_with_tarfile(\\@ARGV, \\@git_similarity);\n# 1}}}\n# Step 1:  Initialize global constants.        {{{1\n#\nmy $nFiles_Found = 0;  # updated in make_file_list\nmy (%Language_by_Extension, %Language_by_Script,\n    %Filters_by_Language, %Not_Code_Extension, %Not_Code_Filename,\n    %Language_by_File_Type, %Language_by_Filename,\n    %Scale_Factor, %Known_Binary_Archives,\n    %Language_by_Prefix, %EOL_Continuation_re,\n   );\nmy $ALREADY_SHOWED_HEADER = 0;\nmy $ALREADY_SHOWED_XML_SECTION = 0;\nmy %Error_Codes = ( 'Unable to read'                => -1,\n                    'Neither file nor directory'    => -2,\n                    'Diff error (quoted comments?)' => -3,\n                    'Diff error, exceeded timeout'  => -4,\n                    'Line count, exceeded timeout'  => -5,\n                  );\nmy %Extension_Collision = (\n    'ADSO/IDSM'                                     => [ 'adso' ] ,\n    'C#/Smalltalk'                                  => [ 'cs'   ] ,\n    'D/dtrace'                                      => [ 'd'    ] ,\n    'F#/Forth'                                      => [ 'fs'   ] ,\n    'Fortran 77/Forth'                              => [ 'f', 'for' ] ,\n    'IDL/Qt Project/Prolog/ProGuard'                => [ 'pro'  ] ,\n    'Lisp/Julia'                                    => [ 'jl'   ] ,\n    'Lisp/OpenCL'                                   => [ 'cl'   ] ,\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury'  => [ 'm'    ] ,\n    'Pascal/Pawn'                                   => [ 'p'    ] ,\n    'Pascal/Puppet'                                 => [ 'pp'   ] ,\n    'Perl/Prolog'                                   => [ 'pl', 'PL'  ] ,\n    'PHP/Pascal/Fortran/Pawn/BitBake'               => [ 'inc'  ] ,\n    'Raku/Prolog'                                   => [ 'p6', 'P6'  ] ,\n    'XML-Qt-GTK/Glade'                              => [ 'ui'   ] ,\n    'TypeScript/Qt Linguist'                        => [ 'ts'   ] ,\n    'Verilog-SystemVerilog/Coq'                     => [ 'v'    ] ,\n    'Visual Basic/TeX/Apex Class'                   => [ 'cls'  ] ,\n    'Scheme/SaltStack'                              => [ 'sls'  ] ,\n    'SKILL/.NET IL'                                 => [ 'il'   ] ,\n    'Clojure/Cangjie'                               => [ 'cj'   ] ,\n    'Unknown/BitBake'                               => [ 'conf' ] ,\n);\nmy @Autogen_to_ignore = no_autogen_files($list_no_autogen);\nif ($opt_force_lang_def) {\n    # replace cloc's definitions\n    read_lang_def(\n        $opt_force_lang_def    , #        Sample values:\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n} else {\n    set_constants(               #\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Language_by_Prefix   , # Language_by_Prefix{Dockerfile}  = 'Dockerfile'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%Known_Binary_Archives, # Known_Binary_Archives{.tar} = 1\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n        if ($opt_no_autogen) {\n            foreach my $F (@Autogen_to_ignore) { $Not_Code_Filename{ $F } = 1; }\n        }\n}\nif ($opt_read_lang_def) {\n    # augment cloc's definitions (keep cloc's where there are overlaps)\n    merge_lang_def(\n        $opt_read_lang_def     , #        Sample values:\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n}\nif ($opt_lang_no_ext and !defined $Filters_by_Language{$opt_lang_no_ext}) {\n    die_unknown_lang($opt_lang_no_ext, \"--lang-no-ext\")\n}\ncheck_scale_existence(\\%Filters_by_Language, \\%Language_by_Extension,\n                      \\%Scale_Factor);\nparse_ignore_regex(\\@opt_ignore_regex, \\%Filters_by_Language, \\%ignore_regex)\n    if @opt_ignore_regex;\n\nmy $nCounted = 0;\n\n# Process command line provided extension-to-language mapping overrides.\n# Make a hash of known languages in lower case for easier matching.\nmy %Recognized_Language_lc = (); # key = language name in lc, value = true name\nforeach my $language (keys %Filters_by_Language) {\n    my $lang_lc = lc $language;\n    $Recognized_Language_lc{$lang_lc} = $language;\n}\nmy %Forced_Extension = (); # file name extensions which user wants to count\nmy $All_One_Language = 0;  # set to !0 if --force-lang's <ext> is missing\nforeach my $pair (@opt_force_lang) {\n    my ($lang, $extension) = split(',', $pair);\n    my $lang_lc = lc $lang;\n    if (defined $extension) {\n        $Forced_Extension{$extension} = $lang;\n\n        die_unknown_lang($lang, \"--force-lang\")\n            unless $Recognized_Language_lc{$lang_lc};\n\n        $Language_by_Extension{$extension} = $Recognized_Language_lc{$lang_lc};\n    } else {\n        # the scary case--count everything as this language\n        $All_One_Language = $Recognized_Language_lc{$lang_lc};\n    }\n}\n\nforeach my $pair (@opt_script_lang) {\n    my ($lang, $script_name) = split(',', $pair);\n    my $lang_lc = lc $lang;\n    if (!defined $script_name) {\n        die \"The --script-lang option requires a comma separated pair of \".\n            \"strings.\\n\";\n    }\n\n    die_unknown_lang($lang, \"--script-lang\")\n        unless $Recognized_Language_lc{$lang_lc};\n\n    $Language_by_Script{$script_name} = $Recognized_Language_lc{$lang_lc};\n}\n\n# If user provided a language definition file, make sure those\n# extensions aren't rejected.\nforeach my $ext (%Language_by_Extension) {\n    next unless defined $Not_Code_Extension{$ext};\n    delete $Not_Code_Extension{$ext};\n}\n\n# If user provided file extensions to ignore, add these to\n# the exclusion list.\nforeach my $ext (map { $_ => 1 } split(/,/, $opt_exclude_ext ) ) {\n    $ext = lc $ext if $ON_WINDOWS or $opt_ignore_case_ext;\n    $Not_Code_Extension{$ext} = 1;\n}\n\n# If SQL or --by-file output is requested, keep track of directory names\n# generated by File::Temp::tempdir and used to temporarily hold the results\n# of compressed archives.  Contents of the SQL table 't' will be much\n# cleaner if these meaningless directory names are stripped from the front\n# of files pulled from the archives.\nmy %TEMP_DIR = ();\nmy $TEMP_OFF =  0;  # Needed for --sdir; keep track of the number of\n                    # scratch directories made in this run to avoid\n                    # file overwrites by multiple extractions to same\n                    # sdir.\n# Also track locations where temporary installations, if necessary, of\n# Algorithm::Diff and/or Regexp::Common are done.  Make sure these\n# directories are not counted as inputs (ref bug #80 2012-11-23).\nmy %TEMP_INST = ();\n\n# invert %Language_by_Script hash to get an easy-to-look-up list of known\n# scripting languages\nmy %Script_Language = map { $_ => 1 } values %Language_by_Script ;\n# 1}}}\n# Step 2:  Early exits for display, summation. {{{1\n#\nprint_extension_info(   $opt_show_ext     ) if defined $opt_show_ext ;\nprint_language_info(    $opt_show_lang, '') if defined $opt_show_lang;\nprint_language_filters( $opt_explain      ) if defined $opt_explain  ;\nexit if (defined $opt_show_ext)  or\n        (defined $opt_show_lang) or\n        (defined $opt_explain)   or\n        $list_no_autogen;\n\nTop_of_Processing_Loop:\n# Sorry, coding purists.  Using a goto to implement --count-and-diff\n# which has to do three passes over the main code, starting with\n# a clean slate each time.\nif ($opt_count_diff) {\n    @ARGV = ( $COUNT_DIFF_ARGV[ $opt_count_diff ] );\n    if ($opt_count_diff == 3) {\n        $opt_diff = 1;\n        @ARGV = @{$COUNT_DIFF_ARGV[ $opt_count_diff ]}; # last arg is list of list\n    } elsif ($opt_diff_list_files) {\n        $opt_diff = 0;\n    }\n    if ($opt_report_file) {\n        # Instead of just one output file, will have three.\n        # Keep their names unique otherwise results are clobbered.\n        # Replace file path separators with underscores otherwise\n        # may end up with illegal file names.\n        my ($fn_0, $fn_1) = (undef, undef);\n        if ($ON_WINDOWS) {\n            ($fn_0 = $ARGV[0]) =~ s{\\\\}{_}g;\n             $fn_0 =~ s{:}{_}g;\n             $fn_0 =~ s{/}{_}g;\n            ($fn_1 = $ARGV[1]) =~ s{\\\\}{_}g if defined $ARGV[1];\n             $fn_1 =~ s{:}{_}g              if defined $ARGV[1];\n             $fn_1 =~ s{/}{_}g              if defined $ARGV[1];\n        } else {\n            ($fn_0 = $ARGV[0]) =~ s{/}{_}g;\n            ($fn_1 = $ARGV[1]) =~ s{/}{_}g  if defined $ARGV[1];\n        }\n\n        if      ($opt_count_diff == 3) {\n            $opt_report_file = $COUNT_DIFF_report_file . \".diff.$fn_0.$fn_1\";\n        } else {\n            $opt_report_file = $COUNT_DIFF_report_file . \".$fn_0\";\n        }\n    } else {\n        # STDOUT; print a header showing what it's working on\n        if ($opt_count_diff == 3) {\n            print \"\\ndiff $ARGV[0] $ARGV[1]::\\n\";\n        } else {\n            print \"\\n\" if $opt_count_diff > 1;\n            print \"$ARGV[0]::\\n\";\n        }\n    }\n    $ALREADY_SHOWED_HEADER      = 0;\n    $ALREADY_SHOWED_XML_SECTION = 0;\n}\n\n#print \"Before glob have [\", join(\",\", @ARGV), \"]\\n\";\n@ARGV = windows_glob(@ARGV) if $ON_WINDOWS;\n#print \"after  glob have [\", join(\",\", @ARGV), \"]\\n\";\n\n# filter out archive files if requested to do so\nif (defined $opt_skip_archive) {\n    my @non_archive = ();\n    foreach my $candidate (@ARGV) {\n        if ($candidate !~ m/${opt_skip_archive}$/) {\n            push @non_archive, $candidate;\n\n        }\n    }\n    @ARGV = @non_archive;\n}\n\nif ($opt_sum_reports and $opt_diff) {\n    my @results = ();\n    if ($opt_csv and !defined($opt_csv_delimiter)) {\n        $opt_csv_delimiter = \",\";\n    }\n    if ($opt_list_file) { # read inputs from the list file\n        my @list = read_list_file($opt_list_file);\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@list);\n        } else {\n            @results = combine_diffs(\\@list);\n        }\n    } elsif ($opt_vcs) { # read inputs from the VCS generator\n        my @list = invoke_generator($opt_vcs, \\@ARGV);\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@list);\n        } else {\n            @results = combine_diffs(\\@list);\n        }\n    } else { # get inputs from the command line\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@ARGV);\n        } else {\n            @results = combine_diffs(\\@ARGV);\n        }\n    }\n    if ($opt_report_file) {\n        write_file($opt_report_file, {}, @results);\n    } else {\n        print \"\\n\", join(\"\\n\", @results), \"\\n\";\n    }\n    exit;\n}\nif ($opt_sum_reports) {\n    my %Results = ();\n    foreach my $type( \"by language\", \"by report file\" ) {\n        my $found_lang = undef;\n        if ($opt_list_file or $opt_vcs) {\n            # read inputs from the list file\n            my @list;\n            if ($opt_vcs) {\n                @list = invoke_generator($opt_vcs, \\@ARGV);\n            } else {\n                @list = read_list_file($opt_list_file);\n            }\n            $found_lang = combine_results(\\@list,\n                                           $type,\n                                          \\%{$Results{ $type }},\n                                          \\%Filters_by_Language );\n        } else { # get inputs from the command line\n            $found_lang = combine_results(\\@ARGV,\n                                           $type,\n                                          \\%{$Results{ $type }},\n                                          \\%Filters_by_Language );\n        }\n        next unless %Results;\n        my $end_time = get_time();\n        my @results  = generate_report($VERSION, $end_time - $start_time,\n                                       $type,\n                                      \\%{$Results{ $type }}, \\%Scale_Factor,\n                                       \"txt\");\n        if ($opt_report_file) {\n            my $ext  = \".lang\";\n               $ext  = \".file\" unless $type eq \"by language\";\n            next if !$found_lang and  $ext  eq \".lang\";\n            write_file($opt_report_file . $ext, {}, @results);\n        } else {\n            print \"\\n\", join(\"\\n\", @results), \"\\n\";\n        }\n    }\n    exit;\n}\nif ($opt_write_lang_def or $opt_write_lang_def_incl_dup) {\n    my $file = $opt_write_lang_def          if $opt_write_lang_def;\n       $file = $opt_write_lang_def_incl_dup if $opt_write_lang_def_incl_dup;\n    write_lang_def($file                 ,\n                  \\%Language_by_Extension,\n                  \\%Language_by_Script   ,\n                  \\%Language_by_File_Type     ,\n                  \\%Filters_by_Language  ,\n                  \\%Not_Code_Extension   ,\n                  \\%Not_Code_Filename    ,\n                  \\%Scale_Factor         ,\n                  \\%EOL_Continuation_re  ,\n                  );\n    exit;\n}\nif ($opt_show_os) {\n    if ($ON_WINDOWS) {\n        print \"Windows\\n\";\n    } else {\n        print \"UNIX\\n\";\n    }\n    exit;\n}\n\nmy $max_processes = get_max_processes();\n\n# 1}}}\n# Step 3:  Create a list of files to consider. {{{1\n#  a) If inputs are binary archives, first cd to a temp\n#     directory, expand the archive with the user-given\n#     extraction tool, then add the temp directory to\n#     the list of dirs to process.\n#  b) Create a list of every file that might contain source\n#     code.  Ignore binary files, zero-sized files, and\n#     any file in a directory the user says to exclude.\n#  c) Determine the language for each file in the list.\n#\nmy @binary_archive = ();\nmy $cwd            = cwd();\nif ($opt_extract_with) {\n#print \"cwd main = [$cwd]\\n\";\n    my @extract_location = ();\n    foreach my $bin_file (@ARGV) {\n        my $extract_dir = undef;\n        if ($opt_sdir) {\n            ++$TEMP_OFF;\n            $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n            File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n            File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n        } else {\n            $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n        }\n        $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n        print \"mkdir $extract_dir\\n\"  if $opt_v;\n        print \"cd    $extract_dir\\n\"  if $opt_v;\n        chdir $extract_dir;\n        my $bin_file_full_path = \"\";\n        if (File::Spec->file_name_is_absolute( $bin_file )) {\n            $bin_file_full_path = $bin_file;\n#print \"bin_file_full_path (was ful) = [$bin_file_full_path]\\n\";\n        } else {\n            $bin_file_full_path = File::Spec->catfile( $cwd, $bin_file );\n#print \"bin_file_full_path (was rel) = [$bin_file_full_path]\\n\";\n        }\n        my     $extract_cmd = uncompress_archive_cmd($bin_file_full_path);\n        print  $extract_cmd, \"\\n\" if $opt_v;\n        system $extract_cmd;\n        push @extract_location, $extract_dir;\n        chdir $cwd;\n    }\n    # It is possible that the binary archive itself contains additional\n    # files compressed the same way (true for Java .ear files).  Go\n    # through all the files that were extracted, see if they are binary\n    # archives and try to extract them.  Lather, rinse, repeat.\n    my $binary_archives_exist = 1;\n    my $count_binary_archives = 0;\n    my $previous_count        = 0;\n    my $n_pass                = 0;\n    while ($binary_archives_exist) {\n        @binary_archive = ();\n        foreach my $dir (@extract_location) {\n            find(\\&archive_files, $dir);  # populates global @binary_archive\n        }\n        foreach my $archive (@binary_archive) {\n            my $extract_dir = undef;\n            if ($opt_sdir) {\n                ++$TEMP_OFF;\n                $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n            } else {\n                $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n            }\n            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n            print \"mkdir $extract_dir\\n\"  if $opt_v;\n            print \"cd    $extract_dir\\n\"  if $opt_v;\n            chdir  $extract_dir;\n\n            my     $extract_cmd = uncompress_archive_cmd($archive);\n            print  $extract_cmd, \"\\n\" if $opt_v;\n            system $extract_cmd;\n            push @extract_location, $extract_dir;\n            unlink $archive;  # otherwise will be extracting it forever\n        }\n        $count_binary_archives = scalar @binary_archive;\n        if ($count_binary_archives == $previous_count) {\n            $binary_archives_exist = 0;\n        }\n        $previous_count = $count_binary_archives;\n    }\n    chdir $cwd;\n\n    @ARGV = @extract_location;\n} else {\n    # see if any of the inputs need to be auto-uncompressed &/or expanded\n    my @updated_ARGS = ();\n    replace_git_hash_with_tarfile(\\@ARGV, \\@git_similarity) if $opt_force_git;\n    foreach my $Arg (@ARGV) {\n        if (is_dir($Arg)) {\n            push @updated_ARGS, $Arg;\n            next;\n        }\n        my $full_path = \"\";\n        if (File::Spec->file_name_is_absolute( $Arg )) {\n            $full_path = $Arg;\n        } else {\n            $full_path = File::Spec->catfile( $cwd, $Arg );\n        }\n#print \"full_path = [$full_path]\\n\";\n        my $extract_cmd = uncompress_archive_cmd($full_path);\n        if ($extract_cmd) {\n            my $extract_dir = undef;\n            if ($opt_sdir) {\n                ++$TEMP_OFF;\n                $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n            } else {\n                $extract_dir = tempdir( CLEANUP => 1 ); # 1 = delete on exit\n            }\n            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n            print \"mkdir $extract_dir\\n\"  if $opt_v;\n            print \"cd    $extract_dir\\n\"  if $opt_v;\n            chdir  $extract_dir;\n            print  $extract_cmd, \"\\n\" if $opt_v;\n            system $extract_cmd;\n            push @updated_ARGS, $extract_dir;\n            chdir $cwd;\n        } else {\n            # this is a conventional, uncompressed, unarchived file\n            # or a directory; keep as-is\n            push @updated_ARGS, $Arg;\n        }\n    }\n    @ARGV = @updated_ARGS;\n\n    # make sure we're not counting any directory containing\n    # temporary installations of Regexp::Common, Algorithm::Diff\n    foreach my $d (sort keys %TEMP_INST) {\n        foreach my $a (@ARGV) {\n            next unless is_dir($a);\n            if ($opt_v > 2) {\n                printf \"Comparing %s (location of %s) to input [%s]\\n\",\n                        $d, $TEMP_INST{$d}, $a;\n            }\n            if ($a eq $d) {\n                die \"File::Temp::tempdir chose directory \",\n                    $d, \" to install \", $TEMP_INST{$d}, \" but this \",\n                    \"matches one of your input directories.  Rerun \",\n                    \"with --sdir and supply a different temporary \",\n                    \"directory for \", $TEMP_INST{$d}, \"\\n\";\n            }\n        }\n    }\n}\n# 1}}}\nmy @Errors    = ();\nmy @file_list = ();  # global variable updated in files()\nmy %Ignored   = ();  # files that are not counted (language not recognized or\n                     # problems reading the file)\nmy %upper_lower_map = ();  # global variable (needed only on Windows) to\n                           # track case of original filename, populated in\n                           # make_file_list() if $ON_WINDOWS\nif ($opt_diff) {\n# Step 4:  Separate code from non-code files.  {{{1\nmy @fh            = ();\nmy @files_for_set = ();\nmy @files_added_tot = ();\nmy @files_removed_tot = ();\nmy @file_pairs_tot = ();\n# make file lists for each separate argument\nif ($opt_diff_list_file) {\n    @files_for_set = ( (), () );\n    file_pairs_from_file($opt_diff_list_file, # in\n                        \\@files_added_tot   , # out\n                        \\@files_removed_tot , # out\n                        \\@file_pairs_tot    , # out\n                       );\n    foreach my $F (@files_added_tot) {\n        if ($ON_WINDOWS) {\n            (my $lc = lc $F) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $F;\n            $F = $lc;\n        }\n        push @{$files_for_set[1]}, $F;\n    }\n    foreach my $F (@files_removed_tot) {\n        if ($ON_WINDOWS) {\n            (my $lc = lc $F) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $F;\n            $F = $lc;\n        }\n        push @{$files_for_set[0]}, $F;\n    }\n    foreach my $pair (@file_pairs_tot) {\n        if ($ON_WINDOWS) {\n            push @{$files_for_set[0]}, lc $pair->[0];\n            push @{$files_for_set[1]}, lc $pair->[1];\n        } else {\n            push @{$files_for_set[0]}, $pair->[0];\n            push @{$files_for_set[1]}, $pair->[1];\n        }\n    }\n    @ARGV = (1, 2); # place holders\n}\nfor (my $i = 0; $i < scalar @ARGV; $i++) {\n    if ($opt_diff_list_file) {\n        push @fh, make_file_list($files_for_set[$i], $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    } elsif ($opt_diff_list_files) {\n        my @list_files = read_list_file($ARGV[$i]);\n        push @fh, make_file_list(\\@list_files, $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    } else {\n        push @fh, make_file_list([ $ARGV[$i] ], $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    }\n    if ($opt_exclude_list_file) {\n        # note: process_exclude_list_file() references global @file_list\n        process_exclude_list_file($opt_exclude_list_file,\n                                 \\%Exclude_Dir,\n                                 \\%Ignored);\n    }\n    if ($opt_no_autogen) {\n        exclude_autogenerated_files(\\@{$files_for_set[$i]},  # in/out\n                                    \\%Error_Codes, \\@Errors, \\%Ignored);\n    }\n    @file_list = ();\n}\n# 1}}}\n# Step 5:  Remove duplicate files.             {{{1\n#\nmy %Language           = ();\nmy %unique_source_file = ();\nmy $n_set = 0;\nforeach my $FH (@fh) {  # loop over each pair of file sets\n    ++$n_set;\n    remove_duplicate_files($FH,\n                               \\%{$Language{$FH}}               ,\n                               \\%{$unique_source_file{$FH}}     ,\n                          \\%Error_Codes                         ,\n                               \\@Errors                         ,\n                               \\%Ignored                        );\n    if ($opt_exclude_content) {\n        exclude_by_regex($opt_exclude_content,              # in\n                        \\%{$unique_source_file{$FH}},       # in/out\n                        \\%Ignored);                         # out\n    } elsif ($opt_include_content) {\n        include_by_regex($opt_include_content,              # in\n                        \\%{$unique_source_file{$FH}},       # in/out\n                        \\%Ignored);                         # out\n    }\n\n    if ($opt_include_lang) {\n        # remove files associated with languages not\n        # specified by --include-lang\n        my @delete_file = ();\n        foreach my $file (keys %{$unique_source_file{$FH}}) {\n            my $keep_file = 0;\n            foreach my $keep_lang (keys %Include_Language) {\n                if (lc($Language{$FH}{$file}) eq $keep_lang) {\n                    $keep_file = 1;\n                    last;\n                }\n            }\n            next if $keep_file;\n            push @delete_file, $file;\n        }\n        foreach my $file (@delete_file) {\n            delete $Language{$FH}{$file};\n        }\n    }\n\n    printf \"%2d: %8d unique file%s.                          \\r\",\n        $n_set,\n        plural_form(scalar keys %unique_source_file)\n        unless $opt_quiet;\n    my $suffix = $n_set == 1 ? \"L\" : \"R\";\n    write_file(\"${opt_unique}_${suffix}\", {}, sort keys %unique_source_file) if $opt_unique;\n}\n# 1}}}\n# Step 6:  Count code, comments, blank lines.  {{{1\n#\nmy %Results_by_Language = ();\nmy %Results_by_File     = ();\nmy %Delta_by_Language   = ();\nmy %Delta_by_File       = ();\nmy %Renamed             = ();\n\nmy %alignment = ();\n\nmy $fset_a = $fh[0];\nmy $fset_b = $fh[1];\n\nmy $n_filepairs_compared = 0;\nmy $tot_counted = 0;\n\nif ( scalar @fh != 2 ) {\n    print \"Error: incorrect length fh array when preparing diff at step 6.\\n\";\n    exit 1;\n}\n\nif ($opt_git_diff_rel and (scalar(keys %git_metadata) == 2)) {\n    # --git --diff with both L and R as git references\n    align_from_git($ARGV[0]                              , # in, before tag\n                   $ARGV[1]                              , # in, after  tag\n                   \\@files_added_tot                     , # out\n                   \\@files_removed_tot                   , # out\n                   \\@file_pairs_tot                      , # out\n                   \\%Renamed                             , # out\n                  );\n} elsif (!$opt_diff_list_file) {\n    align_by_pairs(\\%{$unique_source_file{$fset_a}}      , # in\n                   \\%{$unique_source_file{$fset_b}}      , # in\n                   \\@files_added_tot                     , # out\n                   \\@files_removed_tot                   , # out\n                   \\@file_pairs_tot                      , # out\n                  );\n}\n\n#use Data::Dumper;\n#print \"in files L : \", Dumper($unique_source_file{$fset_a});\n#print \"in files R : \", Dumper($unique_source_file{$fset_b});\n#print \"added : \", Dumper(\\@files_added_tot);\n#print \"removed : \", Dumper(\\@files_removed_tot);\n#print \"pairs : \", Dumper(\\@file_pairs_tot);\n\nif ( $max_processes == 0) {\n    # Multiprocessing is disabled\n    my $part = count_filesets ( $fset_a, $fset_b, \\@files_added_tot,\n                               \\@files_removed_tot, \\@file_pairs_tot,\n                               0, \\%Language, \\%ignore_regex, \\%Ignored);\n    %Results_by_File = %{$part->{'results_by_file'}};\n    %Results_by_Language= %{$part->{'results_by_language'}};\n    %Delta_by_File = %{$part->{'delta_by_file'}};\n    %Delta_by_Language= %{$part->{'delta_by_language'}};\n    %Ignored = ( %Ignored, %{$part->{'ignored'}});\n    %alignment = %{$part->{'alignment'}};\n    $n_filepairs_compared = $part->{'n_filepairs_compared'};\n    push ( @Errors, @{$part->{'errors'}});\n} else {\n    # Multiprocessing is enabled\n    # Do not create more processes than the amount of data to be processed\n    my $num_processes = min(max(scalar @files_added_tot,\n                                scalar @files_removed_tot,\n                                scalar @file_pairs_tot),\n                            $max_processes);\n    # ... but use at least one process.\n       $num_processes = 1\n            if $num_processes == 0;\n    # Start processes for counting\n    my $pm = Parallel::ForkManager->new($num_processes);\n    # When processes finish, they will use the embedded subroutine for\n    # merging the data into global variables.\n    $pm->run_on_finish ( sub {\n        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $part) = @_;\n        my $part_ignored = $part->{'ignored'};\n        my $part_result_by_file = $part->{'results_by_file'};\n        my $part_result_by_language = $part->{'results_by_language'};\n        my $part_delta_by_file = $part->{'delta_by_file'};\n        my $part_delta_by_language = $part->{'delta_by_language'};\n        my $part_alignment = $part->{'alignment'};\n        my $part_errors = $part->{'errors'};\n           $tot_counted += scalar keys %$part_result_by_file;\n           $n_filepairs_compared += $part->{'n_filepairs_compared'};\n        # Since files are processed by multiple processes, we can't measure\n        # the number of processed files exactly. We approximate this by showing\n        # the number of files counted by finished processes.\n        printf \"Counting:  %d\\r\", $tot_counted\n                 if $opt_progress_rate;\n\n        foreach my $this_language ( keys %$part_result_by_language ) {\n            my $counts = $part_result_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                $Results_by_Language{$this_language}{$inner_key} +=\n                    $counts->{$inner_key};\n            }\n        }\n\n        foreach my $this_language ( keys %$part_delta_by_language ) {\n            my $counts = $part_delta_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                my $statuses = $counts->{$inner_key};\n                foreach my $inner_status ( keys %$statuses ) {\n                    $Delta_by_Language{$this_language}{$inner_key}{$inner_status} +=\n                          $counts->{$inner_key}->{$inner_status};\n                }\n            }\n        }\n\n        foreach my $label ( keys %$part_alignment ) {\n            my $inner = $part_alignment->{$label};\n            foreach my $key ( keys %$inner ) {\n                $alignment{$label}{$key} = 1;\n            }\n        }\n\n        %Results_by_File = ( %Results_by_File, %$part_result_by_file );\n        %Delta_by_File = ( %Delta_by_File, %$part_delta_by_file );\n        %Ignored = (%Ignored, %$part_ignored );\n        push ( @Errors, @$part_errors );\n    } );\n\n    my $num_filepairs_per_part = ceil ( ( scalar @file_pairs_tot ) / $num_processes );\n    my $num_filesremoved_per_part = ceil ( ( scalar @files_removed_tot ) / $num_processes );\n    my $num_filesadded_per_part = ceil ( ( scalar @files_added_tot ) / $num_processes );\n\n    while ( 1 ) {\n        my @files_added_part = splice @files_added_tot, 0, $num_filesadded_per_part;\n        my @files_removed_part = splice @files_removed_tot, 0, $num_filesremoved_per_part;\n        my @filepairs_part = splice @file_pairs_tot, 0, $num_filepairs_per_part;\n        if ( scalar @files_added_part == 0 and scalar @files_removed_part == 0 and\n             scalar @filepairs_part == 0 ) {\n            last;\n        }\n\n        $pm->start() and next;\n        my $count_result = count_filesets ( $fset_a, $fset_b,\n            \\@files_added_part, \\@files_removed_part,\n            \\@filepairs_part, 1, \\%Language, \\%ignore_regex, \\%Ignored );\n        $pm->finish(0 , $count_result);\n    }\n    # Wait for processes to finish\n    $pm->wait_all_children();\n}\n\n# Write alignment data if needed requested\nif ($opt_diff_alignment) {\n    write_alignment_data ( $opt_diff_alignment, $n_filepairs_compared, \\%alignment ) ;\n}\n\nmy $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \": \";\nmy @ignored_reasons = map { \"${_}${separator} $Ignored{$_}\" } sort keys %Ignored;\nwrite_file($opt_ignored, {\"file_type\" => \"ignored\",\n                          \"separator\" => \": \",\n                          \"columns\"   => [\"file\", \"reason\"],\n                         }, @ignored_reasons   ) if $opt_ignored;\nwrite_file($opt_counted, {}, sort keys %Results_by_File) if $opt_counted;\n# 1}}}\n# Step 7:  Assemble results.                   {{{1\n#\nmy $end_time = get_time();\nprintf \"%8d file%s ignored.                           \\n\",\n    plural_form(scalar keys %Ignored) unless $opt_quiet;\nprint_errors(\\%Error_Codes, \\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\nif (!%Delta_by_Language) {\n    foreach my $out_style (sort keys %OUTFILE_EXT) {\n        next unless $OUTFILE_EXT{$out_style};\n        produce_null_output($opt_report_file, $out_style);\n        exit;\n    }\n}\ngenerate_diff_sql($end_time - $start_time, \\%Delta_by_File) if $opt_sql;\n\nexit if $skip_generate_report;\n\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    next unless $OUTFILE_EXT{$out_style};\n    my @Lines_Out = ();\n    if ($opt_by_file) {\n        @Lines_Out = diff_report($VERSION, $end_time - $start_time,\n                                \"by file\",\n                                \\%Delta_by_File, \\%Scale_Factor, \\%Renamed);\n    } else {\n        @Lines_Out = diff_report($VERSION, $end_time - $start_time,\n                                \"by language\",\n                                \\%Delta_by_Language, \\%Scale_Factor, undef);\n    }\n    my $outfile = $opt_report_file;\n    produce_output(\\@Lines_Out, $opt_report_file, $out_style);\n}\n\n# 1}}}\n} else {\n# Step 4:  Separate code from non-code files.  {{{1\nmy $fh = 0;\nif ($opt_list_file or $opt_diff_list_files or $opt_vcs) {\n    my @list;\n    if ($opt_vcs) {\n        @list = invoke_generator($opt_vcs, \\@ARGV);\n    } elsif ($opt_list_file) {\n        @list = read_list_file($opt_list_file);\n    } else {\n        @list = read_list_file($ARGV[0]);\n    }\n    $fh = make_file_list(\\@list, 0, \\%Error_Codes, \\@Errors, \\%Ignored);\n} else {\n    $fh = make_file_list(\\@ARGV, 0, \\%Error_Codes, \\@Errors, \\%Ignored);\n    #     make_file_list populates global variable @file_list via call to\n    #     File::Find's find() which in turn calls files()\n}\nif ($opt_exclude_list_file) {\n    # note: process_exclude_list_file() references global @file_list\n    process_exclude_list_file($opt_exclude_list_file,\n                             \\%Exclude_Dir,\n                             \\%Ignored);\n}\nif ($opt_skip_win_hidden and $ON_WINDOWS) {\n    my @file_list_minus_hidden = ();\n    # eval code to run on Unix without 'missing Win32::File module' error.\n    my $win32_file_invocation = '\n        use Win32::File;\n        foreach my $F (@file_list) {\n            my $attr = undef;\n            Win32::File::GetAttributes($F, $attr);\n            if ($attr & HIDDEN) {\n                $Ignored{$F} = \"Windows hidden file\";\n                print \"Ignoring $F since it is a Windows hidden file\\n\"\n                    if $opt_v > 1;\n            } else {\n                push @file_list_minus_hidden, $F;\n            }\n        }';\n    eval $win32_file_invocation;\n    @file_list = @file_list_minus_hidden;\n}\nif ($opt_no_autogen) {\n    exclude_autogenerated_files(\\@file_list,  # in/out\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n}\n#printf \"%8d file%s excluded.                     \\n\",\n#   plural_form(scalar keys %Ignored)\n#   unless $opt_quiet;\n# die print \": \", join(\"\\n: \", @file_list), \"\\n\";\n# 1}}}\n# Step 5:  Remove duplicate files.             {{{1\n#\nmy %Language           = ();\nmy %unique_source_file = ();\nremove_duplicate_files($fh                          ,   # in\n                           \\%Language               ,   # out\n                           \\%unique_source_file     ,   # out\n                      \\%Error_Codes                 ,   # in\n                           \\@Errors                 ,   # out\n                           \\%Ignored                );  # out\nif ($opt_exclude_content) {\n    exclude_by_regex($opt_exclude_content,              # in\n                    \\%unique_source_file ,              # in/out\n                    \\%Ignored);                         # out\n} elsif ($opt_include_content) {\n    include_by_regex($opt_include_content,              # in\n                    \\%unique_source_file ,              # in/out\n                    \\%Ignored);                         # out\n}\nprintf \"%8d unique file%s.                              \\n\",\n    plural_form(scalar keys %unique_source_file)\n    unless $opt_quiet;\nwrite_file($opt_unique, {}, sort keys %unique_source_file) if $opt_unique;\n# 1}}}\n# Step 6:  Count code, comments, blank lines.  {{{1\n#\nmy %Results_by_Language = ();\nmy %Results_by_File     = ();\nmy @results_parts  = ();\nmy @sorted_files = sort keys %unique_source_file;\n\nif ( $max_processes == 0) {\n    # Multiprocessing is disabled\n    my $part = count_files ( \\@sorted_files , 0, \\%ignore_regex, \\%Language);\n    %Results_by_File = %{$part->{'results_by_file'}};\n    %Results_by_Language= %{$part->{'results_by_language'}};\n    %Ignored = ( %Ignored, %{$part->{'ignored'}});\n    push ( @Errors, @{$part->{'errors'}});\n} else {\n    # Do not create more processes than the number of files to be processed\n    my $num_files = scalar @sorted_files;\n    my $num_processes = $num_files >= $max_processes ? $max_processes : $num_files;\n    # Use at least one process.\n       $num_processes = 1\n            if $num_processes == 0;\n    # Start processes for counting\n    my $pm = Parallel::ForkManager->new($num_processes);\n    # When processes finish, they will use the embedded subroutine for\n    # merging the data into global variables.\n    $pm->run_on_finish ( sub {\n        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $part) = @_;\n        my $part_ignored = $part->{'ignored'};\n        my $part_result_by_file = $part->{'results_by_file'};\n        my $part_result_by_language = $part->{'results_by_language'};\n        my $part_errors = $part->{'errors'};\n        my $nCounted+= scalar keys %$part_result_by_file;\n        # Since files are processed by multiple processes, we can't measure\n        # the number of processed files exactly. We approximate this by showing\n        # the number of files counted by finished processes.\n        printf \"Counting:  %d\\r\", $nCounted\n                 if $opt_progress_rate;\n\n        foreach my $this_language ( keys %$part_result_by_language ) {\n            my $counts = $part_result_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                $Results_by_Language{$this_language}{$inner_key} +=\n                    $counts->{$inner_key};\n            }\n        }\n        %Results_by_File = ( %Results_by_File, %$part_result_by_file );\n        %Ignored = (%Ignored, %$part_ignored);\n        push ( @Errors, @$part_errors);\n    } );\n    my $num_files_per_part = ceil ( ( scalar @sorted_files ) / $num_processes );\n    while ( my @part = splice @sorted_files, 0 , $num_files_per_part ) {\n        $pm->start() and next;\n        my $count_result = count_files ( \\@part, 1, \\%ignore_regex, \\%Language );\n        $pm->finish(0 , $count_result);\n    }\n    # Wait for processes to finish\n    $pm->wait_all_children();\n}\n\nmy $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \": \";\nmy @ignored_reasons = map { \"${_}${separator} $Ignored{$_}\" } sort keys %Ignored;\nwrite_file($opt_ignored, {\"file_type\" => \"ignored\",\n                          \"separator\" => $separator,\n                          \"columns\"   => [\"file\", \"reason\"],\n                         }, @ignored_reasons   ) if $opt_ignored;\nif ($opt_summary_cutoff) {\n    %Results_by_Language = apply_cutoff($opt_summary_cutoff,\n                                       \\%Results_by_Language);\n}\nwrite_file($opt_counted, {}, sort keys %Results_by_File) if $opt_counted;\n# 1}}}\n# Step 7:  Assemble results.                   {{{1\n#\nmy $end_time = get_time();\nprintf \"%8d file%s ignored.\\n\", plural_form(scalar keys %Ignored)\n    unless $opt_quiet;\nprint_errors(\\%Error_Codes, \\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\nif (!%Results_by_Language) {\n    write_null_results($opt_json, $opt_xml, $opt_report_file);\n    exit;\n}\n\ngenerate_sql($end_time - $start_time,\n            \\%Results_by_File, \\%Scale_Factor) if $opt_sql;\nexit if $skip_generate_report;\n\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    next unless $OUTFILE_EXT{$out_style};\n    my @Lines_Out = ();\n\n    if      ($opt_by_file_by_lang) {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by file\",\n                                          \\%Results_by_File,    \\%Scale_Factor,\n                                          $out_style);\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by language\",\n                                          \\%Results_by_Language, \\%Scale_Factor,\n                                          $out_style);\n    } elsif ($opt_by_file) {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by file\",\n                                          \\%Results_by_File,    \\%Scale_Factor,\n                                          $out_style);\n    } else {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by language\",\n                                          \\%Results_by_Language, \\%Scale_Factor,\n                                          $out_style);\n    }\n    produce_output(\\@Lines_Out, $opt_report_file, $out_style);\n}\n# 1}}}\n}\n\nif ($opt_count_diff) {\n    ++$opt_count_diff;\n    exit if $opt_count_diff > 3;\n    goto Top_of_Processing_Loop;\n}\n\nsuggest_remedies_for_errors(\\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\n# - - - - - - - - - - - - - - - end of main - - - - - - - - - - - - - - - #\nsub produce_output {                         # {{{1\n    my ($ra_Lines_Out, $outfile, $out_style) = @_;\n    if ($opt_fmt) {\n        my $json_string = \"\";\n        write_file(\\$json_string, {}, @{$ra_Lines_Out});\n        my ($file_len, $lang_len, $header, %contents) = load_json($json_string);\n        @{$ra_Lines_Out} = print_format_n(abs($opt_fmt), $file_len, $lang_len, $header, %contents);\n    }\n    if ($outfile) {\n        my $adjusted_outfile = $outfile;\n        if ($N_OUTPUT_FORMATS > 1 and\n            ($opt_report_file !~ /\\.${out_style}$/)) {\n            # ensure the output filename has a suitable extension\n            $adjusted_outfile .=  \".\" . $out_style;\n        }\n        write_file($adjusted_outfile, {}, @{$ra_Lines_Out});\n    } else {\n        if ($opt_fmt) {\n            print join(\"\", @{$ra_Lines_Out});\n        } else {\n            print \"\\n\" unless $opt_quiet;\n            print join(\"\\n\", @{$ra_Lines_Out}), \"\\n\";\n        }\n    }\n}\n# 1}}}\nsub produce_null_output {                    # {{{1\n    my ($outfile, $out_style) = @_;\n    print \"-> produce_null_output($outfile, $out_style)\\n\" if $opt_v > 2;\n    my @Lines_Out = ( \"Nothing to count.\" );\n    if ($out_style eq \"json\") {\n        @Lines_Out = ( \"{}\" );\n    } elsif ($out_style eq \"xml\") {\n        @Lines_Out = ( '<?xml version=\"1.0\" encoding=\"UTF-8\"?><results/>' );\n    } elsif ($out_style eq \"csv\") {\n        @Lines_Out = ( '' );\n    } elsif ($out_style eq \"md\" or $out_style eq \"yaml\") {\n        @Lines_Out = ( \"# Nothing to count.\" );\n    }\n    if ($outfile) {\n        write_file($outfile, {}, @Lines_Out);\n    } else {\n        print \"@Lines_Out\\n\";\n    }\n    print \"<- produce_null_output()\\n\" if $opt_v > 2;\n}\n# 1}}}\nsub suggest_remedies_for_errors {            # {{{1\n    my ($raa_errors) = @_; #  [ [ numeric error code, filename], .. ]\n    my $hit_timeout = 0;\n    foreach my $pair (@{$raa_errors}) {\n        my ($code, $file) = @{$pair};\n        $hit_timeout = $code == -5 ? 1 : $hit_timeout;\n    }\n    if ($hit_timeout) {\n        print \"\\n\";\n        print \"One or more files took longer to process than expected.\\n\";\n        print \"Try rerunning without timeout guards by adding  --timeout=0\\n\";\n        print \"to your command line arguments.  See the documentation on\\n\";\n        print \"the --timeout switch for more information.\\n\";\n        print \"\\n\";\n    }\n}\n# 1}}}\nsub brief_usage {                            # {{{1\n    return \"\n                       cloc -- Count Lines of Code\n\nUsage:\n    $script [options] <file(s)/dir(s)/git hash(es)>\n        Count physical lines of source code and comments in the given files\n        (may be archives such as compressed tarballs or zip files) and/or\n        recursively below the given directories or git commit hashes.\n        Example:    cloc src/ include/ main.c\n\n    $script [options] --diff <set1>  <set2>\n        Compute differences of physical lines of source code and comments\n        between any pairwise combination of directory names, archive\n        files or git commit hashes.\n        Example:    cloc --diff Python-3.5.tar.xz python-3.6/\n\n$script --help  shows full documentation on the options.\nhttps://$URL has numerous examples and more information.\n\";\n}\n# 1}}}\nsub long_usage {                             # {{{1\n    return \"\nUsage: $script [options] <file(s)/dir(s)/git hash(es)> | <set 1> <set 2> | <report files>\n\n Count, or compute differences of, physical lines of source code in the\n given files (may be archives such as compressed tarballs or zip files,\n or git commit hashes or branch names) and/or recursively below the\n given directories.\n\n ${BB}Input Options${NN}\n   --extract-with=<cmd>      This option is only needed if cloc is unable\n                             to figure out how to extract the contents of\n                             the input file(s) by itself.\n                             Use <cmd> to extract binary archive files (e.g.:\n                             .tar.gz, .zip, .Z).  Use the literal '>FILE<' as\n                             a stand-in for the actual file(s) to be\n                             extracted.  For example, to count lines of code\n                             in the input files\n                                gcc-4.2.tar.gz  perl-5.8.8.tar.gz\n                             on Unix use\n                               --extract-with='gzip -dc >FILE< | tar xf -'\n                             or, if you have GNU tar,\n                               --extract-with='tar zxf >FILE<'\n                             and on Windows use, for example:\n                               --extract-with=\\\"\\\\\\\"c:\\\\Program Files\\\\WinZip\\\\WinZip32.exe\\\\\\\" -e -o >FILE< .\\\"\n                             (if WinZip is installed there).\n   --list-file=<file>        Take the list of file and/or directory names to\n                             process from <file>, which has one file/directory\n                             name per line.  Only exact matches are counted;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.  Set <file>\n                             to - to read file names from a STDIN pipe.\n                             See also --exclude-list-file, --config.\n   --diff-list-file=<file>   Take the pairs of file names to be diff'ed from\n                             <file>, whose format matches the output of\n                             --diff-alignment.  (Run with that option to\n                             see a sample.)  The language identifier at the\n                             end of each line is ignored.  This enables --diff\n                             mode and bypasses file pair alignment logic.\n                             Use --diff-list-files to define the file name\n                             pairs in separate files. See also --config.\n   --diff-list-files <file1> <file2>\n                             Compute differences in code and comments between\n                             the files and directories listed in <file1> and\n                             <file2>.  Each input file should use the same\n                             format as --list-file, where there is one file or\n                             directory name per line.  Only exact matches are\n                             counted; relative path names will be resolved\n                             starting from the directory where cloc is invoked.\n                             This enables --diff mode.  See also --list-file,\n                             --diff-list-file, --diff.\n   --files-from=<CMD>        Synonym for --vcs=<CMD>.\n   --vcs=<CMD>               Invoke a system call to <CMD> to obtain a list of\n                             files to work on.  If <CMD> is 'git', then will\n                             invoke 'git ls-files' to get a file list.  Submodules\n                             are ignored unless --include-submodules is also\n                             given. See also --git which accepts git commit hashes\n                             and branch names. If <VCS> is 'svn' then will invoke\n                             'svn list -R'. The primary benefit is that cloc will\n                             then skip files explicitly excluded by the versioning\n                             tool in question, ie, those in .gitignore or have the\n                             svn:ignore property.\n                             Alternatively <CMD> may be any system command\n                             that generates a list of files.\n                             Note:  cloc must be in a directory which can read\n                             the files as they are returned by <CMD>.  cloc will\n                             not download files from remote repositories.\n                             'svn list -R' may refer to a remote repository\n                             to obtain file names (and therefore may require\n                             authentication to the remote repository), but\n                             the files themselves must be local.\n                             Setting <CMD> to 'auto' selects between 'git'\n                             and 'svn' (or neither) depending on the presence\n                             of a .git or .svn subdirectory below the directory\n                             where cloc is invoked.\n                             --files-from is a synonym for --vcs.\n   --unicode                 Check binary files to see if they contain Unicode\n                             expanded ASCII text.  This causes performance to\n                             drop noticeably.\n\n ${BB}Processing Options${NN}\n   --autoconf                Count .in files (as processed by GNU autoconf) of\n                             recognized languages.  See also --no-autogen.\n   --by-file                 Report results for every source file encountered.\n                             See also --fmt under 'Output Options'.\n   --by-file-by-lang         Report results for every source file encountered\n                             in addition to reporting by language.\n   --config <file>           Read command line switches from <file> instead of\n                             the default location of $config_file.\n                             The file should contain one switch, along with\n                             arguments (if any), per line.  Blank lines and lines\n                             beginning with '#' are skipped.  Options given on\n                             the command line take priority over entries read from\n                             the file.\n                             If a directory is also given with any of these\n                             switches: --list-file, --exclude-list-file,\n                             --read-lang-def, --force-lang-def, --diff-list-file\n                             and a config file exists in that directory, it will\n                             take priority over $config_file.\n   --count-and-diff <set1> <set2>\n                             First perform direct code counts of source file(s)\n                             of <set1> and <set2> separately, then perform a diff\n                             of these.  Inputs may be pairs of files, directories,\n                             or archives.  If --out or --report-file is given,\n                             three output files will be created, one for each\n                             of the two counts and one for the diff.  See also\n                             --diff, --diff-alignment, --diff-timeout,\n                             --ignore-case, --ignore-whitespace.\n   --diff <set1> <set2>      Compute differences in code and comments between\n                             source file(s) of <set1> and <set2>.  The inputs\n                             may be any mix of files, directories, archives,\n                             or git commit hashes.  Use --diff-alignment to\n                             generate a list showing which file pairs where\n                             compared.  File pairs are aligned by matching file\n                             names.  If --git is also given, a more sophisticated\n                             pairing algorithm which additionally attempts to pair\n                             renamed file is used.  When comparing git branches,\n                             only files which have changed in either commit are\n                             compared. See also --git, --count-and-diff,\n                             --diff-alignment, --diff-list-file, --diff-timeout,\n                             --ignore-case, --ignore-whitespace.\n   --diff-timeout <N>        Ignore files which take more than <N> seconds\n                             to process.  Default is 10 seconds.  Setting <N>\n                             to 0 allows unlimited time.  (Large files with many\n                             repeated lines can cause Algorithm::Diff::sdiff()\n                             to take hours.) See also --timeout.\n   --docstring-as-code       cloc considers docstrings to be comments, but this is\n                             not always correct as docstrings represent regular\n                             strings when they appear on the right hand side of an\n                             assignment or as function arguments.  This switch\n                             forces docstrings to be counted as code.\n   --follow-links            [Unix only] Follow symbolic links to directories\n                             (sym links to files are always followed).\n                             See also --stat.\n   --force-lang=<lang>[,<ext>]\n                             Process all files that have a <ext> extension\n                             with the counter for language <lang>.  For\n                             example, to count all .f files with the\n                             Fortran 90 counter (which expects files to\n                             end with .f90) instead of the default Fortran 77\n                             counter, use\n                               --force-lang=\\\"Fortran 90,f\\\"\n                             If <ext> is omitted, every file will be counted\n                             with the <lang> counter.  This option can be\n                             specified multiple times (but that is only\n                             useful when <ext> is given each time).\n                             See also --script-lang, --lang-no-ext.\n   --force-lang-def=<file>   Load language processing filters from <file>,\n                             then use these filters instead of the built-in\n                             filters.  Note:  languages which map to the same\n                             file extension (for example:\n                             MATLAB/Mathematica/Objective-C/MUMPS/Mercury;\n                             Pascal/PHP; Lisp/OpenCL; Lisp/Julia; Perl/Prolog)\n                             will be ignored as these require additional\n                             processing that is not expressed in language\n                             definition files.  Use --read-lang-def to define\n                             new language filters without replacing built-in\n                             filters (see also --write-lang-def,\n                             --write-lang-def-incl-dup, --config).\n   --git                     Forces the inputs to be interpreted as git targets\n                             (commit hashes, branch names, et cetera) if these\n                             are not first identified as file or directory\n                             names.  This option overrides the --vcs=git logic\n                             if this is given; in other words, --git gets its\n                             list of files to work on directly from git using\n                             the hash or branch name rather than from\n                             'git ls-files'.  This option can be used with\n                             --diff to perform line count diffs between git\n                             commits, or between a git commit and a file,\n                             directory, or archive.  Use -v/--verbose to see\n                             the git system commands cloc issues.\n   --git-diff-rel            Same as --git --diff, or just --diff if the inputs\n                             are recognized as git targets.  Only files which\n                             have changed in either commit are compared.\n   --git-diff-all            Git diff strategy #2:  compare all files in the\n                             repository between the two commits.\n   --ignore-whitespace       Ignore horizontal white space when comparing files\n                             with --diff.  See also --ignore-case.\n   --ignore-case             Ignore changes in case within file contents;\n                             consider upper- and lowercase letters equivalent\n                             when comparing files with --diff.  See also\n                             --ignore-whitespace.\n   --ignore-case-ext         Ignore case of file name extensions.  This will\n                             cause problems counting some languages\n                             (specifically, .c and .C are associated with C and\n                             C++; this switch would count .C files as C rather\n                             than C++ on *nix operating systems).  File name\n                             case insensitivity is always true on Windows.\n   --ignore-regex            Ignore lines in source files that match the given\n                             Perl regular expression for the given language(s).\n                             This option can be specified multiple times.\n                             Language names are comma separated and are followed\n                             by the pipe character and the regular expression.\n                             Use * to match all languages.\n                             Examples:\n                               --ignore-regex=\\\"C,Java,C++|^\\\\s*[{};]\\\\s*\\$\\\"\n                               --ignore-regex=\\\"*|DEBUG|TEST\\\\s+ONLY\\\"\n                             These filters are applied after comments are\n                             removed.  Use --strip-comments=EXT to create\n                             new files that show these filters applied.\n                             The primary use case is to ignore lines\n                             containing only braces, brackets, or puctuation.\n   --lang-no-ext=<lang>      Count files without extensions using the <lang>\n                             counter.  This option overrides internal logic\n                             for files without extensions (where such files\n                             are checked against known scripting languages\n                             by examining the first line for #!).  See also\n                             --force-lang, --script-lang.\n   --max-file-size=<MB>      Skip files larger than <MB> megabytes when\n                             traversing directories.  By default, <MB>=100.\n                             cloc's memory requirement is roughly twenty times\n                             larger than the largest file so running with\n                             files larger than 100 MB on a computer with less\n                             than 2 GB of memory will cause problems.\n                             Note:  this check does not apply to files\n                             explicitly passed as command line arguments.\n   --no-autogen[=list]       Ignore files generated by code-production systems\n                             such as GNU autoconf.  To see a list of these files\n                             (then exit), run with --no-autogen list\n                             See also --autoconf.\n   --no-recurse              Count files in the given directories without\n                             recursively descending below them.\n   --original-dir            [Only effective in combination with\n                             --strip-comments or --strip-code]  Write the stripped\n                             files to the same directory as the original files.\n   --only-count-files        Only count files by language.  Blank, comment, and\n                             code counts will be zero.\n   --read-binary-files       Process binary files in addition to text files.\n                             This is usually a bad idea and should only be\n                             attempted with text files that have embedded\n                             binary data.\n   --read-lang-def=<file>    Load new language processing filters from <file>\n                             and merge them with those already known to cloc.\n                             If <file> defines a language cloc already knows\n                             about, cloc's definition will take precedence.\n                             Use --force-lang-def to over-ride cloc's\n                             definitions (see also --write-lang-def,\n                             --write-lang-def-incl-dup, --config).\n   --script-lang=<lang>,<s>  Process all files that invoke <s> as a #!\n                             scripting language with the counter for language\n                             <lang>.  For example, files that begin with\n                                #!/usr/local/bin/perl5.8.8\n                             will be counted with the Perl counter by using\n                                --script-lang=Perl,perl5.8.8\n                             The language name is case insensitive but the\n                             name of the script language executable, <s>,\n                             must have the right case.  This option can be\n                             specified multiple times.  See also --force-lang,\n                             --lang-no-ext.\n   --sdir=<dir>              Use <dir> as the scratch directory instead of\n                             letting File::Temp chose the location.  Files\n                             written to this location are not removed at\n                             the end of the run (as they are with File::Temp).\n   --skip-leading=<N[,ext]>  Skip the first <N> lines of each file.  If a\n                             comma separated list of extensions is also given,\n                             only skip lines from those file types.  Example:\n                               --skip-leading=10,cpp,h\n                             will skip the first ten lines of *.cpp and *.h\n                             files.  This is useful for ignoring boilerplate\n                             text.\n   --skip-uniqueness         Skip the file uniqueness check.  This will give\n                             a performance boost at the expense of counting\n                             files with identical contents multiple times\n                             (if such duplicates exist).\n   --stat                    Some file systems (AFS, CD-ROM, FAT, HPFS, SMB)\n                             do not have directory 'nlink' counts that match\n                             the number of its subdirectories.  Consequently\n                             cloc may undercount or completely skip the\n                             contents of such file systems.  This switch forces\n                             File::Find to stat directories to obtain the\n                             correct count.  File search speed will decrease.\n                             See also --follow-links.\n   --stdin-name=<file>       Give a file name to use to determine the language\n                             for standard input.  (Use - as the input name to\n                             receive source code via STDIN.)\n   --strip-code=<ext>        For each file processed, write to the current\n                             directory a version of the file which has blank\n                             and code lines, including code with (in-line\n                             comments) removed. The name of each stripped file\n                             is the original file name with .<ext> appended to\n                             it. It is written to the current directory unless\n                             --original-dir is on.\n   --strip-comments=<ext>    For each file processed, write to the current\n                             directory a version of the file which has blank\n                             and commented lines removed (in-line comments\n                             persist).  The name of each stripped file is the\n                             original file name with .<ext> appended to it.\n                             It is written to the current directory unless\n                             --original-dir is on.\n   --strip-str-comments      Replace comment markers embedded in strings with\n                             'xx'.  This attempts to work around a limitation\n                             in Regexp::Common::Comment where comment markers\n                             embedded in strings are seen as actual comment\n                             markers and not strings, often resulting in a\n                             'Complex regular subexpression recursion limit'\n                             warning and incorrect counts.  There are two\n                             disadvantages to using this switch:  1/code count\n                             performance drops, and 2/code generated with\n                             --strip-comments will contain different strings\n                             where ever embedded comments are found.\n   --sum-reports             Input arguments are report files previously\n                             created with the --report-file option in plain\n                             format (eg. not JSON, YAML, XML, or SQL).\n                             Makes a cumulative set of results containing the\n                             sum of data from the individual report files.\n   --timeout <N>             Ignore files which take more than <N> seconds\n                             to process at any of the language's filter stages.\n                             The default maximum number of seconds spent on a\n                             filter stage is the number of lines in the file\n                             divided by one thousand.  Setting <N> to 0 allows\n                             unlimited time.  See also --diff-timeout.\n   --processes=NUM           [Available only on systems with a recent version\n                             of the Parallel::ForkManager module.  Not\n                             available on Windows.] Sets the maximum number of\n                             cores that cloc uses.  The default value of 0\n                             disables multiprocessing.\n   --unix                    Override the operating system autodetection\n                             logic and run in UNIX mode.  See also\n                             --windows, --show-os.\n   --use-sloccount           If SLOCCount is installed, use its compiled\n                             executables c_count, java_count, pascal_count,\n                             php_count, and xml_count instead of cloc's\n                             counters.  SLOCCount's compiled counters are\n                             substantially faster than cloc's and may give\n                             a performance improvement when counting projects\n                             with large files.  However, these cloc-specific\n                             features will not be available: --diff,\n                             --count-and-diff, --strip-code, --strip-comments,\n                             --unicode.\n   --windows                 Override the operating system autodetection\n                             logic and run in Microsoft Windows mode.\n                             See also --unix, --show-os.\n\n ${BB}Filter Options${NN}\n   --include-content=<regex> Only count files containing text that matches the\n                             given regular expression.\n   --exclude-content=<regex> Exclude files containing text that matches the given\n                             regular expression.\n   --exclude-dir=<D1>[,D2,]  Exclude the given comma separated directories\n                             D1, D2, D3, et cetera, from being scanned.  For\n                             example  --exclude-dir=.cache,test  will skip\n                             all files and subdirectories that have /.cache/\n                             or /test/ as their parent directory.\n                             Directories named .bzr, .cvs, .hg, .git, .svn,\n                             and .snapshot are always excluded.\n                             This option only works with individual directory\n                             names so including file path separators is not\n                             allowed.  Use --fullpath and --not-match-d=<regex>\n                             to supply a regex matching multiple subdirectories.\n   --exclude-ext=<ext1>[,<ext2>[...]]\n                             Do not count files having the given file name\n                             extensions.\n   --exclude-lang=<L1>[,L2[...]]\n                             Exclude the given comma separated languages\n                             L1, L2, L3, et cetera, from being counted.\n   --exclude-list-file=<file>  Ignore files and/or directories whose names\n                             appear in <file>.  <file> should have one file\n                             name per line.  Only exact matches are ignored;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.\n                             See also --list-file, --config.\n   --fullpath                Modifies the behavior of --match-f, --not-match-f,\n                             and --not-match-d to include the file's path--\n                             relative to the directory from which cloc is\n                             invoked--in the regex, not just the file's basename.\n                             (This does not expand each filename to include its\n                             fully qualified absolute path; instead, it uses as\n                             much of the path as is passed in to cloc.)\n   --include-ext=<ext1>[,ext2[...]]\n                             Count only languages having the given comma\n                             separated file extensions.  Use --show-ext to\n                             see the recognized extensions.\n   --include-lang=<L1>[,L2[...]]\n                             Count only the given comma separated, case-\n                             insensitive languages L1, L2, L3, et cetera.  Use\n                             --show-lang to see the list of recognized languages.\n   --include-submodules      When using --vcs=git, include files in git\n                             submodules.\n   --match-d=<regex>         Only count files in directories matching the Perl\n                             regex.  For example\n                               --match-d='/(src|include)/'\n                             only counts files in directories containing\n                             /src/ or /include/.  Unlike --not-match-d,\n                             --match-f, and --not-match-f, --match-d always\n                             anchors the regex to the directory from which\n                             cloc is invoked.\n   --not-match-d=<regex>     Count all files except those in directories\n                             matching the Perl regex.  Only the trailing\n                             directory name is compared, for example, when\n                             counting in /usr/local/lib, only 'lib' is\n                             compared to the regex.\n                             Add --fullpath to compare parent directories, beginning\n                             from the directory where cloc is invoked, to the regex.\n                             Do not include file path separators at the beginning\n                             or end of the regex. This option may be repeated.\n   --match-f=<regex>         Only count files whose basenames match the Perl\n                             regex.  For example\n                               --match-f='^[Ww]idget'\n                             only counts files that start with Widget or widget.\n                             Add --fullpath to include parent directories\n                             in the regex instead of just the basename.\n   --not-match-f=<regex>     Count all files except those whose basenames\n                             match the Perl regex.  Add --fullpath to include\n                             parent directories in the regex instead of just\n                             the basename. This option may be repeated.\n   --skip-archive=<regex>    Ignore files that end with the given Perl regular\n                             expression.  For example, if given\n                               --skip-archive='(zip|tar(\\.(gz|Z|bz2|xz|7z))?)'\n                             the code will skip files that end with .zip,\n                             .tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and\n                             .tar.7z.\n   --skip-win-hidden         On Windows, ignore hidden files.\n\n ${BB}Debug Options${NN}\n   --categorized=<file>      Save file sizes in bytes, identified languages\n                             and names of categorized files to <file>.\n   --counted=<file>          Save names of processed source files to <file>.\n                             See also --found, --ignored, --unique.\n   --diff-alignment=<file>   Write to <file> a list of files and file pairs\n                             showing which files were added, removed, and/or\n                             compared during a run with --diff.  This switch\n                             forces the --diff mode on.\n   --explain=<lang>          Print the filters used to remove comments for\n                             language <lang> and exit.  In some cases the\n                             filters refer to Perl subroutines rather than\n                             regular expressions.  An examination of the\n                             source code may be needed for further explanation.\n   --help                    Print this usage information and exit.\n   --found=<file>            Save names of every file found to <file>.  See\n                             also --counted, --ignored, --unique.\n   --ignored=<file>          Save names of ignored files and the reason they\n                             were ignored to <file>.  See also --counted,\n                             --found, --unique.\n   --print-filter-stages     Print processed source code before and after\n                             each filter is applied.\n   --show-ext[=<ext>]        Print information about all known (or just the\n                             given) file extensions and exit.\n   --show-lang[=<lang>]      Print information about all known (or just the\n                             given) languages and exit.\n   --show-os                 Print the value of the operating system mode\n                             and exit.  See also --unix, --windows.\n   --unique=<file>           Save names of unique files found to <file>.  See\n                             also --counted, --found, --ignored.\n   -v[=<n>]                  Verbose switch (optional numeric value).\n   -verbose[=<n>]            Long form of -v.\n   --version                 Print the version of this program and exit.\n   --write-lang-def=<file>   Writes to <file> the language processing filters\n                             then exits.  Useful as a first step to creating\n                             custom language definitions. Note: languages which\n                             map to the same file extension will be excluded.\n                             (See also --force-lang-def, --read-lang-def).\n   --write-lang-def-incl-dup=<file>\n                             Same as --write-lang-def, but includes duplicated\n                             extensions.  This generates a problematic language\n                             definition file because cloc will refuse to use\n                             it until duplicates are removed.\n\n ${BB}Output Options${NN}\n   --3                       Print third-generation language output.\n                             (This option can cause report summation to fail\n                             if some reports were produced with this option\n                             while others were produced without it.)\n   --by-percent  X           Instead of comment and blank line counts, show\n                             these values as percentages based on the value\n                             of X in the denominator, where X is\n                                 c    meaning lines of code\n                                 cm   meaning lines of code + comments\n                                 cb   meaning lines of code + blanks\n                                 cmb  meaning lines of code + comments + blanks\n                                 t    meaning sum of values in that column\n                             For example, if using method 'c' and your code\n                             has twice as many lines of comments as lines\n                             of code, the value in the comment column will\n                             be 200%.  Method 't' computes percentages\n                             based on totals for each column.  Another way of\n                             looking at this is that 't' computes percentages\n                             vertically while the other methods compute them\n                             horizontally.\n   --csv                     Write the results as comma separated values.\n   --csv-delimiter=<C>       Use the character <C> as the delimiter for comma\n                             separated files instead of ,.  This switch forces\n   --file-encoding=<E>       Write output files using the <E> encoding instead of\n                             the default ASCII (<E> = 'UTF-7').  Examples: 'UTF-16',\n                             'euc-kr', 'iso-8859-16'.  Known encodings can be\n                             printed with\n                               perl -MEncode -e 'print join(\\\"\\\\n\\\", Encode->encodings(\\\":all\\\")), \\\"\\\\n\\\"'\n   --fmt=<N>                 Alternate text output format where <N> is a number\n                             from 1 to 5. 'total lines' means the sum of code,\n                             comment, and blank lines.  The formats are:\n                               1:  by language (same as cloc default output)\n                               2:  by language with an extra column for total lines\n                               3:  by file with language\n                               4:  by file with a total lines column\n                               5:  by file with language and a total lines column\n   --hide-rate               Do not show elapsed time, line processing rate, or\n                             file processing rates in the output header. This\n                             makes output deterministic.\n   --json                    Write the results as JavaScript Object Notation\n                             (JSON) formatted output.\n   --md                      Write the results as Markdown-formatted text.\n   --out=<file>              Synonym for --report-file=<file>.\n   --percent                 Show counts as percentages of sums for each column.\n                             Same as '--by-percent t'.\n   --progress-rate=<n>       Show progress update after every <n> files are\n                             processed (default <n>=100).  Set <n> to 0 to\n                             suppress progress output (useful when redirecting\n                             output to STDOUT).\n   --quiet                   Suppress all information messages, including errors,\n                             except for the final report.  Add --show-errors to\n                             see errors.\n   --report-file=<file>      Write the results to <file> instead of STDOUT.\n   --show-errors             Show error messages, if any, when running with --quiet.\n   --sql=<file>              Write results as SQL create and insert statements\n                             which can be read by a database program such as\n                             SQLite.  If <file> is -, output is sent to STDOUT.\n   --sql-append              Append SQL insert statements to the file specified\n                             by --sql and do not generate table creation\n                             statements.  Only valid with the --sql option.\n   --sql-project=<name>      Use <name> as the project identifier for the\n                             current run.  Only valid with the --sql option.\n   --sql-style=<style>       Write SQL statements in the given style instead\n                             of the default SQLite format.  Styles include\n                             'Oracle' and 'Named_Columns'.\n   --sum-one                 For plain text reports, show the SUM: output line\n                             even if only one input file is processed.\n   --summary-cutoff=X:N      Aggregate to 'Other' results having X lines\n                             below N where X is one of\n                                c   meaning lines of code\n                                f   meaning files\n                                m   meaning lines of comments\n                                cm  meaning lines of code + comments\n                             Appending a percent sign to N changes\n                             the calculation from straight count to\n                             percentage.\n                             Ignored with --diff or --by-file.\n   --thousands-delimiter=<C> Divides numbers with many digits (i.e. numbers\n                             over 999) into groups using the character <C> as\n                             delimiter (e.g. for <C> = '.': 12345 -> 12.345).\n                             Only works with the '--fmt' option.\n                             Sample values: '.', ',', '_', ' '\n                             Synonym:  --ksep\n   --xml                     Write the results in XML.\n   --xsl=<file>              Reference <file> as an XSL stylesheet within\n                             the XML output.  If <file> is 1 (numeric one),\n                             writes a default stylesheet, cloc.xsl (or\n                             cloc-diff.xsl if --diff is also given).\n                             This switch forces --xml on.\n   --yaml                    Write the results in YAML.\n\";\n}\n# 1}}}\nsub separate_thousands {\n    my ($number, $separator,) = @_;\n    while ($number =~ s/(\\d+)(\\d\\d\\d)/$1\\=$2/) { };\n    $number =~ s/=/${separator}/g;\n    return $number;\n}\nsub summary_cutoff_error {                   # {{{\n    my ($parameter) = @_;\n    print \"-> summary_cutoff_is_ok($parameter)\\n\" if $opt_v > 2;\n    my %known_keys = ( 'c' => 1, 'f' => 1, 'm' => 1, 'cm' => 1 );\n    my $result = \"\";\n    my $by_pct = 0;\n    my ($key, $value);\n    if ($parameter !~ /:/) {\n        $result = \"expected a colon in --summary-cutoff argument\";\n    } else {\n        ($key, $value) = split(':', $parameter, 2);\n        if ($value =~ /%$/) {\n            $by_pct = 1;\n            $value =~ s/%$//;\n        }\n        if (!$known_keys{$key}) {\n            $result = \"--summary-cutoff argument:  '$key' is not 'c', 'f', 'm' or 'cm'\";\n        }\n        if ($value !~ /^\\d+(\\.\\d*)?$/) {\n            $result = \"--summary-cutoff argument:  '$value' is not a number\";\n        }\n    }\n    print \"<- summary_cutoff_is_ok($result)\\n\" if $opt_v > 2;\n    return $result;\n} # 1}}}\nsub apply_cutoff {                           # {{{1\n    my ($criterion,\n        $rhh_by_lang) = @_;\n\n    my %aggregated_Results_by_Language = ();\n    my $by_pct = 0;\n    my ($key, $value) = split(':', $criterion, 2);\n    if ($value =~ /%$/) {\n        $by_pct = 1;\n        $value =~ s/%$//;\n    }\n\n    my %sum = ();\n    if ($by_pct) {\n        foreach my $lang (keys %{$rhh_by_lang}) {\n            foreach my $category (qw(nFiles comment blank code)) {\n                $sum{$category} += $rhh_by_lang->{$lang}{$category};\n            }\n        }\n        if      ($key eq 'c') {\n            $value *= $sum{'code'}/100;\n        } elsif ($key eq 'f') {\n            $value *= $sum{'nFiles'}/100;\n        } elsif ($key eq 'm') {\n            $value *= $sum{'comment'}/100;\n        } elsif ($key eq 'cm') {\n            $value *= ($sum{'code'} + $sum{'comment'})/100;\n        }\n    }\n\n    foreach my $lang (keys %{$rhh_by_lang}) {\n        my %sum = ();\n        my $agg_lang = $lang;\n        if      ($key eq 'c') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'code'}    <= $value;\n        } elsif ($key eq 'f') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'nFiles'}  <= $value;\n        } elsif ($key eq 'm') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'comment'} <= $value;\n        } elsif ($key eq 'cm') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'code'} +\n                                      $rhh_by_lang->{$lang}{'comment'} <= $value;\n        }\n        foreach my $category (qw(nFiles comment blank code)) {\n            $aggregated_Results_by_Language{$agg_lang}{$category} +=\n                $rhh_by_lang->{$lang}{$category};\n        }\n    }\n\n    return %aggregated_Results_by_Language;\n} # 1}}}\nsub exclude_by_regex {                       # {{{1\n    my ($regex,\n        $rh_unique_source_file, # in/out\n        $rh_ignored           , # out\n       ) = @_;\n    my @exclude = ();\n    foreach my $file (keys %{$rh_unique_source_file}) {\n        my $line_num = 0;\n        foreach my $line (read_file($file)) {\n            ++$line_num;\n            if ($line =~ /$regex/) {\n                $rh_ignored->{$file} = \"line $line_num match for --exclude-content=$regex\";\n                push @exclude, $file;\n                last;\n            }\n        }\n    }\n    foreach my $file (@exclude) {\n        delete $rh_unique_source_file->{$file};\n    }\n} # 1}}}\nsub include_by_regex {                       # {{{1\n    my ($regex,\n        $rh_unique_source_file, # in/out\n        $rh_ignored           , # out\n       ) = @_;\n    my @exclude = ();\n    foreach my $file (keys %{$rh_unique_source_file}) {\n        my $keep_this_one = 0;\n        foreach my $line (read_file($file)) {\n            if ($line =~ /$regex/) {\n                $keep_this_one = 1;\n                last;\n            }\n        }\n        if (!$keep_this_one) {\n            $rh_ignored->{$file} = \"does not satisfy --include-content=$regex\";\n            push @exclude, $file;\n        }\n    }\n    foreach my $file (@exclude) {\n        delete $rh_unique_source_file->{$file};\n    }\n} # 1}}}\nsub get_max_processes {                      # {{{1\n    # If user has specified valid number of processes, use that.\n    if (defined $opt_processes) {\n        eval \"use Parallel::ForkManager 0.7.6;\";\n        if ( defined $Parallel::ForkManager::VERSION ) {\n            $HAVE_Parallel_ForkManager = 1;\n        }\n        if ( $opt_processes !~ /^\\d+$/ ) {\n            print \"Error: processes option argument must be numeric.\\n\";\n            exit 1;\n        }\n        elsif ( $opt_processes >0 and ! $HAVE_Parallel_ForkManager ) {\n            print \"Error: cannot use multiple processes, because \" .\n                  \"Parallel::ForkManager is not installed, or the version is too old.\\n\";\n            exit 1;\n        }\n    elsif ( $opt_processes >0 and $ON_WINDOWS ) {\n            print \"Error: cannot use multiple processes on Windows systems.\\n\";\n            exit 1;\n        }\n        else {\n            return $opt_processes;\n        }\n    }\n\n    # Disable multiprocessing on Windows - does not work reliably\n    if ($ON_WINDOWS) {\n        return 0;\n    }\n\n    # Disable multiprocessing if Parallel::ForkManager is not available\n    if ( ! $HAVE_Parallel_ForkManager ) {\n        return 0;\n    }\n\n    # Set to number of cores on Linux\n    if ( $^O =~ /linux/i and -x '/usr/bin/nproc' ) {\n        my $numavcores_linux = `/usr/bin/nproc`;\n        chomp $numavcores_linux;\n        if ( $numavcores_linux =~ /^\\d+$/ ) {\n            return $numavcores_linux;\n        }\n    }\n\n    # Set to number of cores on macOS\n    if ( $^O =~ /darwin/i and -x '/usr/sbin/sysctl') {\n       my $numavcores_macos = `/usr/sbin/sysctl -n hw.physicalcpu`;\n       chomp $numavcores_macos;\n       if ($numavcores_macos =~ /^\\d+$/ ) {\n           return $numavcores_macos;\n       }\n    }\n\n    # Disable multiprocessing in other cases\n    return 0;\n} # 1}}}\nsub exclude_autogenerated_files {            # {{{1\n    my ($ra_file_list, # in/out\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rh_Ignored  , # out\n       ) = @_;\n    print \"-> exclude_autogenerated_files()\\n\" if $opt_v > 2;\n    my @file_list_minus_autogen = ();\n    foreach my $file (@{$ra_file_list}) {\n        if ($file !~ /\\.go$/ && $file !~ /\\.ʕ◔ϖ◔ʔ$/) {\n            # at the moment, only know Go autogenerated files\n            push @file_list_minus_autogen, $file;\n            next;\n        }\n        my $first_line = first_line($file, 1, $rh_Err, $raa_errors);\n        if ($first_line =~ m{^//\\s+Code\\s+generated\\s+.*?\\s+DO\\s+NOT\\s+EDIT\\.$}) {\n            $rh_Ignored->{$file} = 'Go autogenerated file';\n        } else {\n            # Go, but not autogenerated\n            push @file_list_minus_autogen, $file;\n        }\n    }\n    @{$ra_file_list} = @file_list_minus_autogen;\n\n    if ($opt_force_git) {\n        my $repo_dir = git_root_dir();\n        my @file_list_minus_linguist = ();\n        # if there's a .gitattributes file, look for linguist-generated\n        # and linguist-vendored entries to ignore\n        my $GA = \".gitattributes\";\n        if (-f $GA) {\n            foreach my $line (read_file($GA)) {\n                next unless $line =~ /^(.*?)\\s+(linguist-(vendored|generated))/;\n                my $re = glob2regex($1);\n                foreach my $file (@{$ra_file_list}) {\n                    my $full_path = File::Spec->catfile($repo_dir, $file);\n                    my $rel_file  = File::Spec->abs2rel($full_path, $cwd);\n                    my $match = undef;\n                    if ($ON_WINDOWS) {\n                        $rel_file =~ s{\\\\}{/}g;\n                        $match = $rel_file =~ m{$re}i;\n                    } else {\n                        $match = $rel_file =~ m{$re};\n                    }\n                    if ($match) {\n#print \"RULE [$rel_file] v [$re]\\n\";\n                        $rh_Ignored->{$file} = \"matches $GA rule '$line'\";\n                    } else {\n                        push @file_list_minus_linguist, $file;\n                    }\n                }\n            }\n        }\n    }\n    print \"<- exclude_autogenerated_files()\\n\" if $opt_v > 2;\n} # 1}}}\nsub git_root_dir {                           # {{{1\n    # if in a git repo, return the repo's top level directory\n    my $cmd = \"git -c \\\"safe.directory=*\\\" rev-parse --show-toplevel\";\n    print $cmd, \"\\n\" if $opt_v > 1;\n    my $dir = undef;\n    chomp($dir = `$cmd`);\n    die \"Not in a git repository\" unless $dir\n} # 1}}}\nsub file_extension {                         # {{{1\n    my ($fname, ) = @_;\n    $fname =~ m/\\.(\\w+)$/;\n    if ($1) {\n        return $1;\n    } else {\n        return \"\";\n    }\n} # 1}}}\nsub count_files {                            # {{{1\n    my ($filelist, $counter_type, $rha_ignore_regex, $language_hash) = @_;\n    print \"-> count_files()\\n\" if $opt_v > 2;\n    my @p_errors = ();\n    my %p_ignored = ();\n    my %p_rbl = ();\n    my %p_rbf = ();\n    my %Language = %{$language_hash};\n\n    foreach my $file (@$filelist) {\n        if ( ! $counter_type ) {\n            # Multithreading disabled\n            $nCounted++;\n\n            printf \"Counting:  %d\\r\", $nCounted\n                 unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));\n        }\n\n        next if $Ignored{$file};\n        if ($opt_include_ext and not $Include_Ext{ file_extension($file) }) {\n            $p_ignored{$file} = \"not in --include-ext=$opt_include_ext\";\n            next;\n        }\n        if ($opt_include_lang and not $Include_Language{lc($Language{$file})}) {\n            $p_ignored{$file} = \"not in --include-lang=$opt_include_lang\";\n            next;\n        }\n        if ($Exclude_Language{$Language{$file}}) {\n            $p_ignored{$file} = \"--exclude-lang=$Language{$file}\";\n            next;\n        }\n        if ($opt_force_lang_def and ($Language{$file} eq \"XML\") and\n            !defined $Filters_by_Language{XML}) {\n            # XML check is attempted for all unidentified text files.\n            # This can't be done if user forces language definition\n            # that excludes XML.  GH #596\n            next;\n        }\n\n        my $Filters_by_Language_Language_file = ! @{$Filters_by_Language{$Language{$file}} };\n        if ($Filters_by_Language_Language_file) {\n            if ($Language{$file} eq \"(unknown)\") {\n                $p_ignored{$file} = \"language unknown (#1)\";\n            } else {\n                $p_ignored{$file} = \"missing Filters_by_Language{$Language{$file}}\";\n            }\n            next;\n        }\n\n        my ($all_line_count, $blank_count, $comment_count, $code_count) = (0, 0, 0, 0);\n        if (!$opt_only_count_files) {\n            if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\\+\\+|XML|PHP|Pascal|Java)$/) {\n                chomp ($blank_count     = `grep -cv \\\"[^[:space:]]\\\" '$file'`);\n                chomp ($all_line_count  = `cat '$file' | wc -l`);\n                if      ($Language{$file} =~ /^(C|C\\+\\+)$/) {\n                    $code_count = `cat '$file' | c_count      | head -n 1`;\n                } elsif ($Language{$file} eq \"XML\") {\n                    $code_count = `cat '$file' | xml_count    | head -n 1`;\n                } elsif ($Language{$file} eq \"PHP\") {\n                    $code_count = `cat '$file' | php_count    | head -n 1`;\n                } elsif ($Language{$file} eq \"Pascal\") {\n                    $code_count = `cat '$file' | pascal_count | head -n 1`;\n                } elsif ($Language{$file} eq \"Java\") {\n                    $code_count = `cat '$file' | java_count   | head -n 1`;\n                } else {\n                    die \"SLOCCount match failure: file=[$file] lang=[$Language{$file}]\";\n                }\n                $code_count = substr($code_count, 0, -2);\n                $comment_count = $all_line_count - $code_count - $blank_count;\n            } else {\n                ($all_line_count,\n                $blank_count   ,\n                $comment_count ,) = call_counter($file, $Language{$file},\n                                                 $rha_ignore_regex, \\@Errors);\n                $code_count = $all_line_count - $blank_count - $comment_count;\n            }\n        }\n\n        if ($opt_by_file) {\n            $p_rbf{$file}{'code'   } = $code_count     ;\n            $p_rbf{$file}{'blank'  } = $blank_count    ;\n            $p_rbf{$file}{'comment'} = $comment_count  ;\n            $p_rbf{$file}{'lang'   } = $Language{$file};\n            $p_rbf{$file}{'nFiles' } = 1;\n        } else {\n            $p_rbf{$file} = 1;  # just keep track of counted files\n        }\n\n        $p_rbl{$Language{$file}}{'nFiles'}++;\n        $p_rbl{$Language{$file}}{'code'}    += $code_count   ;\n        $p_rbl{$Language{$file}}{'blank'}   += $blank_count  ;\n        $p_rbl{$Language{$file}}{'comment'} += $comment_count;\n\n    }\n    print \"<- count_files()\\n\" if $opt_v > 2;\n    return {\n        \"ignored\" => \\%p_ignored,\n        \"errors\"  => \\@p_errors,\n        \"results_by_file\" => \\%p_rbf,\n        \"results_by_language\" => \\%p_rbl,\n    }\n} # 1}}}\nsub count_filesets {                         # {{{1\n    my ($fset_a,\n        $fset_b,\n        $files_added,\n        $files_removed,\n        $file_pairs,\n        $counter_type,\n        $language_hash,\n        $rha_ignore_regex,\n        $rh_Ignored) = @_;\n    print \"-> count_filesets()\\n\" if $opt_v > 2;\n    my @p_errors = ();\n    my %p_alignment = ();\n    my %p_ignored = ();\n    my %p_rbl = ();\n    my %p_rbf = ();\n    my %p_dbl = ();\n    my %p_dbf = ();\n    my %Language = %$language_hash;\n\n    my $nCounted = 0;\n\n    my %already_counted = (); # already_counted{ filename } = 1\n\n    if (!@$file_pairs) {\n        # Special case where all files were either added or deleted.\n        # In this case, one of these arrays will be empty:\n        #   @files_added, @files_removed\n        # so loop over both to cover both cases.\n        my $status = @$files_added ? 'added' : 'removed';\n        my $fset = @$files_added ? $fset_b : $fset_a;\n        foreach my $file (@$files_added, @$files_removed) {\n            next unless defined $Language{$fset}{$file};\n            my $Lang = $Language{$fset}{$file};\n            next if $Lang eq '(unknown)';\n            if ($Exclude_Language{$Lang}) {\n                $p_ignored{$file} = \"--exclude-lang=$Lang\";\n                next;\n            }\n\n            my ($all_line_count,\n                $blank_count   ,\n                $comment_count ,\n                ) = call_counter($file, $Lang, $rha_ignore_regex, \\@p_errors);\n            $already_counted{$file} = 1;\n            my $code_count = $all_line_count-$blank_count-$comment_count;\n            if ($opt_by_file) {\n                $p_dbf{$file}{'code'   }{$status} += $code_count   ;\n                $p_dbf{$file}{'blank'  }{$status} += $blank_count  ;\n                $p_dbf{$file}{'comment'}{$status} += $comment_count;\n                $p_dbf{$file}{'lang'   }{$status}  = $Lang         ;\n                $p_dbf{$file}{'nFiles' }{$status} += 1             ;\n            }\n            $p_dbl{$Lang}{'code'   }{$status} += $code_count   ;\n            $p_dbl{$Lang}{'blank'  }{$status} += $blank_count  ;\n            $p_dbl{$Lang}{'comment'}{$status} += $comment_count;\n            $p_dbl{$Lang}{'nFiles' }{$status} += 1             ;\n        }\n    }\n\n    #use Data::Dumper::Simple;\n    #use Data::Dumper;\n    #print Dumper(\\@files_added, \\@files_removed, \\@file_pairs);\n    #print \"after align_by_pairs:\\n\";\n    #print \"added:\\n\";\n\n    foreach my $f (@$files_added) {\n        next if $already_counted{$f};\n        #printf \"%10s -> %s\\n\", $f, $Language{$fh[$F+1]}{$f};\n        # Don't proceed unless the file (both L and R versions)\n        # is in a known language.\n        next if $opt_include_ext\n            and not $Include_Ext{ file_extension($f) };\n        if (!defined $Language{$fset_b}{$f}) {\n            $p_ignored{$f} = \"excluded or unknown language\";\n            next;\n        }\n        next if $opt_include_lang\n            and not $Include_Language{lc($Language{$fset_b}{$f})};\n        my $this_lang = $Language{$fset_b}{$f};\n        if (!defined  $Language{$fset_b}{$f}) {\n            # shouldn't happen but could get here if using\n            # --diff-list-file which bypasses earlier checks\n            $p_ignored{$f} = \"empty or uncharacterizeable file\";\n            next;\n        }\n        if ($this_lang eq \"(unknown)\") {\n            $p_ignored{$f} = \"unknown language\";\n            next;\n        }\n        if ($Exclude_Language{$this_lang}) {\n            $p_ignored{$f} = \"--exclude-lang=$this_lang\";\n            next;\n        }\n        $p_alignment{\"added\"}{sprintf \"  + %s ; %s\\n\", $f, $this_lang} = 1;\n        ++$p_dbl{ $this_lang }{'nFiles'}{'added'};\n        # Additionally, add contents of file $f to\n        # Delta_by_File{$f}{comment/blank/code}{'added'}\n        # Delta_by_Language{$lang}{comment/blank/code}{'added'}\n        # via the $p_dbl and $p_dbf variables.\n        my ($all_line_count,\n            $blank_count   ,\n            $comment_count ,\n           ) = call_counter($f, $this_lang, $rha_ignore_regex, \\@p_errors);\n        $p_dbl{ $this_lang }{'comment'}{'added'} += $comment_count;\n        $p_dbl{ $this_lang }{'blank'}{'added'}   += $blank_count;\n        $p_dbl{ $this_lang }{'code'}{'added'}    +=\n           $all_line_count - $blank_count - $comment_count;\n        $p_dbf{ $f }{'comment'}{'added'} = $comment_count;\n        $p_dbf{ $f }{'blank'}{'added'}   = $blank_count;\n        $p_dbf{ $f }{'code'}{'added'}    =\n           $all_line_count - $blank_count - $comment_count;\n    }\n\n    #print \"removed:\\n\";\n    foreach my $f (@$files_removed) {\n        next if $already_counted{$f};\n        # Don't proceed unless the file (both L and R versions)\n        # is in a known language.\n        next if $opt_include_ext\n            and not $Include_Ext{ file_extension($f) };\n        next if $opt_include_lang\n            and (not defined $Language{$fset_a}{$f}\n             or  not defined $Include_Language{lc($Language{$fset_a}{$f})});\n        my $this_lang = $Language{$fset_a}{$f};\n        if ((not defined $this_lang) or ($this_lang eq \"(unknown)\")) {\n            $p_ignored{$f} = \"unknown language\";\n            next;\n        }\n        if ($Exclude_Language{$this_lang}) {\n            $p_ignored{$f} = \"--exclude-lang=$this_lang\";\n            next;\n        }\n        ++$p_dbl{ $this_lang }{'nFiles'}{'removed'};\n        $p_alignment{\"removed\"}{sprintf \"  - %s ; %s\\n\", $f, $this_lang} = 1;\n        #printf \"%10s -> %s\\n\", $f, $Language{$fh[$F  ]}{$f};\n        # Additionally, add contents of file $f to\n        #        Delta_by_File{$f}{comment/blank/code}{'removed'}\n        #        Delta_by_Language{$lang}{comment/blank/code}{'removed'}\n        # via the $p_dbl and $p_dbf variables.\n        my ($all_line_count,\n            $blank_count   ,\n            $comment_count ,\n           ) = call_counter($f, $this_lang, $rha_ignore_regex, \\@p_errors);\n        $p_dbl{ $this_lang}{'comment'}{'removed'} += $comment_count;\n        $p_dbl{ $this_lang}{'blank'}{'removed'}   += $blank_count;\n        $p_dbl{ $this_lang}{'code'}{'removed'}    +=\n             $all_line_count - $blank_count - $comment_count;\n        $p_dbf{ $f }{'comment'}{'removed'} = $comment_count;\n        $p_dbf{ $f }{'blank'}{'removed'}   = $blank_count;\n        $p_dbf{ $f }{'code'}{'removed'}    =\n            $all_line_count - $blank_count - $comment_count;\n    }\n\n    my $n_file_pairs_compared = 0;\n    # Don't know ahead of time how many file pairs will be compared\n    # since duplicates are weeded out below.  The answer is\n    # scalar @file_pairs only if there are no duplicates.\n\n    foreach my $pair (@$file_pairs) {\n        my $file_L = $pair->[0];\n        my $file_R = $pair->[1];\n        if ($ON_WINDOWS) {\n            $file_L = lc $file_L;\n            $file_R = lc $file_R;\n        }\n        my $Lang_L = $Language{$fset_a}{$file_L};\n        my $Lang_R = $Language{$fset_b}{$file_R};\n#use Data::Dumper;\n#print \"Language: \", Dumper(\\%Language);\n#die \"L undefined\" unless defined $Language{$fset_a}{$file_L};\n#die \"R undefined\" unless defined $Language{$fset_b}{$file_R};\n#print \"file_L=$file_L  file_R=$file_R\\n\";\n#print \"fset_a=$fset_a  $Language{$fset_a}{$file_L}\\n\";\n#print \"fset_b=$fset_b  $Language{$fset_b}{$file_R}\\n\";\n        # handle cases where one side of the pair couldn't be identified\n        if      ( defined($Lang_L) and !defined($Lang_R)) {\n            $Lang_R = $Lang_L;\n            $Language{$fset_b}{$file_R} = $Lang_R;\n        } elsif (!defined($Lang_L) and  defined($Lang_R)) {\n            $Lang_L = $Lang_R;\n            $Language{$fset_a}{$file_L} = $Lang_L;\n        } elsif (!defined($Lang_L) or  !defined($Lang_R)) {\n            print \" -> count_filesets skipping $file_L, $file_R \",\n                  \"because language cannot be inferred\\n\" if $opt_v;\n            next;\n        }\n#print \"main step 6 file_L=$file_L ($Lang_L)   file_R=$file_R ($Lang_R)\\n\";\n        ++$nCounted;\n        printf \"Counting:  %d\\r\", $nCounted\n             unless ($counter_type or !$opt_progress_rate or ($nCounted % $opt_progress_rate));\n        next if $p_ignored{$file_L} or $p_ignored{$file_R};\n\n        # filter out non-included extensions\n        if ($opt_include_ext  and not $Include_Ext{ file_extension($file_L) }\n                              and not $Include_Ext{ file_extension($file_R) }) {\n            $p_ignored{$file_L} = \"not in --include-ext=$opt_include_ext\";\n            $p_ignored{$file_R} = \"not in --include-ext=$opt_include_ext\";\n            next;\n        }\n        # filter out non-included languages\n        if ($opt_include_lang and not $Include_Language{lc($Lang_L)}\n                              and not $Include_Language{lc($Lang_R)}) {\n            $p_ignored{$file_L} = \"not in --include-lang=$opt_include_lang\";\n            $p_ignored{$file_R} = \"not in --include-lang=$opt_include_lang\";\n            next;\n        }\n        # filter out excluded or unrecognized languages\n        if ($Exclude_Language{$Lang_L} or $Exclude_Language{$Lang_R}) {\n            $p_ignored{$file_L} = \"--exclude-lang=$Lang_L\";\n            $p_ignored{$file_R} = \"--exclude-lang=$Lang_R\";\n            next;\n        }\n\n        my $not_Filters_by_Language_Lang_LR = 0;\n        #print \"file_LR = [$file_L] [$file_R]\\n\";\n        #print \"Lang_LR = [$Lang_L] [$Lang_R]\\n\";\n        if (($Lang_L eq \"(unknown)\") or\n            ($Lang_R eq \"(unknown)\") or\n            !(@{$Filters_by_Language{$Lang_L} }) or\n            !(@{$Filters_by_Language{$Lang_R} })) {\n            $not_Filters_by_Language_Lang_LR = 1;\n        }\n        if ($not_Filters_by_Language_Lang_LR) {\n            if (($Lang_L eq \"(unknown)\") or ($Lang_R eq \"(unknown)\")) {\n                $p_ignored{$fset_a}{$file_L} = \"language unknown (#1)\";\n                $p_ignored{$fset_b}{$file_R} = \"language unknown (#1)\";\n            } else {\n                $p_ignored{$fset_a}{$file_L} = \"missing Filters_by_Language{$Lang_L}\";\n                $p_ignored{$fset_b}{$file_R} = \"missing Filters_by_Language{$Lang_R}\";\n            }\n            next;\n        }\n\n        # filter out explicitly excluded files\n        if ($opt_exclude_list_file and\n            ($rh_Ignored->{$file_L} or $rh_Ignored->{$file_R})) {\n            my $msg_2;\n            if ($rh_Ignored->{$file_L}) {\n                $msg_2 = \"$file_L (paired to $file_R)\";\n            } else {\n                $msg_2 = \"$file_R (paired to $file_L)\";\n            }\n            my $msg_1 = \"in --exclude-list-file=$opt_exclude_list_file\";\n            $p_ignored{$file_L} = \"$msg_1, $msg_2\";\n            $p_ignored{$file_R} = \"$msg_1, $msg_2\";\n            next;\n        }\n\n        #print \"DIFF($file_L, $file_R)\\n\";\n        # step 0: compare the two files' contents\n        chomp ( my @lines_L = read_file($file_L) );\n        chomp ( my @lines_R = read_file($file_R) );\n        my $language_file_L = \"\";\n        if (defined $Language{$fset_a}{$file_L}) {\n            $language_file_L = $Language{$fset_a}{$file_L};\n        } else {\n            # files $file_L and $file_R do not contain known language\n            next;\n        }\n\n        my $contents_are_same = 1;\n        if (scalar @lines_L == scalar @lines_R) {\n            # same size, must compare line-by-line\n            for (my $i = 0; $i < scalar @lines_L; $i++) {\n               if ($lines_L[$i] ne $lines_R[$i]) {\n                   $contents_are_same = 0;\n                   last;\n               }\n            }\n            if ($contents_are_same) {\n                ++$p_dbl{$language_file_L}{'nFiles'}{'same'};\n            } else {\n                ++$p_dbl{$language_file_L}{'nFiles'}{'modified'};\n            }\n        } else {\n            $contents_are_same = 0;\n            # different sizes, contents have changed\n            ++$p_dbl{$language_file_L}{'nFiles'}{'modified'};\n        }\n\n        if ($opt_diff_alignment) {\n            my $str =  \"$file_L | $file_R ; $language_file_L\";\n            if ($contents_are_same) {\n                $p_alignment{\"pairs\"}{\"  == $str\"} = 1;\n            } else {\n                $p_alignment{\"pairs\"}{\"  != $str\"} = 1;\n            }\n            ++$n_file_pairs_compared;\n        }\n\n        my ($all_line_count_L, $blank_count_L   , $comment_count_L ,\n            $all_line_count_R, $blank_count_R   , $comment_count_R , )  = (0,0,0,0,0,0,);\n        if (!$contents_are_same) {\n            # step 1: identify comments in both files\n            #print \"Diff blank removal L language= $Lang_L\";\n            #print \" scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n            my @original_minus_blanks_L\n                    = rm_blanks(  \\@lines_L, $Lang_L, \\%EOL_Continuation_re);\n            #print \"1: scalar(original_minus_blanks_L)=\", scalar @original_minus_blanks_L, \"\\n\";\n            @lines_L    = @original_minus_blanks_L;\n            #print \"2: scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n            @lines_L    = add_newlines(\\@lines_L); # compensate for rm_comments()\n            @lines_L    = rm_comments( \\@lines_L, $Lang_L, $file_L,\n                                       \\%EOL_Continuation_re);\n            #print \"3: scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n\n            #print \"Diff blank removal R language= $Lang_R\\n\";\n            my @original_minus_blanks_R\n                    = rm_blanks(  \\@lines_R, $Lang_R, \\%EOL_Continuation_re);\n            @lines_R    = @original_minus_blanks_R;\n            @lines_R    = add_newlines(\\@lines_R); # taken away by rm_comments()\n            @lines_R    = rm_comments( \\@lines_R, $Lang_R, $file_R,\n                                       \\%EOL_Continuation_re);\n\n            my (@diff_LL, @diff_LR, );\n                   array_diff( $file_L                  ,   # in\n                       \\@original_minus_blanks_L ,   # in\n                       \\@lines_L                 ,   # in\n                       \"comment\"                 ,   # in\n                       \\@diff_LL, \\@diff_LR      ,   # out\n                       \\@p_errors);                    # in/out\n\n            my (@diff_RL, @diff_RR, );\n                    array_diff( $file_R                  ,   # in\n                       \\@original_minus_blanks_R ,   # in\n                       \\@lines_R                 ,   # in\n                       \"comment\"                 ,   # in\n                       \\@diff_RL, \\@diff_RR      ,   # out\n                       \\@p_errors);                    # in/out\n            # each line of each file is now classified as\n            # code or comment\n            #use Data::Dumper;\n            #print Dumper(\"diff_LL\", \\@diff_LL, \"diff_LR\", \\@diff_LR, );\n            #print Dumper(\"diff_RL\", \\@diff_RL, \"diff_RR\", \\@diff_RR, );\n            #die;\n\n            # step 2: separate code from comments for L and R files\n            my @code_L = ();\n            my @code_R = ();\n            my @comm_L = ();\n            my @comm_R = ();\n            foreach my $line_info (@diff_LL) {\n                if      ($line_info->{'type'} eq \"code\"   ) {\n                    push @code_L, $line_info->{char};\n                } elsif ($line_info->{'type'} eq \"comment\") {\n                    push @comm_L, $line_info->{char};\n                } else {\n                    die \"Diff unexpected line type \",\n                        $line_info->{'type'}, \"for $file_L line \",\n                        $line_info->{'lnum'};\n                }\n            }\n\n            foreach my $line_info (@diff_RL) {\n                if      ($line_info->{type} eq \"code\"   ) {\n                    push @code_R, $line_info->{'char'};\n                } elsif ($line_info->{type} eq \"comment\") {\n                    push @comm_R, $line_info->{'char'};\n                } else {\n                    die \"Diff unexpected line type \",\n                        $line_info->{'type'}, \"for $file_R line \",\n                        $line_info->{'lnum'};\n                }\n            }\n\n            if ($opt_ignore_whitespace) {\n                # strip all whitespace from each line of source code\n                # and comments then use these stripped arrays in diffs\n                foreach (@code_L) { s/\\s+//g }\n                foreach (@code_R) { s/\\s+//g }\n                foreach (@comm_L) { s/\\s+//g }\n                foreach (@comm_R) { s/\\s+//g }\n            }\n            if ($opt_ignore_case) {\n                # change all text to lowercase in diffs\n                foreach (@code_L) { $_ = lc }\n                foreach (@code_R) { $_ = lc }\n                foreach (@comm_L) { $_ = lc }\n                foreach (@comm_R) { $_ = lc }\n            }\n            my $n_code_removed_L = 0;\n            my $n_code_removed_R = 0;\n            @code_L = apply_ignores(\\@code_L, $Lang_L, $file_L, $rha_ignore_regex,\n                                    \\$n_code_removed_L);\n            @code_R = apply_ignores(\\@code_R, $Lang_R, $file_R, $rha_ignore_regex,\n                                    \\$n_code_removed_R);\n            # step 3: compute code diffs\n            array_diff(\"$file_L v. $file_R\"   ,   # in\n                       \\@code_L               ,   # in\n                       \\@code_R               ,   # in\n                       \"revision\"             ,   # in\n                       \\@diff_LL, \\@diff_LR   ,   # out\n                       \\@p_errors);                 # in/out\n            #print Dumper(\"diff_LL\", \\@diff_LL, \"diff_LR\", \\@diff_LR, );\n            #print Dumper(\"diff_LR\", \\@diff_LR);\n            foreach my $line_info (@diff_LR) {\n                my $status = $line_info->{'desc'}; # same|added|removed|modified\n                ++$p_dbl{$Lang_L}{'code'}{$status};\n                if ($opt_by_file) {\n                    ++$p_dbf{$file_L}{'code'}{$status};\n                }\n            }\n            #use Data::Dumper;\n            #print Dumper(\"code diffs:\", \\@diff_LL, \\@diff_LR);\n\n            # step 4: compute comment diffs\n            array_diff(\"$file_L v. $file_R\"   ,   # in\n                       \\@comm_L               ,   # in\n                       \\@comm_R               ,   # in\n                       \"revision\"             ,   # in\n                       \\@diff_LL, \\@diff_LR   ,   # out\n                       \\@Errors);                 # in/out\n            #print Dumper(\"comment diff_LR\", \\@diff_LR);\n            foreach my $line_info (@diff_LR) {\n                my $status = $line_info->{'desc'}; # same|added|removed|modified\n                ++$p_dbl{$Lang_L}{'comment'}{$status};\n                if ($opt_by_file) {\n                    ++$p_dbf{$file_L}{'comment'}{$status};\n                }\n            }\n            #print Dumper(\"comment diffs:\", \\@diff_LL, \\@diff_LR);\n\n            # step 5: compute difference in blank lines (kind of pointless)\n            next if $Lang_L eq '(unknown)' or\n                    $Lang_R eq '(unknown)';\n            ($all_line_count_L,\n             $blank_count_L   ,\n             $comment_count_L ,\n            ) = call_counter($file_L, $Lang_L, $rha_ignore_regex, \\@Errors);\n\n            ($all_line_count_R,\n             $blank_count_R   ,\n             $comment_count_R ,\n            ) = call_counter($file_R, $Lang_R, $rha_ignore_regex, \\@Errors);\n        } else {\n            # L and R file contents are identical, no need to diff\n            ($all_line_count_L,\n             $blank_count_L   ,\n             $comment_count_L ,\n            ) = call_counter($file_L, $Lang_L, $rha_ignore_regex, \\@Errors);\n            $all_line_count_R = $all_line_count_L;\n            $blank_count_R    = $blank_count_L   ;\n            $comment_count_R  = $comment_count_L ;\n            my $code_lines_R  = $all_line_count_R - ($blank_count_R + $comment_count_R);\n            $p_dbl{$Lang_L}{'blank'}{'same'}   += $blank_count_R;\n            $p_dbl{$Lang_L}{'comment'}{'same'} += $comment_count_R;\n            $p_dbl{$Lang_L}{'code'}{'same'}    += $code_lines_R;\n            if ($opt_by_file) {\n                $p_dbf{$file_L}{'blank'}{'same'}   += $blank_count_R;\n                $p_dbf{$file_L}{'comment'}{'same'} += $comment_count_R;\n                $p_dbf{$file_L}{'code'}{'same'}    += $code_lines_R;\n            }\n        }\n\n        if ($blank_count_L <  $blank_count_R) {\n            my $D = $blank_count_R - $blank_count_L;\n            $p_dbl{$Lang_L}{'blank'}{'added'}   += $D;\n        } else {\n            my $D = $blank_count_L - $blank_count_R;\n            $p_dbl{$Lang_L}{'blank'}{'removed'} += $D;\n        }\n        if ($opt_by_file) {\n            if ($blank_count_L <  $blank_count_R) {\n                my $D = $blank_count_R - $blank_count_L;\n                $p_dbf{$file_L}{'blank'}{'added'}   += $D;\n            } else {\n                my $D = $blank_count_L - $blank_count_R;\n                $p_dbf{$file_L}{'blank'}{'removed'} += $D;\n            }\n        }\n\n        my $code_count_L = $all_line_count_L-$blank_count_L-$comment_count_L;\n        if ($opt_by_file) {\n            $p_rbf{$file_L}{'code'   } = $code_count_L    ;\n            $p_rbf{$file_L}{'blank'  } = $blank_count_L   ;\n            $p_rbf{$file_L}{'comment'} = $comment_count_L ;\n            $p_rbf{$file_L}{'lang'   } = $Lang_L          ;\n            $p_rbf{$file_L}{'nFiles' } = 1                ;\n        } else {\n            $p_rbf{$file_L} = 1;  # just keep track of counted files\n        }\n\n        $p_rbl{$Lang_L}{'nFiles'}++;\n        $p_rbl{$Lang_L}{'code'}    += $code_count_L   ;\n        $p_rbl{$Lang_L}{'blank'}   += $blank_count_L  ;\n        $p_rbl{$Lang_L}{'comment'} += $comment_count_L;\n    }\n\n    print \"<- count_filesets()\\n\" if $opt_v > 2;\n    return {\n        \"ignored\" => \\%p_ignored,\n        \"errors\"  => \\@p_errors,\n        \"results_by_file\" => \\%p_rbf,\n        \"results_by_language\" => \\%p_rbl,\n        \"delta_by_file\" => \\%p_dbf,\n        \"delta_by_language\" => \\%p_dbl,\n        \"alignment\" => \\%p_alignment,\n        \"n_filepairs_compared\" => $n_file_pairs_compared\n    }\n} # 1}}}\nsub apply_ignores {                          # {{{1\n    my ($ra_lines             , # in\n        $language             , # in\n        $file                 , # in\n        $rha_ignore_regex     , # in\n        $rs_lines_code_removed, # out\n       ) = @_;\n    my @output = ();\n    print \"-> apply_ignores($file, $language)\\n\" if $opt_v > 2;\n\n    if (%{$rha_ignore_regex} and defined($rha_ignore_regex->{$language})) {\n        foreach my $line (@{$ra_lines}) {\n            my $keep = 1;\n            foreach my $regex (@{$rha_ignore_regex->{$language}}) {\n                if ($line =~ m{$regex}) {\n                    print \"apply_ignores reject '$line' in $file because of '$regex'\\n\"\n                        if $opt_v > 4;\n                    $keep = 0;\n                    ++${$rs_lines_code_removed};\n                    last;\n                }\n            }\n            push @output, $line if $keep;\n        }\n    } else {\n        @output = @{$ra_lines};\n    }\n\n    print \"<- apply_ignores(${$rs_lines_code_removed})\\n\" if $opt_v > 2;\n    return @output;\n} # 1}}}\nsub write_alignment_data {                   # {{{1\n    my ($filename, $n_filepairs_compared, $data ) = @_;\n    print \"-> write_alignment_data($filename)\\n\" if $opt_v > 2;\n    my @output = ();\n    if ( $data->{'added'} ) {\n        my %added_lines = %{$data->{'added'}};\n        push (@output, \"Files added: \" . (scalar keys %added_lines) . \"\\n\");\n        foreach my $line ( sort keys %added_lines ) {\n            push (@output, $line);\n        }\n        push (@output, \"\\n\" );\n    }\n    if ( $data->{'removed'} ) {\n        my %removed_lines = %{$data->{'removed'}};\n        push (@output, \"Files removed: \" . (scalar keys %removed_lines) . \"\\n\");\n        foreach my $line ( sort keys %removed_lines ) {\n            push (@output, $line);\n        }\n        push (@output, \"\\n\");\n    }\n    if ( $data->{'pairs'} ) {\n        my %pairs = %{$data->{'pairs'}};\n        push (@output, \"File pairs compared: \" . $n_filepairs_compared . \"\\n\");\n        foreach my $pair ( sort keys %pairs ) {\n            push (@output, $pair);\n        }\n    }\n    write_file($filename, {}, @output);\n    print \"<- write_alignment_data\\n\" if $opt_v > 2;\n} # 1}}}\nsub exclude_dir_validates {                  # {{{1\n    my ($rh_Exclude_Dir) = @_;\n    # $opt_v hasn't been set yet\n    # print \"-> exclude_dir_validates\\n\" if $opt_v > 2;\n    my $is_OK = 1;\n    foreach my $dir (keys %{$rh_Exclude_Dir}) {\n        if (($ON_WINDOWS and $dir =~ m{\\\\}) or ($dir =~ m{/})) {\n            $is_OK = 0;\n            warn \"--exclude-dir '$dir' :  cannot specify directory paths\\n\";\n        }\n    }\n    if (!$is_OK) {\n        warn \"Use '--fullpath --not-match-d=REGEX' instead\\n\";\n    }\n    # print \"<- exclude_dir_validates\\n\" if $opt_v > 2;\n    return $is_OK;\n} # 1}}}\nsub process_exclude_list_file {              # {{{1\n    my ($list_file      , # in\n        $rh_exclude_dir , # out\n        $rh_ignored     , # out\n       ) = @_;\n    # note: references global @file_list\n    print \"-> process_exclude_list_file($list_file)\\n\" if $opt_v > 2;\n    # reject a specific set of files and/or directories\n    my @reject_list   = ($list_file); # don't count the exclude list file itself\n    push @reject_list, read_list_file($list_file);\n    my @file_reject_list = ();\n    foreach my $F_or_D (@reject_list) {\n        if (is_dir($F_or_D)) {\n            $rh_exclude_dir->{$F_or_D} = 1;\n        } elsif (is_file($F_or_D)) {\n            push @file_reject_list, $F_or_D;\n        }\n    }\n\n    # Normalize file names for better comparison.\n    my %normalized_input   = normalize_file_names(@file_list);\n    my %normalized_reject  = normalize_file_names(@file_reject_list);\n    my %normalized_exclude = normalize_file_names(keys %{$rh_exclude_dir});\n    foreach my $F (keys %normalized_input) {\n        if ($normalized_reject{$F} or is_excluded($F, \\%normalized_exclude)) {\n            my $orig_F = $normalized_input{$F};\n            $rh_ignored->{$orig_F} = \"listed in exclusion file $opt_exclude_list_file\";\n            print \"Ignoring $orig_F because it appears in $opt_exclude_list_file\\n\"\n                if $opt_v > 1;\n        }\n    }\n\n    print \"<- process_exclude_list_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub combine_results {                        # {{{1\n    # returns 1 if the inputs are categorized by language\n    #         0 if no identifiable language was found\n    my ($ra_report_files, # in\n        $report_type    , # in  \"by language\" or \"by report file\"\n        $rhh_count      , # out count{TYPE}{nFiles|code|blank|comment|scaled}\n        $rhaa_Filters_by_Language , # in\n       ) = @_;\n\n    print \"-> combine_results(report_type=$report_type)\\n\" if $opt_v > 2;\n    my $found_language = 0;\n\n    foreach my $file (@{$ra_report_files}) {\n        my $n_results_found = 0;\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n        while (<$IN>) {\n            next if /^(http|Language|SUM|-----)/;\n            if (!$opt_by_file  and\n                m{^(.*?)\\s+         # language\n                   (\\d+)\\s+         # files\n                   (\\d+)\\s+         # blank\n                   (\\d+)\\s+         # comments\n                   (\\d+)\\s+         # code\n                   (                #    next four entries missing with -no3\n                   x\\s+             # x\n                   \\d+\\.\\d+\\s+      # scale\n                   =\\s+             # =\n                   (\\d+\\.\\d+)\\s*    # scaled code\n                   )?\n                   $}x) {\n                if ($report_type eq \"by language\") {\n                    if (!defined $rhaa_Filters_by_Language->{$1}) {\n                        warn \"Unrecognized language '$1' in $file ignored\\n\";\n                        next;\n                    }\n                    # above test necessary to avoid trying to sum reports\n                    # of reports (which have no language breakdown).\n                    $found_language = 1;\n                    $rhh_count->{$1   }{'nFiles' } += $2;\n                    $rhh_count->{$1   }{'blank'  } += $3;\n                    $rhh_count->{$1   }{'comment'} += $4;\n                    $rhh_count->{$1   }{'code'   } += $5;\n                    $rhh_count->{$1   }{'scaled' } += $7 if $opt_3;\n                } else {\n                    $rhh_count->{$file}{'nFiles' } += $2;\n                    $rhh_count->{$file}{'blank'  } += $3;\n                    $rhh_count->{$file}{'comment'} += $4;\n                    $rhh_count->{$file}{'code'   } += $5;\n                    $rhh_count->{$file}{'scaled' } += $7 if $opt_3;\n                }\n                ++$n_results_found;\n            } elsif ($opt_by_file  and\n                m{^(.*?)\\s+         # language\n                   (\\d+)\\s+         # blank\n                   (\\d+)\\s+         # comments\n                   (\\d+)\\s+         # code\n                   (                #    next four entries missing with -no3\n                   x\\s+             # x\n                   \\d+\\.\\d+\\s+      # scale\n                   =\\s+             # =\n                   (\\d+\\.\\d+)\\s*    # scaled code\n                   )?\n                   $}x) {\n                if ($report_type eq \"by language\") {\n                    next unless %{$rhaa_Filters_by_Language->{$1}};\n                    # above test necessary to avoid trying to sum reports\n                    # of reports (which have no language breakdown).\n                    $found_language = 1;\n                    $rhh_count->{$1   }{'nFiles' } +=  1;\n                    $rhh_count->{$1   }{'blank'  } += $2;\n                    $rhh_count->{$1   }{'comment'} += $3;\n                    $rhh_count->{$1   }{'code'   } += $4;\n                    $rhh_count->{$1   }{'scaled' } += $6 if $opt_3;\n                } else {\n                    $rhh_count->{$file}{'nFiles' } +=  1;\n                    $rhh_count->{$file}{'blank'  } += $2;\n                    $rhh_count->{$file}{'comment'} += $3;\n                    $rhh_count->{$file}{'code'   } += $4;\n                    $rhh_count->{$file}{'scaled' } += $6 if $opt_3;\n                }\n                ++$n_results_found;\n            }\n        }\n        warn \"No counts found in $file--is the file format correct?\\n\"\n            unless $n_results_found;\n    }\n    print \"<- combine_results\\n\" if $opt_v > 2;\n    return $found_language;\n} # 1}}}\nsub compute_denominator {                    # {{{1\n    my ($method, $nCode, $nComment, $nBlank, ) = @_;\n    print \"-> compute_denominator\\n\" if $opt_v > 2;\n    my %den        = ( \"c\" => $nCode );\n       $den{\"cm\"}  = $den{\"c\"}  + $nComment;\n       $den{\"cmb\"} = $den{\"cm\"} + $nBlank;\n       $den{\"cb\"}  = $den{\"c\"}  + $nBlank;\n\n    print \"<- compute_denominator\\n\" if $opt_v > 2;\n    return $den{ $method };\n} # 1}}}\nsub yaml_to_json_separators {                # {{{1\n    # YAML and JSON are closely related.  Their differences can be captured\n    # by trailing commas ($C), braces ($open_B, $close_B), and\n    # quotes around text ($Q).\n    print \"-> yaml_to_json_separators()\\n\" if $opt_v > 2;\n    my ($Q, $open_B, $close_B, $start, $C);\n    if ($opt_json) {\n       $C       = ',';\n       $Q       = '\"';\n       $open_B  = '{';\n       $close_B = '}';\n       $start   = '{';\n    } else {\n       $C       = '';\n       $Q       = '' ;\n       $open_B  = '' ;\n       $close_B = '';\n       $start   = \"---\\n# $URL\\n\";\n    }\n    print \"<- yaml_to_json_separators()\\n\" if $opt_v > 2;\n    return ($Q, $open_B, $close_B, $start, $C);\n} # 1}}}\nsub diff_report     {                        # {{{1\n    # returns an array of lines containing the results\n    print \"-> diff_report\\n\" if $opt_v > 2;\n\n    if ($opt_xml) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_xml_report(@_)\n    } elsif ($opt_yaml) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_yaml_report(@_)\n    } elsif ($opt_json) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_json_report(@_)\n    } elsif ($opt_csv or $opt_md) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_csv_report(@_)\n    }\n\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n        $rh_renamed , # in\n       ) = @_;\n    my %orig_case = ();\n    if ($ON_WINDOWS and $report_type eq \"by file\") {\n        # restore the original upper/lowercase version of the file name\n        foreach my $lc_file (sort keys %{$rhhh_count}) {\n          foreach my $cat (sort keys %{$rhhh_count->{$lc_file}}) {\n            foreach my $S (qw(added same modified removed)) {\n                $orig_case{ $upper_lower_map{$lc_file} }{$cat}{$S} =\n                           $rhhh_count->{$lc_file}{$cat}{$S};\n            }\n          }\n        }\n        $rhhh_count = \\%orig_case;\n    }\n\n#use Data::Dumper;\n#print \"diff_report: \", Dumper($rhhh_count), \"\\n\";\n    my @results       = ();\n\n    my $languages     = ();\n    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}\n    my $max_len       = 0;\n    foreach my $language (keys %{$rhhh_count}) {\n        foreach my $V (qw(nFiles blank comment code)) {\n            foreach my $S (qw(added same modified removed)) {\n                $rhhh_count->{$language}{$V}{$S} = 0 unless\n                    defined $rhhh_count->{$language}{$V}{$S};\n                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};\n            }\n        }\n        $max_len      = length($language) if length($language) > $max_len;\n    }\n    my $column_1_offset = 0;\n       $column_1_offset = $max_len - 17 if $max_len > 17;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $spacing_0 = 23;\n    my $spacing_1 = 13;\n    my $spacing_2 =  9;\n    my $spacing_3 = 17;\n    if (!$opt_3) {\n        $spacing_1 = 19;\n        $spacing_2 = 14;\n        $spacing_3 = 27;\n    }\n    $spacing_0 += $column_1_offset;\n    $spacing_1 += $column_1_offset;\n    $spacing_3 += $column_1_offset;\n    my %Format = (\n        '1' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_0}s \",\n               },\n        '2' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_3}s \",\n               },\n        '3' => { 'xml' => 'files_count=\"%d\" ',\n                 'txt' => '%6d ',\n               },\n        '4' => { 'xml' => 'blank=\"%d\" comment=\"%d\" code=\"%d\" ',\n                 'txt' => \"\\%${spacing_2}d \\%${spacing_2}d \\%${spacing_2}d\",\n               },\n        '5' => { 'xml' => 'blank=\"%.2f\" comment=\"%.2f\" code=\"%d\" ',\n                 'txt' => \"\\%3.2f \\%3.2f \\%${spacing_2}d\",\n               },\n        '6' => { 'xml' => 'factor=\"%.2f\" scaled=\"%.2f\" ',\n                 'txt' => ' x %6.2f = %14.2f',\n               },\n    );\n    my $Style = \"txt\";\n       $Style = \"xml\" if $opt_xml ;\n       $Style = \"xml\" if $opt_yaml;  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $opt_json;  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $opt_csv ;  # not a typo; just set to anything but txt\n\n    my $hyphen_line = sprintf \"%s\", '-' x (79 + $column_1_offset);\n       $hyphen_line = sprintf \"%s\", '-' x (68 + $column_1_offset)\n            if (!$opt_3) and (68 + $column_1_offset) > 79;\n    my $data_line  = \"\";\n    my $first_column;\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $first_column = \"Language\";\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $first_column = \"File\";\n        $BY_FILE      = 1;\n    } else {\n        $first_column = \"Report File\";\n    }\n\n    # column headers\n    if (!$opt_3 and $BY_FILE) {\n        my $spacing_n = $spacing_1 - 11;\n        $data_line  = sprintf \"%-${spacing_n}s\" , $first_column;\n    } else {\n        $data_line  = sprintf \"%-${spacing_1}s \", $first_column;\n    }\n    if ($BY_FILE) {\n        $data_line .= sprintf \"%${spacing_2}s\"   , \"\"     ;\n    } else {\n        $data_line .= sprintf \"%${spacing_2}s \"  , \"files\";\n    }\n    my $PCT_symbol = \"\";\n       $PCT_symbol = \" \\%\" if $opt_by_percent;\n    $data_line .= sprintf \"%${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n        \"blank${PCT_symbol}\"         ,\n        \"comment${PCT_symbol}\"       ,\n        \"code${PCT_symbol}\"          ;\n\n    if ($Style eq \"txt\") {\n        push @results, $data_line;\n        push @results, $hyphen_line;\n    }\n\n#use Data::Dumper;\n#print \"diff_report.Renamed:\\n\", Dumper($rh_renamed);\n\n    # sort diff output in descending order of cumulative entries\n    foreach my $lang_or_file (sort {\n                                ($rhhh_count->{$b}{'code'}{'added'}    +\n                                 $rhhh_count->{$b}{'code'}{'same'}     +\n                                 $rhhh_count->{$b}{'code'}{'modified'} +\n                                 $rhhh_count->{$b}{'code'}{'removed'}  )  <=>\n                                ($rhhh_count->{$a}{'code'}{'added'}    +\n                                 $rhhh_count->{$a}{'code'}{'same'}     +\n                                 $rhhh_count->{$a}{'code'}{'modified'} +\n                                 $rhhh_count->{$a}{'code'}{'removed'})\n                              or $a cmp $b }\n                                    keys %{$rhhh_count}) {\n\n        if ($BY_FILE) {\n            my $file = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n#print \"diff_report.file=$file (orig $lang_or_file)\\n\";\n            $file .= \" -> \" . $rh_renamed->{$file} if defined $rh_renamed->{$file};\n            push @results, $file;\n        } else {\n            push @results, $lang_or_file;\n        }\n        foreach my $S (qw(same modified added removed)) {\n            my $indent = $spacing_1 - 2;\n            my $line .= sprintf \" %-${indent}s\", $S;\n            if ($BY_FILE) {\n                $line .= sprintf \"   \";\n            } else {\n                $line .= sprintf \"  %${spacing_2}s\", $rhhh_count->{$lang_or_file}{'nFiles'}{$S};\n            }\n            if ($opt_by_percent) {\n                my $DEN = compute_denominator($opt_by_percent  ,\n                    $rhhh_count->{$lang_or_file}{'code'}{$S}   ,\n                    $rhhh_count->{$lang_or_file}{'comment'}{$S},\n                    $rhhh_count->{$lang_or_file}{'blank'}{$S}  );\n                if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {\n                    $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                        $rhhh_count->{$lang_or_file}{'blank'}{$S}   / $DEN * 100,\n                        $rhhh_count->{$lang_or_file}{'comment'}{$S} / $DEN * 100,\n                        $rhhh_count->{$lang_or_file}{'code'}{$S}    / $DEN * 100;\n                } else {\n                    $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                        0.0, 0.0, $rhhh_count->{$lang_or_file}{'code'}{$S}    ;\n                }\n            } else {\n                $line .= sprintf \" %${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n                    $rhhh_count->{$lang_or_file}{'blank'}{$S}   ,\n                    $rhhh_count->{$lang_or_file}{'comment'}{$S} ,\n                    $rhhh_count->{$lang_or_file}{'code'}{$S}    ;\n            }\n            push @results, $line;\n        }\n    }\n    push @results, $hyphen_line;\n    push @results, \"SUM:\";\n    my $sum_files    = 0;\n    my $sum_lines    = 0;\n    foreach my $S (qw(same modified added removed)) {\n        my $indent = $spacing_1 - 2;\n        my $line .= sprintf \" %-${indent}s\", $S;\n            if ($BY_FILE) {\n                $line .= sprintf \"   \";\n                $sum_files += 1;\n            } else {\n                $line .= sprintf \"  %${spacing_2}s\", $sum{'nFiles'}{$S};\n                $sum_files += $sum{'nFiles'}{$S};\n            }\n        if ($opt_by_percent) {\n            my $DEN = compute_denominator($opt_by_percent,\n                $sum{'code'}{$S}, $sum{'comment'}{$S}, $sum{'blank'}{$S});\n            if ($sum{'code'}{$S} > 0) {\n                $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                    $sum{'blank'}{$S}   / $DEN * 100,\n                    $sum{'comment'}{$S} / $DEN * 100,\n                    $sum{'code'}{$S}    / $DEN * 100;\n            } else {\n                $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                    0.0, 0.0, $sum{'code'}{$S}    ;\n            }\n        } else {\n            $line .= sprintf \" %${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n                $sum{'blank'}{$S}   ,\n                $sum{'comment'}{$S} ,\n                $sum{'code'}{$S}    ;\n        }\n        $sum_lines += $sum{'blank'}{$S} + $sum{'comment'}{$S} + $sum{'code'}{$S};\n        push @results, $line;\n    }\n\n    my $header_line  = sprintf \"%s v %s\", $URL, $version;\n       $header_line .= sprintf(\"  T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                        $elapsed_sec           ,\n                        $sum_files/$elapsed_sec,\n                        $sum_lines/$elapsed_sec) unless $opt_sum_reports or $opt_hide_rate;\n    if ($Style eq \"txt\") {\n        unshift @results, output_header($header_line, $hyphen_line, $BY_FILE);\n    }\n\n    push @results, $hyphen_line;\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    print \"<- diff_report\\n\" if $opt_v > 2;\n\n    return @results;\n} # 1}}}\nsub xml_yaml_or_json_header {                # {{{1\n    my ($URL, $version, $elapsed_sec, $sum_files, $sum_lines, $by_file) = @_;\n    print \"-> xml_yaml_or_json_header\\n\" if $opt_v > 2;\n    my $header      = \"\";\n    my $file_rate   = $sum_files/$elapsed_sec;\n    my $line_rate   = $sum_lines/$elapsed_sec;\n    my $type        = \"\";\n       $type        = \"diff_\" if $opt_diff;\n    my $report_file = \"\";\n    if ($opt_report_file) {\n        my $Fname = $opt_report_file;\n        $Fname =~ s{\\\\}{\\\\\\\\}g if $ON_WINDOWS;\n        if ($opt_sum_reports) {\n            if ($by_file) {\n                $report_file = \"  <report_file>$Fname.file</report_file>\"\n            } else {\n                $report_file = \"  <report_file>$Fname.lang</report_file>\"\n            }\n        } else {\n            $report_file = \"  <report_file>$Fname</report_file>\"\n        }\n    }\n    if ($opt_xml) {\n        $header = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\";\n        $header .= \"\\n<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" . $opt_xsl . \"\\\"?>\" if $opt_xsl;\n        if ($opt_hide_rate) {\n            $header .= \"<${type}results>\n<header>\n  <cloc_url>$URL</cloc_url>\n  <cloc_version>$version</cloc_version>\n  <n_files>$sum_files</n_files>\n  <n_lines>$sum_lines</n_lines>\";\n        } else {\n            $header .= \"<${type}results>\n<header>\n  <cloc_url>$URL</cloc_url>\n  <cloc_version>$version</cloc_version>\n  <elapsed_seconds>$elapsed_sec</elapsed_seconds>\n  <n_files>$sum_files</n_files>\n  <n_lines>$sum_lines</n_lines>\n  <files_per_second>$file_rate</files_per_second>\n  <lines_per_second>$line_rate</lines_per_second>\";\n        }\n        $header .= \"\\n$report_file\"\n            if $opt_report_file;\n        $header .= \"\\n</header>\";\n        if (%git_metadata) {\n            foreach my $target (keys %git_metadata) {\n                $header .= \"\\n<source>\";\n                $header .= \"\\n  <target>$target</target>\";\n                $header .= \"\\n  <origin>$git_metadata{$target}{'origin'}</origin>\";\n                $header .= \"\\n  <branch>$git_metadata{$target}{'branch'}</branch>\";\n                $header .= \"\\n  <commit>$git_metadata{$target}{'commit'}</commit>\";\n                $header .= \"\\n</source>\";\n            }\n        }\n    } elsif ($opt_yaml or $opt_json) {\n        my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n        if ($opt_hide_rate) {\n            $header = \"${start}${Q}header${Q} : $open_B\n  ${Q}cloc_url${Q}           : ${Q}$URL${Q}${C}\n  ${Q}cloc_version${Q}       : ${Q}$version${Q}${C}\n  ${Q}n_files${Q}            : $sum_files${C}\n  ${Q}n_lines${Q}            : $sum_lines\";\n        } else {\n            $header = \"${start}${Q}header${Q} : $open_B\n  ${Q}cloc_url${Q}           : ${Q}$URL${Q}${C}\n  ${Q}cloc_version${Q}       : ${Q}$version${Q}${C}\n  ${Q}elapsed_seconds${Q}    : $elapsed_sec${C}\n  ${Q}n_files${Q}            : $sum_files${C}\n  ${Q}n_lines${Q}            : $sum_lines${C}\n  ${Q}files_per_second${Q}   : $file_rate${C}\n  ${Q}lines_per_second${Q}   : $line_rate\";\n        }\n        if ($opt_report_file) {\n            my $Fname = $opt_report_file;\n            $Fname =~ s{\\\\}{\\\\\\\\}g if $ON_WINDOWS;\n            if ($opt_sum_reports) {\n                if ($by_file) {\n                    $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname.file${Q}\"\n                } else {\n                    $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname.lang${Q}\"\n                }\n            } else {\n                $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname${Q}\";\n            }\n        }\n        $header .= \"${close_B}${C}\";\n    }\n    print \"<- xml_yaml_or_json_header\\n\" if $opt_v > 2;\n    return $header;\n} # 1}}}\nsub diff_yaml_report {                       # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_yaml_report\\n\" if $opt_v > 2;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"$S :\";\n        foreach my $F_or_L (keys %{$rhhh_count}) {\n            # force quoted language or filename in case these\n            # have embedded funny characters, issue #312\n            push @results, \"  '\" . rm_leading_tempdir($F_or_L, \\%TEMP_DIR) . \"' :\";\n            foreach my $k (keys %{$rhhh_count->{$F_or_L}}) {\n                next if $k eq \"lang\"; # present only in those cases\n                                      # where code exists for action $S\n                $rhhh_count->{$F_or_L}{$k}{$S} = 0 unless\n                    defined $rhhh_count->{$F_or_L}{$k}{$S};\n                push @results,\n                    \"    $k : $rhhh_count->{$F_or_L}{$k}{$S}\";\n            }\n        }\n    }\n\n    push @results, \"SUM :\";\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"  $S :\";\n        foreach my $topic (keys %sum) {\n            push @results, \"    $topic : $sum{$topic}{$S}\";\n        }\n    }\n\n    print \"<- diff_yaml_report\\n\" if $opt_v > 2;\n\n    return @results;\n} # 1}}}\nsub diff_json_report {                       # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_json_report\\n\" if $opt_v > 2;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \" \\\"$S\\\" : {\";\n        foreach my $F_or_L (keys %{$rhhh_count}) {\n            push @results, \"  \\\"\" . rm_leading_tempdir($F_or_L, \\%TEMP_DIR) . \"\\\" : {\";\n            foreach my $k (keys %{$rhhh_count->{$F_or_L}}) {\n                next if $k eq \"lang\"; # present only in those cases\n                                      # where code exists for action $S\n                $rhhh_count->{$F_or_L}{$k}{$S} = 0 unless\n                    defined $rhhh_count->{$F_or_L}{$k}{$S};\n                push @results,\n                    \"    \\\"$k\\\" : $rhhh_count->{$F_or_L}{$k}{$S},\";\n            }\n            $results[-1] =~ s/,\\s*$//;\n            push @results, \"  },\"\n        }\n        $results[-1] =~ s/,\\s*$//;\n        push @results, \"  },\"\n    }\n\n    push @results, \"  \\\"SUM\\\" : {\";\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"  \\\"$S\\\" : {\";\n        foreach my $topic (keys %sum) {\n            push @results, \"    \\\"$topic\\\" : $sum{$topic}{$S},\";\n        }\n        $results[-1] =~ s/,\\s*$//;\n        push @results, \"},\";\n    }\n\n    $results[-1] =~ s/,\\s*$//;\n    push @results, \"} }\";\n    print \"<- diff_json_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub diff_header_sum {                        # {{{1\n    my ($report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rhh_sum    , # out sum{nFiles|blank|comment|code}{same|modified|added|removed}\n       ) = @_;\n\n    my $sum_files = 0;\n    my $sum_lines = 0;\n    foreach my $language (keys %{$rhhh_count}) {\n        foreach my $V (qw(nFiles blank comment code)) {\n            foreach my $S (qw(added same modified removed)) {\n                $rhhh_count->{$language}{$V}{$S} = 0 unless\n                    defined $rhhh_count->{$language}{$V}{$S};\n                $rhh_sum->{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};\n                if ($V eq \"nFiles\") {\n                    $sum_files += $rhhh_count->{$language}{$V}{$S};\n                } else {\n                    $sum_lines += $rhhh_count->{$language}{$V}{$S};\n                }\n            }\n        }\n    }\n\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $BY_FILE      = 1;\n    }\n    return $sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE;\n} # 1}}}\nsub diff_xml_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_xml_report\\n\" if $opt_v > 2;\n    my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n\n#print \"diff_report: \", Dumper($rhhh_count), \"\\n\";\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my $languages     = ();\n\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    my $data_line   = \"\";\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n\n    foreach my $S (qw(same modified added removed)) {\n        push @results, \"  <$S>\";\n        foreach my $lang_or_file (sort {\n                                     $rhhh_count->{$b}{'code'} <=>\n                                     $rhhh_count->{$a}{'code'}\n                                   }\n                              keys %{$rhhh_count}) {\n            my $L = \"\";\n\n            if ($BY_FILE) {\n                $L .= sprintf \"    <file name=\\\"%s\\\" files_count=\\\"1\\\" \",\n                    xml_metachars(\n                        rm_leading_tempdir($lang_or_file, \\%TEMP_DIR));\n            } else {\n                $L .= sprintf \"    <language name=\\\"%s\\\" files_count=\\\"%d\\\" \",\n                        $lang_or_file ,\n                        $rhhh_count->{$lang_or_file}{'nFiles'}{$S};\n            }\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent            ,\n                            $rhhh_count->{$lang_or_file}{'code'}{$S}   ,\n                            $rhhh_count->{$lang_or_file}{'comment'}{$S},\n                            $rhhh_count->{$lang_or_file}{'blank'}{$S}  );\n              foreach my $T (qw(blank comment code)) {\n                  if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {\n                    $L .= sprintf \"%s=\\\"%.2f\\\" \",\n                            $T, $rhhh_count->{$lang_or_file}{$T}{$S} / $DEN * 100;\n                  } else {\n                    $L .= sprintf \"%s=\\\"0.0\\\" \", $T;\n                  }\n              }\n            } else {\n              foreach my $T (qw(blank comment code)) {\n                  $L .= sprintf \"%s=\\\"%d\\\" \",\n                          $T, $rhhh_count->{$lang_or_file}{$T}{$S};\n              }\n            }\n            push @results, $L . \"/>\";\n        }\n\n\n        my $L = sprintf \"    <total sum_files=\\\"%d\\\" \", $sum{'nFiles'}{$S};\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent,\n                        $sum{'code'}{$S}   ,\n                        $sum{'comment'}{$S},\n                        $sum{'blank'}{$S}  );\n          foreach my $V (qw(blank comment code)) {\n              if ($sum{'code'}{$S} > 0) {\n                  $L .= sprintf \"%s=\\\"%.2f\\\" \", $V, $sum{$V}{$S} / $DEN * 100;\n              } else {\n                  $L .= sprintf \"%s=\\\"0.0\\\" \", $V;\n              }\n          }\n        } else {\n          foreach my $V (qw(blank comment code)) {\n              $L .= sprintf \"%s=\\\"%d\\\" \", $V, $sum{$V}{$S};\n          }\n        }\n        push @results, $L . \"/>\";\n        push @results, \"  </$S>\";\n    }\n\n    push @results, \"</diff_results>\";\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    print \"<- diff_xml_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub diff_csv_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in  unused\n       ) = @_;\n    print \"-> diff_csv_report\\n\" if $opt_v > 2;\n\n    my @results       = ();\n    my $languages     = ();\n\n    my $data_line   = \"\";\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $BY_FILE      = 1;\n    }\n    my $DELIM = \",\";\n       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;\n       $DELIM = \"|\" if defined $opt_md;\n\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $line = \"Language${DELIM} \";\n       $line = \"File${DELIM} \" if $BY_FILE;\n    foreach my $item (qw(files blank comment code)) {\n        next if $BY_FILE and $item eq 'files';\n        foreach my $symbol ( '==', '!=', '+', '-', ) {\n            $line .= \"$symbol $item${DELIM} \";\n        }\n    }\n\n    my $T_elapsed_sec = \"T=$elapsed_sec s\";\n       $T_elapsed_sec = \"\" if $opt_hide_rate;\n\n    if ($opt_md) {\n        push @results, \"cloc|$URL v $version $T_elapsed_sec\";\n        push @results, \"--- | ---\";\n        push @results, \"\";\n        push @results, $line;\n        my @col_header  = ();\n        push @col_header, \":-------\";\n        foreach (1..16) {\n            push @col_header, \"-------:\";\n        }\n        push @results, join(\"|\", @col_header) . \"|\";\n    } else {\n        $line .= \"\\\"$URL v $version $T_elapsed_sec\\\"\";\n        push @results, $line;\n    }\n\n    foreach my $lang_or_file (keys %{$rhhh_count}) {\n        $rhhh_count->{$lang_or_file}{'code'}{'added'} = 0 unless\n            defined $rhhh_count->{$lang_or_file}{'code'};\n    }\n    foreach my $lang_or_file (sort {\n                                 $rhhh_count->{$b}{'code'} <=>\n                                 $rhhh_count->{$a}{'code'}\n                               }\n                          keys %{$rhhh_count}) {\n        if ($BY_FILE) {\n            $line = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR) . \"$DELIM \";\n        } else {\n            $line = $lang_or_file . \"${DELIM} \";\n        }\n        if ($opt_by_percent) {\n          foreach my $item (qw(nFiles)) {\n              next if $BY_FILE and $item eq 'nFiles';\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {\n                      $line .= \"$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} \";\n                  } else {\n                      $line .= \"0${DELIM} \";\n                  }\n              }\n          }\n          foreach my $item (qw(blank comment code)) {\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol} and\n                      defined $rhhh_count->{$lang_or_file}{'code'}{$symbol} and\n                      $rhhh_count->{$lang_or_file}{'code'}{$symbol} > 0) {\n                      $line .= sprintf(\"%.2f\", $rhhh_count->{$lang_or_file}{$item}{$symbol} / $rhhh_count->{$lang_or_file}{'code'}{$symbol} * 100).${DELIM};\n                  } else {\n                      $line .= \"0.00${DELIM} \";\n                  }\n              }\n          }\n        } else {\n          foreach my $item (qw(nFiles blank comment code)) {\n              next if $BY_FILE and $item eq 'nFiles';\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {\n                      $line .= \"$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} \";\n                  } else {\n                      $line .= \"0${DELIM} \";\n                  }\n              }\n          }\n        }\n        push @results, $line;\n    }\n\n    print \"<- diff_csv_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub rm_leading_tempdir {                     # {{{1\n    my ($in_file, $rh_temp_dirs, ) = @_;\n    my $clean_filename = $in_file;\n    foreach my $temp_d (keys %{$rh_temp_dirs}) {\n        if ($ON_WINDOWS) {\n        # \\ -> / necessary to allow the next if test's\n        # m{} to work in the presence of spaces in file names\n            $temp_d         =~ s{\\\\}{/}g;\n            $clean_filename =~ s{\\\\}{/}g;\n        }\n        if ($clean_filename =~ m{^$temp_d/}) {\n            $clean_filename =~ s{^$temp_d/}{};\n            last;\n        }\n    }\n    if ($ON_WINDOWS and $opt_by_file) { # then go back from / to \\\n        if ($opt_json) {\n            $clean_filename =~ s{/}{\\\\\\\\}g;\n        } else {\n            $clean_filename =~ s{/}{\\\\}g;\n        }\n    }\n    return $clean_filename;\n} # 1}}}\nsub generate_sql    {                        # {{{1\n    my ($elapsed_sec, # in\n        $rhh_count  , # in  count{TYPE}{lang|code|blank|comment|scaled}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> generate_sql\\n\" if $opt_v > 2;\n\n#print \"generate_sql A [$opt_sql_project]\\n\";\n    $opt_sql_project = cwd() unless defined $opt_sql_project;\n    $opt_sql_project = '' unless defined $opt_sql_project; # have seen cwd() fail\n#print \"generate_sql B [$opt_sql_project]\\n\";\n    $opt_sql_project =~ s{/}{\\\\}g if $ON_WINDOWS;\n#print \"generate_sql C [$opt_sql_project]\\n\";\n\n    my $schema = undef;\n    if ($opt_sql_style eq \"oracle\") {\n        $schema = \"\nCREATE TABLE metadata\n(\n  id          INTEGER PRIMARY KEY,\n  timestamp   TIMESTAMP,\n  project     VARCHAR2(500 CHAR),\n  elapsed_s   NUMBER(10, 6)\n)\n/\n\nCREATE TABLE t\n(\n  id             INTEGER           ,\n  project        VARCHAR2(500 CHAR),\n  language       VARCHAR2(500 CHAR),\n  file_fullname  VARCHAR2(500 CHAR),\n  file_dirname   VARCHAR2(500 CHAR),\n  file_basename  VARCHAR2(500 CHAR),\n  nblank         INTEGER,\n  ncomment       INTEGER,\n  ncode          INTEGER,\n  nscaled        NUMBER(10, 6),\nFOREIGN KEY (id)\n    REFERENCES metadata (id)\n)\n/\n\n\";\n    } else {\n        $schema = \"\ncreate table metadata (          -- $URL v $VERSION\n                id        integer primary key,\n                timestamp varchar(500),\n                Project   varchar(500),\n                elapsed_s real);\ncreate table t        (\n                id            integer        ,\n                Project       varchar(500)   ,\n                Language      varchar(500)   ,\n                File          varchar(500)   ,\n                File_dirname  varchar(500)   ,\n                File_basename varchar(500)   ,\n                nBlank        integer        ,\n                nComment      integer        ,\n                nCode         integer        ,\n                nScaled       real           ,\n        foreign key (id)\n            references metadata (id));\n\";\n    }\n    $opt_sql = \"-\" if $opt_sql eq \"1\";\n\n    my $open_mode = \">\";\n       $open_mode = \">>\" if $opt_sql_append;\n\n    my $fh;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne \"-\") {\n        # only use the Win32::LongPath wrapper here when needed,\n        # and only when not writing to STDOUT.\n        $fh = open_file($open_mode, $opt_sql, 1);\n        die \"Unable to write to $opt_sql\\n\" if !defined $fh;\n    } else {\n        $fh = new IO::File; # $opt_sql, \"w\";\n        if (!$fh->open(\"${open_mode}${opt_sql}\")) {\n            die \"Unable to write to $opt_sql  $!\\n\";\n        }\n    }\n    print $fh $schema unless defined $opt_sql_append;\n\n    my $id = int(time());\n    my $insert_into_t = \"insert into t \";\n    if ($opt_sql_style eq \"oracle\") {\n        printf $fh \"insert into metadata values(%d, TO_TIMESTAMP('%s','yyyy-mm-dd hh24:mi:ss'), '%s', %f);\\n\",\n                    $id,\n                    strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    } elsif ($opt_sql_style eq \"named_columns\") {\n        print $fh \"begin transaction;\\n\";\n        $insert_into_t .= \"(id, Project, Language, File, File_dirname, File_basename, nBlank, nComment, nCode, nScaled )\";\n    } else {\n        print $fh \"begin transaction;\\n\";\n        printf $fh \"insert into metadata values(%d, '%s', '%s', %f);\\n\",\n                    $id, strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    }\n\n    my $nIns = 0;\n    foreach my $file (keys %{$rhh_count}) {\n        my $language = $rhh_count->{$file}{'lang'};\n        my $clean_filename = $file;\n        # If necessary (that is, if the input contained an\n        # archive file [.tar.gz, etc]), strip the temporary\n        # directory name which was used to expand the archive\n        # from the file name.\n\n        $clean_filename = rm_leading_tempdir($clean_filename, \\%TEMP_DIR);\n        $clean_filename =~ s/\\'/''/g;  # double embedded single quotes\n                                       # to escape them\n\n        printf $fh \"$insert_into_t values(%d, '%s', '%s', '%s', '%s', '%s', \" .\n                   \"%d, %d, %d, %f);\\n\",\n                    $id                        ,\n                    $opt_sql_project           ,\n                    $language                  ,\n                    $clean_filename            ,\n                    dirname( $clean_filename)  ,\n                    basename($clean_filename)  ,\n                    $rhh_count->{$file}{'blank'},\n                    $rhh_count->{$file}{'comment'},\n                    $rhh_count->{$file}{'code'}   ,\n                    $rhh_count->{$file}{'code'}*$rh_scale->{$language};\n\n        ++$nIns;\n        if (!($nIns % 10_000) and ($opt_sql_style ne \"oracle\")) {\n            print $fh \"commit;\\n\";\n            print $fh \"begin transaction;\\n\";\n        }\n    }\n    if ($opt_sql_style ne \"oracle\") {\n        print $fh \"commit;\\n\";\n    }\n\n    $fh->close unless $opt_sql eq \"-\"; # don't try to close STDOUT\n    print \"<- generate_sql\\n\" if $opt_v > 2;\n\n    # sample query:\n    #\n    #   select project, language,\n    #          sum(nCode)     as Code,\n    #          sum(nComment)  as Comments,\n    #          sum(nBlank)    as Blank,\n    #          sum(nCode)+sum(nComment)+sum(nBlank) as All_Lines,\n    #          100.0*sum(nComment)/(sum(nCode)+sum(nComment)) as Comment_Pct\n    #          from t group by Project, Language order by Project, Code desc;\n    #\n} # 1}}}\nsub generate_diff_sql {                      # {{{1\n    my ($elapsed_sec, # in\n        $rhhh_delta , # in  delta{file}{comment/blank/code}{added/same/modified/removed}\n       ) = @_;\n    print \"-> generate_diff_sql\\n\" if $opt_v > 2;\n\n    $opt_sql_project = cwd() unless defined $opt_sql_project;\n    $opt_sql_project = '' unless defined $opt_sql_project; # have seen cwd() fail\n    $opt_sql_project =~ s{/}{\\\\}g if $ON_WINDOWS;\n\n    my $schema = undef;\n    if ($opt_sql_style eq \"oracle\") {\n        $schema = \"\nCREATE TABLE metadata\n(\n  id          INTEGER PRIMARY KEY,\n  timestamp   TIMESTAMP,\n  project     VARCHAR2(500 CHAR),\n  elapsed_s   NUMBER(10, 6)\n)\n/\n\nCREATE TABLE t_diff\n(\n  id                INTEGER           ,\n  project           VARCHAR2(500 CHAR),\n  language          VARCHAR2(500 CHAR),\n  file_fullname     VARCHAR2(500 CHAR),\n  file_dirname      VARCHAR2(500 CHAR),\n  file_basename     VARCHAR2(500 CHAR),\n  nblank_same       INTEGER,\n  nblank_modified   INTEGER,\n  nblank_added      INTEGER,\n  nblank_removed    INTEGER,\n  ncomment_same     INTEGER,\n  ncomment_modified INTEGER,\n  ncomment_added    INTEGER,\n  ncomment_removed  INTEGER,\n  ncode_same        INTEGER,\n  ncode_modified    INTEGER,\n  ncode_added       INTEGER,\n  ncode_removed     INTEGER,\nFOREIGN KEY (id)\n    REFERENCES metadata (id)\n)\n/\n\n\";\n    } else {\n        $schema = \"\ncreate table metadata (          -- $URL v $VERSION\n                id        integer primary key,\n                timestamp varchar(500),\n                Project   varchar(500),\n                elapsed_s real);\ncreate table t_diff   (\n                id                integer        ,\n                Project           varchar(500)   ,\n                Language          varchar(500)   ,\n                File              varchar(500)   ,\n                File_dirname      varchar(500)   ,\n                File_basename     varchar(500)   ,\n                nBlank_same       integer        ,\n                nBlank_modified   integer        ,\n                nBlank_added      integer        ,\n                nBlank_removed    integer        ,\n                nComment_same     integer        ,\n                nComment_modified integer        ,\n                nComment_added    integer        ,\n                nComment_removed  integer        ,\n                nCode_same        integer        ,\n                nCode_modified    integer        ,\n                nCode_added       integer        ,\n                nCode_removed     integer        ,\n        foreign key (id)\n            references metadata (id));\n\";\n    }\n    $opt_sql = \"-\" if $opt_sql eq \"1\";\n\n    my $open_mode = \">\";\n       $open_mode = \">>\" if $opt_sql_append;\n\n    my $fh;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne \"-\") {\n        # only use the Win32::LongPath wrapper here when needed,\n        # and only when not writing to STDOUT.\n        $fh = open_file($open_mode, $opt_sql, 1);\n        die \"Unable to write to $opt_sql\\n\" if !defined $fh;\n    } else {\n        $fh = new IO::File; # $opt_sql, \"w\";\n        if (!$fh->open(\"${open_mode}${opt_sql}\")) {\n            die \"Unable to write to $opt_sql  $!\\n\";\n        }\n    }\n    print $fh $schema unless defined $opt_sql_append;\n\n    my $id = int(time());\n    my $insert_into_t = \"insert into t_diff \";\n    if ($opt_sql_style eq \"oracle\") {\n        printf $fh \"insert into metadata values(%d, TO_TIMESTAMP('%s',\" .\n                   \"'yyyy-mm-dd hh24:mi:ss'), '%s', %f);\\n\",\n                    $id,\n                    strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    } elsif ($opt_sql_style eq \"named_columns\") {\n        print $fh \"begin transaction;\\n\";\n        $insert_into_t .= \"(id, Project, Language, File, File_dirname, File_basename, \" .\n                          \"nBlank_same, nBlank_modified, nBlank_added, nBlank_removed, \" .\n                          \"nComment_same, nComment_modified, nComment_added, nComment_removed, \" .\n                          \"nCode_same, nCode_modified, nCode_added, nCode_removed )\";\n    } else {\n        print $fh \"begin transaction;\\n\";\n        printf $fh \"insert into metadata values(%d, '%s', '%s', %f);\\n\",\n                    $id, strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    }\n\n    my $nIns = 0;\n    foreach my $file (keys %{$rhhh_delta}) {\n        my $language = $Language_by_Filename{$file};\n        my $clean_filename = $file;\n        # If necessary (that is, if the input contained an\n        # archive file [.tar.gz, etc]), strip the temporary\n        # directory name which was used to expand the archive\n        # from the file name.\n\n        $clean_filename = rm_leading_tempdir($clean_filename, \\%TEMP_DIR);\n        $clean_filename =~ s/\\'/''/g;  # double embedded single quotes\n                                       # to escape them\n\nif (1) {\n        $rhhh_delta->{$file}{'blank'}{'same'}       = 0 unless defined $rhhh_delta->{$file}{'blank'}{'same'}      ;\n        $rhhh_delta->{$file}{'blank'}{'modified'}   = 0 unless defined $rhhh_delta->{$file}{'blank'}{'modified'}  ;\n        $rhhh_delta->{$file}{'blank'}{'added'}      = 0 unless defined $rhhh_delta->{$file}{'blank'}{'added'}     ;\n        $rhhh_delta->{$file}{'blank'}{'removed'}    = 0 unless defined $rhhh_delta->{$file}{'blank'}{'removed'}   ;\n        $rhhh_delta->{$file}{'comment'}{'same'}     = 0 unless defined $rhhh_delta->{$file}{'comment'}{'same'}    ;\n        $rhhh_delta->{$file}{'comment'}{'modified'} = 0 unless defined $rhhh_delta->{$file}{'comment'}{'modified'};\n        $rhhh_delta->{$file}{'comment'}{'added'}    = 0 unless defined $rhhh_delta->{$file}{'comment'}{'added'}   ;\n        $rhhh_delta->{$file}{'comment'}{'removed'}  = 0 unless defined $rhhh_delta->{$file}{'comment'}{'removed'} ;\n        $rhhh_delta->{$file}{'code'}{'same'}        = 0 unless defined $rhhh_delta->{$file}{'code'}{'same'}       ;\n        $rhhh_delta->{$file}{'code'}{'modified'}    = 0 unless defined $rhhh_delta->{$file}{'code'}{'modified'}   ;\n        $rhhh_delta->{$file}{'code'}{'added'}       = 0 unless defined $rhhh_delta->{$file}{'code'}{'added'}      ;\n        $rhhh_delta->{$file}{'code'}{'removed'}     = 0 unless defined $rhhh_delta->{$file}{'code'}{'removed'}    ;\nuse Data::Dumper;\n#print Dumper($rhhh_delta->{$file});\n#die;\n        printf $fh \"$insert_into_t values(%d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d);\\n\",\n                    $id                        ,\n                    $opt_sql_project           ,\n                    $language                  ,\n                    $clean_filename            ,\n                    dirname( $clean_filename)  ,\n                    basename($clean_filename)  ,\n                    $rhhh_delta->{$file}{'blank'}{'same'}      ,\n                    $rhhh_delta->{$file}{'blank'}{'modified'}  ,\n                    $rhhh_delta->{$file}{'blank'}{'added'}     ,\n                    $rhhh_delta->{$file}{'blank'}{'removed'}   ,\n                    $rhhh_delta->{$file}{'comment'}{'same'}    ,\n                    $rhhh_delta->{$file}{'comment'}{'modified'},\n                    $rhhh_delta->{$file}{'comment'}{'added'}   ,\n                    $rhhh_delta->{$file}{'comment'}{'removed'} ,\n                    $rhhh_delta->{$file}{'code'}{'same'}       ,\n                    $rhhh_delta->{$file}{'code'}{'modified'}   ,\n                    $rhhh_delta->{$file}{'code'}{'added'}      ,\n                    $rhhh_delta->{$file}{'code'}{'removed'}    ;\n}\n\n        ++$nIns;\n        if (!($nIns % 10_000) and ($opt_sql_style ne \"oracle\")) {\n            print $fh \"commit;\\n\";\n            print $fh \"begin transaction;\\n\";\n        }\n    }\n    if ($opt_sql_style ne \"oracle\") {\n        print $fh \"commit;\\n\";\n    }\n\n    $fh->close unless $opt_sql eq \"-\"; # don't try to close STDOUT\n    print \"<- generate_diff_sql\\n\" if $opt_v > 2;\n\n} # 1}}}\nsub output_header   {                        # {{{1\n    my ($header_line,\n        $hyphen_line,\n        $BY_FILE    ,)    = @_;\n    print \"-> output_header\\n\" if $opt_v > 2;\n    my @R = ();\n    if      ($opt_xml) {\n        if (!$ALREADY_SHOWED_XML_SECTION) {\n            push @R, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\";\n            push @R, '<?xml-stylesheet type=\"text/xsl\" href=\"' .\n                            $opt_xsl . '\"?>' if $opt_xsl;\n            push @R, \"<results>\";\n            push @R, \"<header>$header_line</header>\";\n            $ALREADY_SHOWED_XML_SECTION = 1;\n        }\n        if ($BY_FILE) {\n            push @R, \"<files>\";\n        } else {\n            push @R, \"<languages>\";\n        }\n    } elsif ($opt_yaml) {\n        push @R, \"---\\n# $header_line\";\n    } elsif ($opt_csv or $opt_md) {\n        # append the header to the end of the column headers\n        # to keep the output a bit cleaner from a spreadsheet\n        # perspective\n    } else {\n        if ($ALREADY_SHOWED_HEADER) {\n            push @R, \"\";\n        } else {\n            push @R, $header_line;\n            $ALREADY_SHOWED_HEADER = 1;\n        }\n        push @R, $hyphen_line;\n    }\n    print \"<- output_header\\n\" if $opt_v > 2;\n    return @R;\n} # 1}}}\nsub generate_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhh_count  , # in  count{TYPE}{nFiles|code|blank|comment|scaled}\n                      #       where TYPE = name of language, source file,\n                      #                    or report file\n        $rh_scale   , # in\n        $out_style  , # in  \"txt\" | \"xml\" | \"yaml\" | \"json\" | \"csv\" | \"md\"\n       ) = @_;\n\n    my %orig_case = ();\n    if ($ON_WINDOWS and $report_type eq \"by file\") {\n        # restore the original upper/lowercase version of the file name\n        foreach my $lc_file (sort keys %{$rhh_count}) {\n            foreach my $cat (sort keys %{$rhh_count->{$lc_file}}) {\n                $orig_case{ $upper_lower_map{$lc_file} }{$cat} =\n                           $rhh_count->{$lc_file}{$cat};\n            }\n        }\n        $rhh_count = \\%orig_case;\n    }\n    print \"-> generate_report\\n\" if $opt_v > 2;\n    my $DELIM = \",\";\n       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;\n       $DELIM = \"|\" if $out_style eq \"md\";\n\n    my @results       = ();\n\n    my $languages     = ();\n\n    my $sum_files     = 0;\n    my $sum_code      = 0;\n    my $sum_blank     = 0;\n    my $sum_comment   = 0;\n    my $max_len       = 0;\n    foreach my $language (keys %{$rhh_count}) {\n        $sum_files   += $rhh_count->{$language}{'nFiles'} ;\n        $sum_blank   += $rhh_count->{$language}{'blank'}  ;\n        $sum_comment += $rhh_count->{$language}{'comment'};\n        $sum_code    += $rhh_count->{$language}{'code'}   ;\n        $max_len      = length($language) if length($language) > $max_len;\n    }\n    my $column_1_offset = 0;\n       $column_1_offset = $max_len - 17 if $max_len > 17;\n    my $sum_lines = $sum_blank + $sum_comment + $sum_code;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $spacing_0 = 23;\n    my $spacing_1 = 13;\n    my $spacing_2 =  9;\n    my $spacing_3 = 17;\n    if (!$opt_3) {\n        $spacing_1 = 19;\n        $spacing_2 = 14;\n        $spacing_3 = 27;\n    }\n    $spacing_0 += $column_1_offset;\n    $spacing_1 += $column_1_offset;\n    $spacing_3 += $column_1_offset;\n    my %Format = (\n        '1' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_0}s \",\n               },\n        '2' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_3}s \",\n               },\n        '3' => { 'xml' => 'files_count=\"%d\" ',\n                 'txt' => '%6d ',\n               },\n        '4' => { 'xml' => 'blank=\"%d\" comment=\"%d\" code=\"%d\" ',\n                 'txt' => \"\\%${spacing_2}d \\%${spacing_2}d \\%${spacing_2}d\",\n               },\n        '5' => { 'xml' => 'blank=\"%3.2f\" comment=\"%3.2f\" code=\"%3.2f\" ',\n                 'txt' => \"\\%14.2f \\%14.2f  \\%13.2f\",\n               },\n        '6' => { 'xml' => 'factor=\"%.2f\" scaled=\"%.2f\" ',\n                 'txt' => ' x %6.2f = %14.2f',\n               },\n    );\n    my $Style = \"txt\";\n       $Style = \"xml\" if $out_style eq \"xml\" ;\n       $Style = \"xml\" if $out_style eq \"yaml\";  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $out_style eq \"json\";  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $out_style eq \"csv\" ;  # not a typo; just set to anything but txt\n\n    my $hyphen_line = sprintf \"%s\", '-' x (79 + $column_1_offset);\n       $hyphen_line = sprintf \"%s\", '-' x (68 + $column_1_offset)\n            if (!$opt_sum_reports) and (!$opt_3) and (68 + $column_1_offset) > 79;\n    my $data_line  = \"\";\n    my $first_column;\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $first_column = \"Language\";\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $first_column = \"File\";\n        $BY_FILE      = 1;\n    } elsif ($report_type eq \"by report file\")     {\n        $first_column = \"File\";\n    } else {\n        $first_column = \"Report File\";\n    }\n\n    my $header_line  = sprintf \"%s v %s\", $URL, $version;\n       $header_line .= sprintf(\"  T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                        $elapsed_sec           ,\n                        $sum_files/$elapsed_sec,\n                        $sum_lines/$elapsed_sec) unless $opt_sum_reports or $opt_hide_rate;\n    if ($out_style eq \"xml\" or $out_style eq \"yaml\" or $out_style eq \"json\") {\n        if (!$ALREADY_SHOWED_HEADER) {\n            if ($opt_by_file_by_lang and $out_style eq \"json\") {\n                push @results, '{ \"by_file\" : ';\n            }\n            push @results, xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                                   $sum_files, $sum_lines, $BY_FILE);\n#           $ALREADY_SHOWED_HEADER = 1 unless $opt_sum_reports;\n            # --sum-reports yields two xml or yaml files, one by\n            # language and one by report file, each of which needs a header\n        }\n        if ($out_style eq \"xml\") {\n            if ($BY_FILE or ($report_type eq \"by report file\")) {\n                push @results, \"<files>\";\n            } else {\n                push @results, \"<languages>\";\n            }\n        }\n    } else {\n        $header_line =~ s/,// if $out_style eq \"csv\";\n        push @results, output_header($header_line, $hyphen_line, $BY_FILE);\n    }\n\n    if ($Style eq \"txt\") {\n        # column headers\n        if (!$opt_3 and $BY_FILE) {\n            my $spacing_n = $spacing_1 - 11;\n            $data_line  = sprintf \"%-${spacing_n}s \", $first_column;\n        } else {\n            $data_line  = sprintf \"%-${spacing_1}s \", $first_column;\n        }\n        if ($BY_FILE) {\n            $data_line .= sprintf \"%${spacing_2}s \"  , \" \"    ;\n        } else {\n            $data_line .= sprintf \"%${spacing_2}s \"  , \"files\";\n        }\n        my $PCT_symbol = \"\";\n           $PCT_symbol = \" \\%\" if $opt_by_percent;\n        $data_line .= sprintf \"%${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n            \"blank${PCT_symbol}\"   ,\n            \"comment${PCT_symbol}\" ,\n            \"code${PCT_symbol}\";\n        $data_line .= sprintf \" %8s   %14s\",\n            \"scale\"         ,\n            \"3rd gen. equiv\"\n              if $opt_3;\n        if ($out_style eq \"md\") {\n            my @col_header  = ();\n            if ($data_line =~ m{\\s%}) {\n                $data_line =~ s{\\s%}{_%}g;\n                foreach my $w ( split(' ', $data_line) ) {\n                    $w =~ s{_%}{ %};\n                    push @col_header, $w;\n                }\n            } else {\n                push @col_header, split(' ', $data_line);\n            }\n            my @col_hyphens    = ( '-------:') x scalar(@col_header);\n               $col_hyphens[0] =   ':-------'; # first column left justified\n            push @results, join(\"|\", @col_header );\n            push @results, join(\"|\", @col_hyphens);\n        } else {\n            push @results, $data_line;\n            push @results, $hyphen_line;\n        }\n    }\n\n    if ($out_style eq \"csv\")  {\n        my $header2;\n        if ($BY_FILE) {\n            $header2 = \"language${DELIM}filename\";\n        } else {\n            $header2 = \"files${DELIM}language\";\n        }\n        $header2 .= \"${DELIM}blank${DELIM}comment${DELIM}code\";\n        $header2 .= \"${DELIM}scale${DELIM}3rd gen. equiv\" if $opt_3;\n        $header2 .= ${DELIM} . '\"' . $header_line . '\"';\n        push @results, $header2;\n    }\n\n    my $sum_scaled = 0;\n    foreach my $lang_or_file (sort {\n                                 $rhh_count->{$b}{'code'} <=>\n                                 $rhh_count->{$a}{'code'}\n                              or $a cmp $b\n                                        }\n                                   keys %{$rhh_count}) {\n        next if $lang_or_file eq \"by report file\";\n        my $clean_lang_or_file = $lang_or_file;   # later, if by-file protect ' and \"\n        my ($factor, $scaled);\n        if ($BY_LANGUAGE or $BY_FILE) {\n            $factor = 1;\n            if ($BY_LANGUAGE) {\n                if (defined $rh_scale->{$lang_or_file}) {\n                    $factor = $rh_scale->{$lang_or_file};\n                } else {\n                    warn \"No scale factor for $lang_or_file; using 1.00\";\n                }\n            } else { # by individual code file\n                if ($report_type ne \"by report file\") {\n                    next unless defined $rhh_count->{$lang_or_file}{'lang'};\n                    next unless defined $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};\n                    $factor = $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};\n                }\n            }\n            $scaled = $factor*$rhh_count->{$lang_or_file}{'code'};\n        } else {\n            if (!defined $rhh_count->{$lang_or_file}{'scaled'}) {\n                $opt_3 = 0;\n                # If we're summing together files previously generated\n                # with --no3 then rhh_count->{$lang_or_file}{'scaled'}\n                # this variable will be undefined.  That should only\n                # happen when summing together by file however.\n            } elsif ($BY_LANGUAGE) {\n                warn \"Missing scaled language info for $lang_or_file\\n\";\n            }\n            if ($opt_3) {\n                $scaled =         $rhh_count->{$lang_or_file}{'scaled'};\n                $factor = $scaled/$rhh_count->{$lang_or_file}{'code'};\n            }\n        }\n\n        if ($BY_FILE) {\n            $clean_lang_or_file = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n            $clean_lang_or_file = xml_metachars($clean_lang_or_file) if $out_style eq \"xml\";\n            if ($out_style eq \"yaml\")  {\n                # YAML does not allow protected single quotes in keys\n                $clean_lang_or_file =~ s/'/0x27/g;\n            } elsif ($out_style eq \"json\")  {\n                # JSON does not allow protected double quotes in keys\n                $clean_lang_or_file =~ s/\"/0x2b/g;\n            } elsif ($out_style ne \"txt\")  {\n                # text output is allowed to keep its quotes as they are\n                $clean_lang_or_file =~ s/'/\\\\'/g;\n                $clean_lang_or_file =~ s/\"/\\\\\"/g;\n            }\n            $data_line  = sprintf $Format{'1'}{$Style}, $clean_lang_or_file;\n        } else {\n            $data_line  = sprintf $Format{'2'}{$Style}, $lang_or_file;\n        }\n        $data_line .= sprintf $Format{3}{$Style}  ,\n                        $rhh_count->{$lang_or_file}{'nFiles'} unless $BY_FILE;\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent       ,\n                        $rhh_count->{$lang_or_file}{'code'}   ,\n                        $rhh_count->{$lang_or_file}{'comment'},\n                        $rhh_count->{$lang_or_file}{'blank'}  );\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{5}{$Style}  ,\n                $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100,\n                $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100,\n                $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100;\n          } else {\n            $data_line .= sprintf $Format{5}{$Style}  ,\n                $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100,\n                $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100,\n                $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{4}{$Style}  ,\n              $rhh_count->{$lang_or_file}{'blank'}  ,\n              $rhh_count->{$lang_or_file}{'comment'},\n              $rhh_count->{$lang_or_file}{'code'}   ;\n        }\n        $data_line .= sprintf $Format{6}{$Style}  ,\n            $factor                               ,\n            $scaled if $opt_3;\n        $sum_scaled  += $scaled if $opt_3;\n\n        if ($out_style eq \"xml\") {\n            if (defined $rhh_count->{$lang_or_file}{'lang'}) {\n                my $lang = $rhh_count->{$lang_or_file}{'lang'};\n                if (!defined $languages->{$lang}) {\n                    $languages->{$lang} = $lang;\n                }\n                $data_line.=' language=\"' . $lang . '\" ';\n            }\n            if ($BY_FILE or ($report_type eq \"by report file\")) {\n                push @results, \"  <file \" . $data_line . \"/>\";\n            } else {\n                push @results, \"  <language \" . $data_line . \"/>\";\n            }\n        } elsif ($out_style eq \"yaml\" or $out_style eq \"json\") {\n            my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n            if ($out_style eq \"yaml\") {\n                # YAML: force quoted language or filename in case these\n                #       have embedded funny characters, issue #312\n                push @results,\"'\" . rm_leading_tempdir($clean_lang_or_file, \\%TEMP_DIR). \"' :$open_B\";\n            } else {\n                push @results,\"${Q}\" . rm_leading_tempdir($clean_lang_or_file, \\%TEMP_DIR). \"${Q} :$open_B\";\n            }\n            push @results,\"  ${Q}nFiles${Q}: \" . $rhh_count->{$lang_or_file}{'nFiles'} . $C\n                unless $BY_FILE;\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent       ,\n                            $rhh_count->{$lang_or_file}{'code'}   ,\n                            $rhh_count->{$lang_or_file}{'comment'},\n                            $rhh_count->{$lang_or_file}{'blank'}  );\n            if ($opt_by_percent eq 't') {\n              push @results,\"  ${Q}blank_pct${Q}: \"   .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100) . $C;\n              push @results,\"  ${Q}comment_pct${Q}: \" .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100) . $C;\n              push @results,\"  ${Q}code_pct${Q}: \"    .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100) . $C;\n            } else {\n              push @results,\"  ${Q}blank_pct${Q}: \"     .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100) . $C;\n              push @results,\"  ${Q}comment_pct${Q}: \" .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . $C;\n              push @results,\"  ${Q}code_pct${Q}: \"    .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100) . $C;\n            }\n            } else {\n              push @results,\"  ${Q}blank${Q}: \"   . $rhh_count->{$lang_or_file}{'blank'}   . $C;\n              push @results,\"  ${Q}comment${Q}: \" . $rhh_count->{$lang_or_file}{'comment'} . $C;\n              push @results,\"  ${Q}code${Q}: \"    . $rhh_count->{$lang_or_file}{'code'}    . $C;\n            }\n            push @results,\"  ${Q}language${Q}: \"  . $Q . $rhh_count->{$lang_or_file}{'lang'} . $Q . $C\n                if $BY_FILE;\n            if ($opt_3) {\n                push @results, \"  ${Q}scaled${Q}: \" . $scaled . $C;\n                push @results, \"  ${Q}factor${Q}: \" . $factor . $C;\n            }\n            if ($out_style eq \"json\") { # replace the trailing comma with }, on the last line\n                $results[-1] =~ s/,\\s*$/},/;\n            }\n        } elsif ($out_style eq \"csv\" or $out_style eq \"md\") {\n            my $extra_3 = \"\";\n               $extra_3 = \"${DELIM}$factor${DELIM}$scaled\" if $opt_3;\n            my $first_column = undef;\n            my $clean_name   = $lang_or_file;\n            my $str;\n            if ($out_style eq \"csv\") {\n                if ($BY_FILE) {\n                    $first_column = $rhh_count->{$lang_or_file}{'lang'};\n                    $clean_name   = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n                } else {\n                    $first_column = $rhh_count->{$lang_or_file}{'nFiles'};\n                }\n                $str = $first_column   . ${DELIM} .\n                       $clean_name     . ${DELIM};\n            } else {\n                if ($BY_FILE) {\n                    $first_column = $rhh_count->{$lang_or_file}{'lang'};\n                    $clean_name   = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n                    $str = $clean_name . ${DELIM};\n                } else {\n                    $first_column = $rhh_count->{$lang_or_file}{'nFiles'};\n                    $str = $clean_name     . ${DELIM} .\n                           $first_column   . ${DELIM};\n                }\n            }\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent               ,\n                            $rhh_count->{$lang_or_file}{'code'}   ,\n                            $rhh_count->{$lang_or_file}{'comment'},\n                            $rhh_count->{$lang_or_file}{'blank'}  );\n              if ($opt_by_percent eq 't') {\n                $str .= sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100) . ${DELIM} ;\n              } else {\n                $str .= sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100) . ${DELIM} ;\n              }\n            } else {\n              $str .= $rhh_count->{$lang_or_file}{'blank'}  . ${DELIM} .\n                      $rhh_count->{$lang_or_file}{'comment'}. ${DELIM} .\n                      $rhh_count->{$lang_or_file}{'code'};\n            }\n            $str .= $extra_3;\n            push @results, $str;\n\n        } else {\n            push @results, $data_line;\n        }\n    }\n\n    my $avg_scale = 1;  # weighted average of scale factors\n       $avg_scale = sprintf(\"%.2f\", $sum_scaled / $sum_code)\n            if $sum_code and $opt_3;\n\n    if ($out_style eq \"xml\") {\n        $data_line = \"\";\n        if (!$BY_FILE) {\n            $data_line .= sprintf \"sum_files=\\\"%d\\\" \", $sum_files;\n        }\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent    ,\n                        $sum_code, $sum_comment, $sum_blank);\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $sum_blank   * 100,\n                $sum_comment / $sum_comment * 100,\n                $sum_code    / $sum_code    * 100;\n          } else {\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $DEN * 100,\n                $sum_comment / $DEN * 100,\n                $sum_code    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{'4'}{$Style},\n              $sum_blank   ,\n              $sum_comment ,\n              $sum_code    ;\n        }\n        $data_line .= sprintf $Format{'6'}{$Style},\n            $avg_scale   ,\n            $sum_scaled  if $opt_3;\n        push @results, \"  <total \" . $data_line . \"/>\";\n\n        if ($BY_FILE or ($report_type eq \"by report file\")) {\n            push @results, \"</files>\";\n        } else {\n            foreach my $language (keys %{$languages}) {\n                push @results, '  <language name=\"' . $language . '\"/>';\n            }\n            push @results, \"</languages>\";\n        }\n\n        if (!$opt_by_file_by_lang or $ALREADY_SHOWED_XML_SECTION) {\n            push @results, \"</results>\";\n        } else {\n            $ALREADY_SHOWED_XML_SECTION = 1;\n        }\n    } elsif ($out_style eq \"yaml\" or $out_style eq \"json\") {\n        my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n        push @results, \"${Q}SUM${Q}: ${open_B}\";\n        if ($opt_by_percent eq 't') {\n          push @results, \"  ${Q}blank${Q}: \"  . sprintf(\"%.2f\", 100) . $C;\n          push @results, \"  ${Q}comment${Q}: \". sprintf(\"%.2f\", 100) . $C;\n          push @results, \"  ${Q}code${Q}: \"   . sprintf(\"%.2f\", 100) . $C;\n        } else {\n          my $DEN = compute_denominator($opt_by_percent    ,\n                        $sum_code, $sum_comment, $sum_blank);\n          push @results, \"  ${Q}blank${Q}: \"  . $sum_blank   . $C;\n          push @results, \"  ${Q}comment${Q}: \". $sum_comment . $C;\n          push @results, \"  ${Q}code${Q}: \"   . $sum_code    . $C;\n        }\n        push @results, \"  ${Q}nFiles${Q}: \" . $sum_files   . $C;\n        if ($opt_3) {\n            push @results, \"  ${Q}scaled${Q}: \" . $sum_scaled . $C;\n            push @results, \"  ${Q}factor${Q}: \" . $avg_scale  . $C;\n        }\n        if ($out_style eq \"json\") {\n            $results[-1] =~ s/,\\s*$/} }/;\n            if ($opt_by_file_by_lang) {\n                if ($ALREADY_SHOWED_HEADER) {\n                    $results[-1] .= ' }';\n                } else {\n                    $results[-1] .= ', \"by_lang\" : {';\n                }\n            }\n        }\n    } elsif ($out_style eq \"csv\") {\n        my @entries = ();\n        if ($opt_by_file) {\n            push @entries, \"SUM\";\n            push @entries, \"\";\n        } else {\n            push @entries, $sum_files;\n            push @entries, \"SUM\";\n        }\n        if ($opt_by_percent) {\n          if ($opt_by_percent eq 't') {\n            push @entries, sprintf(\"%.2f\", 100);\n            push @entries, sprintf(\"%.2f\", 100);\n            push @entries, sprintf(\"%.2f\", 100);\n          } else {\n            my $DEN = compute_denominator($opt_by_percent    ,\n                          $sum_code, $sum_comment, $sum_blank);\n            push @entries, sprintf(\"%.2f\", $sum_blank   / $DEN * 100);\n            push @entries, sprintf(\"%.2f\", $sum_comment / $DEN * 100);\n            push @entries, sprintf(\"%.2f\", $sum_code    / $DEN * 100);\n          }\n        } else {\n            push @entries, $sum_blank;\n            push @entries, $sum_comment;\n            push @entries, $sum_code;\n        }\n        if ($opt_3) {\n            push @entries, $sum_scaled;\n            push @entries, $avg_scale ;\n        }\n        my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n        push @results, join($separator, @entries);\n    } else {\n\n        if ($BY_FILE) {\n            $data_line  = sprintf \"%-${spacing_0}s \", \"SUM:\"  ;\n        } else {\n            $data_line  = sprintf \"%-${spacing_1}s \", \"SUM:\"  ;\n            $data_line .= sprintf \"%${spacing_2}d \", $sum_files;\n        }\n        if ($opt_by_percent) {\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{'5'}{$Style}, 100, 100, 100;\n          } else {\n            my $DEN = compute_denominator($opt_by_percent    ,\n                          $sum_code, $sum_comment, $sum_blank);\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $DEN * 100,\n                $sum_comment / $DEN * 100,\n                $sum_code    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{'4'}{$Style},\n              $sum_blank   ,\n              $sum_comment ,\n              $sum_code    ;\n        }\n        $data_line .= sprintf $Format{'6'}{$Style},\n            $avg_scale   ,\n            $sum_scaled if $opt_3;\n        if ($out_style eq \"md\") {\n            my @words = split(' ', $data_line);\n            my $n_cols = scalar(@words);\n#           my $n_cols = scalar(split(' ', $data_line));  # deprecated\n            $data_line =~ s/\\s+/\\|/g;\n            my @col_hyphens    = ( '--------') x $n_cols;\n            push @results, join(\"|\", @col_hyphens);\n            push @results, $data_line   if $sum_files > 1 or $opt_sum_one;\n            unshift @results, ( \"cloc|$header_line\", \"--- | ---\", \"\", );\n        } else {\n            push @results, $hyphen_line if $sum_files > 1 or $opt_sum_one;\n            push @results, $data_line   if $sum_files > 1 or $opt_sum_one;\n            push @results, $hyphen_line;\n        }\n    }\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    $ALREADY_SHOWED_HEADER = 1 unless $opt_sum_reports;\n    print \"<- generate_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub print_errors {                           # {{{1\n    my ($rh_Error_Codes, # in\n        $raa_errors    , # in\n       ) = @_;\n\n    print \"-> print_errors\\n\" if $opt_v > 2;\n    my %error_string = reverse(%{$rh_Error_Codes});\n    my $nErrors      = scalar @{$raa_errors};\n    warn sprintf \"\\n%d error%s:\\n\", plural_form(scalar @Errors);\n    for (my $i = 0; $i < $nErrors; $i++) {\n        warn sprintf \"%s:  %s\\n\",\n                     $error_string{ $raa_errors->[$i][0] },\n                     $raa_errors->[$i][1] ;\n    }\n    print \"<- print_errors\\n\" if $opt_v > 2;\n\n} # 1}}}\nsub write_lang_def {                         # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # in\n        $rh_Language_by_Script    , # in\n        $rh_Language_by_File_Type      , # in\n        $rhaa_Filters_by_Language , # in\n        $rh_Not_Code_Extension    , # in\n        $rh_Not_Code_Filename     , # in\n        $rh_Scale_Factor          , # in\n        $rh_EOL_Continuation_re   , # in\n       ) = @_;\n\n    print \"-> write_lang_def($file)\\n\" if $opt_v > 2;\n    my @outlines = ();\n\n    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {\n        next if $language =~ /(Brain|\\(unknown\\))/;\n        next if defined $Extension_Collision{$language};\n        push @outlines, $language;\n        foreach my $filter (@{$rhaa_Filters_by_Language->{$language}}) {\n            my $line = \"\";\n            $line .= sprintf \"    filter %s\", $filter->[0];\n            $line .= sprintf \" %s\", $filter->[1] if defined $filter->[1];\n            # $filter->[0] == 'remove_between_general',\n            #                 'remove_between_regex', and\n            #                 'remove_matches_2re' have two args\n            $line .= sprintf \" %s\", $filter->[2] if defined $filter->[2];\n            # $filter->[0] == 'replace_between_regex' has three or four args\n            $line .= sprintf \" %s\", $filter->[3] if defined $filter->[3];\n            $line .= sprintf \" %s\", $filter->[4] if defined $filter->[4];\n            push @outlines, $line;\n        }\n\n        # file extension won't appear if the extension maps to\n        # multiple languages; work around this\n        my $found = 0;\n        foreach my $ext (sort keys %{$rh_Language_by_Extension}) {\n            if ($language eq $rh_Language_by_Extension->{$ext}) {\n                push @outlines, sprintf \"    extension %s\\n\", $ext;\n                $found = 1;\n            }\n        }\n        if (!$found and $opt_write_lang_def_incl_dup) {\n            foreach my $multilang (sort keys %Extension_Collision) {\n                my %Languages = map { $_ => 1 } split('/', $multilang);\n                next unless $Languages{$language};\n                foreach my $ext (@{$Extension_Collision{$multilang}}) {\n                    push @outlines, sprintf \"    extension %s\\n\", $ext;\n                }\n            }\n        }\n\n        foreach my $filename (sort keys %{$rh_Language_by_File_Type}) {\n            if ($language eq $rh_Language_by_File_Type->{$filename}) {\n                push @outlines, sprintf \"    filename %s\\n\", $filename;\n            }\n        }\n        foreach my $script_exe (sort keys %{$rh_Language_by_Script}) {\n            if ($language eq $rh_Language_by_Script->{$script_exe}) {\n                push @outlines, sprintf \"    script_exe %s\\n\", $script_exe;\n            }\n        }\n        push @outlines, sprintf \"    3rd_gen_scale %.2f\\n\", $rh_Scale_Factor->{$language};\n        if (defined $rh_EOL_Continuation_re->{$language}) {\n            push @outlines, sprintf \"    end_of_line_continuation %s\\n\",\n                $rh_EOL_Continuation_re->{$language};\n        }\n    }\n\n    write_file($file, {}, @outlines);\n    print \"<- write_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub read_lang_def {                          # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # out\n        $rh_Language_by_Script    , # out\n        $rh_Language_by_File_Type      , # out\n        $rhaa_Filters_by_Language , # out\n        $rh_Not_Code_Extension    , # out\n        $rh_Not_Code_Filename     , # out\n        $rh_Scale_Factor          , # out\n        $rh_EOL_Continuation_re   , # out\n        $rh_EOL_abc,\n       ) = @_;\n\n\n    print \"-> read_lang_def($file)\\n\" if $opt_v > 2;\n\n    my $language = \"\";\n    my @lines = read_file($file);\n    my $line_num = 0;\n    foreach (@lines) {\n        ++$line_num;\n        next if /^\\s*#/ or /^\\s*$/;\n\n        $_ = lc $_ if $ON_WINDOWS and /^\\s+(filename|extension)\\s/;\n\n        if (/^(\\.?\\w+.*?)\\s*$/) {\n            $language = $1;\n            next;\n        }\n        die \"Missing computer language name, line $line_num of $file\\n\"\n            unless $language;\n\n        if      (/^\\s{4}filter\\s+(remove_between_(general|2re|regex))\n                       \\s+(\\S+)\\s+(\\S+)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                   \\s+(\\S+)\\s+(\\S+)\\s+(\\S+|\\\".*\\\")\\s+(\\S+)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 , $5]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                       \\s+(\\S+)\\s+(\\S+)\\s+(.*?)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\\s+(\\S+)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , '' ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\n                       \\s+(\\S+)\\s+(.+?)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s+(.*?)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]\n\n        } elsif (/^\\s{4}extension\\s+(\\S+)\\s*$/) {\n            if (defined $rh_Language_by_Extension->{$1}) {\n                die \"File extension collision:  $1 \",\n                    \"maps to languages '$rh_Language_by_Extension->{$1}' \",\n                    \"and '$language'\\n\" ,\n                    \"Edit $file and remove $1 from one of these two \",\n                    \"language definitions.\\n\";\n            }\n            $rh_Language_by_Extension->{$1} = $language;\n\n        } elsif (/^\\s{4}filename\\s+(\\S+)\\s*$/) {\n            $rh_Language_by_File_Type->{$1} = $language;\n\n        } elsif (/^\\s{4}script_exe\\s+(\\S+)\\s*$/) {\n            $rh_Language_by_Script->{$1} = $language;\n\n        } elsif (/^\\s{4}3rd_gen_scale\\s+(\\S+)\\s*$/) {\n            $rh_Scale_Factor->{$language} = $1;\n\n        } elsif (/^\\s{4}end_of_line_continuation\\s+(\\S+)\\s*$/) {\n            $rh_EOL_Continuation_re->{$language} = $1;\n\n        } else {\n            die \"Unexpected data line $line_num of $file:\\n$_\\n\";\n        }\n\n    }\n    print \"<- read_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub merge_lang_def {                         # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # in/out\n        $rh_Language_by_Script    , # in/out\n        $rh_Language_by_File_Type      , # in/out\n        $rhaa_Filters_by_Language , # in/out\n        $rh_Not_Code_Extension    , # in/out\n        $rh_Not_Code_Filename     , # in/out\n        $rh_Scale_Factor          , # in/out\n        $rh_EOL_Continuation_re   , # in/out\n        $rh_EOL_abc,\n       ) = @_;\n\n\n    print \"-> merge_lang_def($file)\\n\" if $opt_v > 2;\n\n    my $language        = \"\";\n    my $already_know_it = undef;\n    my @lines = read_file($file);\n    my $line_num = 0;\n    foreach (@lines) {\n        ++$line_num;\n        next if /^\\s*#/ or /^\\s*$/;\n\n        $_ = lc $_ if $ON_WINDOWS and /^\\s+(filename|extension)\\s/;\n\n        if (/^(\\.?\\w+.*?)\\s*$/) {\n            $language = $1;\n            $already_know_it = defined $rh_Scale_Factor->{$language};\n            next;\n        }\n        die \"Missing computer language name, line $line_num of $file\\n\"\n            unless $language;\n\n        if      (/^\\s{4}filter\\s+(remove_between_(general|2re|regex))\n                       \\s+(\\S+)\\s+(\\S+)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                   \\s+(\\S+)\\s+(\\S+)\\s+(\\S+|\\\".*\\\")\\s+(\\S+)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 , $5]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                       \\s+(\\S+)\\s+(\\S+)\\s+(.*?)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\n                       \\s+(\\S+)\\s+(.+?)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s*$/) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s+(.*?)\\s*$/) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]\n\n        } elsif (/^\\s{4}extension\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            if (defined $rh_Language_by_Extension->{$1}) {\n                die \"File extension collision:  $1 \",\n                    \"maps to languages '$rh_Language_by_Extension->{$1}' \",\n                    \"and '$language'\\n\" ,\n                    \"Edit $file and remove $1 from one of these two \",\n                    \"language definitions.\\n\";\n            }\n            $rh_Language_by_Extension->{$1} = $language;\n\n        } elsif (/^\\s{4}filename\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Language_by_File_Type->{$1} = $language;\n\n        } elsif (/^\\s{4}script_exe\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Language_by_Script->{$1} = $language;\n\n        } elsif (/^\\s{4}3rd_gen_scale\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Scale_Factor->{$language} = $1;\n\n        } elsif (/^\\s{4}end_of_line_continuation\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_EOL_Continuation_re->{$language} = $1;\n\n        } else {\n            die \"Unexpected data line $line_num of $file:\\n$_\\n\";\n        }\n\n    }\n    print \"<- merge_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub print_extension_info {                   # {{{1\n    my ($extension,) = @_;\n    printf \"%-15s %s\\n\", \"Extension\", \"Language\";\n    printf \"%-15s %s\\n\", \"---------\", \"-\" x 20;\n    if ($extension) {  # show information on this extension\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            next if $Language_by_Extension{$ext} =~ /Brain/;\n            printf \"%-15s %s\\n\", $ext, $Language_by_Extension{$ext}\n                if $ext =~ m{$extension}i;\n        }\n    } else {           # show information on all  extensions\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            next if $Language_by_Extension{$ext} =~ /Brain/;\n            # Language_by_Extension{f}    = 'Fortran 77'\n            printf \"%-15s %s\\n\", $ext, $Language_by_Extension{$ext};\n        }\n    }\n} # 1}}}\nsub print_language_info {                    # {{{1\n    my ($language,\n        $prefix ,) = @_;\n    my %extensions = (); # the subset matched by the given $language value\n    if ($language) {  # show information on this language\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            push @{$extensions{$Language_by_Extension{$ext}} }, $ext\n                if lc $Language_by_Extension{$ext} eq lc $language;\n#               if $Language_by_Extension{$ext} =~ m{$language}i;\n        }\n    } else {          # show information on all  languages\n        foreach my $ext (sort {lc $a cmp lc $b  or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            push @{$extensions{$Language_by_Extension{$ext}} }, $ext\n        }\n    }\n\n    # add exceptions (one file extension mapping to multiple languages)\n    if (!$language or $language =~ /^(Objective-C|MATLAB|Mathematica|MUMPS|Mercury)$/i) {\n        push @{$extensions{'Objective-C'}}, \"m\";\n        push @{$extensions{'MATLAB'}}     , \"m\";\n        push @{$extensions{'Mathematica'}}, \"m\";\n        push @{$extensions{'MUMPS'}}      , \"m\";\n        delete $extensions{'MATLAB/Mathematica/Objective-C/MUMPS/Mercury'};\n    }\n    if (!$language or $language =~ /^(Lisp|OpenCL)$/i) {\n        push @{$extensions{'Lisp'}}  , \"cl\";\n        push @{$extensions{'OpenCL'}}, \"cl\";\n        delete $extensions{'Lisp/OpenCL'};\n    }\n    if (!$language or $language =~ /^(Lisp|Julia)$/i) {\n        push @{$extensions{'Lisp'}}  , \"jl\";\n        push @{$extensions{'Julia'}} , \"jl\";\n        delete $extensions{'Lisp/Julia'};\n    }\n    if (!$language or $language =~ /^(Perl|Prolog)$/i) {\n        push @{$extensions{'Perl'}}  , \"pl\";\n        push @{$extensions{'Prolog'}}, \"pl\";\n        delete $extensions{'Perl/Prolog'};\n    }\n    if (!$language or $language =~ /^(Raku|Prolog)$/i) {\n        push @{$extensions{'Perl'}}  , \"p6\";\n        push @{$extensions{'Prolog'}}, \"p6\";\n        delete $extensions{'Perl/Prolog'};\n    }\n    if (!$language or $language =~ /^(IDL|Qt Project|Prolog|ProGuard)$/i) {\n        push @{$extensions{'IDL'}}       , \"pro\";\n        push @{$extensions{'Qt Project'}}, \"pro\";\n        push @{$extensions{'Prolog'}}    , \"pro\";\n        push @{$extensions{'ProGuard'}}  , \"pro\";\n        delete $extensions{'IDL/Qt Project/Prolog/ProGuard'};\n    }\n    if (!$language or $language =~ /^(D|dtrace)$/i) {\n        push @{$extensions{'D'}}       , \"d\";\n        push @{$extensions{'dtrace'}}  , \"d\";\n        delete $extensions{'D/dtrace'};\n    }\n    if (!$language or $language =~ /^Forth$/) {\n        push @{$extensions{'Forth'}}     , \"fs\";\n        push @{$extensions{'Forth'}}     , \"f\";\n        push @{$extensions{'Forth'}}     , \"for\";\n        delete $extensions{'Fortran 77/Forth'};\n        delete $extensions{'F#/Forth'};\n    }\n    if (!$language or $language =~ /^Fortran 77$/) {\n        push @{$extensions{'Fortran 77'}}, \"f\";\n        push @{$extensions{'Fortran 77'}}, \"for\";\n        push @{$extensions{'F#'}}        , \"fs\";\n        delete $extensions{'Fortran 77/Forth'};\n    }\n    if (!$language or $language =~ /^F#$/) {\n        push @{$extensions{'F#'}}        , \"fs\";\n        delete $extensions{'F#/Forth'};\n    }\n    if (!$language or $language =~ /^(Verilog-SystemVerilog|Coq)$/) {\n        push @{$extensions{'Coq'}}                   , \"v\";\n        push @{$extensions{'Verilog-SystemVerilog'}} , \"v\";\n        delete $extensions{'Verilog-SystemVerilog/Coq'};\n    }\n    if (!$language or $language =~ /^(TypeScript|Qt Linguist)$/) {\n        push @{$extensions{'TypeScript'}}  , \"ts\";\n        push @{$extensions{'Qt Linguist'}} , \"ts\";\n        delete $extensions{'TypeScript/Qt Linguist'};\n    }\n    if (!$language or $language =~ /^(Qt|Glade)$/) {\n        push @{$extensions{'Glade'}}       , \"ui\";\n        push @{$extensions{'XML-Qt-GTK'}}  , \"ui\";\n        delete $extensions{'XML-Qt-GTK/Glade'};\n    }\n    if (!$language or $language =~ /^(C#|Smalltalk)$/) {\n        push @{$extensions{'C#'}}           , \"cs\";\n        push @{$extensions{'Smalltalk'}}    , \"cs\";\n        delete $extensions{'C#/Smalltalk'};\n    }\n    if (!$language or $language =~ /^(Visual\\s+Basic|TeX|Apex\\s+Class)$/i) {\n        push @{$extensions{'Visual Basic'}} , \"cls\";\n        push @{$extensions{'TeX'}}          , \"cls\";\n        push @{$extensions{'Apex Class'}}   , \"cls\";\n        delete $extensions{'Visual Basic/TeX/Apex Class'};\n    }\n    if (!$language or $language =~ /^(Ant)$/i) {\n        push @{$extensions{'Ant'}}  , \"build.xml\";\n        delete $extensions{'Ant/XML'};\n    }\n    if (!$language or $language =~ /^(Scheme|SaltStack)$/i) {\n        push @{$extensions{'Scheme'}}    , \"sls\";\n        push @{$extensions{'SaltStack'}} , \"sls\";\n        delete $extensions{'Scheme/SaltStack'};\n    }\n    if (!$language or $language =~ /^(Clojure|Cangjie)$/i) {\n        push @{$extensions{'Clojure'}} , \"cj\";\n        push @{$extensions{'Cangjie'}} , \"cj\";\n        delete $extensions{'Clojure/Cangjie'};\n    }\n    printf \"%-26s %s\\n\", \"Language\", \"Extension(s)\";\n    printf \"%-26s %s\\n\", \"-\" x 20, \"-\" x 40;\n    if ($opt_explain) {\n        return unless $extensions{$language};\n        if ($prefix) {\n            printf \"%s %s\\n\", $prefix, join(\", \", @{$extensions{$language}});\n        } else {\n            printf \"%-26s (%s)\\n\", $language, join(\", \", @{$extensions{$language}});\n        }\n    } else {\n        if (%extensions) {\n            foreach my $lang (sort {lc $a cmp lc $b } keys %extensions) {\n                next if $lang =~ /Brain/;\n                if ($prefix) {\n                    printf \"%s %s\\n\", $prefix, join(\", \", @{$extensions{$lang}});\n                } else {\n                    printf \"%-26s (%s)\\n\", $lang, join(\", \", @{$extensions{$lang}});\n                }\n            }\n        }\n    }\n} # 1}}}\nsub print_language_filters {                 # {{{1\n    my ($language,) = @_;\n    if (!$Filters_by_Language{$language} or\n        !@{$Filters_by_Language{$language}}) {\n        warn \"Unknown language: $language\\n\";\n        warn \"Use --show-lang to list all defined languages.\\n\";\n        return;\n    }\n    printf \"%s\\n\", $language;\n    foreach my $filter (@{$Filters_by_Language{$language}}) {\n        printf \"    filter %s\", $filter->[0];\n        printf \"  %s\", $filter->[1] if defined $filter->[1];\n        printf \"  %s\", $filter->[2] if defined $filter->[2];\n        printf \"  %s\", $filter->[3] if defined $filter->[3];\n        printf \"  %s\", $filter->[4] if defined $filter->[4];\n        print  \"\\n\";\n    }\n    print_language_info($language, \"    extensions:\");\n} # 1}}}\nsub top_level_SMB_dir {                      # {{{1\n    # Ref https://github.com/AlDanial/cloc/issues/392, if the\n    # user supplies a directory name which is an SMB mount\n    # point, this directory will appear to File::Find as\n    # though it is empty unless $File::Find::dont_use_nlink\n    # is set to 1.  This subroutine checks to see if any SMB\n    # mounts (identified from stat()'s fourth entry, nlink,\n    # having a value of 2) were passed in on the command line.\n\n    my ($ra_arg_list,) = @_;  # in user supplied file name, directory name, git hash, etc\n    foreach my $entry (@{$ra_arg_list}) {\n        next unless is_dir($entry);\n        # gets here if $entry is a directory; now get its nlink value\n        my $nlink;\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            my $stats = statL($entry);\n            $nlink = $stats->{nlink} if defined $stats;\n        } else {\n            my @stats = stat($entry);\n            $nlink = $stats[3];\n        }\n        return 1 if $nlink == 2;  # meaning it is an SMB mount\n    }\n    return 0;\n}\n# 1}}}\nsub get_git_metadata {                       # {{{1\n    my ($ra_arg_list,             # in  file name, directory name and/or\n                                  #     git commit hash to examine\n        $rh_git_metadata) = @_;   # out repo info\n    # Capture git information where possible--origin, branch, commit hash.\n    my $prt_args = join(\",\", @{$ra_arg_list});\n    print \"-> get_git_metadata($prt_args)\\n\" if $opt_v > 2;\n    foreach my $arg (@{$ra_arg_list}) {\n        next if is_file($arg);\n        my $origin = `git -c \\\"safe.directory=*\\\" remote get-url origin 2>&1`;\n        next if $origin =~ /^fatal:/;\n        chomp($rh_git_metadata->{$arg}{\"origin\"} = $origin);\n        chomp($rh_git_metadata->{$arg}{\"branch\"} = `git -c \\\"safe.directory=*\\\" symbolic-ref --short HEAD`);\n        if (is_dir($arg)) {\n            chomp($rh_git_metadata->{$arg}{\"commit\"}   = `git -c \\\"safe.directory=*\\\" rev-parse HEAD`);\n        } else {\n            chomp($rh_git_metadata->{$arg}{\"commit\"}   = `git -c \\\"safe.directory=*\\\" rev-parse $arg`);\n        }\n    }\n    print \"<- get_git_metadata()\\n\" if $opt_v > 2;\n} # 1}}}\nsub replace_git_hash_with_tarfile {          # {{{1\n    my ($ra_arg_list,             # in  file name, directory name and/or\n                                  #     git commit hash to examine\n        $ra_git_similarity) = @_; # out only if --opt-git-diff-simindex\n    # replace git hashes in $ra_arg_list with tar files\n    # Diff mode and count mode behave differently:\n    #   Diff:\n    #       file  git_hash\n    #          Extract file from the git repo and only compare to it.\n    #       git_hash1  git_hash2\n    #          Get listings of all files in git_hash1 and git_hash2.\n    #            git ls-tree --name-only -r *git_hash1*\n    #            git ls-tree --name-only -r *git_hash2*\n    #          Next, get listings of files that changed with git_hash1\n    #          and git_hash2.\n    #            git diff-tree -r --no-commit-id --name-only *git_hash1* *git_hash2*\n    #          Finally, make two tar files of git repos1 and 2 where the file\n    #          listing is the union of changes.\n    #            git archive -o tarfile1 *git_hash1* \\\n    #               <union of files that changed and exist in this commit>\n    #            git archive -o tarfile2 *git_hash2* \\\n    #               <union of files that changed and exist in this commit>\n    #          To avoid \"Argument list too long\" error, repeat the git\n    #          archive step with chunks of 30,000 files at a time then\n    #          merge the tar files as the final step.\n    #   Regular count:\n    #       Simply make a tar file of all files in the git repo.\n\n    my $prt_args = join(\",\", @{$ra_arg_list});\n    print \"-> replace_git_hash_with_tarfile($prt_args)\\n\" if $opt_v > 2;\n#print \"ra_arg_list 1: @{$ra_arg_list}\\n\";\n\n    my $hash_regex = qr/^([a-f\\d]{5,40}|master|HEAD)(~\\d+)?$/;\n    my %replacement_arg_list = ();\n\n    # early exit if none of the inputs look like git hashes\n    my %git_hash = ();\n    my $i = 0;\n    foreach my $file_or_dir (@{$ra_arg_list}) {\n        ++$i;\n        if (can_read($file_or_dir)) { # readable file or dir; not a git hash\n            $replacement_arg_list{$i} = $file_or_dir;\n            next;\n        } elsif ($opt_force_git or $file_or_dir =~ m/$hash_regex/) {\n            $git_hash{$file_or_dir} = $i;\n        } # else the input can't be understood; ignore for now\n    }\n    return unless %git_hash;\n\n#   my $have_tar_git = external_utility_exists($ON_WINDOWS ? \"unzip\" : \"tar --version\") &&\n    my $have_tar_git = external_utility_exists(\"tar --version\") &&\n                       external_utility_exists(\"git --version\");\n    if (!$have_tar_git) {\n        warn \"One or more inputs looks like a git hash but \" .\n             \"either git or tar is unavailable.\\n\";\n        return;\n    }\n\n    my %repo_listing = ();  # $repo_listing{hash}{files} = 1;\n    foreach my $hash (sort keys %git_hash) {\n        my $git_list_cmd = \"git -c \\\"safe.directory=*\\\" ls-tree --name-only -r \";\n        if ($hash =~ m/(.*?):(.*?)$/) {\n            # requesting specific file(s) from this hash; grep for them\n            # Note:  this capability not fully implemented yet\n            $git_list_cmd .= \"$1|grep '$2'\";\n        } else {\n            $git_list_cmd .= $hash;\n        }\n        print \"$git_list_cmd\\n\" if $opt_v;\n        foreach my $file (`$git_list_cmd`) {\n            $file =~ s/\\s+$//;\n            $repo_listing{$hash}{$file} = 1;\n        }\n    }\n\n    # logic for each of the modes\n    if ($opt_diff) {\n#print \"A DIFF\\n\";\n        # set the default git diff algorithm\n        $opt_git_diff_rel = 1 unless $opt_git_diff_all or\n                                     $opt_git_diff_simindex;\n        # is it git to git, or git to file/dir ?\n        my ($Left, $Right) = @{$ra_arg_list};\n\n#use Data::Dumper;\n#print \"diff_listing= \"; print Dumper(\\%diff_listing);\n#print \"git_hash= \"; print Dumper(\\%git_hash);\n        if ($git_hash{$Left} and $git_hash{$Right}) {\n#print \"A DIFF git-to-git\\n\";\n            # git to git\n            # first make a union of all files that have changed in both commits\n            my %files_union = ();\n\n            my @left_files  = ();\n            my @right_files = ();\n            if ($opt_git_diff_rel) {\n                # Strategy 1:  Union files are what git considers have changed\n                #              between the two commits.\n                my $git_list_cmd = \"git -c \\\"safe.directory=*\\\" diff-tree -r --no-commit-id --name-only $Left $Right\";\n                # print \"$git_list_cmd\\n\" if $opt_v;\n                foreach my $file (`$git_list_cmd`) {\n                    chomp($file);\n                    $files_union{$file} = 1;\n                }\n            } elsif ($opt_git_diff_all) {\n                # Strategy 2:  Union files all files in both repos.\n                foreach my $file (keys %{$repo_listing{$Left }},\n                                  keys %{$repo_listing{$Right}}) {\n                   $files_union{$file} = 1;\n                }\n            } elsif ($opt_git_diff_simindex) {\n                # Strategy 3:  Use git's own similarity index to figure\n                #              out which files to compare.\n                git_similarity_index($Left              , # in\n                                     $Right             , # in\n                                    \\@left_files        , # out\n                                    \\@right_files       , # out\n                                     $ra_git_similarity); # out\n\n            }\n\n            if ($opt_exclude_list_file) {\n                my @reject_list = read_list_file($opt_exclude_list_file);\n                my %entries_to_drop = ();\n                foreach my $f_or_d (@reject_list) {\n                    if (-d $f_or_d) {\n                        # directory match\n                        $entries_to_drop{$f_or_d} = 1;\n                        foreach my $file (keys %files_union) {\n                            $entries_to_drop{$file} = 1 if $file =~ m{$f_or_d/};\n                        }\n                    } else {\n                        # exact match\n                        $entries_to_drop{$f_or_d} = 1;\n                    }\n                }\n                foreach my $file (keys %entries_to_drop) {\n                    delete $files_union{$file};\n                }\n            }\n\n            if ($opt_list_file) {\n                my @include_list = read_list_file($opt_list_file);\n                my %entries_to_add  = ();\n                foreach my $f_or_d (@include_list) {\n                    if (-d $f_or_d) {\n                        # directory match\n                        $entries_to_add{$f_or_d} = 1;\n                        foreach my $file (keys %files_union) {\n                            $entries_to_add{$file} = 1 if $file =~ m{$f_or_d/};\n                        }\n                    } else {\n                        # exact match\n                        $entries_to_add{$f_or_d} = 1;\n                    }\n                }\n                %files_union = %entries_to_add; # and exclude all others\n            }\n\n            # then make truncated tar files of those union files which\n            # actually exist in each repo\n            foreach my $file (sort keys %files_union) {\n                push @left_files , $file if $repo_listing{$Left }{$file};\n                push @right_files, $file if $repo_listing{$Right}{$file};\n            }\n            # backslash whitespace, weird chars within file names (#257, #284)\n\n#           my @Lfiles= map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\$\\?])/\\\\$1/g; $_}   @left_files;\n#           my @Lfiles= @left_files;\n            if(scalar(@left_files) > 0) {\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left , \\@left_files);\n            } else {\n                # In the right side commit ONLY file(s) was added, so no file(s) will exist in the left side commit.\n                # Create empty TAR to detect added lines of code.\n                $replacement_arg_list{$git_hash{$Left}} = empty_tar();\n            }\n#           $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left , \\@Lfiles);\n#           my @Rfiles= map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\$\\?])/\\\\$1/g; $_}   @right_files ;\n#           my @Rfiles= @right_files ;\n#use Data::Dumper;\n#print Dumper('left' , \\@left_files);\n#print Dumper('right', \\@right_files);\n#die;\n\n            if(scalar(@right_files) > 0) {\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \\@right_files);\n            } else {\n                 # In the left side commit ONLY file(s) was deleted, so file(s) will not exist in right side commit.\n                 # Create empty TAR to detect removed lines of code.\n                 $replacement_arg_list{$git_hash{$Right}} = empty_tar();\n            }\n#           $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \\@Rfiles);\n#write_file(\"/tmp/Lfiles.txt\", {}, sort @Lfiles);\n#write_file(\"/tmp/Rfiles.txt\", {}, sort @Rfiles);\n#write_file(\"/tmp/files_union.txt\", {}, sort keys %files_union);\n\n        } else {\n#print \"A DIFF git-to-file or file-to-git Left=$Left Right=$Right\\n\";\n            # git to file/dir or file/dir to git\n            if      ($git_hash{$Left}  and $repo_listing{$Left}{$Right} ) {\n#print \"A DIFF 1\\n\";\n                # $Left is a git hash and $Right is a file\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left, $Right);\n            } elsif ($git_hash{$Right} and $repo_listing{$Right}{$Left}) {\n#print \"A DIFF 2\\n\";\n                # $Left is a file and $Right is a git hash\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, $Left);\n            } elsif ($git_hash{$Left}) {\n#print \"A DIFF 3\\n\";\n                # assume Right is a directory; tar the entire git archive at this hash\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left, \"\");\n            } else {\n#print \"A DIFF 4\\n\";\n                # assume Left  is a directory; tar the entire git archive at this hash\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \"\");\n            }\n        }\n    } else {\n#print \"B COUNT\\n\";\n        foreach my $hash (sort keys %git_hash) {\n            $replacement_arg_list{$git_hash{$hash}} = git_archive($hash);\n        }\n    }\n# print \"git_hash= \"; print Dumper(\\%git_hash);\n#print \"repo_listing= \"; print Dumper(\\%repo_listing);\n\n    # replace the input arg list with the new one\n    @{$ra_arg_list} = ();\n    foreach my $index (sort {$a <=> $b} keys %replacement_arg_list) {\n        push @{$ra_arg_list}, $replacement_arg_list{$index};\n    }\n\n#print \"ra_arg_list 2: @{$ra_arg_list}\\n\";\n    print \"<- replace_git_hash_with_tarfile()\\n\" if $opt_v > 2;\n} # 1}}}\nsub git_similarity_index {                   # {{{\n    my ($git_hash_Left    ,       # in\n        $git_hash_Right   ,       # in\n        $ra_left_files    ,       # out\n        $ra_right_files   ,       # out\n        $ra_git_similarity) = @_; # out\n    die \"this option is not yet implemented\";\n    print \"-> git_similarity_index($git_hash_Left, $git_hash_Right)\\n\" if $opt_v > 2;\n    my $cmd = \"git -c \\\"safe.directory=*\\\" diff -M --name-status $git_hash_Left $git_hash_Right\";\n    print  $cmd, \"\\n\" if $opt_v;\n    open(GSIM, \"$cmd |\") or die \"Unable to run $cmd  $!\";\n    while (<GSIM>) {\n        print \"git similarity> $_\";\n    }\n    close(GSIM);\n    print \"<- git_similarity_index\\n\" if $opt_v > 2;\n} # 1}}}\nsub empty_tar {                              # {{{1\n    my ($Tarfh, $Tarfile);\n    if ($opt_sdir) {\n      File::Path::mkpath($opt_sdir) unless is_dir($opt_sdir);\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, DIR => $opt_sdir, SUFFIX => $ON_WINDOWS ? '.zip' : '.tar');  # delete on exit\n    } else {\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, SUFFIX => $ON_WINDOWS ? '.zip' : '.tar');  # delete on exit\n    }\n    my $cmd = $ON_WINDOWS ? \"type nul > $Tarfile\" : \"tar -cf $Tarfile -T /dev/null\";\n    print  $cmd, \"\\n\" if $opt_v;\n    system $cmd;\n    if (!can_read($Tarfile)) {\n        # not readable\n        die \"Failed to create empty tarfile.\";\n    }\n\n    return $Tarfile;\n} # 1}}}\nsub git_archive {                            # {{{1\n    # Invoke 'git archive' as a system command to create a tar file\n    # using the given argument(s).\n    my ($A1, $A2) = @_;\n    print \"-> git_archive($A1)\\n\" if $opt_v > 2;\n\n    my $args = undef;\n    my @File_Set = ( );\n    my $n_sets   = 1;\n    if (ref $A2 eq 'ARRAY') {\n        # Avoid \"Argument list too long\" for the git archive command\n        # by splitting the inputs into sets of 10,000 files (issue 273).\n        my $FILES_PER_ARCHIVE = 1_000;\n           $FILES_PER_ARCHIVE =   100 if $ON_WINDOWS; # github.com/AlDanial/cloc/issues/404\n\n        my $n_files  = scalar(@{$A2});\n        $n_sets = $n_files/$FILES_PER_ARCHIVE;\n        $n_sets = 1 + int($n_sets) if $n_sets > int($n_sets);\n        $n_sets = 1 if !$n_sets;\n        foreach my $i (0..$n_sets-1) {\n            @{$File_Set[$i]} = ( );\n            my $start = $i*$FILES_PER_ARCHIVE;\n            my $end   = smaller(($i+1)*$FILES_PER_ARCHIVE, $n_files) - 1;\n            # Wrap each file name in single quotes to protect spaces\n            # and other odd characters.  File names that themselves have\n            # single quotes are instead wrapped in double quotes.  File\n            # names with both single and double quotes... jeez.\n            foreach my $fname (@{$A2}[$start .. $end]) {\n                if      ($fname =~ /^\".*?\\\\\".*?\"$/) {\n                    # git pre-handles filenames with double quotes by backslashing\n                    # each double quote then surrounding entire name in double\n                    # quotes; undo this otherwise archive command crashes\n                    $fname =~ s/\\\\\"/\"/g;\n                    $fname =~ s/^\"(.*)\"$/$1/;\n                } elsif ($fname =~ /'/ or $ON_WINDOWS) {\n                    push @{$File_Set[$i]}, \"\\\"$fname\\\"\";\n                } else {\n                    push @{$File_Set[$i]}, \"'$fname'\";\n                }\n            }\n            unshift @{$File_Set[$i]}, \"$A1 \";  # prepend git hash to beginning of list\n\n##xx#        # don't include \\$ in the regex because git handles these correctly\n#            # to each word in @{$A2}[$start .. $end]: first backslash each\n#            # single quote, then wrap all entries in single quotes (#320)\n#            push @File_Set,\n#                 \"$A1 \" . join(\" \", map {$_ =~ s/'/\\'/g; $_ =~ s/^(.*)$/'$1'/g; $_}\n##                \"$A1 \" . join(\" \", map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\?])/\\\\$1/g; $_}\n#                              @{$A2}[$start .. $end]);\n        }\n    } else {\n        if (defined $A2) {\n            push @{$File_Set[0]}, \"$A1 $A2\";\n        } else {\n            push @{$File_Set[0]}, \"$A1\";\n        }\n    }\n\n    my $files_this_commit = join(\" \", @{$File_Set[0]});\n    print \"   git_archive(file_set[0]=$files_this_commit)\\n\" if $opt_v > 2;\n    my ($Tarfh, $Tarfile);\n    my $archive_ext = $ON_WINDOWS ? '.zip'         : '.tar';\n    my $format      = $ON_WINDOWS ? '--format=zip' : \"\";\n    if ($opt_sdir) {\n      File::Path::mkpath($opt_sdir) unless is_dir($opt_sdir);\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, DIR => $opt_sdir, SUFFIX => $archive_ext);  # delete on exit\n    } else {\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, SUFFIX => $archive_ext);  # delete on exit\n    }\n    my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o $Tarfile $files_this_commit\";\n    print  $cmd, \"\\n\" if $opt_v;\n    system $cmd;\n    if (!can_read($Tarfile) or !get_size($Tarfile)) {\n        # not readable, or zero sized\n        die \"Failed to create tarfile of files from git.\";\n    }\n    if ($n_sets > 1) {\n        if ($ON_WINDOWS) {\n            my @tar_files = ( $Tarfile );\n            my $start_dir = cwd;\n            foreach my $i (1..$n_sets-1) {\n                my $fname = sprintf \"%s_extra_%08d\", $Tarfile, $i;\n                my $files_this_commit = join(\" \", @{$File_Set[$i]});\n                my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o $fname $files_this_commit\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                push @tar_files, $fname;\n            }\n            # Windows tar can't combine tar files so expand\n            # them all to one directory then re-tar\n            my $extract_dir = tempdir( CLEANUP => 0 );  # 1 = delete on exit\n            chdir \"$extract_dir\";\n            foreach my $T (@tar_files) {\n                next unless is_file($T) and get_size($T);\n                my $cmd = \"tar -x -f \\\"$T\\\"\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                unlink \"$T\";\n            }\n            chdir \"..\";\n            $Tarfile .= \".final.tar\";\n            my $cmd = \"tar -c -f \\\"${Tarfile}\\\" \\\"$extract_dir\\\"\";\n            print  $cmd, \"\\n\" if $opt_v;\n            system $cmd;\n            chdir \"$start_dir\";\n        } else {\n            foreach my $i (1..$n_sets-1) {\n                my $files_this_commit = join(\" \", @{$File_Set[$i]});\n                my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o ${Tarfile}_extra $files_this_commit\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                # and merge into the first one\n                $cmd = \"tar -A -f ${Tarfile} ${Tarfile}_extra\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n            }\n            unlink \"${Tarfile}_extra\";\n        }\n    }\n    print \"<- git_archive() made $Tarfile\\n\" if $opt_v > 2;\n    return $Tarfile\n} # 1}}}\nsub smaller {                                # {{{1\n    my( $a, $b ) = @_;\n    return $a < $b ? $a : $b;\n} # 1}}}\nsub lower_on_Windows {                       # {{{1\n    # If on Unix(-like), do nothing, just return the input.\n    # If on Windows, return a lowercase version of the file\n    # and also update %upper_lower_map with this new entry.\n    # Needed in make_file_list() because the full file list\n    # isn't known until the end of that routine--where\n    # %upper_lower_map is ordinarily populated.\n    my ($path,) = @_;\n    return $path unless $ON_WINDOWS;\n    my $lower = lc $path;\n    $upper_lower_map{$lower} = $path;\n    return $lower;\n}\n# }}}\nsub make_file_list {                         # {{{1\n    my ($ra_arg_list,  # in   file and/or directory names to examine\n        $iteration  ,  # in   0 if only called once, 1 or 2 if twice for diff\n        $rh_Err     ,  # in   hash of error codes\n        $raa_errors ,  # out  errors encountered\n        $rh_ignored ,  # out  files not recognized as computer languages\n        ) = @_;\n    print \"-> make_file_list(@{$ra_arg_list})\\n\" if $opt_v > 2;\n\n    my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n    my ($fh, $filename);\n    if ($opt_categorized) {\n        if ($iteration) {\n            # am being called twice for diff of Left and Right\n            my $ext = $iteration == 1 ? \"L\" : \"R\";\n            $filename = $opt_categorized . \"-$ext\";\n        } else {\n            $filename = $opt_categorized;\n        }\n        $fh = open_file('+>', $filename, 1);  # open for read/write\n        die \"Unable to write to $filename:  $!\\n\" unless defined $fh;\n    } elsif ($opt_sdir) {\n        # write to the user-defined scratch directory\n        ++$TEMP_OFF;\n        my $scr_dir = \"$opt_sdir/$TEMP_OFF\";\n        File::Path::mkpath($scr_dir) unless is_dir($scr_dir);\n        $filename = $scr_dir . '/cloc_file_list.txt';\n        $fh = open_file('+>', $filename, 1);  # open for read/write\n        die \"Unable to write to $filename:  $!\\n\" unless defined $fh;\n    } else {\n        # let File::Temp create a suitable temporary file\n        ($fh, $filename) = tempfile(UNLINK => 1);  # delete file on exit\n        print \"Using temp file list [$filename]\\n\" if $opt_v;\n    }\n\n    my @dir_list = ();\n    foreach my $file_or_dir (@{$ra_arg_list}) {\n        my $size_in_bytes = 0;\n        my $F = lower_on_Windows($file_or_dir);\n        my $ul_F = $ON_WINDOWS ? $upper_lower_map{$F} : $F;\n        if (!can_read($file_or_dir)) {\n            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];\n            next;\n        }\n        if (is_file($file_or_dir)) {\n            if (!get_size($file_or_dir)) {   # 0 sized file, named pipe, socket\n                $rh_ignored->{$F} = 'zero sized file';\n                next;\n            } elsif (is_binary($file_or_dir) and !$opt_read_binary_files) {\n                # avoid binary files unless user insists on reading them\n                if ($opt_unicode) {\n                    # only ignore if not a Unicode file w/trivial\n                    # ASCII transliteration\n                    if (!unicode_file($file_or_dir)) {\n                        $rh_ignored->{$ul_F} = 'binary file';\n                        next;\n                    }\n                } else {\n                    $rh_ignored->{$ul_F} = 'binary file';\n                    next;\n                }\n            }\n            push @file_list, \"$file_or_dir\";\n        } elsif (is_dir($file_or_dir)) {\n            push @dir_list, $file_or_dir;\n        } elsif (-p $file_or_dir) {\n            # a pipe via process substitution, eg cloc <(cat cloc)\n            my @lines = <>;\n            $tmp_file_to_delete = \"temp_process_substitution_$$\";\n            write_file($tmp_file_to_delete, {}, @lines);\n            push @dir_list, $tmp_file_to_delete;\n        } else {\n            push @{$raa_errors}, [$rh_Err->{'Neither file nor directory'} , $F];\n            $rh_ignored->{$F} = 'not file, not directory';\n        }\n    }\n\n    # apply exclusion rules to file names passed in on the command line\n    my @new_file_list = ();\n    foreach my $File (@file_list) {\n        my ($volume, $directories, $filename) = File::Spec->splitpath( $File );\n        my $ignore_this_file = 0;\n        foreach my $Sub_Dir ( File::Spec->splitdir($directories) ) {\n            my $SD = lower_on_Windows($Sub_Dir);\n            if ($Exclude_Dir{$Sub_Dir}) {\n                $Ignored{$SD} = \"($File) --exclude-dir=$Sub_Dir\";\n                $ignore_this_file = 1;\n                last;\n            }\n        }\n        push @new_file_list, $File unless $ignore_this_file;\n    }\n    @file_list = @new_file_list;\n    foreach my $dir (@dir_list) {\n        my $D = lower_on_Windows($dir);\n#print \"make_file_list dir=$dir  Exclude_Dir{$dir}=$Exclude_Dir{$dir}\\n\";\n        # populates global variable @file_list\n        if ($Exclude_Dir{$dir}) {\n            $Ignored{$D} = \"--exclude-dir=$Exclude_Dir{$dir}\";\n            next;\n        }\n        if ($opt_no_recurse) {\n            my @candidate_file_list = ();\n            if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n                my $d = Win32::LongPath->new();\n                $d->opendirL($dir);\n                foreach my $entry ($d->readdirL()) {\n                    my $F = \"$dir/$entry\";\n                    push @candidate_file_list, $F if is_file($F);\n                }\n                $d->closedirL();\n            } else {\n                opendir(DIR, $dir);\n                push @candidate_file_list, grep(is_file(\"$dir/$_\"), readdir(DIR));\n                closedir(DIR);\n            }\n            my $start_dir = cwd();\n            foreach my $F (@candidate_file_list) {\n                # pretend to be File::Find's wanted() routine, namely subroutine files(),\n                # to apply all file filter rules\n                $File::Find::dir  = $dir;\n                $File::Find::name = basename $F;\n                $_ = basename $F;\n                chdir $dir;\n                files();  # side effect:  populates @file_list\n            }\n            chdir $start_dir;\n            # ... then prepend the directory name to each file\n            @file_list = map { \"$dir/$_\" } @file_list;\n        } else {\n            find({wanted     => \\&files            ,\n                  preprocess => \\&find_preprocessor,\n                  follow     =>  $opt_follow_links }, $dir);\n        }\n    }\n    if ($opt_follow_links) {\n        # giving { 'follow' => 1 } to find() makes it skip the\n        # call to find_preprocessor() so have to call this manually\n        @file_list = manual_find_preprocessor(@file_list);\n    }\n\n    # there's a possibility of file duplication if user provided a list\n    # file or --vcs command that returns directory names; squash these\n    my %unique_file_list = map { $_ => 1 } @file_list;\n    @file_list = sort keys %unique_file_list;\n\n    $nFiles_Found = scalar @file_list;\n    printf \"%8d text file%s.\\n\", plural_form($nFiles_Found) unless $opt_quiet;\n    write_file($opt_found, {}, sort @file_list) if $opt_found;\n\n    my $nFiles_Categorized = 0;\n\n    foreach my $file (@file_list) {\n        my $F = lower_on_Windows($file);\n        if ($ON_WINDOWS) {\n            (my $lc = lc $file) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $file;\n            $file = $lc;\n        }\n        printf \"classifying $file\\n\" if $opt_v > 2;\n\n        my $basename = basename $file;\n        if ($Not_Code_Filename{$basename}) {\n            $rh_ignored->{$F} = \"listed in \" . '$' .\n                \"Not_Code_Filename{$basename}\";\n            next;\n        } elsif ($basename =~ m{~$}) {\n            $rh_ignored->{$F} = \"temporary editor file\";\n            next;\n        }\n\n        my $size_in_bytes;\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            my $stats = statL($file);\n            $size_in_bytes = $stats->{size} if defined $stats;\n        } else {\n            $size_in_bytes = (stat $file)[7];\n        }\n        my $language      = \"\";\n        if ($All_One_Language) {\n            # user over-rode auto-language detection by using\n            # --force-lang with just a language name (no extension)\n            $language      = $All_One_Language;\n        } else {\n            $language      = classify_file($file      ,\n                                           $rh_Err    ,\n                                           $raa_errors,\n                                           $rh_ignored);\n        }\n        my $skip = 0;\n        if (!defined $size_in_bytes) {\n            $rh_ignored->{$F} = \"no longer readable\";\n            $skip = 1;\n        } elsif (!defined $language) {\n            $rh_ignored->{$F} = \"unable to associate with a language\";\n            $skip = 1;\n        } elsif ($language eq \"(unknown)\") {\n            # entry should already be in %{$rh_ignored}\n            $skip = 1;\n        }\n        next if $skip;\n        $Language_by_Filename{$F} = $language; # global\n        printf $fh \"%d%s%s%s%s\\n\", $size_in_bytes, $separator,\n                                   $language, $separator, $file;\n        ++$nFiles_Categorized;\n        #printf \"classified %d files\\n\", $nFiles_Categorized\n        #    unless (!$opt_progress_rate or\n        #            ($nFiles_Categorized % $opt_progress_rate));\n    }\n    printf \"classified %d files\\r\", $nFiles_Categorized\n        if !$opt_quiet and $nFiles_Categorized > 1;\n    print \"<- make_file_list()\\n\" if $opt_v > 2;\n\n    return $fh;   # handle to the file containing the list of files to process\n}  # 1}}}\nsub invoke_generator {                       # {{{1\n    my ($generator, $ra_user_inputs) = @_;\n    # If user provided file/directory inputs, only return\n    # generated files that are in user's request.\n    # Populates global variable %Ignored.\n    print \"-> invoke_generator($generator, @{$ra_user_inputs})\\n\" if $opt_v > 2;\n    my $start_dir = cwd();\n    my @dir_list  = ();\n    my @file_list = ();\n\n    if (!@{$ra_user_inputs}) {\n        # input must be a generator command, ie \"find -type f -name '*.c'\"\n        # issued from the cwd\n        push @dir_list, \".\";\n    }\n    foreach my $file_dir (@{$ra_user_inputs}) {\n        if (is_dir($file_dir)) {\n            push @dir_list, $file_dir;\n        } elsif (is_file($file_dir)) {\n            push @file_list, $file_dir;\n        }\n    }\n\n    my @files = ();\n    foreach my $work_dir (@dir_list) {\n        if ($work_dir ne $start_dir) {\n            chdir $work_dir or die \"Failed to chdir to $work_dir: $!\";\n        }\n        open(FH, \"$generator |\") or die \"Failed to pipe $generator: $!\";\n        while(<FH>) {\n            chomp;\n            my $F = \"$work_dir/$_\";\n            print \"VCS input:  $F\\n\" if $opt_v >= 2;\n            if (!@file_list) {\n                # no files given on the command line; accept all\n                push @files, $F;\n            } else {\n                # is this file desired?\n                my $want_this_one = 0;\n                foreach my $file (@file_list) {\n                    $file =~ s{\\\\}{/}g if $ON_WINDOWS;\n                    if (/^$file/) {\n                        $want_this_one = 1;\n                        last;\n                    }\n                }\n                push @files, $F if $want_this_one;\n            }\n        }\n        close(FH);\n        if ($work_dir ne $start_dir) {\n            chdir $start_dir or die \"Failed to chdir to $start_dir: $!\";\n        }\n    }\n\n    # apply match/not-match file/dir filters to the list so far\n    my @post_filter = ();\n    foreach my $F (@files) {\n        if ($opt_match_f) {\n            push @post_filter, $F if basename($F) =~ m{$opt_match_f};\n            next;\n        }\n        if ($opt_match_d) {\n            push @post_filter, $F if $F =~ m{$opt_match_d};\n            next;\n        }\n        if (@opt_not_match_d) {\n            my $rule;\n            if ($opt_fullpath and any_match($F, 0, \\$rule, @opt_not_match_d)) {\n                $Ignored{$F} = \"--not-match-d=$rule\";\n                next;\n            } elsif (!$opt_fullpath and any_match(basename($F), 0, \\$rule, @opt_not_match_d)) {\n                $Ignored{$F} = \"--not-match-d (basename) =$rule\";\n                next;\n            }\n        }\n        if (@opt_not_match_f) {\n            my $rule;\n            if ($opt_fullpath and any_match($F, 0, \\$rule, @opt_not_match_f)) {\n                $Ignored{$F} = \"--not-match-f=$rule\";\n                next;\n            } elsif (!$opt_fullpath and any_match(basename($F), 0, \\$rule, @opt_not_match_f)) {\n                $Ignored{$F} = \"--not-match-f (basename) =$rule\";\n                next;\n            }\n        }\n        my $nBytes = get_size($F);\n        if (!$nBytes) {\n            $Ignored{$F} = 'zero sized file';\n            printf \"files(%s)  zero size\\n\", $F if $opt_v > 5;\n        }\n        next unless $nBytes;\n        if ($nBytes > $opt_max_file_size*1024**2) {\n            $Ignored{$F} = \"file size of \" .\n                $nBytes/1024**2 . \" MB exceeds max file size of \" .\n                \"$opt_max_file_size MB\";\n            printf \"file(%s)  exceeds $opt_max_file_size MB\\n\",\n                $F if $opt_v > 5;\n            next;\n        }\n        my $is_bin = is_binary($F);\n        printf \"files(%s)  size=%d  -B=%d\\n\",\n            $F, $nBytes, $is_bin if $opt_v > 5;\n        $is_bin = 0 if $opt_unicode and unicode_file($_);\n        $is_bin = 0 if $opt_read_binary_files;\n        next if $is_bin;\n        push @post_filter, $F;\n    }\n    print \"<- invoke_generator\\n\" if $opt_v > 2;\n    return @post_filter;\n} # 1}}}\nsub any_match {                              # {{{1\n    my ($string, $entire, $rs_matched_pattern, @patterns) = @_;\n    print \"-> any_match($string, $entire)\\n\" if $opt_v > 2;\n    foreach my $pattern (@patterns) {\n        if ($entire) {\n            if ($string =~ m{^${pattern}$}) {\n                ${$rs_matched_pattern} = $pattern;\n                print \"<- any_match(1)\\n\" if $opt_v > 2;\n                return 1;\n            }\n        } else {\n            if ($string =~ m{$pattern}) {\n                ${$rs_matched_pattern} = $pattern;\n                print \"<- any_match(1)\\n\" if $opt_v > 2;\n                return 1;\n            }\n        }\n    }\n    print \"<- any_match(0)\\n\" if $opt_v > 2;\n    return 0;\n}\n# }}}\nsub remove_duplicate_files {                 # {{{1\n    my ($fh                   , # in\n        $rh_Language          , # out\n        $rh_unique_source_file, # out\n        $rh_Err               , # in\n        $raa_errors           , # out  errors encountered\n        $rh_ignored           , # out\n        ) = @_;\n\n    # Check for duplicate files by comparing file sizes.\n    # Where files are equally sized, compare their MD5 checksums.\n    print \"-> remove_duplicate_files\\n\" if $opt_v > 2;\n\n    my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n    my $n = 0;\n    my %files_by_size = (); # files_by_size{ # bytes } = [ list of files ]\n    seek($fh, 0, 0); # rewind to beginning of the temp file\n    while (<$fh>) {\n        ++$n;\n        my ($size_in_bytes, $language, $file) = split(/\\Q$separator\\E/, $_, 3);\n        if (!defined($size_in_bytes) or\n            !defined($language)      or\n            !defined($file)) {\n            print \"-> remove_duplicate_files skipping error line [$_]\\n\"\n                if $opt_v;\n            next;\n        }\n        chomp($file);\n        $file =~ s{\\\\}{/}g if $ON_WINDOWS;\n        $rh_Language->{$file} = $language;\n        push @{$files_by_size{$size_in_bytes}}, $file;\n        if ($opt_skip_uniqueness) {\n            $rh_unique_source_file->{$file} = 1;\n        }\n    }\n    return if $opt_skip_uniqueness;\n    if ($opt_progress_rate and ($n > $opt_progress_rate)) {\n        printf \"Duplicate file check %d files (%d known unique)\\r\",\n            $n, scalar keys %files_by_size;\n    }\n    $n = 0;\n    foreach my $bytes (sort {$a <=> $b} keys %files_by_size) {\n        ++$n;\n        printf \"Unique: %8d files                                          \\r\",\n            $n unless (!$opt_progress_rate or ($n % $opt_progress_rate));\n        if (scalar @{$files_by_size{$bytes}} == 1) {\n            # only one file is this big; must be unique\n            $rh_unique_source_file->{$files_by_size{$bytes}[0]} = 1;\n            next;\n        } else {\n#print \"equally sized files: \",join(\", \", @{$files_by_size{$bytes}}), \"\\n\";\n            # Files in the list @{$files_by_size{$bytes} all are\n            # $bytes long.  Sort the list by file basename.\n\n          # # sorting on basename causes repeatability problems\n          # # if the basename is not unique (eg \"includeA/x.h\"\n          # # and \"includeB/x.h\".  Instead, sort on full path.\n          # # Ref bug #114.\n          # my @sorted_bn = ();\n          # my %BN = map { basename($_) => $_ } @{$files_by_size{$bytes}};\n          # foreach my $F (sort keys %BN) {\n          #     push @sorted_bn, $BN{$F};\n          # }\n\n            my @sorted_bn = sort @{$files_by_size{$bytes}};\n\n            foreach my $F (different_files(\\@sorted_bn  ,\n                                            $rh_Err     ,\n                                            $raa_errors ,\n                                            $rh_ignored ) ) {\n                $rh_unique_source_file->{$F} = 1;\n            }\n        }\n    }\n    print \"<- remove_duplicate_files\\n\" if $opt_v > 2;\n} # 1}}}\nsub manual_find_preprocessor {               # {{{1\n    # When running with --follow-links, find_preprocessor() is not\n    # called by find().  Have to do it manually.  Inputs here\n    # are only files, which differs from find_preprocessor() which\n    # gets directories too.\n    # Reads global variable %Exclude_Dir.\n    # Populates global variable %Ignored.\n    # Reject files/directories in cwd which are in the exclude list.\n    print \"-> manual_find_preprocessor(\", cwd(), \")\\n\" if $opt_v > 2;\n    my @ok = ();\n\n    foreach my $File (@_) {  # pure file or directory name, no separators\n        my $Dir = dirname($File);\n        my $got_exclude_dir = 0;\n        foreach my $d (File::Spec->splitdir( $Dir )) {\n            # tests/inputs/issues/407/level2/level/Test/level2 ->\n            # $d iterates over tests, inputs, issues, 407,\n            #                  level2, level, Test, level2\n            # check every item against %Exclude_Dir\n            if ($Exclude_Dir{$d}) {\n                $got_exclude_dir = $d;\n                last;\n            }\n        }\n        if ($got_exclude_dir) {\n            $Ignored{$File} = \"--exclude-dir=$Exclude_Dir{$got_exclude_dir}\";\n#print \"ignoring $File\\n\";\n        } else {\n            if (@opt_not_match_d) {\n                my $rule;\n                if ($opt_fullpath) {\n                    if (any_match($Dir, 1, \\$rule, @opt_not_match_d)) {\n                        $Ignored{$File} = \"--not-match-d=$rule\";\n#print \"matched fullpath\\n\"\n                    } else {\n                        push @ok, $File;\n                    }\n                } elsif (any_match(basename($Dir), 0, \\$rule, @opt_not_match_d)) {\n                    $Ignored{$File} = \"--not-match-d=$rule\";\n#print \"matched partial\\n\"\n                } else {\n                    push @ok, $File;\n                }\n            } else {\n                push @ok, $File;\n            }\n        }\n    }\n\n    print \"<- manual_find_preprocessor(@ok)\\n\" if $opt_v > 2;\n    return @ok;\n} # 1}}}\nsub find_preprocessor {                      # {{{1\n    # invoked by File::Find's find() each time it enters a new directory\n    # Reads global variable %Exclude_Dir.\n    # Populates global variable %Ignored.\n    # Reject files/directories in cwd which are in the exclude list.\n    print \"-> find_preprocessor(\", cwd(), \")\\n\" if $opt_v > 2;\n    my @ok = ();\n\n    foreach my $F_or_D (@_) {  # pure file or directory name, no separators\n        next if $F_or_D =~ /^\\.{1,2}$/;  # skip .  and  ..\n        if ($Exclude_Dir{$F_or_D}) {\n            $Ignored{$File::Find::name} = \"--exclude-dir=$Exclude_Dir{$F_or_D}\";\n        } else {\n#printf \"  F_or_D=%-20s File::Find::name=%s\\n\", $F_or_D, $File::Find::name;\n            if (@opt_not_match_d) {\n                my $rule;\n                if ($opt_fullpath) {\n                    if (any_match($File::Find::name, 0, \\$rule, @opt_not_match_d)) {\n                        $Ignored{$File::Find::name} = \"--not-match-d=$rule\";\n                    } else {\n                        push @ok, $F_or_D;\n                    }\n                } elsif (!is_dir($F_or_D) and\n                         any_match($File::Find::name, 0, \\$rule,\n                                   @opt_not_match_d)) {\n                    $Ignored{$File::Find::name} = \"--not-match-d (basename) =$rule\";\n                } else {\n                    push @ok, $F_or_D;\n                }\n            } else {\n                push @ok, $F_or_D;\n            }\n        }\n    }\n\n    print \"<- find_preprocessor(@ok)\\n\" if $opt_v > 2;\n    return @ok;\n} # 1}}}\nsub files {                                  # {{{1\n    # invoked by File::Find's find()   Populates global variable @file_list.\n    # See also find_preprocessor() which prunes undesired directories.\n\n#   my $Dir = fastcwd();         # fully qualified path -- problematic\n    my $Dir = $File::Find::dir;  # path anchored to cloc's cwd\n    my $rule;\n    if ($opt_fullpath) {\n        # look at as much of the path as is known\n        if ($opt_match_f    ) {\n            return unless $File::Find::name =~ m{$opt_match_f};\n        }\n        if (@opt_not_match_f) {\n            return if any_match($File::Find::name, 0, \\$rule, @opt_not_match_f);\n        }\n    } else {\n        # only look at the basename\n        if ($opt_match_f    ) { return unless m{$opt_match_f}; }\n        if (@opt_not_match_f) { return if     any_match($_, 0, \\$rule, @opt_not_match_f)}\n    }\n    if ($opt_match_d) {\n        return unless \"$Dir/\" =~ m{$opt_match_d} or $Dir =~ m{$opt_match_d};\n    }\n\n    my $nBytes = get_size($_);\n    if (!$nBytes and is_file($File::Find::name)) {\n        $Ignored{$File::Find::name} = 'zero sized file';\n        printf \"files(%s)  zero size\\n\", $File::Find::name if $opt_v > 5;\n    }\n    return unless $nBytes  ; # attempting other tests w/pipe or socket will hang\n    if ($nBytes > $opt_max_file_size*1024**2) {\n        $Ignored{$File::Find::name} = \"file size of \" .\n            $nBytes/1024**2 . \" MB exceeds max file size of \" .\n            \"$opt_max_file_size MB\";\n        printf \"file(%s)  exceeds $opt_max_file_size MB\\n\",\n            $File::Find::name if $opt_v > 5;\n        return;\n    }\n    my $is_dir = is_dir($_);\n    my $is_bin = is_binary($_);\n    printf \"files(%s)  size=%d is_dir=%d  -B=%d\\n\",\n        $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5;\n    $is_bin = 0 if $opt_unicode and unicode_file($_);\n    $is_bin = 0 if $opt_read_binary_files;\n    if ($is_bin and !$is_dir) {\n        $Ignored{$File::Find::name} = \"binary file\";\n        printf \"files(%s)  binary file\\n\", $File::Find::name if $opt_v > 5;\n    }\n    return if $is_dir or $is_bin;\n    ++$nFiles_Found;\n    printf \"%8d files\\r\", $nFiles_Found\n        unless (!$opt_progress_rate or ($nFiles_Found % $opt_progress_rate));\n    push @file_list, $File::Find::name;\n} # 1}}}\nsub archive_files {                          # {{{1\n    # invoked by File::Find's find()  Populates global variable @binary_archive\n    foreach my $ext (keys %Known_Binary_Archives) {\n        push @binary_archive, $File::Find::name\n            if $File::Find::name =~ m{$ext$};\n    }\n} # 1}}}\nsub open_file {                              # {{{1\n    # portable method to open a file. On Windows this uses Win32::LongPath to\n    # allow reading/writing files past the 255 char path length limit. When on\n    # other operating systems, $use_new_file can be used to specify opening a\n    # file with `new IO::File` instead of `open`. Note: `openL` doesn't support\n    # the C-like fopen modes (\"w\", \"r+\", etc.), it only supports Perl mode\n    # strings (\">\", \"+<\", etc.). So be sure to only use Perl mode strings to\n    # ensure compatibility. Additionally, openL doesn't handle pipe modes; if\n    # you need to open a pipe/STDIN/STDOUT, use the native `open` function.\n    my ($mode,         # Perl file mode; can not be C-style file mode\n        $filename,     # filename to open\n        $use_new_file, # whether to use `new IO::File` or `open` when not using Win32::LongPath\n        ) = @_;\n    my $fh = undef;\n    if (defined $opt_encoding) {\n        open($fh,\"<:encoding($opt_encoding)\", $filename) or\n            die \"Failed open('<:encoding($opt_encoding)', $filename): $!\";\n    } else {\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            openL(\\$fh, $mode, $filename);\n        } elsif ($use_new_file) {\n            return new IO::File $filename, $mode;\n        }\n        open($fh, $mode, $filename);\n    }\n    return $fh;\n} # 1}}}\nsub unlink_file {                            # {{{1\n    # portable method to unlink a file. On Windows this uses Win32::LongPath to\n    # allow unlinking files past the 255 char path length limit. Otherwise, the\n    # native `unlink` will be used.\n    my $filename = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return unlinkL($filename);\n    }\n    return unlink $filename;\n} # 1}}}\nsub is_binary {                              # {{{1\n    # portable method to test if item is a binary file. For Windows,\n    # Win32::LongPath doesn't provide a testL option for -B, but -B\n    # accepts a filehandle which does work with files opened with openL.\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        my $IN = open_file('<', $item, 0);\n        if (defined $IN) {\n            my $res = -B $IN;\n            close($IN);\n            return $res;\n        }\n        return;\n    }\n    return (-B $item);\n} # 1}}}\nsub can_read {                               # {{{1\n    # portable method to test if item can be read\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('r', $item);\n    }\n    return (-r $item);\n} # 1}}}\nsub get_size {                               # {{{1\n    # portable method to get size in bytes of a file\n    my $filename = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('s', $filename);\n    }\n    return (-s $filename);\n} # 1}}}\nsub is_file {                                # {{{1\n    # portable method to test if item is a file\n    # (-f doesn't work in ActiveState Perl on Windows)\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('f', $item);\n    }\n    return (-f $item);\n\n#     Was:\n####if ($ON_WINDOWS) {\n####    my $mode = (stat $item)[2];\n####       $mode = 0 unless $mode;\n####    if ($mode & 0100000) { return 1; }\n####    else                 { return 0; }\n####} else {\n####    return (-f $item);  # works on Unix, Linux, CygWin, z/OS\n####}\n} # 1}}}\nsub is_dir {                                 # {{{1\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('d', $item);\n    }\n    return (-d $item); # should work everywhere now (July 2017)\n\n#     Was:\n##### portable method to test if item is a directory\n##### (-d doesn't work in older versions of ActiveState Perl on Windows)\n\n####if ($ON_WINDOWS) {\n####    my $mode = (stat $item)[2];\n####       $mode = 0 unless $mode;\n####    if ($mode & 0040000) { return 1; }\n####    else                 { return 0; }\n####} else {\n####    return (-d $item);  # works on Unix, Linux, CygWin, z/OS\n####}\n} # 1}}}\nsub is_excluded {                            # {{{1\n    my ($file       , # in\n        $excluded   , # in   hash of excluded directories\n       ) = @_;\n    my($filename, $filepath, $suffix) = fileparse($file);\n    foreach my $path (sort keys %{$excluded}) {\n        return 1 if ($filepath =~ m{^\\Q$path\\E/}i);\n    }\n} # 1}}}\nsub classify_file {                          # {{{1\n    my ($full_file   , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rh_ignored  , # out\n       ) = @_;\n\n    print \"-> classify_file($full_file)\\n\" if $opt_v > 2;\n    my $language = \"(unknown)\";\n\n    if (basename($full_file) eq \"-\" && defined $opt_stdin_name) {\n       $full_file = $opt_stdin_name;\n    }\n\n    my $look_at_first_line = 0;\n    my $file = basename $full_file;\n    if ($opt_autoconf and $file =~ /\\.in$/) {\n       $file =~ s/\\.in$//;\n    }\n    return $language if $Not_Code_Filename{$file}; # (unknown)\n    return $language if $file =~ m{~$}; # a temp edit file (unknown)\n    if (defined $Language_by_File_Type{$file}) {\n        if      ($Language_by_File_Type{$file} eq \"Ant/XML\") {\n            return Ant_or_XML(  $full_file, $rh_Err, $raa_errors);\n        } elsif ($Language_by_File_Type{$file} eq \"Maven/XML\") {\n            return Maven_or_XML($full_file, $rh_Err, $raa_errors);\n        } else {\n            return $Language_by_File_Type{$file};\n        }\n    }\n\n    if ($file =~ /\\.([^\\.]+)$/) { # has an extension\n      print \"$full_file extension=[$1]\\n\" if $opt_v > 2;\n      my $extension = $1;\n         # Windows file names are case insensitive so map\n         # all extensions to lowercase there.\n         $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n      my @extension_list = ( $extension );\n      if ($file =~ /\\.([^\\.]+\\.[^\\.]+)$/) { # has a double extension\n          my $extension = $1;\n          $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n          unshift @extension_list, $extension;  # examine double ext first\n      }\n      if ($file =~ /\\.([^\\.]+\\.[^\\.]+\\.[^\\.]+)$/) { # has a triple extension\n          my $extension = $1;\n          $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n          unshift @extension_list, $extension;  # examine triple ext first\n      }\n      foreach my $extension (@extension_list) {\n        if ($Not_Code_Extension{$extension} and\n           !$Forced_Extension{$extension}) {\n           # If .1 (for example) is an extension that would ordinarily be\n           # ignored but the user has insisted this be counted with the\n           # --force-lang option, then go ahead and count it.\n            $rh_ignored->{$full_file} =\n                'listed in $Not_Code_Extension{' . $extension . '}';\n            return $language;\n        }\n        # handle extension collisions\n        if (defined $Language_by_Extension{$extension}) {\n            if ($Language_by_Extension{$extension} eq\n                'MATLAB/Mathematica/Objective-C/MUMPS/Mercury') {\n                my $lang_M_or_O = \"\";\n                matlab_or_objective_C($full_file ,\n                                      $rh_Err    ,\n                                      $raa_errors,\n                                     \\$lang_M_or_O);\n                if ($lang_M_or_O) {\n                    return $lang_M_or_O;\n                } else { # an error happened in matlab_or_objective_C()\n                    $rh_ignored->{$full_file} =\n                        'failure in matlab_or_objective_C($full_file)';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'PHP/Pascal/Fortran/Pawn/BitBake') {\n                my $lang_F_or_P_or_P_or_B = \"\";\n                php_pascal_fortran_pawn_bitbake($full_file ,\n                                        $rh_Err    ,\n                                        $raa_errors,\n                                       \\$lang_F_or_P_or_P_or_B);\n                if ($lang_F_or_P_or_P_or_B) {\n                    return $lang_F_or_P_or_P_or_B;\n                } else { # an error happened in php_pascal_fortran_pawn_bitbake()\n                    $rh_ignored->{$full_file} =\n                        'failure in php_pascal_fortran_pawn_bitbake($full_file)';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Pascal/Puppet') {\n                my $lang_Pasc_or_Pup = \"\";\n                pascal_or_puppet(     $full_file ,\n                                      $rh_Err    ,\n                                      $raa_errors,\n                                     \\$lang_Pasc_or_Pup);\n                if ($lang_Pasc_or_Pup) {\n                    return $lang_Pasc_or_Pup;\n                } else { # an error happened in pascal_or_puppet()\n                    $rh_ignored->{$full_file} =\n                        'failure in pascal_or_puppet()';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Lisp/OpenCL') {\n                return Lisp_or_OpenCL($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Lisp/Julia') {\n                return Lisp_or_Julia( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Perl/Prolog') {\n                return Perl_or_Prolog($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Raku/Prolog') {\n                return Raku_or_Prolog($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq\n                     'IDL/Qt Project/Prolog/ProGuard') {\n                return IDL_or_QtProject($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'D/dtrace') {\n                # is it D or an init.d shell script?\n                my $a_script = really_is_D($full_file, $rh_Err, $raa_errors);\n                if ($a_script) {\n                    # could be dtrace, sh, bash or anything one would\n                    # write an init.d script in\n                    if (defined $Language_by_Script{$a_script}) {\n                        return $Language_by_Script{$a_script};\n                    } else {\n                        $rh_ignored->{$full_file} =\n                            \"Unrecognized script language, '$a_script'\";\n                    }\n                } else {\n                    return 'D';\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Fortran 77/Forth') {\n                return Forth_or_Fortran($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'F#/Forth') {\n                return Forth_or_Fsharp( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Verilog-SystemVerilog/Coq') {\n                return Verilog_or_Coq( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Smarty') {\n                if ($extension ne \"tpl\") {\n                    # unambiguous -- if ends with .smarty, is Smarty\n                    return $Language_by_Extension{$extension};\n                }\n                # Smarty extension .tpl is generic; make sure the\n                # file at least roughly resembles PHP.  Alternatively,\n                # if the user forces the issue, do the count.\n                my $force_smarty = 0;\n                foreach (@opt_force_lang) {\n                    if (lc($_) eq \"smarty,tpl\") {\n                        $force_smarty = 1;\n                        last;\n                    }\n                }\n                if (really_is_smarty($full_file) or $force_smarty) {\n                    return 'Smarty';\n                } else {\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'TypeScript/Qt Linguist') {\n                return TypeScript_or_QtLinguist( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'XML-Qt-GTK/Glade') {\n                return Qt_or_Glade( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'C#/Smalltalk') {\n                my $L = Csharp_or_Smalltalk( $full_file, $rh_Err, $raa_errors);\n                if ($L eq 'C#') {\n                    my $lines = first_line($full_file, 2, $rh_Err, $raa_errors);\n                    $lines =~ s/\\n//mg;\n                    if ($lines =~ m[//\\s+<auto-generated>]) {\n                        $L = \"C# Generated\";\n                        if ($opt_no_autogen) {\n                            $rh_ignored->{$full_file} =\n                                '--no-autogen ignores this auto-generated C# file';\n                            $L = \"(unknown)\"; # forces it to be ignored\n                        }\n                    }\n                }\n                return $L;\n            } elsif ($Language_by_Extension{$extension} eq 'Scheme/SaltStack') {\n                return Scheme_or_SaltStack( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Visual Basic/TeX/Apex Class') {\n                my $lang_VB_T_A = \"\";\n                Visual_Basic_or_TeX_or_Apex($full_file ,\n                                            $rh_Err    ,\n                                            $raa_errors,\n                                           \\$lang_VB_T_A);\n                if ($lang_VB_T_A) {\n                    return $lang_VB_T_A;\n                } else { # an error happened in Visual_Basic_or_TeX_or_Apex\n                    $rh_ignored->{$full_file} =\n                        'failure in Visual_Basic_or_TeX_or_Apex()';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Pascal/Pawn') {\n                my $lang_p_or_p = \"\";\n                return Pascal_or_Pawn($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'SKILL/.NET IL') {\n                return SKILL_or_DotNetIL($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Clojure/Cangjie') {\n                return Clojure_or_Cangjie($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Brainfuck') {\n                if (really_is_bf($full_file)) {\n                    return $Language_by_Extension{$extension};\n                } else {\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Unknown/BitBake') {\n                my $lang_t_or_b = \"\";\n                return really_is_BitBake($full_file, $rh_Err, $raa_errors);\n            } else {\n                return $Language_by_Extension{$extension};\n            }\n        } else { # has an unmapped file extension\n            $look_at_first_line = 1;\n        }\n      }\n      # if all else fails look at the prefix instead of extension\n      ( my $stem = $file ) =~ s/^(.*?)\\.\\S+$/$1/;\n      if ($stem and defined($Language_by_Prefix{$stem})) {\n          return $Language_by_Prefix{$stem}\n      }\n    } elsif (defined $Language_by_File_Type{lc $file}) {\n        return $Language_by_File_Type{lc $file};\n    } elsif ($opt_lang_no_ext and\n             defined $Filters_by_Language{$opt_lang_no_ext}) {\n        return $opt_lang_no_ext;\n    } else {  # no file extension\n        $look_at_first_line = 1;\n    }\n\n    if ($look_at_first_line) {\n        # maybe it is a shell/Perl/Python/Ruby/etc script that\n        # starts with pound bang:\n        #   #!/usr/bin/perl\n        #   #!/usr/bin/env perl\n        my ($script_language, $L) = peek_at_first_line($full_file ,\n                                                       $rh_Err    ,\n                                                       $raa_errors);\n        if (!$script_language) {\n            $rh_ignored->{$full_file} = \"language unknown (#2)\";\n            # returns (unknown)\n        }\n        if (defined $Language_by_Script{$script_language}) {\n            if (defined $Filters_by_Language{\n                            $Language_by_Script{$script_language}}) {\n                $language = $Language_by_Script{$script_language};\n            } else {\n                $rh_ignored->{$full_file} =\n                    \"undefined:  Filters_by_Language{\" .\n                    $Language_by_Script{$script_language} .\n                    \"} for scripting language $script_language\";\n                # returns (unknown)\n            }\n        } else {\n            # #456:  XML files can have a variety of domain-specific file\n            #        extensions.  If the extension is unrecognized, examine\n            #        the first line of the file to see if it is XML\n            if ($L =~ /<\\?xml\\s/) {\n                $language = \"XML\";\n                delete $rh_ignored->{$full_file};\n            } else {\n                $rh_ignored->{$full_file} = \"language unknown (#3)\";\n            }\n            # returns (unknown)\n        }\n    }\n    print \"<- classify_file($full_file)=$language\\n\" if $opt_v > 2;\n    return $language;\n} # 1}}}\nsub first_line {                             # {{{1\n    # return the first $n_lines of text in the file as one string\n    my ($file        , # in\n        $n_lines     , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n    my $line = \"\";\n    print \"-> first_line($file, $n_lines)\\n\" if $opt_v > 2;\n    if (!can_read($file)) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $line;\n    }\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        print \"<- first_line($file, $n_lines)\\n\" if $opt_v > 2;\n        return $line;\n    }\n    # issue 644: Unicode files can have non-zero $n_lines\n    # but empty <$IN> contents\n    for (my $i = 0; $i < $n_lines; $i++) {\n        my $L = <$IN>;\n        last unless defined $L;\n        chomp($line .= $L);\n    }\n    $IN->close;\n    print \"<- first_line($file, $n_lines, '$line')\\n\" if $opt_v > 2;\n    return $line;\n} # 1}}}\nsub peek_at_first_line {                     # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> peek_at_first_line($file)\\n\" if $opt_v > 2;\n\n    my $script_language = \"\";\n    my $first_line = first_line($file, 1, $rh_Err, $raa_errors);\n\n    if (defined $first_line) {\n#print \"peek_at_first_line of [$file] first_line=[$first_line]\\n\";\n        if ($first_line =~ /^#\\!\\s*(\\S.*?)$/) {\n#print \"peek_at_first_line 1=[$1]\\n\";\n            my @pound_bang = split(' ', $1);\n#print \"peek_at_first_line basename 0=[\", basename($pound_bang[0]), \"]\\n\";\n            if (basename($pound_bang[0]) eq \"env\" and\n                scalar @pound_bang > 1) {\n                $script_language = $pound_bang[1];\n#print \"peek_at_first_line pound_bang A $pound_bang[1]\\n\";\n            } else {\n                $script_language = basename $pound_bang[0];\n#print \"peek_at_first_line pound_bang B $script_language\\n\";\n            }\n        }\n    }\n    print \"<- peek_at_first_line($file)\\n\" if $opt_v > 2;\n    return ($script_language, $first_line);\n} # 1}}}\nsub different_files {                        # {{{1\n    # See which of the given files are unique by computing each file's MD5\n    # sum.  Return the subset of files which are unique.\n    my ($ra_files    , # in\n        $rh_Err      , # in\n        $raa_errors  , # out\n        $rh_ignored  , # out\n       ) = @_;\n\n    print \"-> different_files(@{$ra_files})\\n\" if $opt_v > 2;\n    my %file_hash = ();  # file_hash{md5 hash} = [ file1, file2, ... ]\n    foreach my $F (@{$ra_files}) {\n        next if is_dir($F);  # needed for Windows\n        my $IN = open_file('<', $F, 1);\n        if (!defined $IN) {\n            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];\n            $rh_ignored->{$F} = 'cannot read';\n        } else {\n            if ($HAVE_Digest_MD5) {\n                binmode $IN;\n                my $MD5 = Digest::MD5->new->addfile($IN)->hexdigest;\n#print \"$F, $MD5\\n\";\n                push @{$file_hash{$MD5}}, $F;\n            } else {\n                # all files treated unique\n                push @{$file_hash{$F}}, $F;\n            }\n            $IN->close;\n        }\n    }\n\n    # Loop over file sets having identical MD5 sums.  Within\n    # each set, pick the file that most resembles known source\n    # code.\n    my @unique = ();\n    for my $md5 (sort keys %file_hash) {\n        my $i_best = 0;\n        for (my $i = 1; $i < scalar(@{$file_hash{$md5}}); $i++) {\n            my $F = $file_hash{$md5}[$i];\n            my (@nul_a, %nul_h);\n            my $language = classify_file($F, $rh_Err,\n                                        # don't save these errors; pointless\n                                        \\@nul_a, \\%nul_h);\n            $i_best = $i if $language ne \"(unknown)\";\n        }\n        # keep the best one found and identify the rest as ignored\n        for (my $i = 0; $i < scalar(@{$file_hash{$md5}}); $i++) {\n            if ($i == $i_best) {\n                push @unique, $file_hash{$md5}[$i_best];\n            } else {\n                $rh_ignored->{$file_hash{$md5}[$i]} = \"duplicate of \" .\n                    $file_hash{$md5}[$i_best];\n            }\n        }\n\n    }\n    print \"<- different_files(@unique)\\n\" if $opt_v > 2;\n    return @unique;\n} # 1}}}\nsub call_counter {                           # {{{1\n    my ($file                    , # in\n        $language                , # in\n        $rha_ignore_regex        , # in\n        $ra_Errors               , # out\n       ) = @_;\n\n    # Logic:  pass the file through the following filters:\n    #         1. remove leading lines (if --skip-leading)\n    #         2. remove blank lines\n    #         3. remove comments using each filter defined for this language\n    #            (example:  SQL has two, remove_starts_with(--) and\n    #             remove_c_comments() )\n    #         4. if ignore regex filters are defined, remove lines that\n    #            match any of them\n    #         5. compute comment lines as\n    #               total lines - blank lines - lines left over after all\n    #                   comment filters have been applied\n\n    print \"-> call_counter($file, $language)\\n\" if $opt_v > 2;\n#print \"call_counter:  \", Dumper(@routines), \"\\n\";\n\n    my @lines = ();\n    my $ascii = \"\";\n    if (is_binary($file) and $opt_unicode) {\n        # was binary so must be unicode\n\n        $/ = undef;\n        my $IN = open_file('<', $file, 1);\n        my $bin_text = <$IN>;\n        $IN->close;\n        $/ = \"\\n\";\n\n        $ascii = unicode_to_ascii( $bin_text );\n        @lines = split(\"\\n\", $ascii );\n        foreach (@lines) { $_ = \"$_\\n\"; }\n\n    } else {\n        # regular text file\n        @lines = read_file($file);\n        $ascii = join('', @lines);\n    }\n\n    # implement --perl-ignore-data here\n\n    if ($opt_skip_leading) {\n        my $strip = 1;\n        my ($N, @exts) = split(/,/, $opt_skip_leading);\n        if (@exts) {\n            # only apply if this file's extension is listed\n            my $this_file_ext = file_extension($file);\n            $strip = grep(/^${this_file_ext}$/, @exts);\n        }\n        @lines = remove_first_n($N, \\@lines) if $strip;\n    }\n\n    my @original_lines = @lines;\n    my $total_lines    = scalar @lines;\n\n    print_lines($file, \"Original file:\", \\@lines) if $opt_print_filter_stages;\n    @lines = rm_blanks(\\@lines, $language, \\%EOL_Continuation_re); # remove blank lines\n    my $blank_lines = $total_lines - scalar @lines;\n    print \"   call_counter: total_lines=$total_lines  blank_lines=\",\n        $blank_lines, \"\\n\" if $opt_v > 2;\n    print_lines($file, \"Blank lines removed:\", \\@lines)\n        if $opt_print_filter_stages;\n\n    @lines = rm_comments(\\@lines, $language, $file,\n                               \\%EOL_Continuation_re, $ra_Errors);\n\n    my $n_code_removed = 0;\n    @lines = apply_ignores(\\@lines, $language, $file, $rha_ignore_regex,\n                           \\$n_code_removed);\n    $total_lines -= $n_code_removed;\n\n    my $comment_lines = $total_lines - $blank_lines - scalar @lines;\n    if ($opt_strip_comments) {\n        my $stripped_file = \"\";\n        if ($opt_original_dir) {\n            $stripped_file =          $file . \".$opt_strip_comments\";\n        } else {\n            $stripped_file = basename $file . \".$opt_strip_comments\";\n        }\n        write_file($stripped_file, {}, @lines);\n    }\n    if ($opt_strip_code) {\n        my $stripped_file = \"\";\n        if ($opt_original_dir) {\n            $stripped_file =          $file . \".$opt_strip_code\";\n        } else {\n            $stripped_file = basename $file . \".$opt_strip_code\";\n        }\n        write_file($stripped_file, {}, rm_code(\\@original_lines, \\@lines));\n    }\n    if ($opt_html and !$opt_diff) {\n        chomp(@original_lines);  # includes blank lines, comments\n        chomp(@lines);           # no blank lines, no comments\n\n        my (@diff_L, @diff_R, %count);\n\n        # remove blank lines to get better quality diffs; count\n        # blank lines separately\n        my @original_lines_minus_white = ();\n        # however must keep track of how many blank lines were removed and\n        # where they were removed so that the HTML display can include it\n        my %blank_line  = ();\n        my $insert_line = 0;\n        foreach (@original_lines) {\n            if (/^\\s*$/) {\n               ++$count{blank}{same};\n               ++$blank_line{ $insert_line };\n            } else {\n                ++$insert_line;\n                push @original_lines_minus_white, $_;\n            }\n        }\n\n        array_diff( $file                       ,   # in\n                   \\@original_lines_minus_white ,   # in\n                   \\@lines                      ,   # in\n                   \"comment\"                    ,   # in\n                   \\@diff_L, \\@diff_R,          ,   # out\n                    $ra_Errors);                    # in/out\n        write_comments_to_html($file, \\@diff_L, \\@diff_R, \\%blank_line);\n#print Dumper(\"count\", \\%count);\n    }\n\n    print \"<- call_counter($total_lines, $blank_lines, $comment_lines)\\n\"\n        if $opt_v > 2;\n    return ($total_lines, $blank_lines, $comment_lines);\n} # 1}}}\nsub windows_glob {                           # {{{1\n    # Windows doesn't expand wildcards.  Use code from Sean M. Burke's\n    # Win32::Autoglob module to do this.\n    return map {;\n        ( defined($_) and m/[\\*\\?]/ ) ? sort(glob($_)) : $_\n          } @_;\n} # 1}}}\nsub write_file {                             # {{{1\n    my ($file       , # in\n        $rh_options , # in\n        @lines      , # in\n       ) = @_;\n    # If $file is a conventional scalar, it is the name of the file to write to.\n    # if $file is a reference to a scalar, rather than writing @lines to a file,\n    # write @lines to this scalar as a single string.\n\n    my $local_formatting = 0;\n    foreach my $opt (sort keys %{$rh_options}) {\n#       print \"write_file option $opt = $rh_options->{$opt}\\n\";\n        $local_formatting = 1;\n    }\n    my $write_to_file = ref($file) eq \"\" ? 1 : 0;\n\n#print \"write_file 1 [$file]\\n\";\n    # Do ~ expansion (by Tim LaBerge, fixes bug 2787984)\n    if ($write_to_file) {\n        my $preglob_filename = $file;\n    #print \"write_file 2 [$preglob_filename]\\n\";\n        if ($ON_WINDOWS) {\n            $file = (windows_glob($file))[0];\n        } else {\n            $file = File::Glob::bsd_glob($file);\n        }\n    #print \"write_file 3 [$file]\\n\";\n        $file = $preglob_filename unless $file;\n    #print \"write_file 4 [$file]\\n\";\n    }\n\n    if ($write_to_file) {\n        print \"-> write_file($file)\\n\" if $opt_v > 2;\n    } else {\n        print \"-> write_file() -- writing to string variable\\n\" if $opt_v > 2;\n    }\n\n    my @prt_lines = ();\n\n    my $n_col = undef;\n    if ($local_formatting) {\n        $n_col = scalar @{$rh_options->{'columns'}};\n        if ($opt_xml) {\n            push @prt_lines, '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' . \"\\n\";\n            push @prt_lines, \"<all_$rh_options->{'file_type'}>\\n\";\n        } elsif ($opt_yaml) {\n            push @prt_lines, \"---\\n\";\n        } elsif ($opt_md) {\n            push @prt_lines, join(\"|\", @{$rh_options->{'columns'}})  . \"\\n\";\n            push @prt_lines, join(\"|\", map( \":------\", 1 .. $n_col)) . \"\\n\";\n        }\n    }\n\n    chomp(@lines);\n\n    if ($local_formatting) {\n        my @json_lines = ();\n        foreach my $L (@lines) {\n            my @entries;\n            if ($rh_options->{'separator'}) {\n                @entries = split($rh_options->{'separator'}, $L, $n_col);\n            } else {\n                @entries = ( $L );\n            }\n            if ($opt_xml) {\n                push @prt_lines, \"  <$rh_options->{'file_type'} \";\n                for (my $i = 0; $i < $n_col; $i++) {\n                    push @prt_lines, sprintf(\"%s=\\\"%s\\\" \", $rh_options->{'columns'}[$i], $entries[$i]);\n                }\n                push @prt_lines, \"/>\\n\";\n            } elsif ($opt_yaml or $opt_json) {\n                my @pairs = ();\n                for (my $i = 0; $i < $n_col; $i++) {\n                    push @pairs,\n                        sprintf \"\\\"%s\\\":\\\"%s\\\"\", $rh_options->{'columns'}[$i], $entries[$i];\n                }\n                if ($opt_json) {\n                    # JSON can't literal '\\x' in filenames, #575\n                    $pairs[0] =~ s/\\\\x//g;\n                    push @json_lines, join(\", \", @pairs );\n                } else {\n                    push @prt_lines, \"- {\", join(\", \", @pairs) . \"}\\n\";\n                }\n            } elsif ($opt_csv) {\n                push @prt_lines, join(\",\", @entries) . \"\\n\";\n            } elsif ($opt_md) {\n                push @prt_lines, join(\"|\", @entries) . \"\\n\";\n            }\n        }\n        if ($opt_json) {\n            push @prt_lines, \"[{\" . join(\"},\\n {\", @json_lines) . \"}]\\n\";\n        }\n        if (!$opt_json and !$opt_yaml and !$opt_xml and !$opt_csv) {\n            push @prt_lines, join(\"\\n\", @lines) . \"\\n\";\n        }\n    } else {\n        push @prt_lines, join(\"\\n\", @lines) . \"\\n\";\n    }\n\n    if ($local_formatting and $opt_xml) {\n        push @prt_lines, \"</all_$rh_options->{'file_type'}>\\n\";\n    }\n\n    # Create the destination directory if it doesn't already exist.\n    my $abs_file_path = File::Spec->rel2abs( $file );\n    my ($volume, $directories, $filename) = File::Spec->splitpath( $abs_file_path );\n    mkpath($volume . $directories, 1, 0777);\n\n    my $OUT = undef;\n    unlink_file($file);\n    # If $file is a reference to a scalar, write to that scalar.  This works\n    # cleanly on Unix, but on Windows a zero-length file is created.  The\n    # filename starts with \"SCALAR\" followed by a memory address in hex.\n    # This temporary file will need to be cleaned up before the program ends.\n    if ($ON_WINDOWS and (ref($file) eq \"SCALAR\" or $file =~ /^SCALAR/)) {\n        $tmp_file_to_delete = \"$file\"; # string version of the file name\n    }\n    if ($opt_file_encoding) {\n        $OUT = open_file(\">:encoding($opt_file_encoding)\", $file, 0);\n    } else {\n        $OUT = open_file('>', $file, 1);\n    }\n    if (!defined $OUT) {\n        warn \"Unable to write to $file\\n\";\n        print \"<- write_file\\n\" if $opt_v > 2;\n        return;\n    }\n    print $OUT @prt_lines;\n    $OUT->close;\n\n    if (can_read($file)) {\n        print \"Wrote $file\" unless $opt_quiet;\n        print \", $CLOC_XSL\" if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n        print \"\\n\" unless $opt_quiet;\n    }\n\n    print \"<- write_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub file_pairs_from_file {                   # {{{1\n    my ($file             , # in\n        $ra_added         , # out\n        $ra_removed       , # out\n        $ra_compare_list  , # out\n       ) = @_;\n    #\n    # Example valid input format for $file\n    # 1)\n    #   A/d1/hello.f90 | B/d1/hello.f90\n    #   A/hello.C | B/hello.C\n    #   A/d2/hi.py | B/d2/hi.py\n    #\n    # 2)\n    # Files added: 1\n    #   + B/extra_file.pl ; Perl\n    #\n    # Files removed: 1\n    #   - A/d2/hello.java ; Java\n    #\n    # File pairs compared: 3\n    #   != A/d1/hello.f90 | B/d1/hello.f90 ; Fortran 90\n    #   != A/hello.C | B/hello.C ; C++\n    #   == A/d2/hi.py | B/d2/hi.py ; Python\n\n    print \"-> file_pairs_from_file($file)\\n\" if $opt_v and $opt_v > 2;\n    @{$ra_compare_list} = ();\n    my @lines = read_file($file);\n    my $mode = \"compare\";\n    foreach my $L (@lines) {\n        next if $L =~ /^\\s*$/ or $L =~ /^\\s*#/;\n        chomp($L);\n        if      ($L =~ /^Files\\s+(added|removed):/) {\n            $mode = $1;\n        } elsif ($L =~ /^File\\s+pairs\\s+compared:/) {\n            $mode = \"compare\";\n        } elsif ($mode eq \"added\" or $mode eq \"removed\") {\n            $L =~ m/^\\s*[+-]\\s+(.*?)\\s+;/;\n            my $F = $1;\n            if (!defined $1) {\n                warn \"file_pairs_from_file($file) parse failure\\n\",\n                     \"in $mode mode for '$L', ignoring\\n\";\n                next;\n            }\n            if ($mode eq \"added\") {\n                push @{$ra_added}  , $F;\n            } else {\n                push @{$ra_removed}, $F;\n            }\n        } else {\n            $L =~ m/^\\s*([!=]=\\s*)?(.*?)\\s*\\|\\s*(.*?)\\s*(;.*?)?$/;\n            if (!defined $2 or !defined $3) {\n                warn \"file_pairs_from_file($file) parse failure\\n\",\n                     \"in compare mode for '$L', ignoring\\n\";\n                next;\n            }\n            push @{$ra_compare_list}, ( [$2, $3] );\n        }\n    }\n    print \"<- file_pairs_from_file\\n\" if $opt_v and $opt_v > 2;\n}\nsub read_file  {                             # {{{1\n    my ($file, ) = @_;\n    print \"-> read_file($file)\\n\" if $opt_v and $opt_v > 2;\n    my %BoM = (\n        \"fe ff\"           => 2 ,\n        \"ff fe\"           => 2 ,\n        \"ef bb bf\"        => 3 ,\n        \"f7 64 4c\"        => 3 ,\n        \"0e fe ff\"        => 3 ,\n        \"fb ee 28\"        => 3 ,\n        \"00 00 fe ff\"     => 4 ,\n        \"ff fe 00 00\"     => 4 ,\n        \"2b 2f 76 38\"     => 4 ,\n        \"2b 2f 76 39\"     => 4 ,\n        \"2b 2f 76 2b\"     => 4 ,\n        \"2b 2f 76 2f\"     => 4 ,\n        \"dd 73 66 73\"     => 4 ,\n        \"84 31 95 33\"     => 4 ,\n        \"2b 2f 76 38 2d\"  => 5 ,\n        );\n\n    my @lines = ();\n    my $IN = open_file('<', $file, 1);\n    if (defined $IN) {\n        @lines = <$IN>;\n        $IN->close;\n        if ($lines[$#lines]) {  # test necessary for zero content files\n                                # (superfluous?)\n            # Some files don't end with a new line.  Force this:\n            $lines[$#lines] .= \"\\n\" unless $lines[$#lines] =~ m/\\n$/;\n        }\n    } else {\n        warn \"Unable to read $file\\n\";\n    }\n\n    # Are first few characters of the file Unicode Byte Order\n    # Marks (http://en.wikipedia.org/wiki/Byte_Order_Mark)?\n    # If yes, remove them.\n    if (@lines) {\n        my @chrs   = split('', $lines[0]);\n        my $n_chrs = scalar @chrs;\n        my ($n2, $n3, $n4, $n5) = ('', '', '', '');\n        $n2 = sprintf(\"%x %x\", map  ord, @chrs[0,1]) if $n_chrs >= 2;\n        $n3 = sprintf(\"%s %x\", $n2, ord  $chrs[2])   if $n_chrs >= 3;\n        $n4 = sprintf(\"%s %x\", $n3, ord  $chrs[3])   if $n_chrs >= 4;\n        $n5 = sprintf(\"%s %x\", $n4, ord  $chrs[4])   if $n_chrs >= 5;\n        if      (defined $BoM{$n2}) { $lines[0] = substr $lines[0], 2;\n        } elsif (defined $BoM{$n3}) { $lines[0] = substr $lines[0], 3;\n        } elsif (defined $BoM{$n4}) { $lines[0] = substr $lines[0], 4;\n        } elsif (defined $BoM{$n5}) { $lines[0] = substr $lines[0], 5;\n        }\n    }\n\n    # Trim DOS line endings.  This allows Windows files\n    # to be diff'ed with Unix files without line endings\n    # causing every line to differ.\n    foreach (@lines) { s/\\cM$// }\n\n    print \"<- read_file\\n\" if $opt_v and $opt_v > 2;\n    return @lines;\n} # 1}}}\nsub rm_blanks {                              # {{{1\n    my ($ra_in    ,\n        $language ,\n        $rh_EOL_continuation_re) = @_;\n    print \"-> rm_blanks(language=$language)\\n\" if $opt_v > 2;\n#print \"rm_blanks: language = [$language]\\n\";\n    my @out = ();\n    if ($language eq \"COBOL\") {\n        @out = remove_cobol_blanks($ra_in);\n    } else {\n        # removes blank lines\n        if (defined $rh_EOL_continuation_re->{$language}) {\n            @out = remove_matches_2re($ra_in, blank_regex($language),\n                                      $rh_EOL_continuation_re->{$language});\n        } else {\n            @out = remove_matches($ra_in, blank_regex($language));\n        }\n    }\n\n    print \"<- rm_blanks(language=$language, n_remain= \",\n        scalar(@out), \"\\n\" if $opt_v > 2;\n    return @out;\n} # 1}}}\nsub blank_regex {                            # {{{1\n    my ($language) = @_;\n\n    print \"-> blank_regex(language=$language)\\n\" if $opt_v > 2;\n\n    my $blank_regex = '^\\s*$';\n    if ($language eq \"X++\") {\n        $blank_regex = '^\\s*#?\\s*$';\n    }\n\n    print \"<- blank_regex(language=$language) = \\\"\", $blank_regex, \"\\\"\\n\" if $opt_v > 2;\n    return $blank_regex;\n} # 1}}}\nsub rm_comments {                            # {{{1\n    my ($ra_lines , # in, must be free of blank lines\n        $language , # in\n        $file     , # in (some language counters, eg Haskell, need\n                    #     access to the original file)\n        $rh_EOL_continuation_re , # in\n        $raa_Errors , # out\n       ) = @_;\n    print \"-> rm_comments(file=$file)\\n\" if $opt_v > 2;\n    my @routines       = @{$Filters_by_Language{$language}};\n    my @lines          = @{$ra_lines};\n    my @original_lines = @{$ra_lines};\n\n    if (!scalar @original_lines) {\n        return @lines;\n    }\n\n    foreach my $call_string (@routines) {\n        my $subroutine = $call_string->[0];\n        next if $subroutine eq \"rm_comments_in_strings\" and !$opt_strip_str_comments;\n        if (! defined &{$subroutine}) {\n            warn \"rm_comments undefined subroutine $subroutine for $file\\n\";\n            next;\n        }\n        print \"rm_comments file=$file sub=$subroutine\\n\" if $opt_v > 1;\n        my @args  = @{$call_string};\n        shift @args; # drop the subroutine name\n        if (@args and $args[0] eq '>filename<') {\n            shift   @args;\n            unshift @args, $file;\n        }\n\n        # Unusual inputs, namely /* within strings without\n        # a corresponding */ can cause huge delays so put a timer on this.\n        my $max_duration_sec = scalar(@lines)/1000.0; # est lines per second\n           $max_duration_sec = 1.0 if $max_duration_sec < 1;\n        # add a scale factor for super long lines\n        my $max_line_len = 0;\n        foreach my $line (@lines) {\n            my $len = length($line);\n            $max_line_len = $len if $len > $max_line_len;\n        }\n        if ($max_line_len > 1000) {\n            $max_duration_sec *= $max_line_len / 2000;\n        }\n        if (defined $opt_timeout) {\n            $max_duration_sec = $opt_timeout if $opt_timeout > 0;\n        }\n#my $T_start = Time::HiRes::time();\n        eval {\n            local $SIG{ALRM} = sub { die \"alarm\\n\" };\n            alarm $max_duration_sec;\n            no strict 'refs';\n            @lines = &{$subroutine}(\\@lines, @args);   # apply filter...\n            alarm 0;\n        };\n        #$@ = \"alarm\\n\"; # to trigger the timeout case in tests\n        if ($@) {\n            # timed out\n            die unless $@ eq \"alarm\\n\";\n            push @{$raa_Errors},\n                [ $Error_Codes{'Line count, exceeded timeout'}, $file ];\n            @lines = ();\n            if ($opt_v) {\n                warn \"rm_comments($subroutine): exceeded timeout for $file--ignoring\\n\";\n            }\n            next;\n        }\n#print \"end time = \",Time::HiRes::time() - $T_start;\n\n        print \"   rm_comments after $subroutine line count=\",\n            scalar(@lines), \"\\n\" if $opt_v > 2;\n\n#print \"lines after=\\n\";\n#print Dumper(\\@lines);\n\n        print_lines($file, \"After $subroutine(@args)\", \\@lines)\n            if $opt_print_filter_stages;\n        # then remove blank lines which are created by comment removal\n        if (defined $rh_EOL_continuation_re->{$language}) {\n            @lines = remove_matches_2re(\\@lines, '^\\s*$',\n                                        $rh_EOL_continuation_re->{$language});\n        } else {\n            @lines = remove_matches(\\@lines, '^\\s*$');\n        }\n\n        print_lines($file, \"post $subroutine(@args) blank cleanup:\", \\@lines)\n            if $opt_print_filter_stages;\n    }\n\n    foreach (@lines) { chomp }   # make sure no spurious newlines were added\n\n    # Exception for scripting languages:  treat the first #! line as code.\n    # Will need to add it back in if it was removed earlier.\n    chomp( $original_lines[0] );\n    if (defined $Script_Language{$language} and\n        $original_lines[0] =~ /^#!/ and\n        (!scalar(@lines) or ($lines[0] ne $original_lines[0]))) {\n        unshift @lines, $original_lines[0];  # add the first line back\n    }\n\n    print \"<- rm_comments\\n\" if $opt_v > 2;\n    return @lines;\n} # 1}}}\nsub rm_code {                                # {{{1\n    # Return lines containing only comments.\n    my ($ra_lines_w_comments , # in\n        $ra_lines_no_comments, # in\n       )  = @_;\n\n    my @w_comments_no_blanks  = grep { ! /^\\s*$/ } @{$ra_lines_w_comments} ;\n    my @no_comments_no_blanks = grep { ! /^\\s*$/ } @{$ra_lines_no_comments};\n    chomp( @w_comments_no_blanks  );\n    chomp( @no_comments_no_blanks );\n\n    my @sdiffs = sdiff( \\@w_comments_no_blanks, \\@no_comments_no_blanks, );\n    my @comments = ();\n    foreach my $entry (@sdiffs) {\n        my ($out_1, $out_2) = ('', '');\n        next if $entry->[0] eq 'u';\n        if ($entry->[0] eq '-') {\n            $out_1 = $entry->[1];\n        }\n        next if $out_1 =~ /^\\s*$/;\n        push @comments, $out_1;\n    }\n    return @comments;\n} # 1}}}\nsub remove_first_n {                         # {{{1\n    my ($n, $ra_lines, ) = @_;\n    print \"-> remove_first_n\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    if (scalar @{$ra_lines} > $n) {\n        for (my $i = $n; $i < scalar @{$ra_lines}; $i++) {\n            push @save_lines, $ra_lines->[$i];\n        }\n    }\n\n    print \"<- remove_first_n\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_f77_comments {                    # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> remove_f77_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        next if m{^[*cC]};\n        next if m{^\\s*!};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_f77_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_f90_comments {                    # {{{1\n    # derived from SLOCCount\n    my ($ra_lines, ) = @_;\n    print \"-> remove_f90_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        # a comment is              m/^\\s*!/\n        # an empty line is          m/^\\s*$/\n        # a HPF statement is        m/^\\s*!hpf\\$/i\n        # an Open MP statement is   m/^\\s*!omp\\$/i\n        if (! m/^(\\s*!|\\s*$)/ || m/^\\s*!(hpf|omp)\\$/i) {\n            push @save_lines, $_;\n        }\n    }\n\n    print \"<- remove_f90_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub reduce_to_rmd_code_blocks {              #{{{1\n    my ($ra_lines) = @_; #in\n    print \"-> reduce_to_rmd_code_blocks()\\n\" if $opt_v > 2;\n\n    my $in_code_block = 0;\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        if ( m/^```\\{\\s*[[:alpha:]]/ ) {\n            $in_code_block = 1;\n            next;\n        }\n        if ( m/^```\\s*$/ ) {\n            $in_code_block = 0;\n        }\n        next if (!$in_code_block);\n        push @save_lines, $_;\n    }\n\n    print \"<- reduce_to_rmd_code_blocks()\\n\" if $opt_v> 2;\n    return @save_lines;\n} # 1}}}\nsub remove_matches {                         # {{{1\n    my ($ra_lines, # in\n        $pattern , # in   Perl regular expression (case insensitive)\n       ) = @_;\n    print \"-> remove_matches(pattern=$pattern)\\n\" if $opt_v > 2;\n    print \"in:  [\", join(\"]\\nin:  [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n#chomp;\n#print \"remove_matches [$pattern] [$_]\\n\";\n        next if m{$pattern}i;\n#       s{$pattern}{}i;\n#       next unless /\\S/; # at least one non space\n        push @save_lines, $_;\n    }\n\n    print \"out: [\", join(\"]\\nout: [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_matches\\n\" if $opt_v > 2;\n#print \"remove_matches returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_matches_2re {                     # {{{1\n    my ($ra_lines, # in\n        $pattern1, # in Perl regex 1 (case insensitive) to match\n        $pattern2, # in Perl regex 2 (case insensitive) to not match prev line\n       ) = @_;\n    print \"-> remove_matches_2re(pattern=$pattern1,$pattern2)\\n\" if $opt_v > 2;\n    print \"[\", join(\"]\\nin:  [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {\n#       chomp($ra_lines->[$i]);\n#print \"remove_matches_2re [$pattern1] [$pattern2] [$ra_lines->[$i]]\\n\";\n        if ($i) {\n#print \"remove_matches_2re prev=[$ra_lines->[$i-1]] this=[$ra_lines->[$i]]\\n\";\n            next if ($ra_lines->[$i]   =~ m{$pattern1}i) and\n                    ($ra_lines->[$i-1] !~ m{$pattern2}i);\n        } else {\n            # on first line\n            next if $ra_lines->[$i]   =~  m{$pattern1}i;\n        }\n        push @save_lines, $ra_lines->[$i];\n    }\n\n    print \"[\", join(\"]\\nout: [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_matches_2re\\n\" if $opt_v > 2;\n#print \"remove_matches_2re returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_inline {                          # {{{1\n    my ($ra_lines, # in\n        $pattern , # in   Perl regular expression (case insensitive)\n       ) = @_;\n    print \"-> remove_inline(pattern=$pattern)\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    unless ($opt_inline) {\n        return @{$ra_lines};\n    }\n    my $nLines_affected = 0;\n    foreach (@{$ra_lines}) {\n#chomp; print \"remove_inline [$pattern] [$_]\\n\";\n        if (m{$pattern}i) {\n            ++$nLines_affected;\n            s{$pattern}{}i;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_inline\\n\" if $opt_v > 2;\n#print \"remove_inline returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_above {                           # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    print \"-> remove_above(marker=$marker)\\n\" if $opt_v > 2;\n\n    # Make two passes through the code:\n    # 1. check if the marker exists\n    # 2. remove anything above the marker if it exists,\n    #    do nothing if the marker does not exist\n\n    # Pass 1\n    my $found_marker = 0;\n    for (my $line_number  = 1;\n            $line_number <= scalar @{$ra_lines};\n            $line_number++) {\n        if ($ra_lines->[$line_number-1] =~ m{$marker}) {\n            $found_marker = $line_number;\n            last;\n        }\n    }\n\n    # Pass 2 only if needed\n    my @save_lines = ();\n    if ($found_marker) {\n        my $n = 1;\n        foreach (@{$ra_lines}) {\n            push @save_lines, $_\n                if $n >= $found_marker;\n            ++$n;\n        }\n    } else { # marker wasn't found; save all lines\n        foreach (@{$ra_lines}) {\n            push @save_lines, $_;\n        }\n    }\n\n    print \"<- remove_above\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_below {                           # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    print \"-> remove_below(marker=$marker)\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        last if m{$marker};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_below\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_below_above {                     # {{{1\n    my ($ra_lines, $marker_below, $marker_above, ) = @_;\n    # delete lines delimited by start and end line markers such\n    # as Perl POD documentation\n    print \"-> remove_below_above(markerB=$marker_below, A=$marker_above)\\n\"\n        if $opt_v > 2;\n\n    my @save_lines = ();\n    my $between    = 0;\n    foreach (@{$ra_lines}) {\n        if (!$between and m{$marker_below}) {\n            $between    = 1;\n            next;\n        }\n        if ($between and m{$marker_above}) {\n            $between    = 0;\n            next;\n        }\n        next if $between;\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_below_above\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between {                         # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    # $marker must contain one of the balanced pairs understood\n    # by Regexp::Common::balanced, namely\n    # '{}'  '()'  '[]'  or  '<>'\n\n    print \"-> remove_between(marker=$marker)\\n\" if $opt_v > 2;\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    my %acceptable = ('{}'=>1,  '()'=>1,  '[]'=>1,  '<>'=>1, );\n    die \"remove_between:  invalid delimiter '$marker'\\n\",\n        \"the delimiter must be one of these four pairs:\\n\",\n        \"{}  ()  []  <>\\n\" unless\n        $acceptable{$marker};\n\n##  Install_Regexp_Common() unless $HAVE_Rexexp_Common;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    no strict 'vars';\n    # otherwise get:\n    #  Global symbol \"%RE\" requires explicit package name at cloc line xx.\n    if ($all_lines =~ m/$RE{balanced}{-parens => $marker}/) {\n        no warnings;\n        $all_lines =~ s/$1//g;\n    }\n\n    print \"[\", join(\"]\\n[\", split(/\\n/, $all_lines)), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_between\\n\" if $opt_v > 2;\n    return split(\"\\n\", $all_lines);\n} # 1}}}\nsub rm_comments_in_strings {                 # {{{1\n    my ($ra_lines, $string_marker, $start_comment, $end_comment, $multiline_mode) = @_;\n    $multiline_mode = 0 if not defined $multiline_mode;\n    # Replace comments within strings with 'xx'.\n\n    print \"-> rm_comments_in_strings(string_marker=$string_marker, \" .\n          \"start_comment=$start_comment, end_comment=$end_comment)\\n\"\n        if $opt_v > 2;\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    my $in_ml_string = 0;\n    foreach my $line (@{$ra_lines}) {\n       #print \"line=[$line]\\n\";\n        my $new_line = \"\";\n\n        if ($line !~ /${string_marker}/) {\n            # short circuit; no strings on this line\n            if ( $in_ml_string ) {\n                $line =~ s/\\Q${start_comment}\\E/xx/g;\n                $line =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            }\n            push @save_lines, $line;\n            next;\n        }\n\n        # replace backslashed string markers with 'Q'\n        $line =~ s/\\\\${string_marker}/Q/g;\n\n        if ( $in_ml_string and $line =~ /^(.*?)(${string_marker})(.*)$/ ) {\n            # A multiline string ends on this line. Process the part\n            # until the end of the multiline string first.\n            my ($lastpart_ml_string, $firstpart_marker, $rest_of_line )  = ($1, $2, $3);\n            $lastpart_ml_string =~ s/\\Q${start_comment}\\E/xx/g;\n            $lastpart_ml_string =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            $new_line = $lastpart_ml_string . $firstpart_marker;\n            $line = $rest_of_line;\n            $in_ml_string = 0;\n        }\n\n        my @tokens = split(/(${string_marker}.*?${string_marker})/, $line);\n        foreach my $t (@tokens) {\n           #printf \"  t0 = [$t]\\n\";\n            if ($t =~ /${string_marker}.*${string_marker}$/) {\n                # enclosed in quotes; process this token\n                $t =~ s/\\Q${start_comment}\\E/xx/g;\n                $t =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            }\n            elsif ( $multiline_mode and $t =~ /(${string_marker})/ ) {\n                # Unclosed quote present in line. If multiline_mode is enabled,\n                # consider it the start of a multiline string.\n                my $firstpart_marker = $1;\n                my @sub_token = split(/${string_marker}/, $t );\n\n                if ( scalar @sub_token == 1 ) {\n                    # The line ends with a string marker that starts\n                    # a multiline string.\n                    $t = $sub_token[0] . $firstpart_marker;\n                    $in_ml_string = 1;\n                }\n                elsif ( scalar @sub_token == 2 ) {\n                    # The line has some more content after the string\n                    # marker that starts a multiline string\n                    $t = $sub_token[0] . $firstpart_marker;\n                    $sub_token[1] =~ s/\\Q${start_comment}\\E/xx/g;\n                    $sub_token[1] =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n                    $t .= $sub_token[1];\n                    $in_ml_string = 1;\n                } else {\n                    print \"Warning: rm_comments_in_string length \\@sub_token > 2\\n\";\n                }\n\n            }\n            #printf \"  t1 = [$t]\\n\";\n            $new_line .= $t;\n        }\n        push @save_lines, $new_line;\n    }\n\n    print \"[\", join(\"]\\n[\", @save_lines), \"]\\n\" if $opt_v > 4;\n    print \"<- rm_comments_in_strings\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between_general {                 # {{{1\n    my ($ra_lines, $start_marker, $end_marker, ) = @_;\n    # Start and end markers may be any length strings.\n\n    print \"-> remove_between_general(start=$start_marker, end=$end_marker)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/\\Q$start_marker\\E.*?\\Q$end_marker\\E//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\Q$end_marker\\E/) {\n                s/^.*?\\Q$end_marker\\E//;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)\\Q$start_marker\\E/; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)\\Q$start_marker\\E.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_between_general\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between_regex   {                 # {{{1\n    my ($ra_lines, $start_RE, $end_RE, ) = @_;\n    # Start and end regex's may be any length strings.\n\n    print \"-> remove_between_regex(start=$start_RE, end=$end_RE)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${start_RE}.*?${end_RE}//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/$end_RE/) {\n                s/^.*?${end_RE}//;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)${start_RE}/; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)${start_RE}.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_between_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub replace_regex  {                         # {{{1\n    my ($ra_lines, $regex, $replace, ) = @_;\n\n    print \"-> replace_regex(regex=$regex, replace=$replace)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${regex}/${replace}/g;\n        next if /^\\s*$/;\n        push @save_lines, $_;\n    }\n\n    print \"<- replace_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub replace_between_regex  {                 # {{{1\n    my ($ra_lines, $start_RE, $end_RE, $replace_RE, $multiline_mode ) = @_;\n    # If multiline_mode is enabled, $replace_RE should not refer\n    # to any captured groups in $start_RE.\n    $multiline_mode = 1 if not defined $multiline_mode;\n    # Start and end regex's may be any length strings.\n\n    print \"-> replace_between_regex(start=$start_RE, end=$end_RE, replace=$replace_RE)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${start_RE}.*?${end_RE}/${replace_RE}/eeg;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/$end_RE/) {\n                s/^.*?${end_RE}/${replace_RE}/ee;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if $multiline_mode and /^(.*?)${start_RE}/ ; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)${start_RE}.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- replace_between_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_cobol_blanks {                    # {{{1\n    # subroutines derived from SLOCCount\n    my ($ra_lines, ) = @_;\n\n    my $free_format = 0;  # Support \"free format\" source code.\n    my @save_lines  = ();\n\n    foreach (@{$ra_lines}) {\n        next if m/^\\s*$/;\n        my $line = expand($_);  # convert tabs to equivalent spaces\n        $free_format = 1 if $line =~ m/^......\\$.*SET.*SOURCEFORMAT.*FREE/i;\n        if ($free_format) {\n            push @save_lines, $_;\n        } else {\n            # Greg Toth:\n            #  (1) Treat lines with any alphanum in cols 1-6 and\n            #      blanks in cols 7 through 71 as blank line, and\n            #  (2) Treat lines with any alphanum in cols 1-6 and\n            #      slash (/) in col 7 as blank line (this is a\n            #      page eject directive).\n            push @save_lines, $_ unless m/^\\d{6}\\s*$/             or\n                                        ($line =~ m/^.{6}\\s{66}/) or\n                                        ($line =~ m/^......\\//);\n        }\n    }\n    return @save_lines;\n} # 1}}}\nsub remove_cobol_comments {                  # {{{1\n    # subroutines derived from SLOCCount\n    my ($ra_lines, ) = @_;\n\n    my $free_format = 0;  # Support \"free format\" source code.\n    my @save_lines  = ();\n\n    foreach (@{$ra_lines}) {\n        if (m/^......\\$.*SET.*SOURCEFORMAT.*FREE/i) {$free_format = 1;}\n        if ($free_format) {\n            push @save_lines, $_ unless m{^\\s*\\*};\n        } else {\n            push @save_lines, $_ unless m{^......\\*} or m{^\\*};\n        }\n    }\n    return @save_lines;\n} # 1}}}\nsub remove_jcl_comments {                    # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_jcl_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n        next if /^\\s*$/;\n        next if m{^//\\*};\n        last if m{^\\s*//\\s*$};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_jcl_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_jsp_comments {                    # {{{1\n    #  JSP comment is   <%--  body of comment   --%>\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_jsp_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/<\\%\\-\\-.*?\\-\\-\\%>//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\-\\-\\%>/) {\n                s/^.*?\\-\\-\\%>//;\n                $in_comment = 0;\n            }\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)<\\%\\-\\-/;\n        next if defined $1 and $1 =~ /^\\s*$/;\n        next if ($in_comment);\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_jsp_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_html_comments {                   # {{{1\n    #  HTML comment is   <!--  body of comment   -->\n    #  Need to use my own routine until the HTML comment regex in\n    #  the Regexp::Common module can handle  <!--  --  -->\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_html_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/<!\\-\\-.*?\\-\\->//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\-\\->/) {\n                s/^.*?\\-\\->//;\n                $in_comment = 0;\n            }\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)<!\\-\\-/;\n        if (defined $1 and $1 !~ /^\\s*$/) {\n            # has both code and comment\n            push @save_lines, \"$1\\n\";\n            next;\n        }\n        next if ($in_comment);\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_html_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_bf_comments {                     # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_bf_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        s/[^<>+-.,\\[\\]]+//g;\n        next if /^\\s*$/;\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_bf_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub really_is_bf {                           # {{{1\n    my ($file, ) = @_;\n\n    print \"-> really_is_bf\\n\" if $opt_v > 2;\n    my $n_bf_indicators  = 0;\n    my @lines = read_file($file);\n    foreach my $L (@lines) {\n        my $ind = 0;\n        if ($L =~ /([+-]{4,}  |          # at least four +'s or -'s in a row\n                   [\\[\\]]{4,} |          # at least four [ or ] in a row\n                   [<>][+-]   |          # >- or >+ or <+ or <-\n                   <{3,}      |          # at least three < in a row\n                   ^\\s*[\\[\\]]\\s*$)/x) {  # [ or ] on line by itself\n            ++$n_bf_indicators;\n            $ind = 1;\n        }\n        # if ($ind) { print \"YES: $L\"; } else { print \"NO : $L\"; }\n    }\n    my $ratio = scalar(@lines) > 0 ? $n_bf_indicators / scalar(@lines) : 0;\n    my $decision = ($ratio > 0.5) || ($n_bf_indicators > 5);\n    printf \"<- really_is_bf(Y/N=%d %s, R=%.3f, N=%d)\\n\",\n            $decision, $file, $ratio, $n_bf_indicators if $opt_v > 2;\n    return $decision;\n} # 1}}}\nsub remove_indented_block {                  # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    /\n    # or\n    #    -#\n    # followed by indented text on subsequent lines.\n    # http://haml.info/docs/yardoc/file.REFERENCE.html#comments\n    my ($ra_lines, $regex, ) = @_;\n\n    print \"-> remove_indented_block\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        my $line = expand($_);  # convert tabs to equivalent spaces\n        if ($in_comment) {\n            $line =~ /^(\\s*)/;\n            # print \"indent=\", length $1, \"\\n\";\n            if (length $1 < $in_comment) {\n                # indent level is less than comment level\n                # are back in code\n                $in_comment = 0;\n            } else {\n                # still in comments, don't use this line\n                next;\n            }\n        } elsif ($line =~ m{$regex}) {\n            if ($1) {\n                $in_comment = length($1) + 1; # number of leading spaces + 1\n            } else {\n                $in_comment = 1;\n            }\n            # print \"in_comment=$in_comment\\n\";\n            next;\n        }\n        push @save_lines, $line;\n    }\n\n    print \"<- remove_indented_block\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_haml_block {                      # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    /\n    # or\n    #    -#\n    # followed by indented text on subsequent lines.\n    # http://haml.info/docs/yardoc/file.REFERENCE.html#comments\n    my ($ra_lines, ) = @_;\n\n    return remove_indented_block($ra_lines, '^(\\s*)(/|-#)\\s*$');\n\n} # 1}}}\nsub remove_pug_block {                       # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    //\n    # followed by indented text on subsequent lines.\n    # http://jade-lang.com/reference/comments/\n    my ($ra_lines, ) = @_;\n    return remove_indented_block($ra_lines, '^(\\s*)(//)\\s*$');\n} # 1}}}\nsub remove_OCaml_comments {                  # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_OCaml_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;   # counter to depth of nested comments\n    foreach my $L (@{$ra_lines}) {\n        next if $L =~ /^\\s*$/;\n        # make an array of tokens where a token is a start comment\n        # marker, end comment marker, string, or anything else\n        my $clean_line = \"\"; # ie, free of comments\n        my @tokens = split(/(\\(\\*|\\*\\)|\".*?\")/, $L);\n        foreach my $t (@tokens) {\n            next unless $t;\n            if      ($t eq \"(*\") {\n                ++$in_comment;\n            } elsif ($t eq \"*)\") {\n                --$in_comment;\n            } elsif (!$in_comment) {\n                $clean_line .= $t;\n            }\n        }\n        push @save_lines, $clean_line if $clean_line;\n    }\n    print \"<- remove_OCaml_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_TLAPlus_generated_code {          # {{{1\n    my ($ra_lines, ) = @_;\n    # If --no-autogen, remove code created by the PlusCal translator.\n    return @{$ra_lines} if !$opt_no_autogen;\n    return remove_between_regex($ra_lines, '^\\\\\\\\\\\\* BEGIN TRANSLATION\\b', '^\\\\\\\\\\\\* END TRANSLATION\\b');\n} # 1}}}\nsub remove_TLAPlus_comments {                # {{{1\n    my ($ra_lines, ) = @_;\n    # TLA+ block comments are like OCaml comments (remove_OCaml_comments).\n    # However, TLA+ comments may contain PlusCal code, and we must consider the\n    # PlusCal code as code, not comments.\n\n    print \"-> remove_TLAPlus_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;        # counter to depth of nested (* *) comments\n    my $in_pluscal_head = 0;   # whether we saw the start of PlusCal code\n    my $in_pluscal_block = 0;  # counter to depth of nested { } blocks\n    my $saved_in_comment = 0;  # $in_comment before we entered PlusCal code\n    foreach my $L (@{$ra_lines}) {\n        next if $L =~ /^\\s*$/;\n        # make an array of interesting tokens we need to act upon\n        my $clean_line = \"\"; # ie, free of comments\n        my @tokens = split(/(\\(\\*|\\*\\)|\".*?\"|[{}]|--fair\\b|--algorithm|PlusCal options)/, $L);\n        foreach my $t (@tokens) {\n            next unless $t;\n            if      ($t eq \"(*\") {\n                ++$in_comment;\n            } elsif ($t eq \"*)\") {\n                --$in_comment;\n            } elsif ($t eq \"{\" && $in_pluscal_head) {\n                # start block matching when we see '{' in '--algorithm NAME {'\n                $in_pluscal_head = 0;\n                $in_pluscal_block = 1;\n                $saved_in_comment = $in_comment;\n                $in_comment = 0;\n                $clean_line .= $t;\n            } elsif ($t eq \"{\" && $in_pluscal_block && !$in_comment) {\n                ++$in_pluscal_block;\n                $clean_line .= $t;\n            } elsif ($t eq \"}\" && $in_pluscal_block && !$in_comment) {\n                --$in_pluscal_block;\n                if ($in_pluscal_block == 0) {\n                    $in_comment = $saved_in_comment;\n                }\n                $clean_line .= $t;\n            } elsif ($t eq \"--fair\" || $t eq \"--algorithm\") {\n                $in_pluscal_head = 1;\n                $clean_line .= $t;\n            } elsif (!$in_comment || $in_pluscal_head || $in_pluscal_block || $t eq \"PlusCal options\") {\n                $clean_line .= $t;\n            }\n        }\n        push @save_lines, $clean_line if $clean_line;\n    }\n    print \"<- remove_TLAPlus_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_slim_block {                      # {{{1\n    # slim comments start with /\n    # followed by indented text on subsequent lines.\n    # http://www.rubydoc.info/gems/slim/frames\n    my ($ra_lines, ) = @_;\n    return remove_indented_block($ra_lines, '^(\\s*)(/[^!])');\n} # 1}}}\nsub add_newlines {                           # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> add_newlines \\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n\n        push @save_lines, \"$_\\n\";\n    }\n\n    print \"<- add_newlines \\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub docstring_to_C {                         # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Python docstrings to C comments.\n\n    if ($opt_docstring_as_code) {\n        return @{$ra_lines};\n    }\n\n    print \"-> docstring_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        while (/((\"\"\")|('''))/) {\n            if (!$in_docstring) {\n                s{[uU]?((\"\"\")|('''))}{/*};\n                $in_docstring = 1;\n            } else {\n                s{((\"\"\")|('''))}{*/};\n                $in_docstring = 0;\n            }\n        }\n    }\n\n    print \"<- docstring_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub docstring_rm_comments {                  # {{{1\n    my ($ra_lines, ) = @_;\n    # Remove embedded C/C++ style comments in docstrings.\n\n    print \"-> docstring_rm_comments()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        if (/((\"\"\")|('''))(.*?)\\1/) {\n            # single line docstring\n            my ($i_start, $i_end) = ($-[0]+3, $+[0]-3);\n            # replace /*, */, // with xx\n            substr($_, $i_start, $i_end-$i_start) =~ s{(/\\*|\\*/|//)}{xx}g;\n            next;\n        } elsif (m{/\\*.*?((\"\"\")|(''')).*?\\*/}) {\n            # docstring start or end within /* */ comments\n            my $i_start = $-[0]+2;\n            substr($_, $i_start, 3) = \"xxx\";\n        } elsif (m{//.*?((\"\"\")|('''))}) {\n            # docstring start or end after //\n            my $i_start = $-[0]+2;\n            substr($_, $i_start, 3) = \"xxx\";\n        } elsif (/^(.*?)((\"\"\")|('''))/ and  $in_docstring) {\n            $in_docstring = 0;\n            my $i_end = length $1;\n            if ($i_end) {\n                substr($_, 0, $i_end) =~ s{(/\\*|\\*/|//)}{xx}g;\n            }\n        } elsif (/((\"\"\")|('''))(.*?)$/ and !$in_docstring) {\n            $in_docstring = 1;\n            my $i_start = $-[0]+3;\n            substr($_, $i_start) =~ s{(/\\*|\\*/|//)}{xx}g;\n        } elsif ($in_docstring) {\n            s{(/\\*|\\*/|//)}{xx}g;\n        }\n    }\n\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- docstring_rm_comments\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub jupyter_nb {                             # {{{1\n    my ($ra_lines, ) = @_;\n    # Translate .ipynb file content into an equivalent set of code\n    # lines as expected by cloc.\n\n    print \"-> jupyter_nb()\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_code   = 0;\n    my $in_source = 0;\n    foreach (@{$ra_lines}) {\n        if (!$in_code and !$in_source and /^\\s*\"cell_type\":\\s*\"code\",\\s*$/) {\n            $in_code = 1;\n        } elsif ($in_code and !$in_source and /^\\s*\"source\":\\s*\\[\\s*$/) {\n            $in_source = 1;\n        } elsif ($in_code and $in_source) {\n            if (/^\\s*\"\\s*\\\\n\",\\s*$/) {    #  \"\\n\",  -> empty line\n                next;\n            } elsif (/^\\s*\"\\s*#/) {       #  comment within the code block\n                next;\n            } elsif (/^\\s*\\]\\s*$/) {\n                $in_code   = 0;\n                $in_source = 0;\n            } else {\n                push @save_lines, $_;\n            }\n        }\n    }\n\n    print \"<- jupyter_nb\\n\" if $opt_v > 2;\n\n    return @save_lines;\n} # 1}}}\nsub elixir_doc_to_C {                        # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Elixir docs to C comments.\n\n    print \"-> elixir_doc_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        if (!$in_docstring && /(\\@(module)?doc\\s+(~[sScC])?['\"]{3})/) {\n            s{$1}{/*};\n            $in_docstring = 1;\n        } elsif ($in_docstring && /(['\"]{3})/) {\n            s{$1}{*/};\n            $in_docstring = 0;\n        }\n    }\n\n    print \"<- elixir_doc_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub Forth_paren_to_C  {                      # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Forth comment parentheses to C comments.\n\n    print \"-> Forth_paren_to_C()\\n\" if $opt_v > 2;\n\n    my $in_comment = 0;\n    my $max_paren_pair_per_line = 255;\n    foreach (@{$ra_lines}) {\n#print \"Forth_paren_to_C: [$_]\\n\";\n        my $n_iter = 0;\n        while (/\\s\\(\\s/ or ($in_comment and /\\)/)) {\n#print \"TOP n_iter=$n_iter in_comment=$in_comment\\n\";\n            if (/\\s\\(\\s.*?\\)/) {\n                # in-line parenthesis comment; handle here\n                s/\\s+\\(\\s+.*?\\)//g;\n#print \"B\\n\";\n            } elsif (!$in_comment and /\\s\\(\\s/) {\n                s{\\s+\\(\\s+}{/*};\n#print \"C\\n\";\n                $in_comment = 1;\n            } elsif ($in_comment and /\\)/) {\n                s{\\)}{*/};\n#print \"D\\n\";\n                $in_comment = 0;\n            } else {\n                # gets here if it can't find a matching\n                # close parenthesis; in this case the\n                # results will likely be incorrect\n                ++$n_iter;\n#print \"E\\n\";\n                last if $n_iter > $max_paren_pair_per_line;\n            }\n        }\n    }\n\n    print \"<- Forth_paren_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub powershell_to_C {                        # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts PowerShell block comment markers to C comments.\n\n    print \"-> powershell_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        s{<#}{/*}g;\n        s{#>}{*/}g;\n    }\n\n    print \"<- powershell_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub smarty_to_C {                            # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Smarty comments to C comments.\n\n    print \"-> smarty_to_C()\\n\" if $opt_v > 2;\n\n    foreach (@{$ra_lines}) {\n        s[{\\*][/*]g;\n        s[\\*}][*/]g;\n    }\n\n    print \"<- smarty_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub determine_lit_type {                     # {{{1\n  my ($file) = @_;\n\n  my $FILE = open_file('<', $file, 0);\n  while (<$FILE>) {\n    if (m/^\\\\begin\\{code\\}/) { close $FILE; return 2; }\n    if (m/^>\\s/) { close $FILE; return 1; }\n  }\n\n  return 0;\n} # 1}}}\nsub remove_haskell_comments {                # {{{1\n    # SLOCCount's haskell_count script with modifications to handle\n    # Elm empty and nested block comments.\n    # Strips out {- .. -} and -- comments and counts the rest.\n    # Pragmas, {-#...}, are counted as SLOC.\n    # BUG: Doesn't handle strings with embedded block comment markers gracefully.\n    #      In practice, that shouldn't be a problem.\n    my ($ra_lines, $file, ) = @_;\n\n    print \"-> remove_haskell_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    my $incomment  = 0;\n    my $inlitblock = 0;\n    my $literate   = 0;\n    my $is_elm     = 0;\n\n    $is_elm   = 1 if $file =~ /\\.elm$/;\n    $literate = 1 if $file =~ /\\.lhs$/;\n    if ($literate) { $literate = determine_lit_type($file) }\n\n    foreach (@{$ra_lines}) {\n        chomp;\n        if ($literate == 1) {\n            if (!s/^>//) { s/.*//; }\n        } elsif ($literate == 2) {\n            if ($inlitblock) {\n                if (m/^\\\\end\\{code\\}/) { s/.*//; $inlitblock = 0; }\n            } elsif (!$inlitblock) {\n                if (m/^\\\\begin\\{code\\}/) { s/.*//; $inlitblock = 1; }\n                else { s/.*//; }\n            }\n        }\n\n        # keep pragmas\n        if (/^\\s*{-#/) {\n            push @save_lines, $_;\n            next;\n        }\n\n        # Elm allows nested comments so track nesting depth\n        # with $incomment.\n\n        my $n_open  = () = $_ =~ /{-/g;\n        my $n_close = () = $_ =~ /-}/g;\n        s/{-.*?-}//g;\n\n        if ($incomment) {\n            if (m/\\-\\}/) {\n                s/^.*?\\-\\}//;\n                if ($is_elm) {\n                    $incomment += $n_open - $n_close;\n                } else {\n                    $incomment = 0;\n                }\n            } else {\n                s/.*//;\n            }\n        } else {\n            s/--.*//;\n            if (m/{-/ && (!m/{-#/)) {\n                s/{-.*//;\n                if ($is_elm) {\n                    $incomment += $n_open - $n_close;\n                } else {\n                    $incomment = 1;\n                }\n            }\n        }\n        if (m/\\S/) { push @save_lines, $_; }\n    }\n#   if ($incomment) {print \"ERROR: ended in comment in $ARGV\\n\";}\n\n    print \"<- remove_haskell_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub print_lines {                            # {{{1\n    my ($file     , # in\n        $title    , # in\n        $ra_lines , # in\n       ) = @_;\n    printf \"->%-30s %s\\n\", $file, $title;\n    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {\n        printf \"%5d | %s\", $i+1, $ra_lines->[$i];\n        print \"\\n\" unless $ra_lines->[$i] =~ m{\\n$}\n    }\n} # 1}}}\nsub set_constants {                          # {{{1\n    my ($rh_Language_by_Extension , # out\n        $rh_Language_by_Script    , # out\n        $rh_Language_by_File_Type      , # out\n        $rh_Language_by_Prefix    , # out\n        $rhaa_Filters_by_Language , # out\n        $rh_Not_Code_Extension    , # out\n        $rh_Not_Code_Filename     , # out\n        $rh_Scale_Factor          , # out\n        $rh_Known_Binary_Archives , # out\n        $rh_EOL_continuation_re   , # out\n       ) = @_;\n# 1}}}\n%{$rh_Language_by_Extension} = (             # {{{1\n            'abap'        => 'ABAP'                  ,\n            'ac'          => 'm4'                    ,\n            'ada'         => 'Ada'                   ,\n            'adb'         => 'Ada'                   ,\n            'ads'         => 'Ada'                   ,\n            'adso'        => 'ADSO/IDSM'             ,\n            'ahkl'        => 'AutoHotkey'            ,\n            'ahk'         => 'AutoHotkey'            ,\n            'agda'        => 'Agda'                  ,\n            'lagda'       => 'Agda'                  ,\n            'aj'          => 'AspectJ'               ,\n            'am'          => 'make'                  ,\n            'ample'       => 'AMPLE'                 ,\n            'apl'         => 'APL'                   ,\n            'apla'        => 'APL'                   ,\n            'aplf'        => 'APL'                   ,\n            'aplo'        => 'APL'                   ,\n            'apln'        => 'APL'                   ,\n            'aplc'        => 'APL'                   ,\n            'apli'        => 'APL'                   ,\n            'applescript' => 'AppleScript'           ,\n            'dyalog'      => 'APL'                   ,\n            'dyapp'       => 'APL'                   ,\n            'mipage'      => 'APL'                   ,\n            'art'         => 'Arturo'                ,\n            'as'          => 'ActionScript'          ,\n            'adoc'        => 'AsciiDoc'              ,\n            'asciidoc'    => 'AsciiDoc'              ,\n            'dofile'      => 'AMPLE'                 ,\n            'startup'     => 'AMPLE'                 ,\n            'aria'        => 'Aria'                  ,\n            'axd'         => 'ASP'                   ,\n            'ashx'        => 'ASP'                   ,\n            'asa'         => 'ASP'                   ,\n            'asax'        => 'ASP.NET'               ,\n            'ascx'        => 'ASP.NET'               ,\n            'asd'         => 'Lisp'                  , # system definition file\n            'asmx'        => 'ASP.NET'               ,\n            'asp'         => 'ASP'                   ,\n            'aspx'        => 'ASP.NET'               ,\n            'master'      => 'ASP.NET'               ,\n            'sitemap'     => 'ASP.NET'               ,\n            'nasm'        => 'Assembly'              ,\n            'a51'         => 'Assembly'              ,\n            'asm'         => 'Assembly'              ,\n            'astro'       => 'Astro'                 ,\n            'asy'         => 'Asymptote'             ,\n            'cshtml'      => 'Razor'                 ,\n            'razor'       => 'Razor'                 , # Client-side Blazor\n            'nawk'        => 'awk'                   ,\n            'mawk'        => 'awk'                   ,\n            'gawk'        => 'awk'                   ,\n            'auk'         => 'awk'                   ,\n            'awk'         => 'awk'                   ,\n            'axaml'       => 'AXAML'                 ,\n            'bash'        => 'Bourne Again Shell'    ,\n            'bazel'       => 'Starlark'              ,\n            'BUILD'       => 'Bazel'                 ,\n            'dxl'         => 'DOORS Extension Language',\n            'bat'         => 'DOS Batch'             ,\n            'BAT'         => 'DOS Batch'             ,\n            'cmd'         => 'DOS Batch'             ,\n            'CMD'         => 'DOS Batch'             ,\n            'btm'         => 'DOS Batch'             ,\n            'BTM'         => 'DOS Batch'             ,\n            'blade'       => 'Blade'                 ,\n            'blade.php'   => 'Blade'                 ,\n            'b'           => 'Brainfuck'             ,\n            'bel'         => 'Beluga'                ,\n            'bf'          => 'Brainfuck'             ,\n            'bicep'       => 'Bicep'                 ,\n            'bicepparam'  => 'Bicep'                 ,\n            'blp'         => 'Blueprint'             ,\n            'bpmn'        => 'Activiti Business Process',\n            'brs'         => 'BrightScript'          ,\n            'btp'         => 'BizTalk Pipeline'      ,\n            'build.xml'   => 'Ant'                   ,\n            'bzl'         => 'Starlark'              ,\n            'odx'         => 'BizTalk Orchestration' ,\n            'carbon'      => 'Carbon'                ,\n            'cpy'         => 'COBOL'                 ,\n            'cobol'       => 'COBOL'                 ,\n            'ccp'         => 'COBOL'                 ,\n            'cbl'         => 'COBOL'                 ,\n            'CBL'         => 'COBOL'                 ,\n            'idc'         => 'C'                     ,\n            'cats'        => 'C'                     ,\n            'c'           => 'C'                     ,\n            'c++'         => 'C++'                   ,\n            'C'           => 'C++'                   ,\n            'cc'          => 'C++'                   ,\n            'ccm'         => 'C++'                   ,\n            'c++m'        => 'C++'                   ,\n            'cppm'        => 'C++'                   ,\n            'cxxm'        => 'C++'                   ,\n            'h++'         => 'C++'                   ,\n            'inl'         => 'C++'                   ,\n            'ipp'         => 'C++'                   ,\n            'ixx'         => 'C++'                   ,\n            'tcc'         => 'C++'                   ,\n            'tpp'         => 'C++'                   ,\n            'cxx'         => 'C++'                   ,\n            'cpp'         => 'C++'                   ,\n            'CPP'         => 'C++'                   ,\n            'cdc'         => 'Cadence'               ,\n            'ccs'         => 'CCS'                   ,\n            'civet'       => 'Civet'                 ,\n            'cvt'         => 'Civet'                 ,\n            'cvtx'        => 'Civet'                 ,\n            'cfc'         => 'ColdFusion CFScript'   ,\n            'cfml'        => 'ColdFusion'            ,\n            'cfm'         => 'ColdFusion'            ,\n            'chpl'        => 'Chapel'                ,\n            'cl'          => 'Lisp/OpenCL'           ,\n            'riemann.config'=> 'Clojure'               ,\n            'hic'         => 'Clojure'               ,\n            'cljx'        => 'Clojure'               ,\n            'cljscm'      => 'Clojure'               ,\n            'cljs.hl'     => 'Clojure'               ,\n            'cl2'         => 'Clojure'               ,\n            'boot'        => 'Clojure'               ,\n            'cj'          => 'Clojure/Cangjie'       ,\n            'clj'         => 'Clojure'               ,\n            'cljs'        => 'ClojureScript'         ,\n            'cljc'        => 'ClojureC'              ,\n            'cls'         => 'Visual Basic/TeX/Apex Class' ,\n            'cmake.in'    => 'CMake'                 ,\n            'CMakeLists.txt' => 'CMake'              ,\n            'cmake'       => 'CMake'                 ,\n            'cob'         => 'COBOL'                 ,\n            'COB'         => 'COBOL'                 ,\n            'cocoa5'      => 'CoCoA 5'               ,\n            'code-workspace' => 'VSCode Workspace'   ,\n            'ql'          => 'CodeQL'                ,\n            'qll'         => 'CodeQL'                ,\n            'c5'          => 'CoCoA 5'               ,\n            'cpkg5'       => 'CoCoA 5'               ,\n            'cocoa5server'=> 'CoCoA 5'               ,\n            'iced'        => 'CoffeeScript'          ,\n            'cjsx'        => 'CoffeeScript'          ,\n            'cakefile'    => 'CoffeeScript'          ,\n            '_coffee'     => 'CoffeeScript'          ,\n            'coffee'      => 'CoffeeScript'          ,\n            'component'   => 'Visualforce Component' ,\n            'cg3'         => 'Constraint Grammar'    ,\n            'rlx'         => 'Constraint Grammar'    ,\n            'Containerfile'  => 'Containerfile'      ,\n            'cr'          => 'Crystal'               ,\n            'cs'          => 'C#/Smalltalk'          ,\n            'designer.cs' => 'C# Designer'           ,\n            'cake'        => 'Cake Build Script'     ,\n            'csh'         => 'C Shell'               ,\n            'cson'        => 'CSON'                  ,\n            'css'         => \"CSS\"                   ,\n            'csv'         => \"CSV\"                   ,\n            'cu'          => 'CUDA'                  ,\n            'cuh'         => 'CUDA'                  , # CUDA header file\n            'c3'          => 'C3'                    ,\n            'c3i'         => 'C3'                    ,\n            'c3t'         => 'C3'                    ,\n            'd'           => 'D/dtrace'              ,\n# in addition, .d can map to init.d files typically written as\n# bash or sh scripts\n            'dfy'         => 'Dafny'                 ,\n            'da'          => 'DAL'                   ,\n            'daml'        => 'DAML'                  ,\n            'dart'        => 'Dart'                  ,\n            'dsc'         => 'DenizenScript'         ,\n            'derw'        => 'Derw'                  ,\n            'def'         => 'Windows Module Definition',\n            'dhall'       => 'dhall'                 ,\n            'dt'          => 'DIET'                  ,\n            'patch'       => 'diff'                  ,\n            'diff'        => 'diff'                  ,\n            'dmap'        => 'NASTRAN DMAP'          ,\n            'sthlp'       => 'Stata'                 ,\n            'matah'       => 'Stata'                 ,\n            'mata'        => 'Stata'                 ,\n            'ihlp'        => 'Stata'                 ,\n            'doh'         => 'Stata'                 ,\n            'ado'         => 'Stata'                 ,\n            'do'          => 'Stata'                 ,\n            'DO'          => 'Stata'                 ,\n            'Dockerfile'  => 'Dockerfile'            ,\n            'dockerfile'  => 'Dockerfile'            ,\n            'pascal'      => 'Pascal'                ,\n            'lpr'         => 'Pascal'                ,\n            'dfm'         => 'Delphi Form'           ,\n            'dpr'         => 'Pascal'                ,\n            'dita'        => 'DITA'                  ,\n            'drl'         => 'Drools'                ,\n            'dtd'         => 'DTD'                   ,\n            'ec'          => 'C'                     ,\n            'ecpp'        => 'ECPP'                  ,\n            'eex'         => 'EEx'                   ,\n            'el'          => 'Lisp'                  ,\n            'elm'         => 'Elm'                   ,\n            'exs'         => 'Elixir Script'         ,\n            'ex'          => 'Elixir'                ,\n            'ecr'         => 'Embedded Crystal'      ,\n            'ejs'         => 'EJS'                   ,\n            'erb'         => 'ERB'                   ,\n            'ERB'         => 'ERB'                   ,\n            'ets'         => 'ArkTs'                 , # OpenHarmonyOS app language\n            'yrl'         => 'Erlang'                ,\n            'xrl'         => 'Erlang'                ,\n            'rebar.lock'  => 'Erlang'                ,\n            'rebar.config.lock'=> 'Erlang'           ,\n            'rebar.config'=> 'Erlang'                ,\n            'emakefile'   => 'Erlang'                ,\n            'app.src'     => 'Erlang'                ,\n            'erl'         => 'Erlang'                ,\n            'exp'         => 'Expect'                ,\n            '4th'         => 'Forth'                 ,\n            'fish'        => 'Fish Shell'            ,\n            'fsl'         => 'Finite State Language' ,\n            'jssm'        => 'Finite State Language' ,\n            'fnl'         => 'Fennel'                ,\n            'forth'       => 'Forth'                 ,\n            'fr'          => 'Forth'                 ,\n            'frt'         => 'Forth'                 ,\n            'fth'         => 'Forth'                 ,\n            'f83'         => 'Forth'                 ,\n            'fb'          => 'Forth'                 ,\n            'fpm'         => 'Forth'                 ,\n            'e4'          => 'Forth'                 ,\n            'rx'          => 'Forth'                 ,\n            'ft'          => 'Forth'                 ,\n            'f77'         => 'Fortran 77'            ,\n            'F77'         => 'Fortran 77'            ,\n            'f90'         => 'Fortran 90'            ,\n            'F90'         => 'Fortran 90'            ,\n            'f95'         => 'Fortran 95'            ,\n            'F95'         => 'Fortran 95'            ,\n            'f'           => 'Fortran 77/Forth'      ,\n            'F'           => 'Fortran 77'            ,\n            'for'         => 'Fortran 77/Forth'      ,\n            'FOR'         => 'Fortran 77'            ,\n            'ftl'         => 'Freemarker Template'   ,\n            'ftn'         => 'Fortran 77'            ,\n            'FTN'         => 'Fortran 77'            ,\n            'f03'         => 'Fortran 2003'          ,\n            'F03'         => 'Fortran 2003'          ,\n            'fmt'         => 'Oracle Forms'          ,\n            'focexec'     => 'Focus'                 ,\n            'fs'          => 'F#/Forth'              ,\n            'fsi'         => 'F#'                    ,\n            'fsx'         => 'F# Script'             ,\n            'fut'         => 'Futhark'               ,\n            'fxml'        => 'FXML'                  ,\n            'gnumakefile' => 'make'                  ,\n            'Gnumakefile' => 'make'                  ,\n            'gd'          => 'GDScript'              ,\n            'gdshader'    => 'Godot Shaders'         ,\n            'vshader'     => 'GLSL'                  ,\n            'vsh'         => 'GLSL'                  ,\n            'vrx'         => 'GLSL'                  ,\n            'gshader'     => 'GLSL'                  ,\n            'glslv'       => 'GLSL'                  ,\n            'geo'         => 'GLSL'                  ,\n            'fshader'     => 'GLSL'                  ,\n            'fsh'         => 'GLSL'                  ,\n            'frg'         => 'GLSL'                  ,\n            'fp'          => 'GLSL'                  ,\n            'fbs'         => 'Flatbuffers'           ,\n            'gjs'         => 'Glimmer JavaScript'    ,\n            'gts'         => 'Glimmer TypeScript'    ,\n            'glsl'        => 'GLSL'                  ,\n            'graphqls'    => 'GraphQL'               ,\n            'gql'         => 'GraphQL'               ,\n            'graphql'     => 'GraphQL'               ,\n            'vert'        => 'GLSL'                  ,\n            'tesc'        => 'GLSL'                  ,\n            'tese'        => 'GLSL'                  ,\n            'geom'        => 'GLSL'                  ,\n            'feature'     => 'Cucumber'              ,\n            'frag'        => 'GLSL'                  ,\n            'comp'        => 'GLSL'                  ,\n            'g'           => 'ANTLR Grammar'         ,\n            'g4'          => 'ANTLR Grammar'         ,\n            'gleam'       => 'Gleam'                 ,\n            'go'          => 'Go'                    ,\n            'ʕ◔ϖ◔ʔ'       => 'Go'                    ,\n            'gsp'         => 'Grails'                ,\n            'jenkinsfile' => 'Groovy'                ,\n            'gvy'         => 'Groovy'                ,\n            'gtpl'        => 'Groovy'                ,\n            'grt'         => 'Groovy'                ,\n            'groovy'      => 'Groovy'                ,\n            'gant'        => 'Groovy'                ,\n            'gradle'      => 'Gradle'                ,\n            'gradle.kts'  => 'Gradle'                ,\n            'h'           => 'C/C++ Header'          ,\n            'H'           => 'C/C++ Header'          ,\n            'hh'          => 'C/C++ Header'          ,\n            'hpp'         => 'C/C++ Header'          ,\n            'hxx'         => 'C/C++ Header'          ,\n            'hb'          => 'Harbour'               ,\n            'hrl'         => 'Erlang'                ,\n            'tfvars'      => 'HCL'                   ,\n            'hcl'         => 'HCL'                   ,\n            'tf'          => 'HCL'                   ,\n            'nomad'       => 'HCL'                   ,\n            'hlsli'       => 'HLSL'                  ,\n            'fxh'         => 'HLSL'                  ,\n            'hlsl'        => 'HLSL'                  ,\n            'shader'      => 'HLSL'                  ,\n            'cg'          => 'HLSL'                  ,\n            'cginc'       => 'HLSL'                  ,\n            'haml.deface' => 'Haml'                  ,\n            'haml'        => 'Haml'                  ,\n            'handlebars'  => 'Handlebars'            ,\n            'hbs'         => 'Handlebars'            ,\n            'hbm.xml'     => 'Hibernate'             ,\n            'ha'          => 'Hare'                  ,\n            'hxsl'        => 'Haxe'                  ,\n            'hx'          => 'Haxe'                  ,\n            'HC'          => 'HolyC'                 ,\n            'hoon'        => 'Hoon'                  ,\n            'xht'         => 'HTML'                  ,\n            'html.hl'     => 'HTML'                  ,\n            'htm'         => 'HTML'                  ,\n            'html'        => 'HTML'                  ,\n            'heex'        => 'HTML EEx'              ,\n            'hsc'         => 'Haskell'               ,\n            'hs'          => 'Haskell'               ,\n            'lhs'         => 'Haskell'               ,\n            'hs-boot'     => 'Haskell Boot'          ,\n            'lhs-boot'    => 'Haskell Boot'          ,\n            'i3'          => 'Modula3'               ,\n            'ice'         => 'Slice'                 ,\n            'icl'         => 'Clean'                 ,\n            'dcl'         => 'Clean'                 ,\n            'dlm'         => 'IDL'                   ,\n            'idl'         => 'IDL'                   ,\n            'idr'         => 'Idris'                 ,\n            'lidr'        => 'Literate Idris'        ,\n            'imba'        => 'Imba'                  ,\n            'prefs'       => 'INI'                   ,\n            'lektorproject'=> 'INI'                  ,\n            'buildozer.spec'=> 'INI'                 ,\n            'ini'         => 'INI'                   ,\n            'editorconfig'=> 'INI'                   ,\n            'ism'         => 'InstallShield'         ,\n            'ipl'         => 'IPL'                   ,\n            'pro'         => 'IDL/Qt Project/Prolog/ProGuard' ,\n            'ig'          => 'Modula3'               ,\n            'il'          => 'SKILL/.NET IL'         ,\n            'ils'         => 'SKILL++'               ,\n            'inc'         => 'PHP/Pascal/Fortran/Pawn/BitBake' ,\n            'ino'         => 'Arduino Sketch'        ,\n            'ipf'         => 'Igor Pro'              ,\n           #'pde'         => 'Arduino Sketch'        , # pre 1.0\n            'pde'         => 'Processing'            , # pre 1.0\n            'itk'         => 'Tcl/Tk'                ,\n            'java'        => 'Java'                  ,\n            'jcl'         => 'JCL'                   , # IBM Job Control Lang.\n            'jl'          => 'Lisp/Julia'            ,\n            'jai'         => 'Jai'                   ,\n            'janet'       => 'Janet'                 ,\n            'xsjslib'     => 'JavaScript'            ,\n            'xsjs'        => 'JavaScript'            ,\n            'ssjs'        => 'JavaScript'            ,\n            'sjs'         => 'JavaScript'            ,\n            'pac'         => 'JavaScript'            ,\n            'njs'         => 'JavaScript'            ,\n            'mjs'         => 'JavaScript'            ,\n            'cjs'         => 'JavaScript'            ,\n            'jss'         => 'JavaScript'            ,\n            'jsm'         => 'JavaScript'            ,\n            'jsfl'        => 'JavaScript'            ,\n            'jscad'       => 'JavaScript'            ,\n            'jsb'         => 'JavaScript'            ,\n            'jakefile'    => 'JavaScript'            ,\n            'jake'        => 'JavaScript'            ,\n            'bones'       => 'JavaScript'            ,\n            '_js'         => 'JavaScript'            ,\n            'js'          => 'JavaScript'            ,\n            'es6'         => 'JavaScript'            ,\n            'jrxml'       => 'Jasper Report XML/Template' ,\n            'jsf'         => 'JavaServer Faces'      ,\n            'jsx'         => 'JSX'                   ,\n            'xhtml'       => 'XHTML'                 ,\n            'j2'          => 'Jinja Template'        ,\n            'jinja'       => 'Jinja Template'        ,\n            'jinja2'      => 'Jinja Template'        ,\n            'yyp'         => 'JSON'                  ,\n            'webmanifest' => 'JSON'                  ,\n            'webapp'      => 'JSON'                  ,\n            'topojson'    => 'JSON'                  ,\n            'tfstate.backup'=> 'JSON'                  ,\n            'tfstate'     => 'JSON'                  ,\n            'mcmod.info'  => 'JSON'                  ,\n            'mcmeta'      => 'JSON'                  ,\n            'json-tmlanguage'=> 'JSON'                  ,\n            'jsonl'       => 'JSON'                  ,\n            'har'         => 'JSON'                  ,\n            'gltf'        => 'JSON'                  ,\n            'geojson'     => 'JSON'                  ,\n            'composer.lock'=> 'JSON'                  ,\n            'avsc'        => 'JSON'                  ,\n            'watchmanconfig'=> 'JSON'                  ,\n            'tern-project'=> 'JSON'                  ,\n            'tern-config' => 'JSON'                  ,\n            'htmlhintrc'  => 'JSON'                  ,\n            'arcconfig'   => 'JSON'                  ,\n            'json'        => 'JSON'                  ,\n            'json5'       => 'JSON5'                 ,\n            'jsonnet'     => 'Jsonnet'               ,\n            'jsp'         => 'JSP'                   , # Java server pages\n            'jspf'        => 'JSP'                   , # Java server pages\n            'tld'         => 'JSP Tag Library Definition',\n            'junos'       => 'Juniper Junos'         ,\n            'just'        => 'Justfile'              ,\n            'vm'          => 'Velocity Template Language' ,\n            'kv'          => 'kvlang'                ,\n            'ksc'         => 'Kermit'                ,\n            'ksh'         => 'Korn Shell'            ,\n            'ktm'         => 'Kotlin'                ,\n            'kt'          => 'Kotlin'                ,\n            'kts'         => 'Kotlin'                ,\n            'hlean'       => 'Lean'                  ,\n            'lean'        => 'Lean'                  ,\n            'lex'         => 'lex'                   ,\n            'l'           => 'lex'                   ,\n            'ld'          => 'Linker Script'         ,\n            'lb.xml'      => 'Liquibase'             ,\n            'lem'         => 'Lem'                   ,\n            'less'        => 'LESS'                  ,\n            'lfe'         => 'LFE'                   ,\n            'liquid'      => 'liquid'                ,\n            'lsp'         => 'Lisp'                  ,\n            'lisp'        => 'Lisp'                  ,\n            'll'          => 'LLVM IR'               ,\n            'lgt'         => 'Logtalk'               ,\n            'logtalk'     => 'Logtalk'               ,\n            'lp'          => 'AnsProlog'             ,  # Answer Set Programming / clingo\n            'wlua'        => 'Lua'                   ,\n            'rbxs'        => 'Lua'                   ,\n            'pd_lua'      => 'Lua'                   ,\n            'p8'          => 'Lua'                   ,\n            'nse'         => 'Lua'                   ,\n            'lua'         => 'Lua'                   ,\n            'luau'        => 'Luau'                  ,\n            'm3'          => 'Modula3'               ,\n            'm4'          => 'm4'                    ,\n            'makefile'    => 'make'                  ,\n            'Makefile'    => 'make'                  ,\n            'mao'         => 'Mako'                  ,\n            'mako'        => 'Mako'                  ,\n            'workbook'    => 'Markdown'              ,\n            'ronn'        => 'Markdown'              ,\n            'mkdown'      => 'Markdown'              ,\n            'mkdn'        => 'Markdown'              ,\n            'mkd'         => 'Markdown'              ,\n            'mdx'         => 'Markdown'              ,\n            'mdwn'        => 'Markdown'              ,\n            'mdown'       => 'Markdown'              ,\n            'markdown'    => 'Markdown'              ,\n            'contents.lr' => 'Markdown'              ,\n            'md'          => 'Markdown'              ,\n            'org'         => 'Org Mode'              ,\n            'mc'          => 'Windows Message File'  ,\n            'met'         => 'Teamcenter met'        ,\n            'mg'          => 'Modula3'               ,\n            'mojom'       => 'Mojom'                 ,\n            'mojo'        => 'Mojo'                  ,\n            '🔥'          => 'Mojo'                  ,\n            'mbt'         => 'MoonBit'               ,\n            'mbti'        => 'MoonBit'               ,\n            'mbtx'        => 'MoonBit'               ,\n            'mbty'        => 'MoonBit'               ,\n            'meson.build' => 'Meson'                 ,\n            'metal'       => 'Metal'                 ,\n            'mk'          => 'make'                  ,\n#           'mli'         => 'ML'                    , # ML not implemented\n#           'ml'          => 'ML'                    ,\n            'ml4'         => 'OCaml'                 ,\n            'eliomi'      => 'OCaml'                 ,\n            'eliom'       => 'OCaml'                 ,\n            'ml'          => 'OCaml'                 ,\n            'mli'         => 'OCaml'                 ,\n            'mly'         => 'OCaml'                 ,\n            'mll'         => 'OCaml'                 ,\n            'm'           => 'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' ,\n            'mm'          => 'Objective-C++'         ,\n            'msg'         => 'Gencat NLS'            ,\n            'magik'       => 'Magik'                 ,\n            'nbp'         => 'Mathematica'           ,\n            'mathematica' => 'Mathematica'           ,\n            'ma'          => 'Mathematica'           ,\n            'cdf'         => 'Mathematica'           ,\n            'mt'          => 'Mathematica'           ,\n            'wl'          => 'Mathematica'           ,\n            'wlt'         => 'Mathematica'           ,\n            'mo'          => 'Modelica'              ,\n            'mustache'    => 'Mustache'              ,\n            'wdproj'      => 'MSBuild script'        ,\n            'csproj'      => 'MSBuild script'        ,\n            'vcproj'      => 'MSBuild script'        ,\n            'wixproj'     => 'MSBuild script'        ,\n            'btproj'      => 'MSBuild script'        ,\n            'msbuild'     => 'MSBuild script'        ,\n            'sln'         => 'Visual Studio Solution',\n            'mps'         => 'MUMPS'                 ,\n            'mth'         => 'Teamcenter mth'        ,\n            'n'           => 'Nemerle'               ,\n            'nlogo'       => 'NetLogo'               ,\n            'nls'         => 'NetLogo'               ,\n            'nf'          => 'Nextflow'              ,\n            'ncl'         => 'Nickel'                ,\n            'nims'        => 'Nim'                   ,\n            'nimrod'      => 'Nim'                   ,\n            'nimble'      => 'Nim'                   ,\n            'nim.cfg'     => 'Nim'                   ,\n            'nim'         => 'Nim'                   ,\n            'nix'         => 'Nix'                   ,\n            'nu'          => 'Nushell'               ,\n            'nuon'        => 'Nushell Object Notation',\n            'nut'         => 'Squirrel'              ,\n            'njk'         => 'Nunjucks'              ,\n            'odin'        => 'Odin'                  ,\n            'oscript'     => 'LiveLink OScript'      ,\n            'bod'         => 'Oracle PL/SQL'         ,\n            'bdy'         => 'Oracle PL/SQL'         ,\n            'spc'         => 'Oracle PL/SQL'         ,\n            'fnc'         => 'Oracle PL/SQL'         ,\n            'prc'         => 'Oracle PL/SQL'         ,\n            'trg'         => 'Oracle PL/SQL'         ,\n            'p'           => 'Pascal/Pawn'           ,\n            'pad'         => 'Ada'                   , # Oracle Ada preprocessor\n            'page'        => 'Visualforce Page'      ,\n            'pas'         => 'Pascal'                ,\n            'pcc'         => 'C++'                   , # Oracle C++ preprocessor\n            'rexfile'     => 'Perl'                  ,\n            'psgi'        => 'Perl'                  ,\n            'ph'          => 'Perl'                  ,\n            'makefile.pl' => 'Perl'                  ,\n            'cpanfile'    => 'Perl'                  ,\n            'al'          => 'Perl'                  ,\n            'ack'         => 'Perl'                  ,\n            'perl'        => 'Perl'                  ,\n            'pfo'         => 'Fortran 77'            ,\n            'pgc'         => 'C'                     , # Postgres embedded C/C++\n            'phpt'        => 'PHP'                   ,\n            'phps'        => 'PHP'                   ,\n            'phakefile'   => 'PHP'                   ,\n            'ctp'         => 'PHP'                   ,\n            'aw'          => 'PHP'                   ,\n            'php_cs.dist' => 'PHP'                   ,\n            'php_cs'      => 'PHP'                   ,\n            'php3'        => 'PHP'                   ,\n            'php4'        => 'PHP'                   ,\n            'php5'        => 'PHP'                   ,\n            'php'         => 'PHP'                   ,\n            'phtml'       => 'PHP'                   ,\n            'pig'         => 'Pig Latin'             ,\n            'plh'         => 'Perl'                  ,\n            'pl'          => 'Perl/Prolog'           ,\n            'PL'          => 'Perl/Prolog'           ,\n            'p6'          => 'Raku/Prolog'           ,\n            'P6'          => 'Raku/Prolog'           ,\n            'plx'         => 'Perl'                  ,\n            'pm'          => 'Perl'                  ,\n            'pm6'         => 'Raku'                  ,\n            'raku'        => 'Raku'                  ,\n            'rakumod'     => 'Raku'                  ,\n            'pom.xml'     => 'Maven'                 ,\n            'pom'         => 'Maven'                 ,\n            'scad'        => 'OpenSCAD'              ,\n            'yap'         => 'Prolog'                ,\n            'prolog'      => 'Prolog'                ,\n            'P'           => 'Prolog'                ,\n            'pp'          => 'Pascal/Puppet'         ,\n            'viw'         => 'SQL'                   ,\n            'udf'         => 'SQL'                   ,\n            'tab'         => 'SQL'                   ,\n            'mysql'       => 'SQL'                   ,\n            'cql'         => 'SQL'                   ,\n            'psql'        => 'SQL'                   ,\n            'xpy'         => 'Python'                ,\n            'wsgi'        => 'Python'                ,\n            'wscript'     => 'Python'                ,\n            'workspace'   => 'Python'                ,\n            'tac'         => 'Python'                ,\n            'snakefile'   => 'Python'                ,\n            'sconstruct'  => 'Python'                ,\n            'sconscript'  => 'Python'                ,\n            'pyt'         => 'Python'                ,\n            'pyp'         => 'Python'                ,\n            'pyi'         => 'Python'                ,\n            'pyde'        => 'Python'                ,\n            'py3'         => 'Python'                ,\n            'lmi'         => 'Python'                ,\n            'gypi'        => 'Python'                ,\n            'gyp'         => 'Python'                ,\n            'build.bazel' => 'Python'                ,\n            'buck'        => 'Python'                ,\n            'gclient'     => 'Python'                ,\n            'py'          => 'Python'                ,\n            'pyw'         => 'Python'                ,\n            'ipynb'       => 'Jupyter Notebook'      ,\n            'pyj'         => 'RapydScript'           ,\n            'pxi'         => 'Cython'                ,\n            'pxd'         => 'Cython'                ,\n            'pyx'         => 'Cython'                ,\n            'qbs'         => 'QML'                   ,\n            'qml'         => 'QML'                   ,\n            'watchr'      => 'Ruby'                  ,\n            'vagrantfile' => 'Ruby'                  ,\n            'thorfile'    => 'Ruby'                  ,\n            'thor'        => 'Ruby'                  ,\n            'snapfile'    => 'Ruby'                  ,\n            'ru'          => 'Ruby'                  ,\n            'rbx'         => 'Ruby'                  ,\n            'rbw'         => 'Ruby'                  ,\n            'rbuild'      => 'Ruby'                  ,\n            'rabl'        => 'Ruby'                  ,\n            'puppetfile'  => 'Ruby'                  ,\n            'podfile'     => 'Ruby'                  ,\n            'mspec'       => 'Ruby'                  ,\n            'mavenfile'   => 'Ruby'                  ,\n            'jbuilder'    => 'Ruby'                  ,\n            'jarfile'     => 'Ruby'                  ,\n            'guardfile'   => 'Ruby'                  ,\n            'god'         => 'Ruby'                  ,\n            'gemspec'     => 'Ruby'                  ,\n            'gemfile.lock'=> 'Ruby'                  ,\n            'gemfile'     => 'Ruby'                  ,\n            'fastfile'    => 'Ruby'                  ,\n            'eye'         => 'Ruby'                  ,\n            'deliverfile' => 'Ruby'                  ,\n            'dangerfile'  => 'Ruby'                  ,\n            'capfile'     => 'Ruby'                  ,\n            'buildfile'   => 'Ruby'                  ,\n            'builder'     => 'Ruby'                  ,\n            'brewfile'    => 'Ruby'                  ,\n            'berksfile'   => 'Ruby'                  ,\n            'appraisals'  => 'Ruby'                  ,\n            'pryrc'       => 'Ruby'                  ,\n            'irbrc'       => 'Ruby'                  ,\n            'rb'          => 'Ruby'                  ,\n            'podspec'     => 'Ruby'                  ,\n            'rake'        => 'Ruby'                  ,\n         #  'resx'        => 'ASP.NET'               ,\n            'rex'         => 'Oracle Reports'        ,\n            'pprx'        => 'Rexx'                  ,\n            'rexx'        => 'Rexx'                  ,\n            'rhtml'       => 'Ruby HTML'             ,\n            'circom'      => 'Circom'                ,\n            'cairo'       => 'Cairo'                 ,\n            'clar'        => 'Clarity'                ,\n            'rs.in'       => 'Rust'                  ,\n            'rs'          => 'Rust'                  ,\n            'rst.txt'     => 'reStructuredText'      ,\n            'rest.txt'    => 'reStructuredText'      ,\n            'rest'        => 'reStructuredText'      ,\n            'rst'         => 'reStructuredText'      ,\n            's'           => 'Assembly'              ,\n            'S'           => 'Assembly'              ,\n            'SCA'         => 'Visual Fox Pro'        ,\n            'sca'         => 'Visual Fox Pro'        ,\n            'sbt'         => 'Scala'                 ,\n            'kojo'        => 'Scala'                 ,\n            'scala'       => 'Scala'                 ,\n            'sbl'         => 'Softbridge Basic'      ,\n            'SBL'         => 'Softbridge Basic'      ,\n            'sed'         => 'sed'                   ,\n            'sp'          => 'SparForte'             ,\n            'sol'         => 'Solidity'              ,\n            'p4'          => 'P4'                    ,\n            'ses'         => 'Patran Command Language'   ,\n            'pcl'         => 'Patran Command Language'   ,\n            'pwn'         => 'Pawn'                  ,\n            'pawn'        => 'Pawn'                  ,\n            'pek'         => 'Pek'                   ,\n            'peg'         => 'PEG'                   ,\n            'pegjs'       => 'peg.js'                ,\n            'peggy'       => 'peggy'                 ,\n            'pest'        => 'Pest'                  ,\n            'pkl'         => 'Pkl'                   ,\n            'prisma'      => 'Prisma Schema'         ,\n            'tspeg'       => 'tspeg'                 ,\n            'jspeg'       => 'tspeg'                 ,\n            'pl1'         => 'PL/I'                  ,\n            'plm'         => 'PL/M'                  ,\n            'lit'         => 'PL/M'                  ,\n            'iuml'        => 'PlantUML'              ,\n            'pu'          => 'PlantUML'              ,\n            'puml'        => 'PlantUML'              ,\n            'plantuml'    => 'PlantUML'              ,\n            'wsd'         => 'PlantUML'              ,\n            'properties'  => 'Properties'            ,\n            'po'          => 'PO File'               ,\n            'pony'        => 'Pony'                  ,\n            'pbt'         => 'PowerBuilder'          ,\n            'sra'         => 'PowerBuilder'          ,\n            'srf'         => 'PowerBuilder'          ,\n            'srm'         => 'PowerBuilder'          ,\n            'srs'         => 'PowerBuilder'          ,\n            'sru'         => 'PowerBuilder'          ,\n            'srw'         => 'PowerBuilder'          ,\n            'jade'        => 'Pug'                   ,\n            'pug'         => 'Pug'                   ,\n            'purs'        => 'PureScript'            ,\n            'prefab'      => 'Unity-Prefab'          ,\n            'proto'       => 'Protocol Buffers'      ,\n            'mat'         => 'Unity-Prefab'          ,\n            'ps1'         => 'PowerShell'            ,\n            'psd1'        => 'PowerShell'            ,\n            'psm1'        => 'PowerShell'            ,\n            'prql'        => 'PRQL'                  ,\n            'rsx'         => 'R'                     ,\n            'rd'          => 'R'                     ,\n            'expr-dist'   => 'R'                     ,\n            'rprofile'    => 'R'                     ,\n            'R'           => 'R'                     ,\n            'r'           => 'R'                     ,\n            'raml'        => 'RAML'                  ,\n            'ring'        => 'Ring'                  ,\n            'rh'          => 'Ring'                  ,\n            'rform'       => 'Ring'                  ,\n            'rktd'        => 'Racket'                ,\n            'rkt'         => 'Racket'                ,\n            'rktl'        => 'Racket'                ,\n            'Rmd'         => 'Rmd'                   ,\n            'rhai'        => 'Rhai'                  ,\n            're'          => 'ReasonML'              ,\n            'rei'         => 'ReasonML'              ,\n            'res'         => 'ReScript'              ,\n            'resi'        => 'ReScript'              ,\n            'scrbl'       => 'Racket'                ,\n            'sps'         => 'Scheme'                ,\n            'sc'          => 'Scheme'                ,\n            'ss'          => 'Scheme'                ,\n            'scm'         => 'Scheme'                ,\n            'sch'         => 'Scheme'                ,\n            'sls'         => 'Scheme/SaltStack'      ,\n            'sld'         => 'Scheme'                ,\n            'robot'       => 'RobotFramework'        ,\n            'rc'          => 'Windows Resource File' ,\n            'rc2'         => 'Windows Resource File' ,\n            'sas'         => 'SAS'                   ,\n            'sass'        => 'Sass'                  ,\n            'scss'        => 'SCSS'                  ,\n            'sh'          => 'Bourne Shell'          ,\n            'smarty'      => 'Smarty'                ,\n            'sml'         => 'Standard ML'           ,\n            'sig'         => 'Standard ML'           ,\n            'fun'         => 'Standard ML'           ,\n            'slim'        => 'Slim'                  ,\n            'e'           => 'Specman e'             ,\n            'sql'         => 'SQL'                   ,\n            'SQL'         => 'SQL'                   ,\n            'sproc.sql'   => 'SQL Stored Procedure'  ,\n            'spoc.sql'    => 'SQL Stored Procedure'  ,\n            'spc.sql'     => 'SQL Stored Procedure'  ,\n            'udf.sql'     => 'SQL Stored Procedure'  ,\n            'data.sql'    => 'SQL Data'              ,\n            'sss'         => 'SugarSS'               ,\n            'slint'       => 'Slint'                 ,\n            'st'          => 'Smalltalk'             ,\n            'rules'       => 'Snakemake'             ,\n            'smk'         => 'Snakemake'             ,\n            'styl'        => 'Stylus'                ,\n            'surql'       => 'SurrealQL'             ,\n            'i'           => 'SWIG'                  ,\n            'svelte'      => 'Svelte'                ,\n            'sv'          => 'Verilog-SystemVerilog' ,\n            'svh'         => 'Verilog-SystemVerilog' ,\n            'svg'         => 'SVG'                   ,\n            'SVG'         => 'SVG'                   ,\n            'v'           => 'Verilog-SystemVerilog/Coq' ,\n            'td'          => 'TableGen'              ,\n            'tcl'         => 'Tcl/Tk'                ,\n            'tcsh'        => 'C Shell'               ,\n            'tk'          => 'Tcl/Tk'                ,\n            'teal'        => 'TEAL'                  ,\n            'templ'       => 'Templ'                 ,\n            'mkvi'        => 'TeX'                   ,\n            'mkiv'        => 'TeX'                   ,\n            'mkii'        => 'TeX'                   ,\n            'ltx'         => 'TeX'                   ,\n            'lbx'         => 'TeX'                   ,\n            'ins'         => 'TeX'                   ,\n            'cbx'         => 'TeX'                   ,\n            'bib'         => 'TeX'                   ,\n            'bbx'         => 'TeX'                   ,\n            'aux'         => 'TeX'                   ,\n            'tex'         => 'TeX'                   , # TeX, LaTex, MikTex, ..\n            'toml'        => 'TOML'                  ,\n            'sty'         => 'TeX'                   ,\n#           'cls'         => 'TeX'                   ,\n            'dtx'         => 'TeX'                   ,\n            'bst'         => 'TeX'                   ,\n            'txt'         => 'Text'                  ,\n            'text'        => 'Text'                  ,\n            'tres'        => 'Godot Resource'        ,\n            'tscn'        => 'Godot Scene'           ,\n            'thrift'      => 'Thrift'                ,\n            'tla'         => 'TLA+'                  ,\n            'tpl'         => 'Smarty'                ,\n            'trigger'     => 'Apex Trigger'          ,\n            'ttcn'        => 'TTCN'                  ,\n            'ttcn2'       => 'TTCN'                  ,\n            'ttcn3'       => 'TTCN'                  ,\n            'ttcnpp'      => 'TTCN'                  ,\n            'sdl'         => 'TNSDL'                 ,\n            'ssc'         => 'TNSDL'                 ,\n            'sdt'         => 'TNSDL'                 ,\n            'spd'         => 'TNSDL'                 ,\n            'sst'         => 'TNSDL'                 ,\n            'rou'         => 'TNSDL'                 ,\n            'cin'         => 'TNSDL'                 ,\n            'cii'         => 'TNSDL'                 ,\n            'interface'   => 'TNSDL'                 ,\n            'in1'         => 'TNSDL'                 ,\n            'in2'         => 'TNSDL'                 ,\n            'in3'         => 'TNSDL'                 ,\n            'in4'         => 'TNSDL'                 ,\n            'inf'         => 'TNSDL'                 ,\n            'tpd'         => 'TITAN Project File Information',\n            'ts'          => 'TypeScript/Qt Linguist',\n            'cts'         => 'TypeScript'            ,\n            'mts'         => 'TypeScript'            ,\n            'tsx'         => 'TypeScript'            ,\n            'tss'         => 'Titanium Style Sheet'  ,\n            'twig'        => 'Twig'                  ,\n            'typ'         => 'Typst'                 ,\n            'um'          => 'Umka'                  ,\n            'uss'         => 'USS'                   ,\n            'uxml'        => 'UXML'                  ,\n            'ui'          => 'XML-Qt-GTK/Glade'      ,\n            'glade'       => 'Glade'                 ,\n            'vala'        => 'Vala'                  ,\n            'vapi'        => 'Vala Header'           ,\n            'vhw'         => 'VHDL'                  ,\n            'vht'         => 'VHDL'                  ,\n            'vhs'         => 'VHDL'                  ,\n            'vho'         => 'VHDL'                  ,\n            'vhi'         => 'VHDL'                  ,\n            'vhf'         => 'VHDL'                  ,\n            'vhd'         => 'VHDL'                  ,\n            'VHD'         => 'VHDL'                  ,\n            'vhdl'        => 'VHDL'                  ,\n            'VHDL'        => 'VHDL'                  ,\n            'bas'         => 'Visual Basic'          ,\n            'BAS'         => 'Visual Basic'          ,\n            'ctl'         => 'Visual Basic'          ,\n            'dsr'         => 'Visual Basic'          ,\n            'Dsr'         => 'Visual Basic'          ,\n            'frm'         => 'Visual Basic'          ,\n            'frx'         => 'Visual Basic'          ,\n            'FRX'         => 'Visual Basic'          ,\n            'vba'         => 'VBA'                   ,\n            'VBA'         => 'VBA'                   ,\n            'vbhtml'      => 'Visual Basic .NET'     ,\n            'VBHTML'      => 'Visual Basic .NET'     ,\n            'vbproj'      => 'Visual Basic .NET'     ,\n            'vbp'         => 'Visual Basic'          , # .vbp - autogenerated\n            'vbs'         => 'VBScript'              ,\n            'VBS'         => 'VBScript'              ,\n            'vb'          => 'Visual Basic .NET'     ,\n            'VB'          => 'Visual Basic .NET'     ,\n            'vbw'         => 'Visual Basic'          , # .vbw - autogenerated\n            'vue'         => 'Vuejs Component'       ,\n            'vy'          => 'Vyper'                 ,\n            'webinfo'     => 'ASP.NET'               ,\n            'wsdl'        => 'Web Services Description',\n            'x'           => 'Logos'                 ,\n            'xm'          => 'Logos'                 ,\n            'xpo'         => 'X++'                   , # Microsoft Dynamics AX 4.0 export format\n            'xmi'         => 'XMI'                   ,\n            'XMI'         => 'XMI'                   ,\n            'zcml'        => 'XML'                   ,\n            'xul'         => 'XML'                   ,\n            'xspec'       => 'XML'                   ,\n            'xproj'       => 'XML'                   ,\n            'xml.dist'    => 'XML'                   ,\n            'xliff'       => 'XML'                   ,\n            'xlf'         => 'XML'                   ,\n            'xib'         => 'XML'                   ,\n            'xacro'       => 'XML'                   ,\n            'x3d'         => 'XML'                   ,\n            'wsf'         => 'XML'                   ,\n            'web.release.config'=> 'XML'             ,\n            'web.debug.config'=> 'XML'               ,\n            'web.config'  => 'XML'                   ,\n            'wxml'        => 'WXML'                  ,\n            'wxss'        => 'WXSS'                  ,\n            'vxml'        => 'XML'                   ,\n            'vstemplate'  => 'XML'                   ,\n            'vssettings'  => 'XML'                   ,\n            'vsixmanifest'=> 'XML'                   ,\n            'vcxproj'     => 'XML'                   ,\n            'ux'          => 'XML'                   ,\n            'urdf'        => 'XML'                   ,\n            'tmtheme'     => 'XML'                   ,\n            'tmsnippet'   => 'XML'                   ,\n            'tmpreferences'=> 'XML'                  ,\n            'tmlanguage'  => 'XML'                   ,\n            'tml'         => 'XML'                   ,\n            'tmcommand'   => 'XML'                   ,\n            'targets'     => 'XML'                   ,\n            'sublime-snippet'=> 'XML'                   ,\n            'sttheme'     => 'XML'                   ,\n            'storyboard'  => 'XML'                   ,\n            'srdf'        => 'XML'                   ,\n            'shproj'      => 'XML'                   ,\n            'sfproj'      => 'XML'                   ,\n            'settings.stylecop'=> 'XML'                   ,\n            'scxml'       => 'XML'                   ,\n            'rss'         => 'XML'                   ,\n            'resx'        => 'XML'                   ,\n            'rdf'         => 'XML'                   ,\n            'pt'          => 'XML'                   ,\n            'psc1'        => 'XML'                   ,\n            'ps1xml'      => 'XML'                   ,\n            'props'       => 'XML'                   ,\n            'proj'        => 'XML'                   ,\n            'plist'       => 'XML'                   ,\n            'pkgproj'     => 'XML'                   ,\n            'packages.config'=> 'XML'                   ,\n            'osm'         => 'XML'                   ,\n            'odd'         => 'XML'                   ,\n            'nuspec'      => 'XML'                   ,\n            'nuget.config'=> 'XML'                   ,\n            'nproj'       => 'XML'                   ,\n            'ndproj'      => 'XML'                   ,\n            'natvis'      => 'XML'                   ,\n            'mjml'        => 'XML'                   ,\n            'mdpolicy'    => 'XML'                   ,\n            'launch'      => 'XML'                   ,\n            'kml'         => 'XML'                   ,\n            'jsproj'      => 'XML'                   ,\n            'jelly'       => 'XML'                   ,\n            'ivy'         => 'XML'                   ,\n            'iml'         => 'XML'                   ,\n            'grxml'       => 'XML'                   ,\n            'gmx'         => 'XML'                   ,\n            'fsproj'      => 'XML'                   ,\n            'filters'     => 'XML'                   ,\n            'dotsettings' => 'XML'                   ,\n            'dll.config'  => 'XML'                   ,\n            'ditaval'     => 'XML'                   ,\n            'ditamap'     => 'XML'                   ,\n            'depproj'     => 'XML'                   ,\n            'ct'          => 'XML'                   ,\n            'csl'         => 'XML'                   ,\n            'csdef'       => 'XML'                   ,\n            'cscfg'       => 'XML'                   ,\n            'cproject'    => 'XML'                   ,\n            'clixml'      => 'XML'                   ,\n            'ccxml'       => 'XML'                   ,\n            'ccproj'      => 'XML'                   ,\n            'builds'      => 'XML'                   ,\n            'axml'        => 'XML'                   ,\n            'app.config'  => 'XML'                   ,\n            'ant'         => 'XML'                   ,\n            'admx'        => 'XML'                   ,\n            'adml'        => 'XML'                   ,\n            'project'     => 'XML'                   ,\n            'classpath'   => 'XML'                   ,\n            'xml'         => 'XML'                   ,\n            'XML'         => 'XML'                   ,\n            'mxml'        => 'MXML'                  ,\n            'xml.builder' => 'builder'               ,\n            'build'       => 'NAnt script'           ,\n            'vim'         => 'vim script'            ,\n            'swift'       => 'Swift'                 ,\n            'xaml'        => 'XAML'                  ,\n            'wast'        => 'WebAssembly'           ,\n            'wat'         => 'WebAssembly'           ,\n            'wgsl'        => 'WGSL'                  ,\n            'wxs'         => 'WiX source'            ,\n            'wxi'         => 'WiX include'           ,\n            'wxl'         => 'WiX string localization' ,\n            'prw'         => 'xBase'                 ,\n            'prg'         => 'xBase'                 ,\n            'ch'          => 'xBase Header'          ,\n            'xqy'         => 'XQuery'                ,\n            'xqm'         => 'XQuery'                ,\n            'xql'         => 'XQuery'                ,\n            'xq'          => 'XQuery'                ,\n            'xquery'      => 'XQuery'                ,\n            'xsd'         => 'XSD'                   ,\n            'XSD'         => 'XSD'                   ,\n            'xslt'        => 'XSLT'                  ,\n            'XSLT'        => 'XSLT'                  ,\n            'xsl'         => 'XSLT'                  ,\n            'XSL'         => 'XSLT'                  ,\n            'xtend'       => 'Xtend'                 ,\n            'yacc'        => 'yacc'                  ,\n            'y'           => 'yacc'                  ,\n            'yml.mysql'   => 'YAML'                  ,\n            'yaml-tmlanguage'=> 'YAML'                  ,\n            'syntax'      => 'YAML'                  ,\n            'sublime-syntax'=> 'YAML'                  ,\n            'rviz'        => 'YAML'                  ,\n            'reek'        => 'YAML'                  ,\n            'mir'         => 'YAML'                  ,\n            'glide.lock'  => 'YAML'                  ,\n            'gemrc'       => 'YAML'                  ,\n            'clang-tidy'  => 'YAML'                  ,\n            'clang-format'=> 'YAML'                  ,\n            'yaml'        => 'YAML'                  ,\n            'yml'         => 'YAML'                  ,\n            'yang'        => 'Yang'                  ,\n            'yarn'        => 'Yarn'                  ,\n            'zig'         => 'Zig'                   ,\n            'zsh'         => 'zsh'                   ,\n            'rego'        => 'Rego'                  ,\n            'bb'          => 'BitBake'               ,\n            'bbappend'    => 'BitBake'               ,\n            'bbclass'     => 'BitBake'               ,\n            'conf'        => 'Unknown/BitBake'       ,\n            );\n# 1}}}\n%{$rh_Language_by_Script}    = (             # {{{1\n            'awk'       => 'awk'                   ,\n            'bash'      => 'Bourne Again Shell'    ,\n            'bc'        => 'bc'                    ,# calculator\n            'crystal'   => 'Crystal'               ,\n            'csh'       => 'C Shell'               ,\n            'dmd'       => 'D'                     ,\n            'dtrace'    => 'dtrace'                ,\n            'escript'   => 'Erlang'                ,\n            'groovy'    => 'Groovy'                ,\n            'idl'       => 'IDL'                   ,\n            'kermit'    => 'Kermit'                ,\n            'ksh'       => 'Korn Shell'            ,\n            'lua'       => 'Lua'                   ,\n            'luau'      => 'Luau'                  ,\n            'make'      => 'make'                  ,\n            'octave'    => 'Octave'                ,\n            'perl5'     => 'Perl'                  ,\n            'perl'      => 'Perl'                  ,\n            'miniperl'  => 'Perl'                  ,\n            'nextflow'  => 'Nextflow'              ,\n            'php'       => 'PHP'                   ,\n            'php5'      => 'PHP'                   ,\n            'python'    => 'Python'                ,\n            'python2.6' => 'Python'                ,\n            'python2.7' => 'Python'                ,\n            'python3'   => 'Python'                ,\n            'python3.3' => 'Python'                ,\n            'python3.4' => 'Python'                ,\n            'python3.5' => 'Python'                ,\n            'python3.6' => 'Python'                ,\n            'python3.7' => 'Python'                ,\n            'python3.8' => 'Python'                ,\n            'python3.9' => 'Python'                ,\n            'python3.10'=> 'Python'                ,\n            'python3.11'=> 'Python'                ,\n            'python3.12'=> 'Python'                ,\n            'python3.13'=> 'Python'                ,\n            'python3.14'=> 'Python'                ,\n            'perl6'     => 'Raku'                  ,\n            'raku'      => 'Raku'                  ,\n            'rakudo'    => 'Raku'                  ,\n            'rexx'      => 'Rexx'                  ,\n            'regina'    => 'Rexx'                  ,\n            'ruby'      => 'Ruby'                  ,\n            'sed'       => 'sed'                   ,\n            'sh'        => 'Bourne Shell'          ,\n            'swipl'     => 'Prolog'                ,\n            'tcl'       => 'Tcl/Tk'                ,\n            'tclsh'     => 'Tcl/Tk'                ,\n            'tcsh'      => 'C Shell'               ,\n            'wish'      => 'Tcl/Tk'                ,\n            'zsh'       => 'zsh'                   ,\n            );\n# 1}}}\n%{$rh_Language_by_File_Type}      = (        # {{{1\n            'build.xml'         => 'Ant/XML'            ,\n            'BUILD'             => 'Bazel'              ,\n            'WORKSPACE'         => 'Bazel'              ,\n            'cmakelists.txt'    => 'CMake'              ,\n            'CMakeLists.txt'    => 'CMake'              ,\n            'Jamfile'           => 'Jam'                ,\n            'jamfile'           => 'Jam'                ,\n            'Jamrules'          => 'Jam'                ,\n            'justfile'          => 'Justfile'           ,\n            'Justfile'          => 'Justfile'           ,\n            'Makefile'          => 'make'               ,\n            'makefile'          => 'make'               ,\n            'meson.build'       => 'Meson'              ,\n            'Gnumakefile'       => 'make'               ,\n            'gnumakefile'       => 'make'               ,\n            'pom.xml'           => 'Maven/XML'          ,\n            'Rakefile'          => 'Ruby'               ,\n            'rakefile'          => 'Ruby'               ,\n            'Snakefile'         => 'Snakemake'          ,\n            'Dockerfile'        => 'Dockerfile'         ,\n            'Dockerfile.m4'     => 'Dockerfile'         ,\n            'Dockerfile.cmake'  => 'Dockerfile'         ,\n            'dockerfile'        => 'Dockerfile'         ,\n            'dockerfile.m4'     => 'Dockerfile'         ,\n            'dockerfile.cmake'  => 'Dockerfile'         ,\n            'Containerfile'     => 'Containerfile'      ,\n            'Jenkinsfile'       => 'Groovy'             ,\n            'jenkinsfile'       => 'Groovy'             ,\n            );\n# 1}}}\n%{$rh_Language_by_Prefix}     = (            # {{{1\n            'Dockerfile'        => 'Dockerfile'         ,\n            'Containerfile'     => 'Containerfile'         ,\n            );\n# 1}}}\n%{$rhaa_Filters_by_Language} = (            # {{{1\n    '(unknown)'          => [ ],\n    'ABAP'               => [   [ 'remove_matches'      , '^\\*'    ], ],\n    'ActionScript'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Activiti Business Process' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Apex Class'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'AppleScript'         => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_comments_in_strings', '\"', '(*', '*)' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'ASP'                => [   [ 'remove_matches'      , '^\\s*\\47'], ],  # \\47 = '\n    'ASP.NET'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_between_general', '<%--', '--%>' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                            ],\n    'Ada'                => [   [ 'remove_matches'      , '^\\s*--' ], ],\n    'ADSO/IDSM'          => [   [ 'remove_matches'      , '^\\s*\\*[\\+\\!]' ], ],\n    'Agda'               => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'AMPLE'              => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'APL'                => [\n                                [ 'remove_matches'      , '^\\s*⍝' ],\n                            ],\n    'AnsProlog'          => [\n                                [ 'remove_between_general', '%*', '*%' ],\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Ant/XML'            => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'ANTLR Grammar'      => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Ant'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Apex Trigger'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Aria'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Arduino Sketch'     => [ # Arduino IDE inserts problematic 0xA0 characters; strip them\n                                [ 'replace_regex' , '\\xa0', \" \" ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ArkTs'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Arturo'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'AsciiDoc'           => [\n                                [ 'remove_between_general', '////', '////' ],\n                                [ 'remove_matches'      , '^\\s*\\/\\/'  ],\n                            ],\n    'AspectJ'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Assembly'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*\\@' ],\n                                [ 'remove_matches'      , '^\\s*\\|' ],\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                                [ 'remove_inline'       , '\\@.*$'  ],\n                                [ 'remove_inline'       , '\\|.*$'  ],\n                                [ 'remove_inline'       , '!.*$'   ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                                [ 'remove_matches'      , '^\\*'    ],  # z/OS Assembly\n                            ],\n    'Astro'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Asymptote'          => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'AutoHotkey'         => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'awk'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'AXAML'              => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Bazel'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'bc'                 => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Beluga'             => [\n                                [ 'remove_between_general', '%{', '%}' ],\n                                [ 'remove_matches'      , '^\\s*%'      ],\n                            ],\n    'Bicep'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'BizTalk Pipeline' =>   [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'BizTalk Orchestration' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Blade'              => [\n                                [ 'remove_between_general', '{{--', '--}}' ],\n                                [ 'remove_html_comments',                  ],\n                            ],\n    'Blueprint'          => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Bourne Again Shell' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Bourne Shell'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Brainfuck'          => [ # puerile name for a language\n#                               [ 'call_regexp_common'  , 'Brainfuck' ],  # inaccurate\n                                [ 'remove_bf_comments',               ],\n                            ],\n    'BrightScript'       => [\n                                [ 'remove_matches'      , '^\\s*rem', ],\n                                [ 'remove_matches'      , '^\\s*\\'',  ],\n                            ],\n    'builder'            => [\n                                [ 'remove_matches'      , '^\\s*xml_markup.comment!'  ],\n                            ],\n    'C'                  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C++'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C/C++ Header'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cadence'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cangjie'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Carbon'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Chapel'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clean'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clojure'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_matches'      , '^\\s*#_'  ],\n                            ],\n    'ClojureScript'      => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'ClojureC'           => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'Clojure/Cangjie'    => [ [ 'die' ,  ], ], # never called\n    'CMake'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Crystal'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Constraint Grammar' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'CUDA'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cython'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'C#/Smalltalk' => [ [ 'die' ,  ], ], # never called\n    'C#'                 => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C# Designer'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C# Generated'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cake Build Script'  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'CCS'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Civet'              => [\n                                [ 'call_parse_civet'               ],\n                            ],\n    'CSS'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'CSV'                => [  # comma separated value files have no comments;\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ], # included simply to allow diff's\n    'COBOL'              => [   [ 'remove_cobol_comments',         ], ],\n    'CoCoA 5'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'CodeQL'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'CoffeeScript'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'ColdFusion'         => [   [ 'remove_html_comments',          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'ColdFusion CFScript'=> [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Containerfile'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Coq'                => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Crystal Reports'    => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'CSON'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Cucumber'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                            ],\n    'C3'                 => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_between_general', '<*', '*>' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'D/dtrace'           => [ [ 'die' ,          ], ], # never called\n    'D'                  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/+', '+/' ],\n                                [ 'remove_between_general', '/+', '+/' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'DAL'                => [\n                                [ 'remove_between_general', '[', ']', ],\n                            ],\n    'DAML'               => [\n                                [ 'remove_haskell_comments', '>filename<' ],\n                            ],\n    'Dart'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'DenizenScript'      => [ # same as YAML\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Derw'               => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_between_general', '{-', '-}' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Dafny'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'dhall'              => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Delphi Form'        => [ # same as Pascal\n                                [ 'remove_between_regex', '\\{[^$]', '}' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'DIET'               => [  # same as Pug\n                                [ 'remove_pug_block'    ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    # diff is kind of weird: anything but a space in the first column\n    # will count as code, with the exception of #, ---, +++.  Spaces\n    # in the first column denote context lines which aren't part of the\n    # difference.\n    'diff'               => [\n                                [ 'remove_matches'      , '^#' ],\n                                [ 'remove_matches'      , '^\\-\\-\\-' ],\n                                [ 'remove_matches'      , '^\\+\\+\\+' ],\n                                [ 'remove_matches'      , '^\\s' ],\n                            ],\n    'DITA'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'DOORS Extension Language' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Drools'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'dtrace'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'ECPP'               => [\n                                [ 'remove_between_general',\n                                  '<%doc>', '</%doc>',             ],\n                                [ 'remove_between_general',\n                                  '<#'    , '#>'     ,             ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'EEx'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'EJS'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Elm'                => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Embedded Crystal'   => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'ERB'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'Gencat NLS'         => [   [ 'remove_matches'       , '^\\$ .*$' ], ],\n    'NASTRAN DMAP'       => [\n                                [ 'remove_matches'      , '^\\s*\\$' ],\n                                [ 'remove_inline'       , '\\$.*$'  ],\n                            ],\n    'Dockerfile'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'DOS Batch'          => [\n                                [ 'remove_matches'      , '^\\s*rem' ],\n                                [ 'remove_matches'      , '^\\s*::'  ],\n                            ],\n    'DTD'                => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Elixir'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'elixir_doc_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Elixir Script'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'elixir_doc_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Erlang'             => [\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Expect'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Fennel'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Finite State Language' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Fish Shell'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Focus'              => [   [ 'remove_matches'      , '^\\s*\\-\\*'  ], ],\n    'Forth'              => [\n                                [ 'remove_matches'      , '^\\s*\\\\\\\\.*$'  ],\n                                [ 'Forth_paren_to_C'                 ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                                [ 'remove_inline'       , '\\\\\\\\.*$'  ],\n                            ],\n    'Fortran 77'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 77/Forth'   => [ [ 'die' ,          ], ], # never called\n    'F#/Forth'           => [ [ 'die' ,          ], ], # never called\n    'Fortran 90'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_f90_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 95'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_f90_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 2003'       => [\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                            ],\n    'Freemarker Template' => [\n                                [ 'remove_between_general', '<#--', '-->' ],\n                            ],\n    'Futhark'            => [\n                                [ 'remove_matches'      , '^\\s*--'  ],\n                            ],\n    'FXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'F#'                 => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'F# Script'          => [\n                                [ 'call_regexp_common'  , 'Pascal' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Flatbuffers'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Godot Scene'        => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Godot Resource'     => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Godot Shaders'      => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'GDScript'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Glade'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Gleam'              => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Glimmer JavaScript' => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Glimmer TypeScript' => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'GLSL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Go'                 => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '[\"`]', '*/*', '' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Gradle'             => [ # same as Groovy\n                                [ 'remove_inline'       , '//.*$'  ],\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Grails'             => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'GraphQL'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Groovy'             => [\n                                [ 'remove_inline'       , '//.*$'  ],\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Haml'               => [\n                                [ 'remove_haml_block'   ,          ],\n                                [ 'remove_html_comments',          ],\n                                [ 'remove_matches'      , '^\\s*/\\s*\\S+' ],\n                                [ 'remove_matches'      , '^\\s*-#\\s*\\S+' ],\n                            ],\n    'Handlebars'         => [\n                                [ 'remove_between_general', '{{!--', '--}}' ],\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Harbour'            => [\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Hare'               => [\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '//.*$' ],\n                            ],\n    'Haxe'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HCL'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HLSL'               => [\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HTML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'HTML EEx'           => [\n                                [ 'remove_matches'       , '^\\s*<% #' ],\n                                [ 'remove_between_general', '<%!--', '--%>' ],\n                            ],\n    'Hibernate'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'HolyC'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Hoon'               => [\n                                [ 'remove_matches'      , '^\\s*:[:><]' ],\n                                [ 'remove_inline'       , ':[:><].*$'  ],\n                            ],\n    'INI'                => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'XHTML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Haskell'            => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Haskell Boot'       => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'IDL'                => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'IDL/Qt Project/Prolog/ProGuard' => [ [ 'die' ,          ], ], # never called\n    'Idris'              => [\n                                [ 'remove_haskell_comments', '>filename<' ],\n                                [ 'remove_matches'      , '^\\s*\\|{3}' ],\n                            ],\n    'Igor Pro'           => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Literate Idris'     => [\n                                [ 'remove_matches'      , '^[^>]'  ],\n                            ],\n    'Imba'               => [\n                                [ 'remove_matches'      , '^\\s*#\\s'],\n                                [ 'remove_inline'       , '#\\s.*$' ],\n                                [ 'remove_between_regex', '###', '###' ],\n                            ],\n    'InstallShield'      => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'IPL'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jai'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jam'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Janet'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'JSP'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'JSP Tag Library Definition' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Jasper Report XML/Template' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'JavaServer Faces'   => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Java'               => [\n                                [ 'docstring_rm_comments', ],\n                                [ 'replace_regex', '\\\\\\\\$', ' '],\n                                # Java seems to have more path globs in strings\n                                # than other languages.  The variations makes\n                                # it tricky to craft a universal fix.\n                                # \\1 is a backreference to the first group, meaning\n                                # either single or double quote\n                                [ 'replace_between_regex', '([\"\\'])(.*?/\\*)(.*?)\\1',\n                                  '(.*?)' , '\"xx\"'],\n                                [ 'replace_between_regex', '([\"\\'])(.*?\\*/)(.*?)\\1',\n                                  '(.*?)' , '\"xx\"'],\n                               ## separate /* inside quoted strings with two\n                               ## concatenated strings split between / and *\n                               ##    -> defeated by \"xx/**/*_xx\" issue 365\n                               #[ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                               #  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"'],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'JavaScript'         => [\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jinja Template'     => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'JSX'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'JCL'                => [   [ 'remove_jcl_comments' ,          ], ],\n    'JSON'               => [   # ECMA-404, the JSON standard definition\n                                # makes no provision for JSON comments\n                                # so just use a placeholder filter\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'JSON5'              => [   # same as JavaScript\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jsonnet'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Julia'              => [\n                                [ 'remove_between_general', '#=', '=#' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Juniper Junos'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Justfile'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'kvlang'             => [\n                                [\"remove_matches\", '^\\s*#[^:]'],\n                            ],\n    'Kotlin'             => [\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Lean'               => [\n                                [ 'remove_between_general', '/-', '-/' ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Lem'                => [\n                                [ 'remove_OCaml_comments',         ],\n                            ],\n    'LESS'               => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'lex'                => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'LFE'                => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_between_general', '#|', '|#' ],\n                            ],\n    'Linker Script'      => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/'],\n                                [ 'call_regexp_common',     'C'            ],\n                            ],\n    'Liquibase'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'liquid'             => [\n                                [ 'remove_between_general', '{% comment %}',\n                                                            '{% endcomment %}' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Lisp'               => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_between_general', '#|', '|#' ],\n                            ],\n    'Lisp/OpenCL'        => [ [ 'die' ,          ], ], # never called\n    'Lisp/Julia'         => [ [ 'die' ,          ], ], # never called\n    'LiveLink OScript'   => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'LLVM IR'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Logos'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Logtalk'            => [  # same filters as Prolog\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Lua'                => [\n                                [ 'remove_between_general', '--[=====[', ']=====]' ],\n                                [ 'remove_between_general', '--[====[', ']====]' ],\n                                [ 'remove_between_general', '--[===[', ']===]' ],\n                                [ 'remove_between_general', '--[==[', ']==]' ],\n                                [ 'remove_between_general', '--[=[', ']=]' ],\n                                [ 'remove_between_general', '--[[', ']]' ],\n                                [ 'remove_matches'      , '^\\s*\\-\\-' ],\n                            ],\n    'Luau'               => [\n                                [ 'remove_between_general', '--[=====[', ']=====]' ],\n                                [ 'remove_between_general', '--[====[', ']====]' ],\n                                [ 'remove_between_general', '--[===[', ']===]' ],\n                                [ 'remove_between_general', '--[==[', ']==]' ],\n                                [ 'remove_between_general', '--[=[', ']=]' ],\n                                [ 'remove_between_general', '--[[', ']]' ],\n                                [ 'remove_matches'      , '^\\s*\\-\\-' ],\n                            ],\n    'make'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Meson'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'MATLAB'             => [\n                                [ 'remove_between_general', '%{', '%}' ],\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Magik'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Mathematica'        => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Maven/XML'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Maven'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Mercury'            => [\n                                [ 'remove_inline'       , '%.*$'   ],\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                            ],\n    'Metal'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Modelica'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Modula3'            => [   [ 'call_regexp_common'  , 'Pascal' ], ],\n        # Modula 3 comments are (* ... *) so applying the Pascal filter\n        # which also treats { ... } as a comment is not really correct.\n    'Mojom'              => [   [ 'call_regexp_common' , 'C++' ], ],\n    'Mojo'               => [\n                                [ 'remove_matches'      , '/\\*'    ],\n                                [ 'remove_matches'      , '\\*/'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'MoonBit'            => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'Nemerle'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nextflow'             => [\n                                # copy of Groovy\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nunjucks'           => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'Nushell'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Nushell Object Notation' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Objective-C'        => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Objective-C++'      => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'OCaml'              => [\n                                [ 'rm_comments_in_strings', '\"', '(*', '*)', 1 ],\n                                [ 'remove_OCaml_comments',         ],\n                            ],\n    'OpenCL'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PHP/Pascal/Fortran/Pawn/BitBake' => [ [ 'die' ,          ], ], # never called\n    'Mako'               => [\n                                [ 'remove_matches'       , '##.*$'  ],\n                            ],\n    'Markdown'           => [\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'remove_between_regex',\n                                  '\\[(comment|\\/\\/)?\\]\\s*:?\\s*(<\\s*>|#)?\\s*\\(.*?', '.*?\\)' ],\n                                # http://stackoverflow.com/questions/4823468/comments-in-markdown\n                            ],\n    'Org Mode'           => [\n                                # https://orgmode.org/guide/Comment-Lines.html\n                                [ 'remove_matches'      , '^\\s*#\\s.*'   ],\n                                [ 'remove_between_general', '#+BEGIN_COMMENT', '#+END_COMMENT' ],\n                                [ 'remove_between_general', '#+begin_comment', '#+end_comment' ],\n                                [ 'remove_between_regex',\n                                  '^\\*+\\s+COMMENT\\b.*',\n                                  '^\\*+\\s+(?!COMMENT\\b)'\n                                ],\n                            ],\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' => [ [ 'die' ,          ], ], # never called\n    'MUMPS'              => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'Mustache'           => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                            ],\n    '.NET IL'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nickel'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Nim'                => [\n                                [ 'remove_between_general', '#[', ']#' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n#                               [ 'docstring_to_C'                 ],\n#                               [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'NetLogo'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Nix'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Octave'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Odin'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'OpenSCAD'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Oracle Forms'       => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Oracle Reports'     => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Oracle PL/SQL'      => [\n                              # [ 'call_regexp_common'  , 'PL/SQL' ], # bad results\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Pascal'             => [\n                                [ 'remove_between_regex', '\\{[^$]', '}' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Pascal/Puppet'            => [ [ 'die' ,          ], ], # never called\n    'Puppet'             => [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'P4'                 => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Patran Command Language'=> [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'remove_matches'      , '^\\s*\\$#' ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                            ],\n    'Pawn'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Perl'               => [   [ 'remove_below'        , '^__(END|DATA)__'],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above' , '^=(?:pod|over|head\\d+)', '^=cut' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'PEG'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'peg.js'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'peggy'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Pek'                => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Pest'               => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Perl/Prolog'        => [ [ 'die' ,          ], ], # never called\n    'Pig Latin'          => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                            ],\n    'Pkl'                => [\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PL/I'               => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'PL/M'               => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'PlantUML'           => [\n                                [ 'remove_between_general', \"/'\", \"'/\" ],\n                                [ 'remove_matches'      , \"^\\\\s*'\" ],\n                            ],\n    'Prisma Schema'      => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Processing'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ProGuard'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'PO File'            => [\n                                [ 'remove_matches'      , '^\\s*#[^,]' ],  # '#,' is not a comment\n                            ],\n    'Pony'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PowerBuilder'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PowerShell'         => [\n                                [ 'powershell_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Prolog'             => [\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Properties'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                            ],\n    'Protocol Buffers'   => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PRQL'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                            ],\n    'Pug'                => [\n                                [ 'remove_pug_block'    ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'PureScript'         => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_between_general', '{-', '-}' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Python'             => [\n                                [ 'remove_matches'      , '/\\*'    ],\n                                [ 'remove_matches'      , '\\*/'    ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Jupyter Notebook'   => [   # these are JSON files; have no comments\n                                # would have to parse JSON for\n                                #      \"cell_type\": \"code\"\n                                # to count code lines\n                                [ 'jupyter_nb'                     ],\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'PHP'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'QML'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'XML (Qt/GTK)'       => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Qt Linguist'        => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Qt Project'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'R'                  => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ring'               => [\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Rmd'                => [\n                                [ 'reduce_to_rmd_code_blocks'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Racket'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Raku'               => [   [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above'  , '^=head1', '^=cut'  ],\n                                [ 'remove_below_above'  , '^=begin', '^=end'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Raku/Prolog'        => [ [ 'die' ,          ], ], # never called\n    'RAML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'RapydScript'        => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Razor'              => [\n                                [ 'remove_between_general', '@*', '*@' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                            ],\n    'reStructuredText'   => [\n                                [ 'remove_between_regex', '^\\.\\.', '^[^ \\n\\t\\r\\f\\.]' ]\n                            ],\n    'Rexx'               => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'ReasonML'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Rhai'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ReScript'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'RobotFramework'     => [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'remove_matches'      , '^\\s*Comment' ],\n                                [ 'remove_matches'      , '^\\s*\\*{3}\\s+(Variables|Test\\s+Cases|Settings|Keywords)\\s+\\*{3}' ] ,\n                                [ 'remove_matches'      , '^\\s*\\[(Documentation|Tags)\\]' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ruby'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above'  , '^=begin', '^=end' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ruby HTML'          => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Circom'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cairo'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clarity'            => [\n                                [ 'remove_matches'      , '^\\s*;;' ],\n                                [ 'remove_inline'       , ';;.*$'  ],\n                            ],\n    'Rust'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SaltStack'          => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'SAS'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_between_general', '*', ';' ],\n                            ],\n    'Sass'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Scala'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Scheme/SaltStack' => [ [ 'die' ,          ], ], # never called\n    'Scheme'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'SCSS'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'sed'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Slice'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Slim'               => [\n                                [ 'remove_slim_block'   ,          ],\n                            ],\n    'Slint'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SKILL/.NET IL'      => [   [ 'die' ,          ], ], # never called\n    'SKILL'              => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'SKILL++'            => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Smalltalk'          => [\n                                [ 'call_regexp_common'  , 'Smalltalk'      ],\n                            ],\n    'Smarty'             => [\n                                [ 'smarty_to_C'                    ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Snakemake'          => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Solidity'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SparForte'          => [\n                                [ 'remove_matches'      , '^\\s*#!' ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                            ],\n    'Specman e'          => [\n                                [ 'pre_post_fix'        , \"'>\", \"<'\"],\n                                [ 'remove_between_general', \"^'>\", \"^<'\" ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++',   ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_last_line'        , ],  # undo pre_post_fix addition\n                                                              # of trailing line of just <'\n                            ],\n    'Squirrel'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Starlark'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'SQL'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SQL Stored Procedure'=> [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SQL Data'           => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SurrealQL'          => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '--', '' ],\n                                [ 'rm_comments_in_strings', '\"', '#', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Standard ML'        => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Stata'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Stylus'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SugarSS'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Svelte'             => [\n                                [ 'rm_comments_in_strings', \"`\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SVG'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Swift'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SWIG'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n\n    'm4'                 => [   [ 'remove_matches'      , '^dnl\\s'  ], ],\n    'C Shell'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Kermit'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Korn Shell'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TableGen'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Tcl/Tk'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TEAL'               => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Teamcenter met'     => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Teamcenter mth'     => [   [ 'remove_matches'      , '^\\s*#'  ], ],\n    'Templ'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '[\"`]', '*/*', '' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'TeX'                => [\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Text'               => [\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'TLA+'               => [\n                                [ 'remove_TLAPlus_generated_code'                 ],\n                                [ 'remove_matches'               , '^\\\\s*\\\\\\\\\\\\*' ],\n                                [ 'remove_TLAPlus_comments'                       ],\n                            ],\n    'Thrift'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Titanium Style Sheet'  => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'remove_between_regex', '/[^/]', '[^/]/' ],\n                            ],\n    'TNSDL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                            ],\n    'TOML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TTCN'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                            ],\n    'TITAN Project File Information'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'tspeg'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Twig'               => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'TypeScript'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Typst'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Umka'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Unity-Prefab'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'USS'                => [   # same as CSS\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'UXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visual Fox Pro'     =>  [\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_inline'       , '\\*.*$'  ],\n                                [ 'remove_matches'      , '^\\s*&&' ],\n                                [ 'remove_inline'       , '&&.*$'  ],\n                            ],\n    'Softbridge Basic'   => [   [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'], ],  # \\47 = '\n    # http://www.altium.com/files/learningguides/TR0114%20VHDL%20Language%20Reference.pdf\n    'Vala'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vala Header'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Velocity Template Language' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*##' ],\n                                [ 'remove_between_general', '#**', '*#' ],\n                                [ 'add_newlines'        ,          ],\n                            ],\n    'Verilog-SystemVerilog/Coq' => [ ['die'] ], # never called\n    'Verilog-SystemVerilog' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'VHDL'               => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'vim script'         => [\n                                [ 'remove_matches'      , '^\\s*\"'  ],\n                                [ 'remove_inline'       , '\".*$'   ],\n                            ],\n    'VBScript' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visual Basic .NET' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'VBA' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visual Basic'       => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visualforce Component' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visualforce Page'   => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visual Studio Module' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Visual Studio Solution' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'VSCode Workspace'    => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vuejs Component'     => [\n                                [ 'remove_html_comments',          ],\n#                               [ 'call_regexp_common'  , 'HTML'   ], # problematic, ref #876\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vyper'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Teamcenter def'     => [   [ 'remove_matches'      , '^\\s*#'  ], ],\n    'Windows Module Definition' => [\n                                [ 'remove_matches'      , '^\\s*;' ],\n                                [ 'remove_inline'       , ';.*$'  ],\n                            ],\n    'yacc'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'YAML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'XAML'               => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'xBase Header'       => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'xBase'              => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'MXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Web Services Description' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WebAssembly'           => [\n                                [ 'remove_matches'      , '^\\s*;;' ],\n                            ],\n    'WGSL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Windows Message File'  => [\n                                [ 'remove_matches'      , '^\\s*;\\s*//' ],\n                                [ 'call_regexp_common'  , 'C'          ],\n                                [ 'remove_matches'      , '^\\s*;\\s*$'  ],\n#                               next line only hypothetical\n#                               [ 'remove_matches_2re'  , '^\\s*;\\s*/\\*',\n#                                                         '^\\s*;\\s*\\*/', ],\n                            ],\n    'Windows Resource File' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'WiX source'         => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WiX include'        => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WiX string localization' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WXSS'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'X++'                => [\n                                [ 'remove_matches', '\\s*#\\s*//' ],\n                                [ 'remove_between_regex', '#\\s*/\\*', '\\*/' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'XMI'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'XML'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'XQuery'             => [\n                                [ 'remove_between_general', '(:', ':)' ],\n                            ],\n    'XSD'                => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'XSLT'               => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Xtend'              => [   # copy of Java, plus triple << inline\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*\\x{c2ab}{3}'  ], # doesn't work\n                                # \\xCA2B is unicode << character\n                            ],\n    'NAnt script'       => [    [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'MSBuild script'    => [    [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Yang'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Yarn'               => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                            ],\n    'Zig'                => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'zsh'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    \"Rego\"               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    \"BitBake\"            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    );\n# 1}}}\n%{$rh_EOL_continuation_re} = (               # {{{1\n    'ActionScript'       =>     '\\\\\\\\$'         ,\n    'AspectJ'            =>     '\\\\\\\\$'         ,\n    'Assembly'           =>     '\\\\\\\\$'         ,\n    'ASP'                =>     '\\\\\\\\$'         ,\n    'ASP.NET'            =>     '\\\\\\\\$'         ,\n    'Ada'                =>     '\\\\\\\\$'         ,\n    'awk'                =>     '\\\\\\\\$'         ,\n    'bc'                 =>     '\\\\\\\\$'         ,\n    'C'                  =>     '\\\\\\\\$'         ,\n    'C++'                =>     '\\\\\\\\$'         ,\n    'C/C++ Header'       =>     '\\\\\\\\$'         ,\n    'CMake'              =>     '\\\\\\\\$'         ,\n    'Cython'             =>     '\\\\\\\\$'         ,\n    'C#'                 =>     '\\\\\\\\$'         ,\n    'C# Designer'        =>     '\\\\\\\\$'         ,\n    'Cake Build Script'  =>     '\\\\\\\\$'         ,\n    'D'                  =>     '\\\\\\\\$'         ,\n    'Dart'               =>     '\\\\\\\\$'         ,\n    'Expect'             =>     '\\\\\\\\$'         ,\n    'Futhark'            =>     '\\\\\\\\$'         ,\n    'Gencat NLS'         =>     '\\\\\\\\$'         ,\n    'Go'                 =>     '\\\\\\\\$'         ,\n    'IDL'                =>     '\\$\\\\$'         ,\n    'Igor Pro'           =>     '\\\\$'           ,\n#   'Java'               =>     '\\\\\\\\$'         ,\n    'JavaScript'         =>     '\\\\\\\\$'         ,\n    'JSON5'              =>     '\\\\\\\\$'         ,\n    'JSX'                =>     '\\\\\\\\$'         ,\n    'LESS'               =>     '\\\\\\\\$'         ,\n    'Lua'                =>     '\\\\\\\\$'         ,\n    'Luau'               =>     '\\\\\\\\$'         ,\n    'make'               =>     '\\\\\\\\$'         ,\n    'MATLAB'             =>     '\\.\\.\\.\\s*$'    ,\n    'Meson'              =>     '\\\\\\\\$'         ,\n    'Metal'              =>     '\\\\\\\\$'         ,\n    'MXML'               =>     '\\\\\\\\$'         ,\n    'Objective-C'        =>     '\\\\\\\\$'         ,\n    'Objective-C++'      =>     '\\\\\\\\$'         ,\n    'OCaml'              =>     '\\\\\\\\$'         ,\n    'Octave'             =>     '\\.\\.\\.\\s*$'    ,\n    'Qt Project'         =>     '\\\\\\\\$'         ,\n    'Patran Command Language'=> '\\\\\\\\$'         ,\n    'PowerBuilder'       =>     '\\\\\\\\$'         ,\n    'PowerShell'         =>     '\\\\\\\\$'         ,\n    'Python'             =>     '\\\\\\\\$'         ,\n    'R'                  =>     '\\\\\\\\$'         ,\n    'Rmd'                =>     '\\\\\\\\$'         ,\n    'Ruby'               =>     '\\\\\\\\$'         ,\n    'sed'                =>     '\\\\\\\\$'         ,\n    'Swift'              =>     '\\\\\\\\$'         ,\n    'Bourne Again Shell' =>     '\\\\\\\\$'         ,\n    'Bourne Shell'       =>     '\\\\\\\\$'         ,\n    'C Shell'            =>     '\\\\\\\\$'         ,\n    'kvlang'             =>     '\\\\\\\\$'         ,\n    'Kermit'             =>     '\\\\\\\\$'         ,\n    'Korn Shell'         =>     '\\\\\\\\$'         ,\n    'Slint'              =>     '\\\\\\\\$'         ,\n    'Snakemake'          =>     '\\\\\\\\$'         ,\n    'Starlark'           =>     '\\\\\\\\$'         ,\n    'Solidity'           =>     '\\\\\\\\$'         ,\n    'Stata'              =>     '///$'          ,\n    'Stylus'             =>     '\\\\\\\\$'         ,\n    'Tcl/Tk'             =>     '\\\\\\\\$'         ,\n    'TTCN'               =>     '\\\\\\\\$'         ,\n    'TypeScript'         =>     '\\\\\\\\$'         ,\n    'lex'                =>     '\\\\\\\\$'         ,\n    'Vala'               =>     '\\\\\\\\$'         ,\n    'Vala Header'        =>     '\\\\\\\\$'         ,\n    'Vyper'              =>     '\\\\\\\\$'         ,\n    'X++'                =>     '\\\\\\\\$'         ,\n    'zsh'                =>     '\\\\\\\\$'         ,\n    );\n# 1}}}\n%{$rh_Not_Code_Extension}    = (             # {{{1\n   '1'             => 1,  # Man pages (documentation):\n   '2'             => 1,\n   '3'             => 1,\n   '4'             => 1,\n   '5'             => 1,\n   '6'             => 1,\n   '7'             => 1,\n   '8'             => 1,\n   '9'             => 1,\n   'a'             => 1,  # Static object code.\n   'ad'            => 1,  # X application default resource file.\n   'afm'           => 1,  # font metrics\n   'arc'           => 1,  # arc(1) archive\n   'arj'           => 1,  # arj(1) archive\n   'au'            => 1,  # Audio sound filearj(1) archive\n   'bak'           => 1,  # Backup files - we only want to count the \"real\" files.\n   'bdf'           => 1,\n   'bmp'           => 1,\n   'bz2'           => 1,  # bzip2(1) compressed file\n   'csv'           => 1,\n   'desktop'       => 1,\n   'dic'           => 1,\n   'doc'           => 1,\n   'elc'           => 1,\n   'eps'           => 1,\n   'fig'           => 1,\n   'gif'           => 1,\n   'gz'            => 1,\n   'h5'            => 1,  # hierarchical data format\n   'hdf'           => 1,  # hierarchical data format\n   'in'            => 1,  # Debatable.\n   'jpg'           => 1,\n   'kdelnk'        => 1,\n   'man'           => 1,\n   'mf'            => 1,\n   'mp3'           => 1,\n   'n'             => 1,\n   'o'             => 1,  # Object code is generated from source code.\n   'o.cmd'         => 1,  # not DOS Batch; Linux kernel compilation optimization file\n   'o.d'           => 1,  # cmake object dependency file\n   'pbm'           => 1,\n   'pdf'           => 1,\n   'pfb'           => 1,\n   'png'           => 1,\n   'ppt'           => 1,\n   'pptx'          => 1,\n   'ps'            => 1,  # Postscript is _USUALLY_ generated automatically.\n   'sgm'           => 1,\n   'sgml'          => 1,\n   'so'            => 1,  # Dynamically-loaded object code.\n   'Tag'           => 1,\n   'tfm'           => 1,\n   'tgz'           => 1,  # gzipped tarball\n   'tiff'          => 1,\n   'tsv'           => 1,  # tab separated values\n   'vf'            => 1,\n   'wav'           => 1,\n   'xbm'           => 1,\n   'xls'           => 1,\n   'xlsx'          => 1,\n   'xpm'           => 1,\n   'Y'             => 1,  # file compressed with \"Yabba\"\n   'Z'             => 1,  # file compressed with \"compress\"\n   'zip'           => 1,  # zip archive\n   'gitattributes' => 1,\n   'gitignore'     => 1,\n   'gitmodules'    => 1,\n); # 1}}}\n%{$rh_Not_Code_Filename}     = (             # {{{1\n   'AUTHORS'     => 1,\n   'BUGS'        => 1,\n   'BUGS'        => 1,\n   'Changelog'   => 1,\n   'ChangeLog'   => 1,\n   'ChangeLog'   => 1,\n   'Changes'     => 1,\n   'CHANGES'     => 1,\n   'COPYING'     => 1,\n   'COPYING'     => 1,\n   'DESCRIPTION' => 1, # R packages metafile\n   '.cvsignore'  => 1,\n   'Entries'     => 1,\n   'FAQ'         => 1,\n   'INSTALL'     => 1,\n   'MAINTAINERS' => 1,\n   'MD5SUMS'     => 1,\n   'NAMESPACE'   => 1, # R packages metafile\n   'NEWS'        => 1,\n   'readme'      => 1,\n   'Readme'      => 1,\n   'README'      => 1,\n   'README.tk'   => 1, # used in kdemultimedia, it's confusing.\n   'Repository'  => 1,\n   'Root'        => 1, # CVS\n   'TODO'        => 1,\n);\n# 1}}}\n%{$rh_Scale_Factor}          = (             # {{{1\n    '(unknown)'                    =>   0.00,\n    '1st generation default'       =>   0.25,\n    '2nd generation default'       =>   0.75,\n    '3rd generation default'       =>   1.00,\n    '4th generation default'       =>   4.00,\n    '5th generation default'       =>  16.00,\n    'ABAP'                         =>   5.00,\n    'ActionScript'                 =>   1.36,\n    'Activiti Business Process'    =>   2.00,\n    'Ada'                          =>   0.52,\n    'ADSO/IDSM'                    =>   3.00,\n    'Agda'                         =>   2.11,\n    'AMPLE'                        =>   2.00,\n    'AnsProlog'                    =>   1.25,\n    'Ant/XML'                      =>   1.90,\n    'Ant'                          =>   1.90,\n    'ANTLR Grammar'                =>   2.00,\n    'SQL'                          =>   6.15,\n    'SQL Stored Procedure'         =>   6.15,\n    'SQL Data'                     =>   1.00,\n    'Apex Class'                   =>   1.50,\n    'APL'                          =>   2.50,\n    'Aria'                         =>   3.50,\n    'ArkTs'                        =>   2.50,\n    'Arturo'                       =>   4.00,\n    'AsciiDoc'                     =>   1.50,\n    'AspectJ'                      =>   1.36,\n    'asa'                          =>   1.29,\n    'ASP'                          =>   1.29,\n    'ASP.NET'                      =>   1.29,\n    'Apex Trigger'                 =>   1.4 ,\n    'AppleScript'                  =>   4.0 ,\n    'Arduino Sketch'               =>   1.00,\n    'Assembly'                     =>   0.25,\n    'Astro'                        =>   3.0,\n    'Asymptote'                    =>   2.50,\n    'autocoder'                    =>   0.25,\n    'AutoHotkey'                   =>   1.29,\n    'awk'                          =>   3.81,\n    'AXAML'                        =>   2.00,\n    'basic'                        =>   0.75,\n    'Bazel'                        =>   1.00,\n    'bc'                           =>   1.50,\n    'Bicep'                        =>   3.00,\n    'Beluga'                       =>   5.00,\n    'Blade'                        =>   2.00,\n    'bliss'                        =>   0.75,\n    'Blueprint'                    =>   2.50,\n    'bmsgen'                       =>   2.22,\n    'bteq'                         =>   6.15,\n    'Brainfuck'                    =>   0.10,\n    'BrightScript'                 =>   2.00,\n    'builder'                      =>   2.00,\n    'C'                            =>   0.77,\n    'C#'                           =>   1.36,\n    'C# Designer'                  =>   1.36,\n    'C# Generated'                 =>   1.36,\n    'Cake Build Script'            =>   1.36,\n    'C++'                          =>   1.51,\n    'Cadence'                      =>   3.00,\n    'Cangjie'                      =>   3.00,\n    'Carbon'                       =>   1.51,\n    'CCS'                          =>   5.33,\n    'Civet'                        =>   3.00,\n    'ColdFusion'                   =>   4.00,\n    'ColdFusion CFScript'          =>   4.00,\n    'Chapel'                       =>   2.96,\n    'Clean'                        =>   2.50,\n    'Clojure'                      =>   1.25,\n    'ClojureScript'                =>   1.25,\n    'ClojureC'                     =>   1.25,\n    'CMake'                        =>   1.00,\n    'COBOL'                        =>   1.04,\n    'CoCoA 5'                      =>   1.04,\n    'CodeQL'                       =>   2.50,\n    'CoffeeScript'                 =>   2.00,\n    'Constraint Grammar'           =>   4.00,\n    'Containerfile'                =>   2.00,\n    'Coq'                          =>   5.00,\n    'Crystal'                      =>   2.50,\n    'Crystal Reports'              =>   4.00,\n    'csl'                          =>   1.63,\n    'CSON'                         =>   2.50,\n    'csp'                          =>   1.51,\n    'cssl'                         =>   1.74,\n    'CSS'                          =>   1.0,\n    'CSV'                          =>   0.1,\n    'Cucumber'                     =>   3.00,\n    'CUDA'                         =>   1.00,\n    'C3'                           =>   1.61,\n    'D'                            =>   1.70,\n    'Dafny'                        =>   3.00,\n    'DAL'                          =>   1.50,\n    'DAML'                         =>   2.11,\n    'Dart'                         =>   2.00,\n    'DenizenScript'                =>   1.00,\n    'Delphi Form'                  =>   2.00,\n    'DIET'                         =>   2.00,\n    'diff'                         =>   1.00,\n    'Derw'                         =>   3.00,\n    'dhall'                        =>   2.11,\n    'DITA'                         =>   1.90,\n    'dtrace'                       =>   2.00,\n    'NASTRAN DMAP'                 =>   2.35,\n    'DOORS Extension Language'     =>   1.50,\n    'Dockerfile'                   =>   2.00,\n    'DOS Batch'                    =>   0.63,\n    'Drools'                       =>   2.00,\n    'ECPP'                         =>   1.90,\n    'eda/sql'                      =>   6.67,\n    'edscheme 3.4'                 =>   1.51,\n    'EEx'                          =>   2.00,\n    'EJS'                          =>   2.50,\n    'Elixir Script'                =>   2.11,\n    'Elixir'                       =>   2.11,\n    'Elm'                          =>   2.50,\n    'Embedded Crystal'             =>   2.00,\n    'ERB'                          =>   2.00,\n    'Erlang'                       =>   2.11,\n    'Fennel'                       =>   2.50,\n    'Finite State Language'        =>   2.00,\n    'Focus'                        =>   1.90,\n    'Forth'                        =>   1.25,\n    'Fortran 66'                   =>   0.63,\n    'Fortran 77'                   =>   0.75,\n    'Fortran 90'                   =>   1.00,\n    'Fortran 95'                   =>   1.13,\n    'Fortran II'                   =>   0.63,\n    'Fortran 2003'                 =>   2.50,\n    'foundation'                   =>   2.76,\n    'Freemarker Template'          =>   1.48,\n    'Futhark'                      =>   3.00, # Guessed from value of ML\n    'F#'                           =>   2.50,\n    'F# Script'                    =>   2.50,\n    'Flatbuffers'                  =>   2.50,\n    'Glade'                        =>   2.00,\n    'Gleam'                        =>   2.50,\n    'GLSL'                         =>   2.00,\n    'Glimmer JavaScript'           =>   3.50,\n    'Glimmer TypeScript'           =>   3.50,\n    'gml'                          =>   1.74,\n    'gpss'                         =>   1.74,\n    'guest'                        =>   2.86,\n    'guru'                         =>   1.63,\n    'GDScript'                     =>   2.50,\n    'Godot Scene'                  =>   2.50,\n    'Godot Resource'               =>   2.50,\n    'Godot Shaders'                =>   2.50,\n    'Go'                           =>   2.50,\n    'Gradle'                       =>   4.00,\n    'Grails'                       =>   1.48,\n    'GraphQL'                      =>   4.00,\n    'Groovy'                       =>   4.10,\n    'gw basic'                     =>   0.82,\n    'HCL'                          =>   2.50,\n    'high c'                       =>   0.63,\n    'hlevel'                       =>   1.38,\n    'hp basic'                     =>   0.63,\n    'Haml'                         =>   2.50,\n    'Handlebars'                   =>   2.50,\n    'Harbour'                      =>   2.00,\n    'Hare'                         =>   2.50,\n    'Haskell'                      =>   2.11,\n    'Haskell Boot'                 =>   2.11,\n    'Haxe'                         =>   2.00,\n    'Hibernate'                    =>   2.00,\n    'HolyC'                        =>   2.50,\n    'Hoon'                         =>   2.00,\n    'HTML'                         =>   1.90,\n    'HTML EEx'                     =>   3.00,\n    'XHTML'                        =>   1.90,\n    'XMI'                          =>   1.90,\n    'XML'                          =>   1.90,\n    'FXML'                         =>   1.90,\n    'MXML'                         =>   1.90,\n    'XSLT'                         =>   1.90,\n    'DTD'                          =>   1.90,\n    'XSD'                          =>   1.90,\n    'NAnt script'                  =>   1.90,\n    'MSBuild script'               =>   1.90,\n    'Visual Studio Module'         =>   1.00,\n    'Visual Studio Solution'       =>   1.00,\n    'HLSL'                         =>   2.00,\n    'Idris'                        =>   2.00,\n    'Literate Idris'               =>   2.00,\n    'Igor Pro'                     =>   4.00,\n    'Imba'                         =>   3.00,\n    'INI'                          =>   1.00,\n    'InstallShield'                =>   1.90,\n    'IPL'                          =>   2.00,\n    'Jai'                          =>   1.13,\n    'Jam'                          =>   2.00,\n    'Janet'                        =>   3.00,\n    'Jasper Report XML/Template'   =>   2.00,\n    'Java'                         =>   1.36,\n    'JavaScript'                   =>   1.48,\n    'JavaServer Faces'             =>   1.5 ,\n    'Jinja Template'               =>   1.5 ,\n    'JSON'                         =>   2.50,\n    'JSON5'                        =>   2.50,\n    'Jsonnet'                      =>   2.50,\n    'JSP'                          =>   1.48,\n    'JSP Tag Library Definition'   =>   2.00,\n    'JSX'                          =>   1.48,\n    'Velocity Template Language'   =>   1.00,\n    'JCL'                          =>   1.67,\n    'Juniper Junos'                =>   2.00,\n    'Justfile'                     =>   2.50,\n    'kvlang'                       =>   2.00,\n    'Kermit'                       =>   2.00,\n    'Korn Shell'                   =>   3.81,\n    'Kotlin'                       =>   2.00,\n    'Lean'                         =>   3.00,\n    'LESS'                         =>   1.50,\n    'Lem'                          =>   3.00,\n    'LFE'                          =>   1.25,\n    'Linker Script'                =>   1.00,\n    'Liquibase'                    =>   2.00,\n    'liquid'                       =>   3.00,\n    'Lisp'                         =>   1.25,\n    'LiveLink OScript'             =>   3.5 ,\n    'LLVM IR'                      =>   0.90,\n    'Logos'                        =>   2.00,\n    'Logtalk'                      =>   2.00,\n    'm4'                           =>   1.00,\n    'make'                         =>   2.50,\n    'Mako'                         =>   1.50,\n    'Markdown'                     =>   1.00,\n    'mathcad'                      =>  16.00,\n    'Maven'                        =>   1.90,\n    'Meson'                        =>   1.00,\n    'Metal'                        =>   1.51,\n    'Modelica'                     =>   2.00,\n    'MUMPS'                        =>   4.21,\n    'Mustache'                     =>   1.75,\n    'MoonBit'                      =>   2.50,\n    'Nastran'                      =>   1.13,\n    'Nemerle'                      =>   2.50,\n    '.NET IL'                      =>   3.00,\n    'NetLogo'                      =>   4.00,\n    'Nextflow'                     =>   4.10,\n    'Nickel'                       =>   2.00,\n    'Nim'                          =>   2.00,\n    'Nix'                          =>   2.70,\n    'Nunjucks'                     =>   1.5 ,\n    'Nushell'                      =>   3.81,\n    'Nushell Object Notation'      =>   2.50,\n    'Objective-C'                  =>   2.96,\n    'Objective-C++'                =>   2.96,\n    'OCaml'                        =>   3.00,\n    'Odin'                         =>   2.00,\n    'OpenSCAD'                     =>   1.00,\n    'Oracle Reports'               =>   2.76,\n    'Oracle Forms'                 =>   2.67,\n    'Oracle Developer/2000'        =>   3.48,\n    'Other'                        =>   1.00,\n    'Org Mode'                     =>   1.00,\n    'P4'                           =>   1.5 ,\n    'Pawn'                         =>   2.00,\n    'Pascal'                       =>   0.88,\n    'Patran Command Language'      =>   2.50,\n    'Perl'                         =>   4.00,\n    'PEG'                          =>   3.00,\n    'peg.js'                       =>   3.00,\n    'peggy'                        =>   3.00,\n    'Pek'                          =>   2.50,\n    'Pest'                         =>   2.00,\n    'tspeg'                        =>   3.00,\n    'Pig Latin'                    =>   1.00,\n    'Pkl'                          =>   3.00,\n    'PL/I'                         =>   1.38,\n    'PL/M'                         =>   1.13,\n    'PlantUML'                     =>   2.00,\n    'Oracle PL/SQL'                =>   2.58,\n    'PO File'                      =>   1.50,\n    'Pony'                         =>   3.00,\n    'PowerBuilder'                 =>   3.33,\n    'PowerShell'                   =>   3.00,\n    'Prisma Schema'                =>   2.50,\n    'Processing'                   =>   2.50,\n    'ProGuard'                     =>   2.50,\n    'Prolog'                       =>   1.25,\n    'Properties'                   =>   1.36,\n    'Protocol Buffers'             =>   2.00,\n    'PRQL'                         =>   3.00,\n    'Pug'                          =>   2.00,\n    'Puppet'                       =>   2.00,\n    'PureScript'                   =>   2.00,\n    'QML'                          =>   1.25,\n    'XML (Qt/GTK)'                 =>   2.00,\n    'Qt Linguist'                  =>   1.00,\n    'Qt Project'                   =>   1.00,\n    'R'                            =>   3.00,\n    'Rmd'                          =>   3.00,\n    'Racket'                       =>   1.50,\n    'Raku'                         =>   4.00,\n    'rally'                        =>   2.00,\n    'ramis ii'                     =>   2.00,\n    'RAML'                         =>   0.90,\n    'ReasonML'                     =>   2.50,\n    'ReScript'                     =>   2.50,\n    'reStructuredText'             =>   1.50,\n    'Razor'                        =>   2.00,\n    'Rexx'                         =>   1.19,\n    'Rhai'                         =>   3.00,\n    'Ring'                         =>   4.20,\n    'RobotFramework'               =>   2.50,\n    'Circom'                       =>   1.00,\n    'Cairo'                        =>   1.00,\n    'Clarity'                      =>   1.47,\n    'Rust'                         =>   1.00,\n    'sas'                          =>   1.95,\n    'Scala'                        =>   4.10,\n    'Scheme'                       =>   1.51,\n    'Slim'                         =>   3.00,\n    'Solidity'                     =>   1.48,\n    'Bourne Shell'                 =>   3.81,\n    'Bourne Again Shell'           =>   3.81,\n    'ksh'                          =>   3.81,\n    'zsh'                          =>   3.81,\n    'Fish Shell'                   =>   3.81,\n    'C Shell'                      =>   3.81,\n    'SaltStack'                    =>   2.00,\n    'SAS'                          =>   1.5 ,\n    'Sass'                         =>   1.5 ,\n    'SCSS'                         =>   1.5 ,\n    'SKILL'                        =>   2.00,\n    'SKILL++'                      =>   2.00,\n    'Slice'                        =>   1.50,\n    'Slint'                        =>   1.00,\n    'Smalltalk'                    =>   4.00,\n    'Smarty'                       =>   3.50,\n    'Softbridge Basic'             =>   2.76,\n    'SparForte'                    =>   3.80,\n    'sps'                          =>   0.25,\n    'spss'                         =>   2.50,\n    'Specman e'                    =>   2.00,\n    'SQL'                          =>   2.29,\n    'Squirrel'                     =>   2.50,\n    'Standard ML'                  =>   3.00,\n    'Stata'                        =>   3.00,\n    'Stylus'                       =>   1.48,\n    'SugarSS'                      =>   2.50,\n    'SurrealQL'                    =>   2.50,\n    'Svelte'                       =>   2.00,\n    'SVG'                          =>   1.00,\n    'Swift'                        =>   2.50,\n    'SWIG'                         =>   2.50,\n    'TableGen'                     =>   2.00,\n    'Tcl/Tk'                       =>   4.00,\n    'TEAL'                         =>   0.50,\n    'Teamcenter def'               =>   1.00,\n    'Teamcenter met'               =>   1.00,\n    'Teamcenter mth'               =>   1.00,\n    'Templ'                        =>   2.50,\n    'TeX'                          =>   1.50,\n    'Text'                         =>   0.50,\n    'Thrift'                       =>   2.50,\n    'TLA+'                         =>   1.00,\n    'Titanium Style Sheet'         =>   2.00,\n    'TOML'                         =>   2.76,\n    'Twig'                         =>   2.00,\n    'TNSDL'                        =>   2.00,\n    'TTCN'                         =>   2.00,\n    'TITAN Project File Information' =>   1.90,\n    'TypeScript'                   =>   2.00,\n    'Typst'                        =>   3.00,\n    'Umka'                         =>   2.00,\n    'Unity-Prefab'                 =>   2.50,\n    'USS'                          =>   1.0,\n    'UXML'                         =>   1.90,\n    'Vala'                         =>   1.50,\n    'Vala Header'                  =>   1.40,\n    'Verilog-SystemVerilog'        =>   1.51,\n    'VHDL'                         =>   4.21,\n    'vim script'                   =>   3.00,\n    'Visual Basic'                 =>   2.76,\n    'VBA'                          =>   2.76,\n    'Visual Basic .NET'            =>   2.76,\n    'VBScript'                     =>   2.76,\n    'Visual Fox Pro'               =>   4.00, # Visual Fox Pro is not available in the language gearing ratios listed at Mayes Consulting web site\n    'Visualforce Component'        =>   1.9 ,\n    'Visualforce Page'             =>   1.9 ,\n    'VSCode Workspace'             =>   2.50,\n    'Vuejs Component'              =>   2.00,\n    'Vyper'                        =>   4.20,\n    'Web Services Description'     =>   1.00,\n    'WebAssembly'                  =>   0.45,\n    'WGSL'                         =>   2.50,\n    'Windows Message File'         =>   1.00,\n    'Windows Resource File'        =>   1.00,\n    'Windows Module Definition'    =>   1.00,\n    'WiX source'                   =>   1.90,\n    'WiX include'                  =>   1.90,\n    'WiX string localization'      =>   1.90,\n    'WXML'                         =>   1.90,\n    'WXSS'                         =>   1.00,\n    'xBase'                        =>   2.00,\n    'xBase Header'                 =>   2.00,\n    'xlisp'                        =>   1.25,\n    'X++'                          =>   1.51, # This is a guess. Copied from C++, because the overhead for C++ headers might be equivalent to the overhead of structuring elements in XPO files\n    'XAML'                         =>   1.90,\n    'XQuery'                       =>   2.50,\n    'yacc'                         =>   1.51,\n    'yacc++'                       =>   1.51,\n    'YAML'                         =>   0.90,\n    'Yarn'                         => 2.00,\n    'Expect'                       => 2.00,\n    'Gencat NLS'                   => 1.50,\n    'C/C++ Header'                 => 1.00,\n    'inc'                          => 1.00,\n    'lex'                          => 1.00,\n    'Julia'                        => 4.00,\n    'MATLAB'                       => 4.00,\n    'Magik'                        => 2.50,\n    'Mathematica'                  => 5.00,\n    'Mercury'                      => 3.00,\n    'Maven/XML'                    => 2.5,\n    'IDL'                          => 3.80,\n    'Octave'                       => 4.00,\n    'ML'                           => 3.00,\n    'Modula3'                      => 2.00,\n    'Mojom'                        => 2.00,\n    'Mojo'                         => 4.20,\n    'PHP'                          => 3.50,\n    'Jupyter Notebook'             => 4.20,\n    'Python'                       => 4.20,\n    'Snakemake'                    => 4.20,\n    'RapydScript'                  => 4.20,\n    'Starlark'                     => 4.20,\n    'BizTalk Pipeline'             => 1.00,\n    'BizTalk Orchestration'        => 1.00,\n    'Cython'                       => 3.80,\n    'Ruby'                         => 4.20,\n    'Ruby HTML'                    => 4.00,\n    'sed'                          => 4.00,\n    'Lua'                          => 4.00,\n    'Luau'                         => 4.50,\n    'OpenCL'                       => 1.50,\n    'Xtend'                        => 2.00,\n    'Yang'                         => 3.00,\n    'Zig'                          => 2.50,\n    \"Rego\"                         => 1.00,\n    \"BitBake\"                      => 1.00,\n    # aggregates; value is meaningless\n    'C#/Smalltalk'                    => 1.00,\n    'D/dtrace'                        => 1.00,\n    'F#/Forth'                        => 1.00,\n    'Fortran 77/Forth'                => 1.00,\n    'Lisp/Julia'                      => 1.00,\n    'Lisp/OpenCL'                     => 1.00,\n    'PHP/Pascal/Fortran/Pawn/Bitbake' => 1.00,\n    'Pascal/Puppet'                   => 1.00,\n    'Perl/Prolog'                     => 1.00,\n    'Raku/Prolog'                     => 1.00,\n    'Verilog-SystemVerilog/Coq'    => 1.00,\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' => 1.00,\n    'IDL/Qt Project/Prolog/ProGuard'     => 1.00,\n    'SKILL/.NET IL'                => 1.00,\n    'Clojure/Cangjie'              => 1.00,\n    'Unknown/BitBake'              => 1.00,\n);\n# 1}}}\n%{$rh_Known_Binary_Archives} = (             # {{{1\n            '.tar'     => 1 ,\n            '.tar.Z'   => 1 ,\n            '.tar.gz'  => 1 ,\n            '.tar.bz2' => 1 ,\n            '.zip'     => 1 ,\n            '.Zip'     => 1 ,\n            '.ZIP'     => 1 ,\n            '.ear'     => 1 ,  # Java\n            '.war'     => 1 ,  # contained within .ear\n            '.xz'      => 1 ,\n            '.whl'     => 1 ,  # Python wheel files (zip)\n            );\n# 1}}}\n} # end sub set_constants()\nsub check_scale_existence {                  # {{{1\n    # do a few sanity checks\n    my ($rhaa_Filters_by_Language,\n        $rh_Language_by_Extension,\n        $rh_Scale_Factor) = @_;\n\n    my $OK = 1;\n    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {\n        next if defined $Extension_Collision{$language};\n        if (!defined $rh_Scale_Factor->{$language}) {\n            $OK = 0;\n            warn \"Missing scale factor for $language\\n\";\n        }\n    }\n\n    my %seen_it = ();\n    foreach my $ext (sort keys %{$rh_Language_by_Extension}) {\n        my $language = $rh_Language_by_Extension->{$ext};\n        next if defined $Extension_Collision{$language};\n        next if $seen_it{$language};\n        if (!$rhaa_Filters_by_Language->{$language}) {\n            $OK = 0;\n            warn \"Missing language filter for $language\\n\";\n        }\n        $seen_it{$language} = 1;\n    }\n    die unless $OK;\n} # 1}}}\nsub pre_post_fix {                           # {{{1\n    # Return the input lines prefixed and postfixed\n    # by the given strings.\n    my ($ra_lines, $prefix, $postfix ) = @_;\n    print \"-> pre_post_fix with $prefix, $postfix\\n\" if $opt_v > 2;\n\n    my $all_lines = $prefix . join(\"\"  , @{$ra_lines}) . $postfix;\n\n    print \"<- pre_post_fix\\n\" if $opt_v > 2;\n    return split(\"\\n\", $all_lines);\n} # 1}}}\nsub rm_last_line {                           # {{{1\n    # Return all but the last line.\n    my ($ra_lines, ) = @_;\n    print \"-> rm_last_line\\n\" if $opt_v > 2;\n    print \"<- rm_last_line\\n\" if $opt_v > 2;\n    my $n = scalar(@{$ra_lines}) - 2;\n    return @{$ra_lines}[0..$n];\n} # 1}}}\nsub call_parse_civet {                       # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> call_parse_civet\\n\" if $opt_v > 2;\n    my $coffeeComment = 0;\n    foreach my $L (@{$ra_lines}) {\n        if ($L =~ /^\\s*civet\\s+coffee(Comment|Compat)/) {\n            $coffeeComment = 1;\n            last;\n        }\n    }\n    my (@step_1, @step_2, @step_3, @step_4);\n    if ($coffeeComment) {\n        @step_1 = remove_between_general($ra_lines, '###', '###');\n        @step_4 = remove_matches(        \\@step_1, '^\\s*#');\n    } else {\n        @step_1 = call_regexp_common($ra_lines, 'C');\n        @step_2 = remove_matches(        \\@step_1, '^///');\n        @step_3 = remove_matches(        \\@step_2, '^\\s*//[^/]');\n        @step_4 = remove_between_general(\\@step_3, '###', '###');\n    }\n    print \"<- call_parse_civet\\n\" if $opt_v > 2;\n    return @step_4;\n} # 1}}}\nsub call_regexp_common {                     # {{{1\n    my ($ra_lines, $language ) = @_;\n    print \"-> call_regexp_common for $language\\n\" if $opt_v > 2;\n\n##  Install_Regexp_Common() unless $HAVE_Rexexp_Common;\n\n    my $all_lines = undef;\n    if ($language eq \"C++\") { # Regexp::Common's C++ comment regex is multi-line\n#       $all_lines = join(\"\\n\", @{$ra_lines});\n        $all_lines = \"\";\n        foreach (@{$ra_lines}) {\n            if (m/\\\\$/) {  # line ends with a continuation marker\n                $all_lines .= $_;\n            } else {\n                $all_lines .= \"$_\\n\";\n            }\n        }\n    } else {\n        $all_lines = join(\"\"  , @{$ra_lines});\n    }\n\n    {\n    my @ra_lines = split(\"\\n\", $all_lines);\n    print \"in:  [\", join(\"]\\nin:  [\", @ra_lines), \"]\\n\" if $opt_v > 4;\n    }\n\n    no strict 'vars';\n    # otherwise get:\n    #  Global symbol \"%RE\" requires explicit package name at cloc line xx.\n    if ($all_lines =~ $RE{comment}{$language}) {\n        # Suppress \"Use of uninitialized value in regexp compilation\" that\n        # pops up when $1 is undefined--happens if there's a bug in the $RE\n        # This Pascal comment will trigger it:\n        #         (* This is { another } test. **)\n        # Curiously, testing for \"defined $1\" breaks the substitution.\n        no warnings;\n        # Remove comments.\n        $all_lines =~ s/$1//g;\n    }\n    # a bogus use of %RE to avoid:\n    # Name \"main::RE\" used only once: possible typo at cloc line xx.\n    print scalar keys %RE if $opt_v < -20;\n    my @out = split(\"\\n\", $all_lines);\n    print \"out: [\", join(\"]\\nout: [\", @out), \"]\\n\" if $opt_v > 4;\n    print \"<- call_regexp_common\\n\" if $opt_v > 2;\n    return @out;\n} # 1}}}\nsub plural_form {                            # {{{1\n    # For getting the right plural form on some English nouns.\n    my $n = shift @_;\n    if ($n == 1) { return ( 1, \"\" ); }\n    else         { return ($n, \"s\"); }\n} # 1}}}\nsub matlab_or_objective_C {                  # {{{1\n    # Decide if code is MATLAB, Mathematica, Objective-C, MUMPS, or Mercury\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n    print \"-> matlab_or_objective_C\\n\" if $opt_v > 2;\n    # matlab markers:\n    #   first line starts with \"function\"\n    #   some lines start with \"%\"\n    #   high marks for lines that start with [\n    #\n    # Objective-C markers:\n    #   must have at least two brace characters, { }\n    #   has /* ... */ style comments\n    #   some lines start with @\n    #   some lines start with #include\n    #\n    # MUMPS:\n    #   has ; comment markers\n    #   do not match:  \\w+\\s*=\\s*\\w\n    #   lines begin with   \\s*\\.?\\w+\\s+\\w\n    #   high marks for lines that start with \\s*K\\s+ or \\s*Kill\\s+\n    #\n    # Mercury:\n    #   any line that begins with :- immediately triggers this\n    #\n    # Mathematica:\n    #   (* .. *)\n    #   BeginPackage\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG              = 0;\n\n    my $matlab_points      = 0;\n    my $mathematica_points = 0;\n    my $objective_C_points = 0;\n    my $mumps_points       = 0;\n    my $mercury_points     = 0;\n    my $has_braces         = 0;\n    while (<$IN>) {\n        ++$has_braces if $_ =~ m/[{}]/;\n#print \"LINE $. has_braces=$has_braces\\n\";\n        ++$mumps_points if $. == 1 and m{^[A-Z]};\n        if      (m{^\\s*/\\*} or m {^\\s*//}) {   #   /* or //\n            $objective_C_points += 5;\n            $matlab_points      -= 5;\nprintf \".m:  /*|//  obj C=% 2d  matlab=% 2d  mathematica=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^:-\\s+}) {      # gotta be mercury\n            $mercury_points = 1000;\n            last;\n        } elsif (m{\\w+\\s*=\\s*\\[}) {      # matrix assignment, very matlab\n            $matlab_points += 5;\n        }\n        if (m{\\w+\\[}) {      # function call by []\n            $mathematica_points += 2;\nprintf \".m:  \\\\w=[   obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*\\w+\\s*=\\s*}) {    # definitely not MUMPS\n            --$mumps_points;\nprintf \".m:  \\\\w=    obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*\\.?(\\w)\\s+(\\w)} and $1 !~ /\\d/ and $2 !~ /\\d/) {\n            ++$mumps_points;\nprintf \".m:  \\\\w \\\\w  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*;}) {\n            ++$mumps_points;\nprintf \".m:  ;      obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        }\n        if (m{^\\s*#(include|import)}) {\n            # Objective-C without a doubt\n            $objective_C_points = 1000;\n            $matlab_points      = 0;\nprintf \".m: #include obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n            $has_braces         = 2;\n            last;\n        } elsif (m{^\\s*@(interface|implementation|protocol|public|protected|private|end)\\s}o) {\n            # Objective-C without a doubt\n            $objective_C_points = 1000;\n            $matlab_points      = 0;\nprintf \".m: keyword obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n            last;\n        } elsif (m{^\\s*BeginPackage}) {\n            $mathematica_points += 2;\n        } elsif (m{^\\s*\\[}) {             #   line starts with [  -- very matlab\n            $matlab_points += 5;\nprintf \".m:  [      obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\sK(ill)?\\s+}) {\n            $mumps_points  += 5;\nprintf \".m:  Kill   obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*function}) {\n            --$objective_C_points;\n            ++$matlab_points;\nprintf \".m:  funct  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*%}) {              #   %\n            # matlab commented line\n            --$objective_C_points;\n            ++$matlab_points;\nprintf \".m:  pcent  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        }\n    }\n    $IN->close;\nprintf \"END LOOP    obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n\n    # next heuristic is unreliable for small files\n#   $objective_C_points = -9.9e20 unless $has_braces >= 2;\n\n    my %points = ( 'MATLAB'      => $matlab_points     ,\n                   'Mathematica' => $mathematica_points     ,\n                   'MUMPS'       => $mumps_points      ,\n                   'Objective-C' => $objective_C_points,\n                   'Mercury'     => $mercury_points    , );\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n\n    print \"<- matlab_or_objective_C($file: matlab=$matlab_points, mathematica=$mathematica_points, C=$objective_C_points, mumps=$mumps_points, mercury=$mercury_points) => ${$rs_language}\\n\"\n        if $opt_v > 2;\n\n} # 1}}}\nsub php_pascal_fortran_pawn_bitbake {                # {{{1\n    # Decide if code is Fortran, PHP, Pascal, Pawn\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n    print \"-> php_pascal_or_fortran\\n\" if $opt_v > 2;\n    # fortran markers:\n    #   'implicit none' or 'implicit real' or 'implicit integer'\n    #   'program' or 'subroutine' or 'function' or 'module'\n    #   'end program' or 'end subroutine' or 'end function' or 'end module'\n    #   'write(', 'enddo'\n    #\n    # PHP:\n    #   must have at least two brace characters, { }\n    #   has /* ... */ style comments\n    #   some lines start with @\n    #   some lines start with #include\n    #\n    # Pascal:\n    #   lines ending with ;\n    #   writeln\n    #\n    # Pawn:\n    #   lines ending with ;\n    #   has /* ... */ style comments\n    #   writeln\n    #\n    # BitBake:\n    #   some lines start with variables: SRC_URI, SRC_REV, SUMMARY, LICENSE, DEPENDS, RDEPENDS, LIC_FILES_CHKSUM\n    #   some lines start with tasks: do_compile, do_install, do_configure, python\n    #   some lines start with include, require, inherit statements\n    #   contains .=, =., ?=, ??= operators\n    #   contains :... = assignments\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG           = 0;\n\n    my $fortran_90      = 0;\n    my $fortran_points  = 0;\n    my $php_points      = 0;\n    my $pascal_points   = 0;\n    my $pawn_points     = 0;\n    my $bitbake_points  = 0;\n    while (<$IN>) {\n        if (/^\\s*<\\?php/i) {\n            $php_points += 100;\n            last;\n        } elsif (/^\\s*end\\./i ) {\n            $pascal_points += 100;\n            last;\n        } elsif (/^\\s*implicit\\s+(none|real|integer|complex|double)/i) {\n            $fortran_points += 100;\n            # don't end here; try to get 77 or 90 flavor\n        } elsif (/^\\s*end;/i ) {\n            ++$pascal_points;\n            last;\n        } elsif (/^\\s*program\\b/i) {\n            ++$fortran_points;\n            ++$pascal_points;\n        # 'function' is common to all three languages so ignore it\n        } elsif (/^\\s*(subroutine|module|stop)\\b/i or\n                 /^\\s*write\\s*\\(/i                 or\n                 /^\\s*end\\s+(program|subroutine)/i or\n                 /^\\s*end\\s*(if|do)\\b/i) {\n            ++$fortran_points;\n        } elsif (/^\\s*(writeln|begin|procedure|interface|implementation|const)\\b/i) {\n            ++$pascal_points;\n        } elsif (/^\\s*(<|\\?>)/) {\n            ++$php_points;\n        } elsif (/;\\s*$/) {\n            ++$pascal_points;\n            ++$php_points;\n        } elsif (/^\\@/ or /^\\s*(Float:|bool:)/) {\n            $pawn_points += 1e+20;\n            last;\n        }\n        if (/^\\s*(integer|real|complex|double|character|logical|public|private).*?::/i or\n            /^\\s*(allocatable|dimension)/i or\n            /^\\s*(end\\s+)?(interface|type|function|module)\\b/i) {\n            ++$fortran_90;\n        }\n        if (/^\\s*(SRC_URI|SRC_REV|SUMMARY|LICENSE|DEPENDS|RDEPENDS|LIC_FILES_CHKSUM)\\s*=/i or\n            /^\\s*(do_compile|do_install|do_configure|python)\\b/i or\n            /^\\s*(inherit|include|require)\\b/i) {\n            ++$bitbake_points;\n        }\n        if (/\\.=/i or /=\\./i or /\\?=/i or /\\?\\?=/i) {\n            ++$bitbake_points;\n        }\n        if (/^[A-Z0-9_:-]+:[A-Za-z0-9_-]+\\s*=/) {\n            ++$bitbake_points;\n        }\n    }\n    $IN->close;\n\n    my %points = ( 'Fortran'      => $fortran_points     ,\n                   'PHP'          => $php_points         ,\n                   'Pascal'       => $pascal_points      ,\n                   'Pawn'         => $pawn_points        ,\n                   'BitBake'      => $bitbake_points     , );\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n    if (${$rs_language} eq 'Fortran') {\n        if ($fortran_90) {\n            ${$rs_language} = 'Fortran 90';\n        } else {\n            ${$rs_language} = 'Fortran 77';\n        }\n    }\n\n    print \"<- php_pascal_fortran_pawn_bitbake($file: fortran=$fortran_points, php=$php_points, \",\n          \"pascal=$pascal_points, pawn=$pawn_points, bitbake=$bitbake_points) => ${$rs_language}\\n\"\n        if $opt_v > 2;\n\n} # 1}}}\nsub Lisp_or_OpenCL {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Lisp_or_OpenCL\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $lisp_points   = 0;\n    my $opcl_points = 0;\n    while (<$IN>) {\n        ++$lisp_points if  /^\\s*;/;\n        ++$lisp_points if  /\\((def|eval|require|export|let|loop|dec|format)/;\n        ++$opcl_points if  /^\\s*(int|float|const|{)/;\n    }\n    $IN->close;\n    # print \"lisp_points=$lisp_points   opcl_points=$opcl_points\\n\";\n    if ($lisp_points > $opcl_points) {\n        $lang = \"Lisp\";\n    } else {\n        $lang = \"OpenCL\";\n    }\n\n    print \"<- Lisp_or_OpenCL\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Lisp_or_Julia {                          # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Lisp_or_Julia\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $lisp_points   = 0;\n    my $julia_points = 0;\n    while (<$IN>) {\n        ++$lisp_points if  /^\\s*;/;\n        ++$lisp_points if  /\\((def|eval|require|export|let|loop|dec|format)/;\n        ++$julia_points if  /^\\s*(function|end|println|for|while)/;\n    }\n    $IN->close;\n    # print \"lisp_points=$lisp_points   julia_points=$julia_points\\n\";\n    if ($lisp_points > $julia_points) {\n        $lang = \"Lisp\";\n    } else {\n        $lang = \"Julia\";\n    }\n\n    print \"<- Lisp_or_Julia\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Perl_or_Prolog {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Perl_or_Prolog\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $perl_points = 0;\n    my $prolog_points = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if ($. == 1 and /^#!.*?\\bperl/) {\n            $perl_points = 100;\n            last;\n        }\n        ++$perl_points   if  /^=(head|over|item|cut)/;\n        ++$perl_points   if  /;\\s*$/;\n        ++$perl_points   if  /(\\{|\\})/;\n        ++$perl_points   if  /^\\s*sub\\s+/;\n        ++$perl_points   if  /\\s*<<'/;  # start HERE block\n        ++$perl_points   if  /\\$(\\w+\\->|[_!])/;\n        ++$prolog_points if !/\\s*#/ and /\\.\\s*$/;\n        ++$prolog_points if  /:-/;\n    }\n    $IN->close;\n    # print \"perl_points=$perl_points   prolog_points=$prolog_points\\n\";\n    if ($perl_points > $prolog_points) {\n        $lang = \"Perl\";\n    } else {\n        $lang = \"Prolog\";\n    }\n\n    printf \"<- Perl_or_Prolog(%s, Perl=%d Prolog=%d)\\n\",\n        $file, $perl_points, $prolog_points if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Raku_or_Prolog {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Raku_or_Prolog\\n\" if $opt_v > 2;\n    my $lang = Perl_or_Prolog($file, $rh_Err, $raa_errors);\n    $lang = \"Raku\" if $lang eq \"Perl\";\n\n    print \"<- Raku_or_Prolog\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub IDL_or_QtProject {                       # {{{1\n    # IDL, QtProject, Prolog, or ProGuard\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> IDL_or_QtProject($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $idl_points      = 0;\n    my $qtproj_points   = 0;\n    my $prolog_points   = 0;\n    my $proguard_points = 0;\n    while (<$IN>) {\n        ++$idl_points      if /^\\s*;/;\n        ++$idl_points      if /plot\\(/i;\n        ++$qtproj_points   if /^\\s*(qt|configs|sources|template|target|targetpath|subdirs)\\b/i;\n        ++$qtproj_points   if /qthavemodule/i;\n        ++$prolog_points   if /\\.\\s*$/;\n        ++$prolog_points   if /:-/;\n        ++$proguard_points if /^\\s*#/;\n        ++$proguard_points if /^-keep/;\n        ++$proguard_points if /^-(dont)?obfuscate/;\n    }\n    $IN->close;\n    # print \"idl_points=$idl_points   qtproj_points=$qtproj_points\\n\";\n\n    my %points = ( 'IDL'        => $idl_points       ,\n                   'Qt Project' => $qtproj_points    ,\n                   'Prolog'     => $prolog_points    ,\n                   'ProGuard'   => $proguard_points  ,\n                 );\n\n    $lang = (sort { $points{$b} <=> $points{$a} or $a cmp $b} keys %points)[0];\n\n    print \"<- IDL_or_QtProject(idl_points=$idl_points, \",\n          \"qtproj_points=$qtproj_points, prolog_points=$prolog_points, \",\n          \"proguard_points=$proguard_points)\\n\"\n           if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Ant_or_XML {                             # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Ant_or_XML($file)\\n\" if $opt_v > 2;\n\n    my $lang = \"XML\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Ant_points   = 0;\n    my $XML_points   = 1;\n    while (<$IN>) {\n        if (/^\\s*<project\\s+/) {\n            ++$Ant_points  ;\n            --$XML_points  ;\n        }\n        if (/xmlns:artifact=\"antlib:org.apache.maven.artifact.ant\"/) {\n            ++$Ant_points  ;\n            --$XML_points  ;\n        }\n    }\n    $IN->close;\n\n    if ($XML_points >= $Ant_points) {\n        # tie or better goes to XML\n        $lang = \"XML\";\n    } else {\n        $lang = \"Ant\";\n    }\n\n    print \"<- Ant_or_XML($lang)\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Maven_or_XML {                           # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Maven_or_XML($file)\\n\" if $opt_v > 2;\n\n    my $lang = \"XML\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Mvn_points   = 0;\n    my $XML_points   = 1;\n    while (<$IN>) {\n        if (/^\\s*<project\\s+/) {\n            ++$Mvn_points  ;\n            --$XML_points  ;\n        }\n        if (m{xmlns=\"http://maven.apache.org/POM/}) {\n            ++$Mvn_points  ;\n            --$XML_points  ;\n        }\n    }\n    $IN->close;\n\n    if ($XML_points >= $Mvn_points) {\n        # tie or better goes to XML\n        $lang = \"XML\";\n    } else {\n        $lang = \"Maven\";\n    }\n\n    print \"<- Maven_or_XML($lang)\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub pascal_or_puppet {                       # {{{1\n    # Decide if code is Pascal or Puppet manifest\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n\n    print \"-> pascal_or_puppet\\n\" if $opt_v > 2;\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG              = 0;\n    my $pascal_points      = 0;\n    my $puppet_points      = 0;\n\n    while (<$IN>) {\n\n        if ( /^\\s*\\#\\s+/ ) {\n                $puppet_points += .001;\n                next;\n        }\n\n        ++$pascal_points if /\\bprogram\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bunit\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bmodule\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bprocedure\\b/i;\n        ++$pascal_points if /\\bfunction\\b/i;\n        ++$pascal_points if /^\\s*interface\\s+/i;\n        ++$pascal_points if /^\\s*implementation\\s+/i;\n        ++$pascal_points if /^\\s*uses\\s+/i;\n        ++$pascal_points if /(?<!\\:\\:)\\bbegin\\b(?!\\:\\:)/i;\n        ++$pascal_points if /(?<!\\:\\:)\\bend\\b(?!\\:\\:)/i;\n        ++$pascal_points if /\\:\\=/;\n        ++$pascal_points if /\\<\\>/;\n        ++$pascal_points if /^\\s*\\{\\$(I|INCLUDE)\\s+.*\\}/i;\n        ++$pascal_points if /writeln/;\n\n        ++$puppet_points if /^\\s*class\\s+/ and not /class\\s+operator\\s+/;\n        ++$puppet_points if /^\\s*function\\s+[a-z][a-z0-9]+::[a-z][a-z0-9]+\\s*/;\n        ++$puppet_points if /^\\s*type\\s+[A-Z]\\w+::[A-Z]\\w+\\s+/;\n        ++$puppet_points if /^\\s*case\\s+/;\n        ++$puppet_points if /^\\s*package\\s+/;\n        ++$puppet_points if /^\\s*file\\s+/;\n        ++$puppet_points if /^\\s*include\\s\\w+/;\n        ++$puppet_points if /^\\s*service\\s+/;\n        ++$puppet_points if /\\s\\$\\w+\\s*\\=\\s*\\S/;\n        ++$puppet_points if /\\S\\s*\\=\\>\\s*\\S/;\n\n        # No need to process rest of file if language seems obvious.\n        last\n                if (abs ($pascal_points - $puppet_points ) > 20 );\n    }\n    $IN->close;\n\n    print \"<- pascal_or_puppet(pascal=$pascal_points, puppet=$puppet_points)\\n\"\n        if $opt_v > 2;\n\n    if ($pascal_points > $puppet_points) {\n        ${$rs_language} = \"Pascal\";\n    } else {\n        ${$rs_language} = \"Puppet\";\n    }\n\n} # 1}}}\nsub Forth_or_Fortran {                       # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Forth_or_Fortran\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $forth_points = 0;\n    my $fortran_points = 0;\n    while (<$IN>) {\n        ++$forth_points if  /^:\\s/;\n        ++$fortran_points if  /^([c*][^a-z]|\\s{6,}(subroutine|program|end|implicit)\\s|\\s*!)/i;\n    }\n    $IN->close;\n    if ($forth_points > $fortran_points) {\n        $lang = \"Forth\";\n    } else {\n        $lang = \"Fortran 77\";\n    }\n\n    print \"<- Forth_or_Fortran\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Forth_or_Fsharp {                        # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Forth_or_Fsharp\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $forth_points = 0;\n    my $fsharp_points = 0;\n    while (<$IN>) {\n        ++$forth_points if  /^:\\s/;\n        ++$fsharp_points if  /^\\s*(#light|import|let|module|namespace|open|type)/;\n    }\n    $IN->close;\n    if ($forth_points > $fsharp_points) {\n        $lang = \"Forth\";\n    } else {\n        $lang = \"F#\";\n    }\n\n    print \"<- Forth_or_Fsharp\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Verilog_or_Coq {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Verilog_or_Coq\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $coq_points     = 0;\n    my $verilog_points = 0;\n    while (<$IN>) {\n        ++$verilog_points if  /^\\s*(module|begin|input|output|always)/;\n        ++$coq_points if /\\b(Inductive|Fixpoint|Definition|\n                             Theorem|Lemma|Proof|Qed|forall|\n                             Section|Check|Notation|Variable|\n                             Goal|Fail|Require|Scheme|Module|Ltac|\n                             Set|Unset|Parameter|Coercion|Axiom|\n                             Locate|Type|Record|Existing|Class)\\b/x;\n    }\n    $IN->close;\n    if ($coq_points > $verilog_points) {\n        $lang = \"Coq\";\n    } else {\n        $lang = \"Verilog-SystemVerilog\";\n    }\n\n    print \"<- Verilog_or_Coq\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub TypeScript_or_QtLinguist {               # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> TypeScript_or_QtLinguist\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $tscript_points  = 0;\n    my $linguist_points = 0;\n    while (<$IN>) {\n        ++$linguist_points if m{\\b</?(message|source|translation)>};\n        ++$tscript_points  if /^\\s*(var|const|let|class|document)\\b/;\n        ++$tscript_points  if /[;}]\\s*$/;\n        ++$tscript_points  if m{^\\s*//};\n    }\n    $IN->close;\n    if ($tscript_points >= $linguist_points) {\n        $lang = \"TypeScript\";\n    } else {\n        $lang = \"Qt Linguist\";\n    }\n    print \"<- TypeScript_or_QtLinguist\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Qt_or_Glade {                            # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Qt_or_Glade\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $qt_points    =  1;\n    my $glade_points = -1;\n    while (<$IN>) {\n        if (/generated\\s+with\\s+glade/i) {\n            $glade_points =  1;\n            $qt_points    = -1;\n            last;\n        }\n    }\n    $IN->close;\n    if ($glade_points > $qt_points) {\n        $lang = \"Glade\";\n    } else {\n        $lang = \"XML (Qt/GTK)\";\n    }\n    print \"<- Qt_or_Glade\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Csharp_or_Smalltalk {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Csharp_or_Smalltalk($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $cs_points        = 0;\n    my $smalltalk_points = 0;\n    while (<$IN>) {\n        s{//.*?$}{};        # strip inline C# comments for better clarity\n        next if /^\\s*$/;\n        if (/[;}{]\\s*$/) {\n            ++$cs_points       ;\n        } elsif (/^(using|namespace)\\s/) {\n            $cs_points += 20;\n        } elsif (/^\\s*(public|private|new)\\s/) {\n            $cs_points += 20;\n        } elsif (/^\\s*\\[assembly:/) {\n            ++$cs_points       ;\n        }\n        if (/(\\!|\\]\\.)\\s*$/) {\n            ++$smalltalk_points;\n            --$cs_points       ;\n        }\n    }\n    $IN->close;\n    if ($smalltalk_points > $cs_points) {\n        $lang = \"Smalltalk\";\n    } else {\n        $lang = \"C#\";\n    }\n    print \"<- Csharp_or_Smalltalk($file)=$lang\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Visual_Basic_or_TeX_or_Apex {            # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n\n    print \"-> Visual_Basic_or_TeX_or_Apex($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $VB_points        = 0;\n    my $tex_points       = 0;\n    my $apex_points      = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n#print \"$_\";\n        if (/\\s*%/ or /\\s*\\\\/) {\n            ++$tex_points   ;\n        } else {\n            if (/^\\s*(public|private)\\s/i) {\n                ++$VB_points    ;\n                ++$apex_points  ;\n#print \"+VB1 +A1\";\n            } elsif (/^\\s*(end|attribute|version)\\s/i) {\n                ++$VB_points    ;\n#print \"+VB2\";\n            }\n            if (/[{}]/ or /;\\s*$/) {\n                ++$apex_points  ;\n#print \"+A2\";\n            }\n#print \"\\n\";\n        }\n    }\n    $IN->close;\n\n    my %points = ( 'Visual Basic'   => $VB_points   ,\n                   'TeX'            => $tex_points  ,\n                   'Apex Class'     => $apex_points ,);\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n\n    print \"<- Visual_Basic_or_TeX_or_Apex($file: VB=$VB_points, TeX=$tex_points, Apex=$apex_points\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Scheme_or_SaltStack {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Scheme_or_SaltStack($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Sch_points = 0;\n    my $SS_points  = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/{\\%.*%}/) {\n            $SS_points += 5;\n        } elsif (/map\\.jinja\\b/) {\n            $SS_points += 5;\n        } elsif (/\\((define|lambda|let|cond|do)\\s/) {\n            $Sch_points += 1;\n        } else {\n        }\n    }\n    $IN->close;\n\n    print \"<- Scheme_or_SaltStack($file: Scheme=$Sch_points, SaltStack=$SS_points\\n\" if $opt_v > 2;\n    if ($Sch_points > $SS_points) {\n        return \"Scheme\";\n    } else {\n        return \"SaltStack\";\n    }\n} # 1}}}\nsub Pascal_or_Pawn {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Pascal_or_Pawn($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $scal = 0;\n    my $wn   = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(program|begin|end|[Ww]riteln|procedure)\\s/) {\n            $scal += 1e+20;\n            last;\n        } elsif (/^\\@/ or m{/\\*} or m{\\*/} or /^\\s*(Float:|bool:)/) {\n            $wn += 1e+20;\n            last;\n        } elsif (/^\\s*(static|printf?|switch)\\s/) {\n            $wn += 1;\n        } elsif (/;\\s*$/) {\n            $scal += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- Pascal_or_Pawn($file: Pascal=$scal, Pawn=$wn\\n\" if $opt_v > 2;\n    if ($scal > $wn) {\n        return \"Pascal\";\n    } else {\n        return \"Pawn\";\n    }\n} # 1}}}\nsub SKILL_or_DotNetIL {                      # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> SKILL_or_DotNetIL($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $skill   = 0;\n    my $dnet_il = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*;/) {\n            $skill += 50;\n        } elsif (/^\\.(class|assembly|method|custom|entrypoint)/) {\n            $dnet_il += 50;\n            last;\n        } elsif (/{\\s*$/ or /^\\s*}/) {\n            $dnet_il += 5;\n        } elsif (/^\\s*(procedure|let|foreach)\\b/) {\n            $skill += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- SKILL_or_DotNetIL($file: SKILL=$skill, .NET IL=$dnet_il\\n\" if $opt_v > 2;\n    if ($skill > $dnet_il) {\n        return \"SKILL\";\n    } else {\n        return \".NET IL\";\n    }\n} # 1}}}\nsub Clojure_or_Cangjie {                     # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Clojure_or_Cangjie($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $clojure   = 0;\n    my $cangjie = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(;|\\(|\\[)/) {\n            $clojure += 50;\n        } elsif (/^(import|func|main)/) {\n            $cangjie += 50;\n        } elsif (/{\\s*$/ or /^\\s*}$/) {\n            $cangjie += 5;\n        } elsif (/^\\s*(procedure|let|foreach)\\b/) {\n            $clojure += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- Clojure_or_Cangjie($file: clojure=$clojure, .NET IL=$cangjie\\n\" if $opt_v > 2;\n    if ($clojure > $cangjie) {\n        return \"Clojure\";\n    } else {\n        return \"Cangjie\";\n    }\n} # 1}}}\nsub really_is_BitBake {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> really_is_BitBake($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $text   = 3; # Text is assumed if no BitBake markers are found\n    my $bitbake = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(SRC_URI|SRC_REV|SUMMARY|LICENSE|DEPENDS|RDEPENDS|LIC_FILES_CHKSUM)\\s*=/i or\n            /^\\s*(BBFILE|LAYER).*\\s*=/i or\n            /^\\s*(do_compile|do_install|do_configure|python)\\b/i or\n            /^\\s*(inherit|include|require)\\b/i) {\n            ++$bitbake;\n        }\n        if (/\\.=/i or /=\\./i or /\\?=/i or /\\?\\?=/i) {\n            ++$bitbake;\n        }\n        if (/^[A-Z0-9_:-]+:[A-Za-z0-9_-]+\\s*=/) {\n            ++$bitbake;\n        }\n    }\n    $IN->close;\n\n    print \"<- really_is_BitBake($file: Text=$text, BitBake=$bitbake\\n\" if $opt_v > 2;\n    if ($text > $bitbake) {\n        return undef;\n    } else {\n        return \"BitBake\";\n    }\n} # 1}}}\nsub html_colored_text {                      # {{{1\n    # http://www.pagetutor.com/pagetutor/makapage/pics/net216-2.gif\n    my ($color, $text) = @_;\n#?#die \"html_colored_text($text)\";\n    if      ($color =~ /^red$/i)   {\n        $color = \"#ff0000\";\n    } elsif ($color =~ /^green$/i) {\n        $color = \"#00ff00\";\n    } elsif ($color =~ /^blue$/i)  {\n        $color = \"#0000ff\";\n    } elsif ($color =~ /^grey$/i)  {\n        $color = \"#cccccc\";\n    }\n#   return \"\" unless $text;\n    return '<font color=\"' . $color . '\">' . html_metachars($text) . \"</font>\";\n} # 1}}}\nsub xml_metachars {                          # {{{1\n    # http://en.wikipedia.org/wiki/Character_encodings_in_HTML#XML_character_references\n    my ($string, ) = shift @_;\n\n    my  @in_chars    = split(//, $string);\n    my  @out_chars   = ();\n    foreach my $c (@in_chars) {\n        if      ($c eq '&') { push @out_chars, '&amp;'\n        } elsif ($c eq '<') { push @out_chars, '&lt;'\n        } elsif ($c eq '>') { push @out_chars, '&gt;'\n        } elsif ($c eq '\"') { push @out_chars, '&quot;'\n        } elsif ($c eq \"'\") { push @out_chars, '&apos;'\n        } else {\n            push @out_chars, $c;\n        }\n    }\n    return join \"\", @out_chars;\n} # 1}}}\nsub html_metachars {                         # {{{1\n    # Replace HTML metacharacters with their printable forms.\n    # Future:  use HTML-Encoder-0.00_04/lib/HTML/Encoder.pm\n    # from Fabiano Reese Righetti's HTML::Encoder module if\n    # this subroutine proves to be too simplistic.\n    my ($string, ) = shift @_;\n\n    my  @in_chars    = split(//, $string);\n    my  @out_chars   = ();\n    foreach my $c (@in_chars) {\n        if      ($c eq '<') {\n            push @out_chars, '&lt;'\n        } elsif ($c eq '>') {\n            push @out_chars, '&gt;'\n        } elsif ($c eq '&') {\n            push @out_chars, '&amp;'\n        } else {\n            push @out_chars, $c;\n        }\n    }\n    return join \"\", @out_chars;\n} # 1}}}\nsub test_alg_diff {                          # {{{1\n    my ($file_1 ,\n        $file_2 )\n       = @_;\n    my $fh_1 = open_file('<', $file_1, 1);\n    die \"Unable to read $file_1:  $!\\n\" unless defined $fh_1;\n    chomp(my @lines_1 = <$fh_1>);\n    $fh_1->close;\n\n    my $fh_2 = open_file('<', $file_2, 1);\n    die \"Unable to read $file_2:  $!\\n\" unless defined $fh_2;\n    chomp(my @lines_2 = <$fh_2>);\n    $fh_2->close;\n\n    my $n_no_change = 0;\n    my $n_modified  = 0;\n    my $n_added     = 0;\n    my $n_deleted   = 0;\n    my @min_sdiff   = ();\nmy $NN = chr(27) . \"[0m\";  # normal\nmy $BB = chr(27) . \"[1m\";  # bold\n\n    my @sdiffs = sdiff( \\@lines_1, \\@lines_2 );\n    foreach my $entry (@sdiffs) {\n        my ($out_1, $out_2) = ('', '');\n        if ($entry->[0] eq 'u') {\n            ++$n_no_change;\n          # $out_1 = $entry->[1];\n          # $out_2 = $entry->[2];\n            next;\n        }\n#       push @min_sdiff, $entry;\n        if      ($entry->[0] eq 'c') {\n            ++$n_modified;\n            ($out_1, $out_2) = diff_two_strings($entry->[1], $entry->[2]);\n            $out_1 =~ s/\\cA(\\w)/${BB}$1${NN}/g;\n            $out_2 =~ s/\\cA(\\w)/${BB}$1${NN}/g;\n          # $out_1 =~ s/\\cA//g;\n          # $out_2 =~ s/\\cA//g;\n        } elsif ($entry->[0] eq '+') {\n            ++$n_added;\n            $out_1 = $entry->[1];\n            $out_2 = $entry->[2];\n        } elsif ($entry->[0] eq '-') {\n            ++$n_deleted;\n            $out_1 = $entry->[1];\n            $out_2 = $entry->[2];\n        } elsif ($entry->[0] eq 'u') {\n        } else { die \"unknown entry->[0]=[$entry->[0]]\\n\"; }\n        printf \"%-80s | %s\\n\", $out_1, $out_2;\n    }\n\n#   foreach my $entry (@min_sdiff) {\n#       printf \"DIFF:  %s  %s  %s\\n\", @{$entry};\n#   }\n} # 1}}}\nsub write_comments_to_html {                 # {{{1\n    my ($filename      , # in\n        $rah_diff_L    , # in  see routine array_diff() for explanation\n        $rah_diff_R    , # in  see routine array_diff() for explanation\n        $rh_blank      , # in  location and counts of blank lines\n       ) = @_;\n\n    print \"-> write_comments_to_html($filename)\\n\" if $opt_v > 2;\n    my $file = $filename . \".html\";\n\n    my $approx_line_count = scalar @{$rah_diff_L};\n       $approx_line_count = 1 unless $approx_line_count;\n    my $n_digits = 1 + int(log($approx_line_count)/2.30258509299405); # log_10\n\n    my $html_out = html_header($filename);\n\n    my $comment_line_number = 0;\n    for (my $i = 0; $i < scalar @{$rah_diff_R}; $i++) {\n        if (defined $rh_blank->{$i}) {\n            foreach (1..$rh_blank->{$i}) {\n                $html_out .= \"<!-- blank -->\\n\";\n            }\n        }\n        my $line_num = \"\";\n        my $pre      = \"\";\n        my $post     = '</span> &nbsp;';\nwarn \"undef rah_diff_R[$i]{type} \" unless defined $rah_diff_R->[$i]{type};\n        if ($rah_diff_R->[$i]{type} eq 'nonexist') {\n            ++$comment_line_number;\n            $line_num = sprintf \"\\&nbsp; <span class=\\\"clinenum\\\"> %0${n_digits}d %s\",\n                            $comment_line_number, $post;\n            $pre = '<span class=\"comment\">';\n            $html_out .= $line_num;\n            $html_out .= $pre .\n                         html_metachars($rah_diff_L->[$i]{char}) .\n                         $post . \"\\n\";\n            next;\n        }\n        if      ($rah_diff_R->[$i]{type} eq 'code' and\n                 $rah_diff_R->[$i]{desc} eq 'same') {\n            # entire line remains as-is\n            $line_num = sprintf \"\\&nbsp; <span class=\\\"linenum\\\"> %0${n_digits}d %s\",\n                            $rah_diff_R->[$i]{lnum}, $post;\n            $pre    = '<span class=\"normal\">';\n            $html_out .= $line_num;\n            $html_out .= $pre .\n                         html_metachars($rah_diff_R->[$i]{char}) . $post;\n#XX     } elsif ($rah_diff_R->[$i]{type} eq 'code') { # code+comments\n#XX\n#XX         $line_num = '<span class=\"linenum\">' .\n#XX                      $rah_diff_R->[$i]{lnum} . $post;\n#XX         $html_out .= $line_num;\n#XX\n#XX         my @strings = @{$rah_diff_R->[$i]{char}{strings}};\n#XX         my @type    = @{$rah_diff_R->[$i]{char}{type}};\n#XX         for (my $i = 0; $i < scalar @strings; $i++) {\n#XX             if ($type[$i] eq 'u') {\n#XX                 $pre = '<span class=\"normal\">';\n#XX             } else {\n#XX                 $pre = '<span class=\"comment\">';\n#XX             }\n#XX             $html_out .= $pre .  html_metachars($strings[$i]) . $post;\n#XX         }\n# print Dumper(@strings, @type); die;\n\n        } elsif ($rah_diff_R->[$i]{type} eq 'comment') {\n            $line_num = '<span class=\"clinenum\">' . $comment_line_number . $post;\n            # entire line is a comment\n            $pre    = '<span class=\"comment\">';\n            $html_out .= $pre .\n                         html_metachars($rah_diff_R->[$i]{char}) . $post;\n        }\n#printf \"%-30s %s %-30s\\n\", $line_1, $separator, $line_2;\n        $html_out .= \"\\n\";\n    }\n\n    $html_out .= html_end();\n\n    my $out_file = \"$filename.html\";\n    write_file($out_file, {}, ( $html_out ) );\n\n    print \"<- write_comments_to_html\\n\" if $opt_v > 2;\n} # 1}}}\nsub array_diff {                             # {{{1\n    my ($file          , # in  only used for error reporting\n        $ra_lines_L    , # in  array of lines in Left  file (no blank lines)\n        $ra_lines_R    , # in  array of lines in Right file (no blank lines)\n        $mode          , # in  \"comment\" | \"revision\"\n        $rah_diff_L    , # out\n        $rah_diff_R    , # out\n        $raa_Errors    , # in/out\n       ) = @_;\n\n    # This routine operates in two ways:\n    # A. Computes diffs of the same file with and without comments.\n    #    This is used to classify lines as code, comments, or blank.\n    # B. Computes diffs of two revisions of a file.  This method\n    #    requires a prior run of method A using the older version\n    #    of the file because it needs lines to be classified.\n\n    # $rah_diff structure:\n    # An array with n entries where n equals the number of lines in\n    # an sdiff of the two files.  Each entry in the array describes\n    # the contents of the corresponding line in file Left and file Right:\n    #  diff[]{type} = blank | code | code+comment | comment | nonexist\n    #        {lnum} = line number within the original file (1-based)\n    #        {desc} = same | added | removed | modified\n    #        {char} = the input line unless {desc} = 'modified' in\n    #                 which case\n    #        {char}{strings} = [ substrings ]\n    #        {char}{type}    = [ disposition (added, removed, etc)]\n    #\n\n    @{$rah_diff_L} = ();\n    @{$rah_diff_R} = ();\n\n    print \"-> array_diff()\\n\" if $opt_v > 2;\n    my $COMMENT_MODE = 0;\n       $COMMENT_MODE = 1 if $mode eq \"comment\";\n\n#print \"array_diff(mode=$mode)\\n\";\n#print Dumper(\"block left:\" , $ra_lines_L);\n#print Dumper(\"block right:\", $ra_lines_R);\n\n    my @sdiffs = ();\n    eval {\n        local $SIG{ALRM} = sub { die \"alarm\\n\" };\n        alarm $opt_diff_timeout;\n        @sdiffs = sdiff($ra_lines_L, $ra_lines_R);\n        alarm 0;\n    };\n    if ($@) {\n        # timed out\n        die unless $@ eq \"alarm\\n\"; # propagate unexpected errors\n        push @{$raa_Errors},\n             [ $Error_Codes{'Diff error, exceeded timeout'}, $file ];\n        if ($opt_v) {\n          warn \"array_diff: diff timeout failure for $file--ignoring\\n\";\n        }\n        return;\n    }\n\n    my $n_L        = 0;\n    my $n_R        = 0;\n    my $n_sdiff    = 0;  # index to $rah_diff_L, $rah_diff_R\n    foreach my $triple (@sdiffs) {\n        my $flag   = $triple->[0];\n        my $line_L = $triple->[1];\n        my $line_R = $triple->[2];\n        $rah_diff_L->[$n_sdiff]{char} = $line_L;\n        $rah_diff_R->[$n_sdiff]{char} = $line_R;\n        if      ($flag eq 'u') {  # u = unchanged\n            ++$n_L;\n            ++$n_R;\n            if ($COMMENT_MODE) {\n                # line exists in both with & without comments, must be code\n                $rah_diff_L->[$n_sdiff]{type} = \"code\";\n                $rah_diff_R->[$n_sdiff]{type} = \"code\";\n            }\n            $rah_diff_L->[$n_sdiff]{desc} = \"same\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"same\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n        } elsif ($flag eq 'c') {  # c = changed\n# warn \"per line sdiff() commented out\\n\"; if (0) {\n            ++$n_L;\n            ++$n_R;\n\n            if ($COMMENT_MODE) {\n                # line has text both with & without comments;\n                # count as code\n                $rah_diff_L->[$n_sdiff]{type} = \"code\";\n                $rah_diff_R->[$n_sdiff]{type} = \"code\";\n            }\n\n            my @chars_L = split '', $line_L;\n            my @chars_R = split '', $line_R;\n\n            $rah_diff_L->[$n_sdiff]{desc} = \"modified\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"modified\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n\n        } elsif ($flag eq '+') {  # + = added\n            ++$n_R;\n            if ($COMMENT_MODE) {\n                # should never get here, but may due to sdiff() bug,\n                # ref https://rt.cpan.org/Public/Bug/Display.html?id=131629\n                # Rather than failing, ignore and continue.  A possible\n                # consequence is counts may be inconsistent.\n#####           @{$rah_diff_L} = ();\n#####           @{$rah_diff_R} = ();\n#####           push @{$raa_Errors},\n#####                [ $Error_Codes{'Diff error (quoted comments?)'}, $file ];\n                if ($opt_v) {\n                  warn \"array_diff: diff failure (diff says the\\n\";\n                  warn \"comment-free file has added lines).\\n\";\n                  warn \"$n_sdiff  $line_L\\n\";\n                }\n            }\n####        $rah_diff_L->[$n_sdiff]{type} = \"nonexist\";\n            $rah_diff_L->[$n_sdiff]{type} = \"comment\";\n            $rah_diff_L->[$n_sdiff]{desc} = \"removed\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"added\";\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n        } elsif ($flag eq '-') {  # - = removed\n            ++$n_L;\n            if ($COMMENT_MODE) {\n                # line must be comment because blanks already gone\n                $rah_diff_L->[$n_sdiff]{type} = \"comment\";\n            }\n            $rah_diff_R->[$n_sdiff]{type} = \"nonexist\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"removed\";\n            $rah_diff_L->[$n_sdiff]{desc} = \"added\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n        }\n#printf \"%-30s %s %-30s\\n\", $line_L, $separator, $line_R;\n        ++$n_sdiff;\n    }\n#use Data::Dumper::Simple;\n#print Dumper($rah_diff_L, $rah_diff_R);\n#print Dumper($rah_diff_L);\n\n    print \"<- array_diff\\n\" if $opt_v > 2;\n} # 1}}}\nsub remove_leading_dir {                     # {{{1\n    my @filenames = @_;\n    #\n    #  Input should be a list of file names\n    #  with the same leading directory such as\n    #\n    #      dir1/dir2/a.txt\n    #      dir1/dir2/b.txt\n    #      dir1/dir2/dir3/c.txt\n    #\n    #  Output is the same list minus the common\n    #  directory path:\n    #\n    #      a.txt\n    #      b.txt\n    #      dir3/c.txt\n    #\n    print \"-> remove_leading_dir()\\n\" if $opt_v > 2;\n    my @D = (); # a matrix:   [ [ dir1, dir2 ],         # dir1/dir2/a.txt\n                #               [ dir1, dir2 ],         # dir1/dir2/b.txt\n                #               [ dir1, dir2 , dir3] ]  # dir1/dir2/dir3/c.txt\n    if ($ON_WINDOWS) {\n        foreach my $F (@filenames) {\n            $F =~ s{\\\\}{/}g;\n            $F = ucfirst($F) if $F =~ /^\\w:/;  # uppercase drive letter\n        }\n    }\n    if (scalar @filenames == 1) {\n        # special case:  with only one filename\n        # cannot determine a baseline, just remove first directory level\n        $filenames[0] =~ s{^.*?/}{};\n        # print \"-> $filenames[0]\\n\";\n        return $filenames[0];\n    }\n    foreach my $F (@filenames) {\n        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);\n        my @x = File::Spec->splitdir( $Dir );\n        pop @x unless $x[$#x]; # last entry usually null, remove it\n        if ($ON_WINDOWS) {\n            if (defined($Vol) and $Vol) {\n                # put the drive letter, eg, C:, at the front\n                unshift @x, uc $Vol;\n            }\n        }\n#print \"F=$F, Dir=$Dir  x=[\", join(\"][\", @x), \"]\\n\";\n        push @D, [ @x ];\n    }\n\n    # now loop over columns until either they are all\n    # eliminated or a unique column is found\n\n    my @common   = ();  # to contain the common leading directories\n    my $mismatch = 0;\n    while (!$mismatch) {\n        for (my $row = 1; $row < scalar @D; $row++) {\n#print \"comparing $D[$row][0] to $D[0][0]\\n\";\n\n            if (!defined $D[$row][0] or !defined $D[0][0] or\n                ($D[$row][0] ne $D[0][0])) {\n                $mismatch = 1;\n                last;\n            }\n        }\n#print \"mismatch=$mismatch\\n\";\n        if (!$mismatch) {\n            push @common, $D[0][0];\n            # all terms in the leading match; unshift the batch\n            foreach my $ra (@D) {\n                shift @{$ra};\n            }\n        }\n    }\n\n    push @common, \" \";  # so that $leading will end with \"/ \"\n    my $leading = File::Spec->catdir( @common );\n       $leading =~ s{ $}{};  # now take back the bogus appended space\n#print \"remove_leading_dir leading=[$leading]\\n\"; die;\n    if ($ON_WINDOWS) {\n       $leading =~ s{\\\\}{/}g;\n    }\n    foreach my $F (@filenames) {\n        $F =~ s{^$leading}{};\n    }\n\n    print \"<- remove_leading_dir()\\n\" if $opt_v > 2;\n    return @filenames;\n\n} # 1}}}\nsub strip_leading_dir {                      # {{{1\n    my ($leading, @filenames) = @_;\n    #  removes the string $leading from each entry in @filenames\n    print \"-> strip_leading_dir()\\n\" if $opt_v > 2;\n\n#print \"remove_leading_dir leading=[$leading]\\n\"; die;\n    if ($ON_WINDOWS) {\n       $leading =~ s{\\\\}{/}g;\n        foreach my $F (@filenames) {\n            $F =~ s{\\\\}{/}g;\n        }\n    }\n    foreach my $F (@filenames) {\n#print \"strip_leading_dir F before $F\\n\";\n        if ($ON_WINDOWS) {\n            $F =~ s{^$leading}{}i;\n        } else {\n            $F =~ s{^$leading}{};\n        }\n#print \"strip_leading_dir F after  $F\\n\";\n    }\n\n    print \"<- strip_leading_dir()\\n\" if $opt_v > 2;\n    return @filenames;\n\n} # 1}}}\nsub find_deepest_file {                      # {{{1\n    my @filenames = @_;\n    #\n    #  Input should be a list of file names\n    #  with the same leading directory such as\n    #\n    #      dir1/dir2/a.txt\n    #      dir1/dir2/b.txt\n    #      dir1/dir2/dir3/c.txt\n    #\n    #  Output is the file with the most parent directories:\n    #\n    #      dir1/dir2/dir3/c.txt\n\n    print \"-> find_deepest_file()\\n\" if $opt_v > 2;\n\n    my $deepest    = undef;\n    my $max_subdir = -1;\n    foreach my $F (sort @filenames) {\n        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);\n        my @x = File::Spec->splitdir( $Dir );\n        pop @x unless $x[$#x]; # last entry usually null, remove it\n        if (scalar @x > $max_subdir) {\n            $deepest    = $F;\n            $max_subdir = scalar @x;\n        }\n    }\n\n    print \"<- find_deepest_file()\\n\" if $opt_v > 2;\n    return $deepest;\n\n} # 1}}}\nsub find_uncommon_parent_dir {               # {{{1\n    my ($file_L, $file_R) = @_;\n    #\n    # example:\n    #\n    #   file_L = \"perl-5.16.1/cpan/CPANPLUS/lib/CPANPLUS/Internals/Source/SQLite/Tie.pm\"\n    #   file_R = \"/tmp/8VxQG0OLbp/perl-5.16.3/cpan/CPANPLUS/lib/CPANPLUS/Internals/Source/SQLite/Tie.pm\"\n    #\n    # then return\n    #\n    #   \"perl-5.16.1\",\n    #   \"/tmp/8VxQG0OLbp/perl-5.16.3\",\n\n    my ($Vol_L, $Dir_L, $File_L) = File::Spec->splitpath($file_L);\n    my @x_L = File::Spec->splitdir( $Dir_L );\n    my ($Vol_R, $Dir_R, $File_R) = File::Spec->splitpath($file_R);\n    my @x_R = File::Spec->splitdir( $Dir_R );\n\n    my @common  = ();\n\n    # work backwards\n    while ($x_L[$#x_L] eq $x_R[$#x_R]) {\n        push @common, $x_L[$#x_L];\n        pop  @x_L;\n        pop  @x_R;\n    }\n    my $success = scalar @common;\n\n    my $dirs_L = File::Spec->catdir( @x_L );\n    my $dirs_R = File::Spec->catdir( @x_R );\n    my $lead_L = File::Spec->catpath( $Vol_L, $dirs_L, \"\" );\n    my $lead_R = File::Spec->catpath( $Vol_R, $dirs_R, \"\" );\n\n    return $lead_L, $lead_R, $success;\n\n} # 1}}}\nsub get_leading_dirs {                       # {{{1\n    my ($rh_file_list_L, $rh_file_list_R) = @_;\n    # find uniquely named files in both sets to help determine the\n    # leading directory positions\n    my %unique_filename = ();\n    my %basename_L = ();\n    my %basename_R = ();\n    foreach my $f (keys %{$rh_file_list_L}) {\n        my $bn = basename($f);\n        $basename_L{ $bn }{'count'}   += 1;\n        $basename_L{ $bn }{'fullpath'} = $f;\n    }\n    foreach my $f (keys %{$rh_file_list_R}) {\n        my $bn = basename($f);\n        $basename_R{ $bn }{'count'}   += 1;\n        $basename_R{ $bn }{'fullpath'} = $f;\n    }\n    foreach my $f (keys %basename_L) {\n        next unless $basename_L{$f}{'count'} == 1;\n        next unless defined $basename_R{$f} and $basename_R{$f}{'count'} == 1;\n        $unique_filename{$f}{'L'} = $basename_L{ $f }{'fullpath'};\n        $unique_filename{$f}{'R'} = $basename_R{ $f }{'fullpath'};\n    }\n    return undef, undef, 0 unless %unique_filename;\n\n    my ($L_drop, $R_drop) = (undef, undef);\n    foreach my $f (keys %unique_filename) {\n        my $fL = $unique_filename{ $f }{'L'};\n        my $fR = $unique_filename{ $f }{'R'};\n\n        my @DL = File::Spec->splitdir($fL);\n        my @DR = File::Spec->splitdir($fR);\n        # find the most number of common directories between L and R\n        if (!defined $L_drop) {\n            $L_drop = dirname $fL;\n        }\n        if (!defined $R_drop) {\n            $R_drop = dirname $fR;\n        }\n        my $n_path_elements_L = scalar @DL;\n        my $n_path_elements_R = scalar @DR;\n        my $n_path_elem = $n_path_elements_L < $n_path_elements_R ?\n                          $n_path_elements_L : $n_path_elements_R;\n        my ($n_L_drop_this_pair, $n_R_drop_this_pair) = (0, 0);\n        for (my $i = 0; $i < $n_path_elem; $i++) {\n            last if $DL[ $#DL - $i] ne $DR[ $#DR - $i];\n            ++$n_L_drop_this_pair;\n            ++$n_R_drop_this_pair;\n        }\n        my $L_common = File::Spec->catdir( @DL[0..($#DL-$n_L_drop_this_pair)] );\n        my $R_common = File::Spec->catdir( @DR[0..($#DR-$n_R_drop_this_pair)] );\n        $L_drop = $L_common if length $L_common < length $L_drop;\n        $R_drop = $R_common if length $R_common < length $R_drop;\n\n        $L_drop = $L_drop . \"/\" if $L_drop;\n        $R_drop = $R_drop . \"/\" if $R_drop;\n    }\n    # at this point path separator on Windows is already /\n\n    while ($L_drop =~ m{//}) {\n        $L_drop =~ s{//}{/}g;\n    }\n    while ($R_drop =~ m{//}) {\n        $R_drop =~ s{//}{/}g;\n    }\n\n    return $L_drop, $R_drop, 1;\n} # 1}}}\nsub align_by_pairs {                         # {{{1\n    my ($rh_file_list_L        , # in\n        $rh_file_list_R        , # in\n        $ra_added              , # out\n        $ra_removed            , # out\n        $ra_compare_list       , # out\n        ) = @_;\n    print \"-> align_by_pairs()\\n\" if $opt_v > 2;\n    @{$ra_compare_list} = ();\n\n    my @files_L = sort keys %{$rh_file_list_L};\n    my @files_R = sort keys %{$rh_file_list_R};\n    return () unless @files_L or  @files_R;  # at least one must have stuff\n    if ($ON_WINDOWS) {\n        foreach (@files_L) { $_ =~ s{\\\\}{/}g; }\n        foreach (@files_R) { $_ =~ s{\\\\}{/}g; }\n        if ($opt_ignore_case_ext) {\n            foreach (@files_L) { $_ = lc $_; }\n            foreach (@files_R) { $_ = lc $_; }\n        }\n    }\n\n    if      ( @files_L and !@files_R) {\n        # left side has stuff, right side is empty; everything deleted\n        @{$ra_added   }     = ();\n        @{$ra_removed }     = @files_L;\n        @{$ra_compare_list} = ();\n        return;\n    } elsif (!@files_L and  @files_R) {\n        # left side is empty, right side has stuff; everything added\n        @{$ra_added   }     = @files_R;\n        @{$ra_removed }     = ();\n        @{$ra_compare_list} = ();\n        return;\n    } elsif (scalar(@files_L) == 1 and scalar(@files_R) == 1) {\n        # Special case of comparing one file against another.  In\n        # this case force the pair to be aligned with each other,\n        # otherwise the file naming logic will think one file\n        # was added and the other deleted.\n        @{$ra_added   }     = ();\n        @{$ra_removed }     = ();\n        @{$ra_compare_list} = ( [$files_L[0], $files_R[0]] );\n        return;\n    }\n#use Data::Dumper::Simple;\n#print Dumper(\"align_by_pairs\", %{$rh_file_list_L}, %{$rh_file_list_R},);\n#die;\n\n    # The harder case:  compare groups of files.  This only works\n    # if the groups are in different directories so the first step\n    # is to strip the leading directory names from file lists to\n    # make it possible to align by file names.\n    my @files_L_minus_dir = undef;\n    my @files_R_minus_dir = undef;\n\n    my $deepest_file_L    = find_deepest_file(@files_L);\n    my $deepest_file_R    = find_deepest_file(@files_R);\n#print \"deepest L = [$deepest_file_L]\\n\";\n#print \"deepest R = [$deepest_file_R]\\n\";\n    my ($leading_dir_L, $leading_dir_R, $success) =\n                get_leading_dirs($rh_file_list_L, $rh_file_list_R);\n#print \"leading_dir_L=[$leading_dir_L]\\n\";\n#print \"leading_dir_R=[$leading_dir_R]\\n\";\n#print \"success      =[$success]\\n\";\n    if ($success) {\n        @files_L_minus_dir = strip_leading_dir($leading_dir_L, @files_L);\n        @files_R_minus_dir = strip_leading_dir($leading_dir_R, @files_R);\n    } else {\n        # otherwise fall back to old strategy\n        @files_L_minus_dir = remove_leading_dir(@files_L);\n        @files_R_minus_dir = remove_leading_dir(@files_R);\n    }\n\n    # Keys of the stripped_X arrays are canonical file names;\n    # should overlap mostly.  Keys in stripped_L but not in\n    # stripped_R are files that have been deleted.  Keys in\n    # stripped_R but not in stripped_L have been added.\n    my %stripped_L = ();\n       @stripped_L{ @files_L_minus_dir } = @files_L;\n    my %stripped_R = ();\n       @stripped_R{ @files_R_minus_dir } = @files_R;\n\n    my %common = ();\n    foreach my $f (keys %stripped_L) {\n        $common{$f}  = 1 if     defined $stripped_R{$f};\n    }\n\n    my %deleted = ();\n    foreach my $f (keys %stripped_L) {\n        $deleted{$stripped_L{$f}} = $f unless defined $stripped_R{$f};\n    }\n\n    my %added = ();\n    foreach my $f (keys %stripped_R) {\n        $added{$stripped_R{$f}}   = $f unless defined $stripped_L{$f};\n    }\n\n#use Data::Dumper::Simple;\n#print Dumper(\"align_by_pairs\", %stripped_L, %stripped_R);\n#print Dumper(\"align_by_pairs\", %common, %added, %deleted);\n\n    foreach my $f (sort keys %common) {\n        push @{$ra_compare_list}, [ $stripped_L{$f},\n                                    $stripped_R{$f} ];\n    }\n    @{$ra_added   } = keys %added  ;\n    @{$ra_removed } = keys %deleted;\n\n    print \"<- align_by_pairs()\\n\" if $opt_v > 2;\n    return;\n#print Dumper(\"align_by_pairs\", @files_L_minus_dir, @files_R_minus_dir);\n#die;\n} # 1}}}\nsub align_from_git {                         # {{{1\n    # have git identify the files that changed, as well as how\n    my ($L_tag_in              , # in\n        $R_tag_in              , # in\n        $ra_added              , # out\n        $ra_removed            , # out\n        $ra_compare_list       , # out\n        $rh_renamed            , # out\n        ) = @_;\n    print \"-> align_from_git()\\n\" if $opt_v > 2;\n\n    my $L_tag = $L_tag_in;\n    my $R_tag = $R_tag_in;\n    if ($ON_WINDOWS) {\n        $L_tag =~ s{\\\\}{/}g;\n        $R_tag =~ s{\\\\}{/}g;\n    }\n    # On the command line, L_tag and R_tag are commit hashes or tags.  Here they are\n    # replaced with temp directories like /tmp/vGxIL7AWRw and /tmp/BS400yIQEl\n    my $cmd = \"git -c \\\"safe.directory=*\\\" --no-pager diff --name-status --diff-filter=ADRM $L_tag $R_tag\";\n    # Note:  the above command has a problematic side-effect in a git-bash\n    #        terminal on Windows in that the output file path uses the\n    #        native Windows location instead of the Unix-like path.  Here's\n    #        an example:\n    # $ git -c \"safe.directory=*\" --no-pager diff --name-status --diff-filter=ADRM /tmp/pyXXfAJosD /tmp/GftmAmyjOH\n    # M       C:/Users/al/AppData/Local/Temp/pyXXfAJosD/file.js\n    #        In other words, /tmp was replaced by C:/Users/al/AppData/Local/Temp\n    #        This has to be undone otherwise the file pairing will be broken.\n\n\n    # A = added, D = deleted, M = modified, R = renamed; entries tab separated\n    # Example:\n    # M   README.md\n    # R089    package.json    dist/pack age.json-AND\n    # M   package-lock.json\n    # A   src/apps/compare-tags-branches-commits-llm-explanation/README.md\n    # A   src/internals/cloc-git/cloc-diff-rel.ts\n    # D   src/internals/cloc-git/cloc-git-diff-rel-between-commits.ts\n\n    print $cmd, \"\\n\" if $opt_v > 1;\n    open(GSIM, \"$cmd |\") or die \"Unable to run $cmd  $!\";\n    while (<GSIM>) {\n        chomp;\n        my @words = split(/\\t/);\n        if ($ON_MINGW64) {\n            # \"C:/Users/al/AppData/Local/Temp\" => \"/tmp\"\n            $words[1] =~ s{^[A-Z]:/.*?/AppData/Local/Temp}{/tmp};\n        }\n        #print \"align_from_git: words=[@words]\\n\";\n        if (scalar(@words) == 2) {\n            if ($words[0] =~ /^M/) {\n                ( my $right = $words[1] ) =~ s[^${L_tag}/][${R_tag}/];\n                push @{$ra_compare_list}, [ $words[1], $right ];\n            } elsif ($words[0] =~ /^A/) {\n                push @{$ra_added}  , $words[1];\n            } elsif ($words[0] =~ /^D/) {\n                push @{$ra_removed}, $words[1];\n            } else {\n                die \"cloc.align_from_git() parse failure with [$_]\\n\";\n            }\n        } elsif (scalar(@words) == 3) {\n            if ($words[0] =~ /^R/) { # rename\n                ( my $clean_L = $words[1] ) =~ s[^${L_tag}/][];\n                ( my $clean_R = $words[2] ) =~ s[^${R_tag}/][];\n                $rh_renamed->{ $clean_L } = $clean_R;\n                push @{$ra_compare_list}, [ $words[1], $words[2] ];\n            } elsif ($words[0] =~ /^A/) {\n                push @{$ra_added}  , $words[1];\n            } elsif ($words[0] =~ /^D/) {\n                push @{$ra_removed}, $words[1];\n            } else {\n                die \"cloc.align_from_git() parse failure with [$_]\\n\";\n            }\n        } else {\n            die \"Unexpected output from git diff --name-status\\n\";\n        }\n    }\n    close(GSIM);\n\n    print \"<- align_from_git()\\n\" if $opt_v > 2;\n    return;\n} # 1}}}\nsub html_header {                            # {{{1\n    my ($title , ) = @_;\n\n    print \"-> html_header\\n\" if $opt_v > 2;\n    return\n'<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<meta name=\"GENERATOR\" content=\"cloc http://github.com/AlDanial/cloc\">\n' .\n\"\n<!-- Created by $script v$VERSION -->\n<title>$title</title>\n\" .\n'\n<style TYPE=\"text/css\">\n<!--\n    body {\n        color: black;\n        background-color: white;\n        font-family: monospace\n    }\n\n    .whitespace {\n        background-color: gray;\n    }\n\n    .comment {\n        color: gray;\n        font-style: italic;\n    }\n\n    .clinenum {\n        color: red;\n    }\n\n    .linenum {\n        color: green;\n    }\n -->\n</style>\n</head>\n<body>\n<pre><tt>\n';\n    print \"<- html_header\\n\" if $opt_v > 2;\n} # 1}}}\nsub html_end {                               # {{{1\nreturn\n'</tt></pre>\n</body>\n</html>\n';\n} # 1}}}\nsub die_unknown_lang {                       # {{{1\n    my ($lang, $option_name) = @_;\n    die \"Unknown language '$lang' used with $option_name option.  \" .\n        \"The command\\n  $script --show-lang\\n\" .\n        \"will print all recognized languages.  Language names are \" .\n        \"case sensitive.\\n\" ;\n} # 1}}}\nsub unicode_file {                           # {{{1\n    my $file = shift @_;\n\n    print \"-> unicode_file($file)\\n\" if $opt_v > 2;\n    return 0 if (get_size($file) > 2_000_000);\n    # don't bother trying to test binary files bigger than 2 MB\n\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        warn \"Unable to read $file; ignoring.\\n\";\n        return 0;\n    }\n    my @lines = <$IN>;\n    $IN->close;\n\n    if (unicode_to_ascii( join('', @lines) )) {\n        print \"<- unicode_file()\\n\" if $opt_v > 2;\n        return 1;\n    } else {\n        print \"<- unicode_file()\\n\" if $opt_v > 2;\n        return 0;\n    }\n\n} # 1}}}\nsub unicode_to_ascii {                       # {{{1\n    my $string = shift @_;\n\n    # A trivial attempt to convert UTF-16 little or big endian\n    # files into ASCII.  These files exhibit the following byte\n    # sequence:\n    #   byte   1:  255\n    #   byte   2:  254\n    #   byte   3:  ord of ASCII character\n    #   byte   4:    0\n    #   byte 3+i:  ord of ASCII character\n    #   byte 4+i:    0\n    # or\n    #   byte   1:  255\n    #   byte   2:  254\n    #   byte   3:    0\n    #   byte   4:  ord of ASCII character\n    #   byte 3+i:    0\n    #   byte 4+i:  ord of ASCII character\n    #\n    print \"-> unicode_to_ascii()\\n\" if $opt_v > 2;\n\n    my $length  = length $string;\n#print \"length=$length\\n\";\n    return '' if $length <= 3;\n    my @unicode = split(//, $string);\n\n    # check the first 100 characters (= 200 bytes) for big or\n    # little endian UTF-16 encoding\n    my $max_peek     = $length < 200 ? $length : 200;\n    my $max_for_pass = $length < 200 ? 0.9*$max_peek/2 : 90;\n    my @view_1   = ();\n    for (my $i = 2; $i < $max_peek; $i += 2) { push @view_1, $unicode[$i] }\n    my @view_2   = ();\n    for (my $i = 3; $i < $max_peek; $i += 2) { push @view_2, $unicode[$i] }\n\n    my $points_1 = 0;\n    foreach my $C (@view_1) {\n        ++$points_1 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13\n                                                          or ord($C) == 10\n                                                          or ord($C) ==  9;\n    }\n\n    my $points_2 = 0;\n    foreach my $C (@view_2) {\n        ++$points_2 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13\n                                                          or ord($C) == 10\n                                                          or ord($C) ==  9;\n    }\n#print \"points 1: $points_1\\n\";\n#print \"points 2: $points_2\\n\";\n#print \"max_peek    : $max_peek\\n\";\n#print \"max_for_pass: $max_for_pass\\n\";\n\n    my $offset = undef;\n    if    ($points_1 > $max_for_pass) { $offset = 2; }\n    elsif ($points_2 > $max_for_pass) { $offset = 3; }\n    else                   {\n        print \"<- unicode_to_ascii() a p1=$points_1 p2=$points_2\\n\" if $opt_v > 2;\n        return '';\n    }  # neither big or little endian UTF-16\n\n    my @ascii              = ();\n    for (my $i = $offset; $i < $length; $i += 2) {\n        # some compound characters are made of HT (9), LF (10), or CR (13)\n        # True HT, LF, CR are followed by 00; only add those.\n        my $L = $unicode[$i];\n        if (ord($L) == 9 or ord($L) == 10 or ord($L) == 13) {\n            my $companion;\n            if ($points_1) {\n                last if $i+1 >= $length;\n                $companion = $unicode[$i+1];\n            } else {\n                $companion = $unicode[$i-1];\n            }\n            if (ord($companion) == 0) {\n                push @ascii, $L;\n            } else {\n                push @ascii, \" \";  # no clue what this letter is\n            }\n        } else {\n            push @ascii, $L;\n        }\n    }\n    print \"<- unicode_to_ascii() b p1=$points_1 p2=$points_2\\n\" if $opt_v > 2;\n    return join(\"\", @ascii);\n} # 1}}}\nsub uncompress_archive_cmd {                 # {{{1\n    my ($archive_file, ) = @_;\n\n    # Wrap $archive_file in single or double quotes in the system\n    # commands below to avoid filename chicanery (including\n    # spaces in the names).\n\n    print \"-> uncompress_archive_cmd($archive_file)\\n\" if $opt_v > 2;\n    my $extract_cmd = \"\";\n    my $missing     = \"\";\n    if ($opt_extract_with) {\n        ( $extract_cmd = $opt_extract_with ) =~ s/>FILE</$archive_file/g;\n    } elsif (basename($archive_file) eq \"-\" and !$ON_WINDOWS) {\n        $extract_cmd = \"cat > -\";\n    } elsif ($archive_file =~ /\\.tar$/ and $ON_WINDOWS) {\n        $extract_cmd = \"tar -xf \\\"$archive_file\\\"\";\n    } elsif (($archive_file =~ /\\.tar\\.(gz|Z)$/ or\n              $archive_file =~ /\\.tgz$/       ) and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"gzip --version\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"gzip -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"gzip\";\n        }\n    } elsif ($archive_file =~ /\\.tar\\.bz2$/ and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"bzip2 --help\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"bzip2 -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"bzip2\";\n        }\n    } elsif ($archive_file =~ /\\.tar\\.xz$/ and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"unxz --version\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"unxz -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"bzip2\";\n        }\n    } elsif ($archive_file =~ /\\.tar$/ and !$ON_WINDOWS)    {\n        $extract_cmd = \"tar xf '$archive_file'\";\n    } elsif ($archive_file =~ /\\.src\\.rpm$/i and !$ON_WINDOWS) {\n        if (external_utility_exists(\"cpio --version\")) {\n            if (external_utility_exists(\"rpm2cpio\")) {\n                $extract_cmd = \"rpm2cpio '$archive_file' | cpio -i\";\n            } else {\n                $missing = \"rpm2cpio\";\n            }\n        } else {\n            $missing = \"cpio\";\n        }\n    } elsif ($archive_file =~ /\\.(whl|zip)$/i and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"unzip\")) {\n            $extract_cmd = \"unzip -qq -d . '$archive_file'\";\n        } else {\n            $missing = \"unzip\";\n        }\n    } elsif ($archive_file =~ /\\.deb$/i and !$ON_WINDOWS)    {\n        # only useful if the .deb contains source code--most\n        # .deb files just have compiled executables\n        if (external_utility_exists(\"dpkg-deb\")) {\n            $extract_cmd = \"dpkg-deb -x '$archive_file' .\";\n        } else {\n            $missing = \"dpkg-deb\";\n        }\n    } elsif ($ON_WINDOWS and $archive_file =~ /\\.(whl|zip)$/i) {\n        # use unzip on Windows (comes with git-for-Windows)\n        if (external_utility_exists(\"unzip\")) {\n             $extract_cmd = \"unzip -qq -d . \\\"$archive_file\\\" \";\n        } else {\n            $missing = \"unzip\";\n        }\n    }\n    print \"<- uncompress_archive_cmd\\n\" if $opt_v > 2;\n    if ($missing) {\n        die \"Unable to expand $archive_file because external\\n\",\n            \"utility '$missing' is not available.\\n\",\n            \"Another possibility is to use the --extract-with option.\\n\";\n    } else {\n        return $extract_cmd;\n    }\n}\n# 1}}}\nsub read_list_file {                         # {{{1\n    my ($file, ) = @_;\n    # reads filenames from a STDIN pipe if $file == \"-\"\n\n    print \"-> read_list_file($file)\\n\" if $opt_v > 2;\n    my @entry = ();\n\n    if ($file eq \"-\") {\n        # read from a STDIN pipe\n        my $IN;\n        open($IN, $file);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            return ();\n        }\n        while (<$IN>) {\n            next if /^\\s*$/ or /^\\s*#/; # skip empty or commented lines\n            s/\\cM$//;  # DOS to Unix\n            chomp;\n            push @entry, $_;\n        }\n        $IN->close;\n    } else {\n        # read from an actual file\n        foreach my $line (read_file($file)) {\n            next if $line =~ /^\\s*$/ or $line =~ /^\\s*#/;\n            $line =~ s/\\cM$//;  # DOS to Unix\n            chomp $line;\n            push @entry, $line;\n        }\n    }\n\n    print \"<- read_list_file\\n\" if $opt_v > 2;\n    return @entry;\n}\n# 1}}}\nsub external_utility_exists {                # {{{1\n    my $exe = shift @_;\n\n    # remove args, if any\n    my $leading_exe = $exe;\n    $leading_exe =~ s/^(\\S+)\\s*.*?$/$1/;\n\n    my $success      = 0;\n    if ($ON_WINDOWS) {\n        $success = 1 unless system $exe . ' > nul';\n    } else {\n        $success = 1 unless system $exe . ' >/dev/null 2>&1';\n        if (!$success) {\n            $success = 1 unless system \"which\" . \" $leading_exe\" . ' >/dev/null 2>&1';\n        }\n    }\n\n    return $success;\n} # 1}}}\nsub write_xsl_file {                         # {{{1\n    print \"-> write_xsl_file\\n\" if $opt_v > 2;\n    my $XSL =             # <style>  </style> {{{2\n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- XSL file by Paul Schwann, January 2009.\n     Fixes for by-file and by-file-by-lang by d_uragan, November 2010.\n     -->\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n  <xsl:output method=\"html\"/>\n  <xsl:template match=\"/\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n      <head>\n        <title>CLOC Results</title>\n      </head>\n      <style type=\"text/css\">\n        table {\n          table-layout: auto;\n          border-collapse: collapse;\n          empty-cells: show;\n        }\n        td, th {\n          padding: 4px;\n        }\n        th {\n          background-color: #CCCCCC;\n        }\n        td {\n          text-align: center;\n        }\n        table, td, tr, th {\n          border: thin solid #999999;\n        }\n      </style>\n      <body>\n        <h3><xsl:value-of select=\"results/header\"/></h3>\n';\n# 2}}}\n\n    if ($opt_by_file) {\n        $XSL .=             # <table> </table>{{{2\n'        <table>\n          <thead>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n              <th>Language</th>\n';\n        $XSL .=\n'             <th>3<sup>rd</sup> Generation Equivalent</th>\n              <th>Scale</th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"results/files/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n              <td><xsl:value-of select=\"@language\"/></td>\n';\n        $XSL .=\n'             <td><xsl:value-of select=\"@factor\"/></td>\n              <td><xsl:value-of select=\"@scaled\"/></td>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </xsl:for-each>\n            <tr>\n              <th>Total</th>\n              <th><xsl:value-of select=\"results/files/total/@blank\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@comment\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@code\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@language\"/></th>\n';\n        $XSL .=\n'             <th><xsl:value-of select=\"results/files/total/@factor\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@scaled\"/></th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </tbody>\n        </table>\n        <br/>\n';\n# 2}}}\n    }\n\n    if (!$opt_by_file or $opt_by_file_by_lang) {\n        $XSL .=             # <table> </table> {{{2\n'       <table>\n          <thead>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n';\n        $XSL .=\n'             <th>Scale</th>\n              <th>3<sup>rd</sup> Generation Equivalent</th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"results/languages/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n';\n        $XSL .=\n'             <td><xsl:value-of select=\"@factor\"/></td>\n              <td><xsl:value-of select=\"@scaled\"/></td>\n' if $opt_3;\n        $XSL .=\n'          </tr>\n          </xsl:for-each>\n            <tr>\n              <th>Total</th>\n              <th><xsl:value-of select=\"results/languages/total/@sum_files\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@blank\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@comment\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@code\"/></th>\n';\n        $XSL .=\n'             <th><xsl:value-of select=\"results/languages/total/@factor\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@scaled\"/></th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </tbody>\n        </table>\n';\n# 2}}}\n    }\n\n    $XSL.= <<'EO_XSL'; # {{{2\n      </body>\n    </html>\n  </xsl:template>\n</xsl:stylesheet>\n\nEO_XSL\n# 2}}}\n\n    my $XSL_DIFF = <<'EO_DIFF_XSL'; # {{{2\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- XSL file by Blazej Kroll, November 2010 -->\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n  <xsl:output method=\"html\"/>\n  <xsl:template match=\"/\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n      <head>\n        <title>CLOC Results</title>\n      </head>\n      <style type=\"text/css\">\n        table {\n          table-layout: auto;\n          border-collapse: collapse;\n          empty-cells: show;\n          margin: 1em;\n        }\n        td, th {\n          padding: 4px;\n        }\n        th {\n          background-color: #CCCCCC;\n        }\n        td {\n          text-align: center;\n        }\n        table, td, tr, th {\n          border: thin solid #999999;\n        }\n      </style>\n      <body>\n        <h3><xsl:value-of select=\"results/header\"/></h3>\nEO_DIFF_XSL\n# 2}}}\n\n    if ($opt_by_file) {\n        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Same</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/same/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Modified</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/modified/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Added</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/added/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Removed</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/removed/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\nEO_DIFF_XSL\n# 2}}}\n    }\n\n    if (!$opt_by_file or $opt_by_file_by_lang) {\n        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Same</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/same/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Modified</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/modified/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Added</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/added/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Removed</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/removed/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\nEO_DIFF_XSL\n# 2}}}\n\n    }\n\n    $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n      </body>\n    </html>\n  </xsl:template>\n</xsl:stylesheet>\nEO_DIFF_XSL\n# 2}}}\n    if ($opt_diff) {\n        write_file($CLOC_XSL, {}, ( $XSL_DIFF ) );\n    } else {\n        write_file($CLOC_XSL, {}, ( $XSL ) );\n    }\n    print \"<- write_xsl_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub normalize_file_names {                   # {{{1\n    print \"-> normalize_file_names\\n\" if $opt_v > 2;\n    my (@files, ) = @_;\n\n    # Returns a hash of file names reduced to a canonical form\n    # (fully qualified file names, all path separators changed to /,\n    # Windows file names lowercased).  Hash values are the original\n    # file name.\n\n    my %normalized = ();\n    foreach my $F (@files) {\n        my $F_norm = $F;\n        if ($ON_WINDOWS) {\n            $F_norm = lc $F_norm; # for case insensitive file name comparisons\n            $F_norm =~ s{\\\\}{/}g; # Windows directory separators to Unix\n            $F_norm =~ s{^\\./}{}g;  # remove leading ./\n            if (($F_norm !~ m{^/}) and ($F_norm !~ m{^\\w:/})) {\n                # looks like a relative path; prefix with cwd\n                $F_norm = lc \"$cwd/$F_norm\";\n            }\n        } else {\n            $F_norm =~ s{^\\./}{}g;  # remove leading ./\n            if ($F_norm !~ m{^/}) {\n                # looks like a relative path; prefix with cwd\n                $F_norm = \"$cwd/$F_norm\";\n            }\n        }\n        # Remove trailing / so it does not interfere with further regex code\n        # that does not expect it\n        $F_norm =~ s{/+$}{};\n        $normalized{ $F_norm } = $F;\n    }\n    print \"<- normalize_file_names\\n\" if $opt_v > 2;\n    return %normalized;\n} # 1}}}\nsub combine_diffs {                          # {{{1\n    # subroutine by Andy (awalshe@sf.net)\n    # https://sourceforge.net/tracker/?func=detail&aid=3261017&group_id=174787&atid=870625\n    my ($ra_files) = @_;\n    print \"-> combine_diffs\\n\" if $opt_v > 2;\n\n    my $res   = \"$URL v $VERSION\\n\";\n    my $dl    = '-';\n    my $width = 79;\n    # columns are in this order\n    my @cols  = ('files', 'blank', 'comment', 'code');\n    my %HoH   = ();\n\n    foreach my $file (@{$ra_files}) {\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n\n        my $sec;\n        while (<$IN>) {\n            chomp;\n            s/\\cM$//;\n            next if /^(http|Language|-----)/;\n            if (/^[A-Za-z0-9]+/) {        # section title\n                $sec = $_;\n                chomp($sec);\n                $HoH{$sec} = () if ! exists $HoH{$sec};\n                next;\n            }\n\n            if (/^\\s(same|modified|added|removed)/) {  # calculated totals row\n                my @ar = grep { $_ ne '' } split(/ /, $_);\n                chomp(@ar);\n                my $ttl = shift @ar;\n                my $i = 0;\n                foreach(@ar) {\n                    my $t = \"${ttl}${dl}${cols[$i]}\";\n                    $HoH{$sec}{$t} = 0 if ! exists $HoH{$sec}{$t};\n                    $HoH{$sec}{$t} += $_;\n                    $i++;\n                }\n            }\n        }\n        $IN->close;\n    }\n\n    # rows are in this order\n    my @rows = ('same', 'modified', 'added', 'removed');\n\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n    $res .= sprintf(\"%-19s %14s %14s %14s %14s\\n\", 'Language',\n                    $cols[0], $cols[1], $cols[2], $cols[3]);\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n\n    # no inputs? %HoH will be empty\n    return $res unless %HoH;\n\n    for my $sec ( keys %HoH ) {\n        next if $sec =~ /SUM:/;\n        next unless defined $HoH{$sec};  # eg, the header line\n        $res .= \"$sec\\n\";\n        foreach (@rows) {\n            $res .= sprintf(\" %-18s %14s %14s %14s %14s\\n\",\n                            $_, $HoH{$sec}{\"${_}${dl}${cols[0]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[1]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[2]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[3]}\"});\n        }\n    }\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n    my $sec = 'SUM:';\n    $res .= \"$sec\\n\";\n    foreach (@rows) {\n        $res .= sprintf(\" %-18s %14s %14s %14s %14s\\n\",\n                        $_, $HoH{$sec}{\"${_}${dl}${cols[0]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[1]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[2]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[3]}\"});\n    }\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n\n    print \"<- combine_diffs\\n\" if $opt_v > 2;\n    return $res;\n} # 1}}}\nsub combine_csv_diffs {                      # {{{1\n    my ($delimiter, $ra_files) = @_;\n    print \"-> combine_csv_diffs\\n\" if $opt_v > 2;\n\n    my %sum = ();  # sum{ language } = array of 17 values\n    foreach my $file (@{$ra_files}) {\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n\n        my $sec;\n        while (<$IN>) {\n            next if /^Language${delimiter}\\s==\\sfiles${delimiter}/;\n            chomp;\n            my @words = split(/$delimiter/);\n            my $n_col = scalar(@words);\n            if ($n_col != 18) {\n                warn \"combine_csv_diffs(): Parse failure line $. of $file\\n\";\n                warn \"Expected 18 columns, got $n_col\\n\";\n                die;\n            }\n            my $Lang = $words[0];\n            my @count = map { int($_) } @words[1..16];\n            if (defined $sum{$Lang}) {\n                for (my $i = 0; $i < 16; $i++) {\n                    $sum{$Lang}[$i] += $count[$i];\n                }\n            } else {\n                @{$sum{$Lang}} = @count;\n            }\n        }\n        $IN->close;\n    }\n\n    my @header = (\"Language\", \"== files\", \"!= files\", \"+ files\", \"- files\",\n                  \"== blank\", \"!= blank\", \"+ blank\", \"- blank\", \"== comment\",\n                  \"!= comment\", \"+ comment\", \"- comment\", \"== code\",\n                  \"!= code\", \"+ code\", \"- code\", \"$URL v $VERSION\" );\n\n    my $res = join(\"$delimiter \", @header) . \"$delimiter\\n\";\n    foreach my $Lang (sort keys %sum) {\n        $res .= $Lang . \"$delimiter \";\n        for (my $i = 0; $i < 16; $i++) {\n            $res .= $sum{$Lang}[$i] . \"$delimiter \";\n        }\n        $res .= \"\\n\";\n    }\n\n    print \"<- combine_csv_diffs\\n\" if $opt_v > 2;\n    return $res;\n} # 1}}}\nsub get_time {                               # {{{1\n    if ($HAVE_Time_HiRes) {\n        return Time::HiRes::time();\n    } else {\n        return time();\n    }\n} # 1}}}\nsub really_is_D {                            # {{{1\n    # Ref bug 131, files ending with .d could be init.d scripts\n    # instead of D language source files.\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n    print \"-> really_is_D($file)\\n\" if $opt_v > 2;\n    my ($possible_script, $L) = peek_at_first_line($file, $rh_Err, $raa_errors);\n\n    print \"<- really_is_D($file)\\n\" if $opt_v > 2;\n    return $possible_script;    # null string if D, otherwise a language\n} # 1}}}\nsub no_autogen_files {                       # {{{1\n    # ref https://github.com/AlDanial/cloc/issues/151\n    my ($print,) = @_;\n    print \"-> no_autogen($print)\\n\" if $opt_v > 2;\n\n    # These sometimes created manually?\n    #               acinclude.m4\n    #               configure.ac\n    #               Makefile.am\n\n    my @files = qw (\n                    aclocal.m4\n                    announce-gen\n                    autogen.sh\n                    bootstrap\n                    compile\n                    config.guess\n                    config.h.in\n                    config.rpath\n                    config.status\n                    config.sub\n                    configure\n                    configure.in\n                    depcomp\n                    gendocs.sh\n                    gitlog-to-changelog\n                    git-version-gen\n                    gnupload\n                    gnu-web-doc-update\n                    install-sh\n                    libtool\n                    libtool.m4\n                    link-warning.h\n                    ltmain.sh\n                    lt~obsolete.m4\n                    ltoptions.m4\n                    ltsugar.m4\n                    ltversion.in\n                    ltversion.m4\n                    Makefile.in\n                    mdate-sh\n                    missing\n                    mkinstalldirs\n                    test-driver\n                    texinfo.tex\n                    update-copyright\n                    useless-if-before-free\n                    vc-list-files\n                    ylwrap\n                   );\n\n    if ($print) {\n        printf \"cloc will ignore these %d files with --no-autogen:\\n\", scalar @files;\n        foreach my $F (@files) {\n            print \"    $F\\n\";\n        }\n        print \"Additionally, Go files with '// Code generated by .* DO NOT EDIT.'\\n\";\n        print \"on the first line are ignored.\\n\";\n    }\n    print \"<- no_autogen()\\n\" if $opt_v > 2;\n    return @files;\n} # 1}}}\nsub load_from_config_file {                  # {{{1\n    # Supports all options except --config itself which would\n    # be pointless.\n    my ($config_file,\n                                                 $rs_by_file             ,\n                                                 $rs_by_file_by_lang     ,\n                                                 $rs_categorized         ,\n                                                 $rs_counted             ,\n                                                 $rs_include_ext         ,\n                                                 $rs_include_lang        ,\n                                                 $rs_include_content     ,\n                                                 $rs_exclude_content     ,\n                                                 $rs_exclude_lang        ,\n                                                 $rs_exclude_dir         ,\n                                                 $rs_exclude_list_file   ,\n                                                 $rs_explain             ,\n                                                 $rs_extract_with        ,\n                                                 $rs_found               ,\n                                                 $rs_count_diff          ,\n                                                 $rs_diff_list_files     ,\n                                                 $rs_diff                ,\n                                                 $rs_diff_alignment      ,\n                                                 $rs_diff_timeout        ,\n                                                 $rs_timeout             ,\n                                                 $rs_html                ,\n                                                 $rs_ignored             ,\n                                                 $rs_unique              ,\n                                                 $rs_quiet               ,\n                                                 $rs_force_lang_def      ,\n                                                 $rs_read_lang_def       ,\n                                                 $rs_show_ext            ,\n                                                 $rs_show_lang           ,\n                                                 $rs_progress_rate       ,\n                                                 $rs_print_filter_stages ,\n                                                 $rs_report_file         ,\n                                                 $ra_script_lang         ,\n                                                 $rs_sdir                ,\n                                                 $rs_skip_uniqueness     ,\n                                                 $rs_strip_code          ,\n                                                 $rs_strip_comments      ,\n                                                 $rs_original_dir        ,\n                                                 $rs_sum_reports         ,\n                                                 $rs_hide_rate           ,\n                                                 $rs_processes           ,\n                                                 $rs_unicode             ,\n                                                 $rs_3                   ,\n                                                 $rs_v                   ,\n                                                 $rs_vcs                 ,\n                                                 $rs_include_submodules  ,\n                                                 $rs_version             ,\n                                                 $rs_write_lang_def      ,\n                                                 $rs_write_lang_def_incl_dup,\n                                                 $rs_xml                 ,\n                                                 $rs_xsl                 ,\n                                                 $ra_force_lang          ,\n                                                 $rs_lang_no_ext         ,\n                                                 $rs_yaml                ,\n                                                 $rs_csv                 ,\n                                                 $rs_csv_delimiter       ,\n                                                 $rs_json                ,\n                                                 $rs_md                  ,\n                                                 $rs_fullpath            ,\n                                                 $rs_match_f             ,\n                                                 $ra_not_match_f         ,\n                                                 $rs_match_d             ,\n                                                 $ra_not_match_d         ,\n                                                 $rs_list_file           ,\n                                                 $rs_help                ,\n                                                 $rs_skip_win_hidden     ,\n                                                 $rs_read_binary_files   ,\n                                                 $rs_sql                 ,\n                                                 $rs_sql_project         ,\n                                                 $rs_sql_append          ,\n                                                 $rs_sql_style           ,\n                                                 $rs_inline              ,\n                                                 $rs_exclude_ext         ,\n                                                 $rs_ignore_whitespace   ,\n                                                 $rs_ignore_case         ,\n                                                 $rs_ignore_case_ext     ,\n                                                 $ra_ignore_regex        ,\n                                                 $rs_follow_links        ,\n                                                 $rs_autoconf            ,\n                                                 $rs_sum_one             ,\n                                                 $rs_by_percent          ,\n                                                 $rs_stdin_name          ,\n                                                 $rs_force_on_windows    ,\n                                                 $rs_force_on_unix       ,\n                                                 $rs_show_os             ,\n                                                 $rs_skip_archive        ,\n                                                 $rs_max_file_size       ,\n                                                 $rs_use_sloccount       ,\n                                                 $rs_no_autogen          ,\n                                                 $rs_force_git           ,\n                                                 $rs_strip_str_comments  ,\n                                                 $rs_file_encoding       ,\n                                                 $rs_docstring_as_code   ,\n                                                 $rs_stat                ,\n                                                 $rs_thousands_delimiter ,\n                                                 $rs_show_errors         ,\n        ) = @_;\n        # look for runtime configuration file in\n        #    $ENV{'HOME'}/.config/cloc/options.txt         -> POSIX\n        #    $ENV{'APPDATA'} . 'cloc'\n\n    print \"-> load_from_config_file($config_file)\\n\" if $opt_v and $opt_v > 2;\n    if (!is_file($config_file)) {\n        print \"<- load_from_config_file() (no such file: $config_file)\\n\" if $opt_v and $opt_v > 2;\n        return;\n    } elsif (!can_read($config_file)) {\n        print \"<- load_from_config_file() (unable to read $config_file)\\n\" if $opt_v and $opt_v > 2;\n        return;\n    }\n    print \"Reading options from $config_file.\\n\" if defined $opt_v;\n\n    my $has_force_lang = @{$ra_force_lang};\n    my $has_script_lang = @{$ra_script_lang};\n    my @lines = read_file($config_file);\n    foreach (@lines) {\n        next if /^\\s*$/ or /^\\s*#/;\n        s/\\s*--//;\n        s/^\\s+//;\n        if      (!defined ${$rs_by_file}             and /^(by_file|by-file)/)                                { ${$rs_by_file}            = 1;\n        } elsif (!defined ${$rs_by_file_by_lang}     and /^(by_file_by_lang|by-file-by-lang)/)                { ${$rs_by_file_by_lang}    = 1;\n        } elsif (!defined ${$rs_categorized}         and /^categorized(=|\\s+)(.*?)$/)                         { ${$rs_categorized}        = $2;\n        } elsif (!defined ${$rs_counted}             and /^counted(=|\\s+)(.*?)$/)                             { ${$rs_counted}            = $2;\n        } elsif (!defined ${$rs_include_ext}         and /^(?:include_ext|include-ext)(=|\\s+)(.*?)$/)         { ${$rs_include_ext}        = $2;\n        } elsif (!defined ${$rs_include_lang}        and /^(?:include_lang|include-lang)(=|\\s+)(.*?)$/)       { ${$rs_include_lang}       = $2;\n        } elsif (!defined ${$rs_include_content}     and /^(?:include_content|include-content)(=|\\s+)(.*?)$/) { ${$rs_include_content}    = $2;\n        } elsif (!defined ${$rs_exclude_content}     and /^(?:exclude_content|exclude-content)(=|\\s+)(.*?)$/) { ${$rs_exclude_content}    = $2;\n        } elsif (!defined ${$rs_exclude_lang}        and /^(?:exclude_lang|exclude-lang)(=|\\s+)(.*?)$/)       { ${$rs_exclude_lang}       = $2;\n        } elsif (!defined ${$rs_exclude_dir}         and /^(?:exclude_dir|exclude-dir)(=|\\s+)(.*?)$/)         { ${$rs_exclude_dir}        = $2;\n        } elsif (!defined ${$rs_explain}             and /^explain(=|\\s+)(.*?)$/)                             { ${$rs_explain}            = $2;\n        } elsif (!defined ${$rs_extract_with}        and /^(?:extract_with|extract-with)(=|\\s+)(.*?)$/)       { ${$rs_extract_with}       = $2;\n        } elsif (!defined ${$rs_found}               and /^found(=|\\s+)(.*?)$/)                               { ${$rs_found}              = $2;\n        } elsif (!defined ${$rs_count_diff}          and /^(count_and_diff|count-and-diff)/)                  { ${$rs_count_diff}         = 1;\n        } elsif (!defined ${$rs_diff_list_files}     and /^(diff_list_files|diff-list-files)/)                { ${$rs_diff_list_files}    = 1;\n        } elsif (!defined ${$rs_diff}                and /^diff/)                                             { ${$rs_diff}               = 1;\n        } elsif (!defined ${$rs_diff_alignment}      and /^(?:diff-alignment|diff_alignment)(=|\\s+)(.*?)$/)   { ${$rs_diff_alignment}     = $2;\n        } elsif (!defined ${$rs_diff_timeout}        and /^(?:diff-timeout|diff_timeout)(=|\\s+)i/)            { ${$rs_diff_timeout}       = $1;\n        } elsif (!defined ${$rs_timeout}             and /^timeout(=|\\s+)i/)                                  { ${$rs_timeout}            = $1;\n        } elsif (!defined ${$rs_html}                and /^html/)                                             { ${$rs_html}               = 1;\n        } elsif (!defined ${$rs_ignored}             and /^ignored(=|\\s+)(.*?)$/)                             { ${$rs_ignored}            = $2;\n        } elsif (!defined ${$rs_unique}              and /^unique(=|\\s+)(.*?)$/)                              { ${$rs_unique}            = $2;\n        } elsif (!defined ${$rs_quiet}               and /^quiet/)                                            { ${$rs_quiet}              = 1;\n        } elsif (!defined ${$rs_force_lang_def}      and /^(?:force_lang_def|force-lang-def)(=|\\s+)(.*?)$/)   { ${$rs_force_lang_def}     = $2;\n        } elsif (!defined ${$rs_read_lang_def}       and /^(?:read_lang_def|read-lang-def)(=|\\s+)(.*?)$/)     { ${$rs_read_lang_def}      = $2;\n        } elsif (!defined ${$rs_progress_rate}       and /^(?:progress_rate|progress-rate)(=|\\s+)(\\d+)/)      { ${$rs_progress_rate}      = $2;\n        } elsif (!defined ${$rs_print_filter_stages} and /^(print_filter_stages|print-filter-stages)/)        { ${$rs_print_filter_stages}= 1;\n        } elsif (!defined ${$rs_report_file}         and /^(?:report_file|report-file)(=|\\s+)(.*?)$/)         { ${$rs_report_file}        = $2;\n        } elsif (!defined ${$rs_report_file}         and /^out(=|\\s+)(.*?)$/)                                 { ${$rs_report_file}        = $2;\n        } elsif (!defined ${$rs_sdir}                and /^sdir(=|\\s+)(.*?)$/)                                { ${$rs_sdir}               = $2;\n        } elsif (!defined ${$rs_skip_uniqueness}     and /^(skip_uniqueness|skip-uniqueness)/)                { ${$rs_skip_uniqueness}    = 1;\n        } elsif (!defined ${$rs_strip_code}          and /^(?:strip_code|strip-code)(=|\\s+)(.*?)$/)           { ${$rs_strip_code}         = $2;\n        } elsif (!defined ${$rs_strip_comments}      and /^(?:strip_comments|strip-comments)(=|\\s+)(.*?)$/)   { ${$rs_strip_comments}     = $2;\n        } elsif (!defined ${$rs_original_dir}        and /^(original_dir|original-dir)/)                      { ${$rs_original_dir}       = 1;\n        } elsif (!defined ${$rs_sum_reports}         and /^(sum_reports|sum-reports)/)                        { ${$rs_sum_reports}        = 1;\n        } elsif (!defined ${$rs_hide_rate}           and /^(hid_rate|hide-rate)/)                             { ${$rs_hide_rate}          = 1;\n        } elsif (!defined ${$rs_processes}           and /^processes(=|\\s+)(\\d+)/)                            { ${$rs_processes}          = $2;\n        } elsif (!defined ${$rs_unicode}             and /^unicode/)                                          { ${$rs_unicode}            = 1;\n        } elsif (!defined ${$rs_3}                   and /^3/)                                                { ${$rs_3}                  = 1;\n        } elsif (!defined ${$rs_vcs}                 and /^vcs(=|\\s+)(\\S+)/)                                  { ${$rs_vcs}                = $2;\n        } elsif (!defined ${$rs_include_submodules}  and /^include-submodules/)                               { ${$rs_include_submodules} = 1;\n        } elsif (!defined ${$rs_version}             and /^version/)                                          { ${$rs_version}            = 1;\n        } elsif (!defined ${$rs_write_lang_def}      and /^(?:write_lang_def|write-lang-def)(=|\\s+)(.*?)$/)   { ${$rs_write_lang_def}     = $2;\n        } elsif (!defined ${$rs_write_lang_def_incl_dup} and /^(?:write_lang_def_incl_dup|write-lang-def-incl-dup)(=|\\s+)(.*?)$/) { ${$rs_write_lang_def_incl_dup} = $2;\n        } elsif (!defined ${$rs_xml}                 and /^xml/)                                              { ${$rs_xml}                = 1;\n        } elsif (!defined ${$rs_xsl}                 and /^xsl(=|\\s+)(.*?)$/)                                 { ${$rs_xsl}                = $2;\n        } elsif (!defined ${$rs_lang_no_ext}         and /^(?:lang_no_ext|lang-no-ext)(=|\\s+)(.*?)$/)         { ${$rs_lang_no_ext}        = $2;\n        } elsif (!defined ${$rs_yaml}                and /^yaml/)                                             { ${$rs_yaml}               = 1;\n        } elsif (!defined ${$rs_csv}                 and /^csv/)                                              { ${$rs_csv}                = 1;\n        } elsif (!defined ${$rs_csv_delimiter}       and /^(?:csv_delimiter|csv-delimiter)(=|\\s+)(.*?)$/)     { ${$rs_csv_delimiter}      = $2;\n        } elsif (!defined ${$rs_json}                and /^json/)                                             { ${$rs_json}               = 1;\n        } elsif (!defined ${$rs_md}                  and /^md/)                                               { ${$rs_md}                 = 1;\n        } elsif (!defined ${$rs_fullpath}            and /^fullpath/)                                         { ${$rs_fullpath}           = 1;\n        } elsif (!defined ${$rs_match_f}             and /^(?:match_f|match-f)(=|\\s+)['\"]?(.*?)['\"]?$/)       { ${$rs_match_f}            = $2;\n        } elsif (!        @{$ra_not_match_f}         and /^(?:not_match_f|not-match-f)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_not_match_f}   , $2;\n        } elsif (!defined ${$rs_match_d}             and /^(?:match_d|match-d)(=|\\s+)['\"]?(.*?)['\"]?$/)       { ${$rs_match_d}            = $2;\n        } elsif (!        @{$ra_not_match_d}         and /^(?:not_match_d|not-match-d)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_not_match_d}   , $2;\n        } elsif (!defined ${$rs_list_file}           and /^(?:list_file|list-file)(=|\\s+)(.*?)$/)             { ${$rs_list_file}          = $2;\n        } elsif (!defined ${$rs_help}                and /^help/)                                             { ${$rs_help}               = 1;\n        } elsif (!defined ${$rs_skip_win_hidden}     and /^(skip_win_hidden|skip-win-hidden)/)                { ${$rs_skip_win_hidden}    = 1;\n        } elsif (!defined ${$rs_read_binary_files}   and /^(read_binary_files|read-binary-files)/)            { ${$rs_read_binary_files}  = 1;\n        } elsif (!defined ${$rs_sql}                 and /^sql(=|\\s+)(.*?)$/)                                 { ${$rs_sql}                = $2;\n        } elsif (!defined ${$rs_sql_project}         and /^(?:sql_project|sql-project)(=|\\s+)(.*?)$/)         { ${$rs_sql_project}        = $2;\n        } elsif (!defined ${$rs_sql_append}          and /^(sql_append|sql-append)/)                          { ${$rs_sql_append}         = 1;\n        } elsif (!defined ${$rs_sql_style}           and /^(?:sql_style|sql-style)(=|\\s+)(.*?)$/)             { ${$rs_sql_style}          = $2;\n        } elsif (!defined ${$rs_inline}              and /^inline/)                                           { ${$rs_inline}             = 1;\n        } elsif (!defined ${$rs_exclude_ext}         and /^(?:exclude_ext|exclude-ext)(=|\\s+)(.*?)$/)         { ${$rs_exclude_ext}        = $2;\n        } elsif (!defined ${$rs_ignore_whitespace}   and /^(ignore_whitespace|ignore-whitespace)/)            { ${$rs_ignore_whitespace}  = 1;\n        } elsif (!defined ${$rs_ignore_case_ext}     and /^(ignore_case_ext|ignore-case-ext)/)                { ${$rs_ignore_case_ext}    = 1;\n        } elsif (!defined ${$rs_ignore_case}         and /^(ignore_case|ignore-case)/)                        { ${$rs_ignore_case}        = 1;\n        } elsif (!        @{$ra_ignore_regex}        and /^(?:ignore_regex|ignore-regex)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_ignore_regex}, $2;\n        } elsif (!defined ${$rs_follow_links}        and /^(follow_links|follow-links)/)                      { ${$rs_follow_links}       = 1;\n        } elsif (!defined ${$rs_autoconf}            and /^autoconf/)                                         { ${$rs_autoconf}           = 1;\n        } elsif (!defined ${$rs_sum_one}             and /^(sum_one|sum-one)/)                                { ${$rs_sum_one}            = 1;\n        } elsif (!defined ${$rs_by_percent}          and /^(?:by_percent|by-percent)(=|\\s+)(.*?)$/)           { ${$rs_by_percent}         = $2;\n        } elsif (!defined ${$rs_stdin_name}          and /^(?:stdin_name|stdin-name)(=|\\s+)(.*?)$/)           { ${$rs_stdin_name}         = $2;\n        } elsif (!defined ${$rs_force_on_windows}    and /^windows/)                                          { ${$rs_force_on_windows}   = 1;\n        } elsif (!defined ${$rs_force_on_unix}       and /^unix/)                                             { ${$rs_force_on_unix}      = 1;\n        } elsif (!defined ${$rs_show_os}             and /^(show_os|show-os)/)                                { ${$rs_show_os}            = 1;\n        } elsif (!defined ${$rs_skip_archive}        and /^(?:skip_archive|skip-archive)(=|\\s+)(.*?)$/)       { ${$rs_skip_archive}       = $2;\n        } elsif (!defined ${$rs_max_file_size}       and /^(?:max_file_size|max-file-size)(=|\\s+)(\\d+)/)      { ${$rs_max_file_size}      = $2;\n        } elsif (!defined ${$rs_use_sloccount}       and /^(use_sloccount|use-sloccount)/)                    { ${$rs_use_sloccount}      = 1;\n        } elsif (!defined ${$rs_no_autogen}          and /^(no_autogen|no-autogen)/)                          { ${$rs_no_autogen}         = 1;\n        } elsif (!defined ${$rs_force_git}           and /^git/)                                              { ${$rs_force_git}          = 1;\n        } elsif (!defined ${$rs_exclude_list_file}   and /^(?:exclude_list_file|exclude-list-file)(=|\\s+)(.*?)$/)\n                                                                   { ${$rs_exclude_list_file}  = $2;\n        } elsif (!defined ${$rs_v} and /^(verbose|v)((=|\\s+)(\\d+))?/) {\n            if (!defined $4) { ${$rs_v} =  0; }\n            else             { ${$rs_v} = $4; }\n        } elsif (!$has_script_lang and /^(?:script_lang|script-lang)(=|\\s+)(.*?)$/)         {\n                                                            push @{$ra_script_lang}          , $2;\n        } elsif (!$has_force_lang and /^(?:force_lang|force-lang)(=|\\s+)(.*?)$/)           {\n                                                            push @{$ra_force_lang}           , $2;\n        } elsif (!defined ${$rs_show_ext}          and /^(show_ext|show-ext)((=|\\s+)(.*))?$/)  {\n            if (!defined $4) { ${$rs_show_ext} =  0; }\n            else             { ${$rs_show_ext} = $4; }\n        } elsif (!defined ${$rs_show_lang}         and /^(show_lang|show-lang)((=|\\s+)(.*))?s/){\n            if (!defined $4) { ${$rs_show_lang} =  0; }\n            else             { ${$rs_show_lang} = $4; }\n        } elsif (!defined ${$rs_strip_str_comments}  and /^(strip_str_comments|strip-str-comments)/)     { ${$rs_strip_str_comments} = 1;\n        } elsif (!defined ${$rs_file_encoding}       and /^(?:file_encoding|file-encoding)(=|\\s+)(\\S+)/) { ${$rs_file_encoding}      = $2;\n        } elsif (!defined ${$rs_docstring_as_code}   and /^(docstring_as_code|docstring-as-code)/)       { ${$rs_docstring_as_code}  = 1;\n        } elsif (!defined ${$rs_stat}                and /stat/)                                         { ${$rs_stat}               = 1;\n        } elsif (!defined ${$rs_thousands_delimiter} and /^ksep|thousands-delimiter(=|\\s+)(.*?)$/)       { ${$rs_thousands_delimiter}= $2;\n        } elsif (!defined ${$rs_show_errors}         and /show_errors|show-errors/)                      { ${$rs_show_errors}        = 1;\n        }\n\n    }\n} # 1}}}\nsub trick_pp_packer_encode {                 # {{{1\n    use Encode;\n    # PAR::Packer gives 'Unknown PerlIO layer \"encoding\"' unless it is\n    # forced into using this module.\n    my ($OUT, $JunkFile) = tempfile(UNLINK => 1);  # delete on exit\n    open($OUT, \"> :encoding(utf8)\", $JunkFile);\n    close($OUT);\n}\n# 1}}}\nsub really_is_smarty {                       # {{{1\n    # Given filename, returns TRUE if its contents look like Smarty template\n    my ($filename, ) = @_;\n\n    print \"-> really_is_smarty($filename)\\n\" if $opt_v > 2;\n\n    my @lines = read_file($filename);\n\n    my $points = 0;\n    foreach my $L (@lines) {\n        if (($L =~ /\\{(if|include)\\s/) or\n            ($L =~ /\\{\\/if\\}/)         or\n            ($L =~ /(\\{\\*|\\*\\})/)      or\n            ($L =~ /\\{\\$\\w/)) {\n            ++$points;\n        }\n        last if $points >= 2;\n    }\n    print \"<- really_is_smarty(points=$points)\\n\" if $opt_v > 2;\n    return $points >= 2;\n} # 1}}}\nsub check_alternate_config_files {           # {{{1\n    my ($list_file, $exclude_list_file, $read_lang_def,\n        $force_lang_def, $diff_list_file, ) = @_;\n    my $found_it = \"\";\n    foreach my $file ($list_file,\n                      $exclude_list_file,\n                      $read_lang_def,\n                      $force_lang_def,\n                      $diff_list_file ) {\n        next unless defined $file;\n        my $dir = dirname $file;\n        next unless can_read($dir) and is_dir($dir);\n        my $bn = basename $config_file;\n        if (can_read(\"$dir/$bn\")) {\n            $found_it = \"$dir/$bn\";\n            print \"Using configuration file $found_it\\n\" if $opt_v;\n            last;\n        }\n    }\n    return $found_it;\n}\n# 1}}}\nsub write_null_results {                     # {{{\n    my ($json, $xml, $report_file,) = @_;\n    print \"-> write_null_results\\n\" if $opt_v > 2;\n    if ((defined $json) or (defined $xml)) {\n        my $line = \"\";\n        if (defined $json) {\n            $line = \"{}\";\n        } else {\n            $line = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><results/>';\n        }\n        if (defined $report_file) {\n            open OUT, \">$report_file\" or die \"Cannot write to $report_file $!\\n\";\n            print OUT \"$line\\n\";\n            close OUT;\n        } else {\n            print \"$line\\n\";\n        }\n    }\n    print \"<- write_null_results\\n\" if $opt_v > 2;\n} # }}}\nsub glob2regex {                             # {{{\n    # convert simple xpath-style glob pattern to a regex\n    my $globstr = shift;\n    my $re = $globstr;\n    $re =~ s{^[\"']}{};\n    $re =~ s{^\\.\\/}{};\n    $re =~ s{[\"']$}{};\n    $re =~ s{\\.}{\\\\.}g;\n    $re =~ s{\\*\\*}{\\cx}g;  # ctrl x  = .*?\n    $re =~ s{\\*}{\\cy}g;    # ctrl y = [^/]*\n    $re =~ s{\\cx}{.*?}g;\n    $re =~ s{\\cy}{[^/]*}g;\n    return '^' . $re . '$';\n} # }}}\nsub load_json {                              # {{{1\n    #\n    # Load a cloc-generated JSON string into %contents\n    #   $contents{filename}{blank|comment|code|language} = value\n    # then print in a variety of formats.\n    #\n    my ($json_string, ) = @_;\n    print \"-> load_json()\\n\" if $opt_v > 2;\n\n    my %contents = ();\n    my $heading = undef;\n    foreach (split /\\n/, $json_string) {\n        if (/^{?\"(.*?)\"/) {\n            $heading = $1;\n        } else {\n            if (/^\\s+\"(.*?)\"\\s*:\\s+(\\d+(\\.\\d+)?)\\b/) {\n                # numeric value\n                $contents{$heading}{$1} = $2;\n            } elsif (/^\\s+\"(.*?)\"\\s*:\\s+\"(.*?)\"/) {\n                $contents{$heading}{$1} = $2;\n            }\n        }\n    }\n    my $url = $contents{'header'}{'cloc_url'};\n    my $ver = $contents{'header'}{'cloc_version'};\n    my $sec = $contents{'header'}{'elapsed_seconds'};\n    my $n_file = $contents{'header'}{'n_files'};\n    my $n_line = $contents{'header'}{'n_lines'};\n    $sec = $sec == 0 ? 1.0e-3 : $sec;\n    my $header = sprintf \"%s v %s T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                          $url, $ver, $sec, $n_file/$sec, $n_line/$sec;\n    delete $contents{'header'};\n    delete $contents{'SUM'};\n\n    my @file_list = (sort { $contents{$b}{'code'} <=>\n                            $contents{$a}{'code'} } keys %contents );\n#die Dumper(\\%contents);\n    # Determine column widths for output\n    my $file_len = 0;\n    my $lang_len = 0;\n    foreach my $file (keys %contents) {\n        my $flen = length $file;\n        my $llen = length $contents{$file}{'language'};\n        $file_len = $file_len > $flen ? $file_len : $flen;\n        $lang_len = $lang_len > $llen ? $lang_len : $llen;\n    }\n    print \"<- load_json()\\n\" if $opt_v > 2;\n    return $file_len, $lang_len, $header, %contents;\n}\n# 1}}}\nsub print_format_n {                         # {{{1\n    # by file with\n    # format 1 : Language | files | blank | comment | code\n    # format 2 : Language | files | blank | comment | code | total\n    # format 3 : File | Language | blank | comment | code\n    # format 4 : File | blank | comment | code | total\n    # format 5 : File | Language | blank | comment | code | total\n    my ($format, $file_len, $lang_len, $header, %contents) = @_;\n    print \"-> print_format_n($format)\\n\" if $opt_v > 2;\n    my @prt_lines = ();\n\n    # 8 = characters in \"Language\"\n    $lang_len = max(8, $lang_len);\n    my %str_fmt = (\n        1 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        2 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        3 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n        4 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len),\n        5 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n    );\n    my %val_fmt = (\n        1 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        2 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        3 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n        4 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len),\n        5 => sprintf(\"%%-%ds  %%-%ds  %%7d  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n    );\n    my %language = ();\n    foreach my $file (keys %contents) {\n        my $lang = $contents{$file}{'language'};\n        $language{$lang}{'files'} += 1;\n        foreach my $category ('blank', 'comment', 'code',) {\n            $language{$lang}{$category} += $contents{$file}{$category};\n            $language{$lang}{'total'}   += $contents{$file}{$category};\n        }\n    }\n    my @file_list = (sort { $contents{$b}{'code'} <=>\n                            $contents{$a}{'code'} } keys %contents );\n    my @lang_list = (sort { $language{$b}{'code'} <=>\n                            $language{$a}{'code'} } keys %language );\n\n    my %hyphens = (\n        1 => \"-\" x ($lang_len + 4*9),\n        2 => \"-\" x ($lang_len + 5*9),\n        3 => \"-\" x ($lang_len + $file_len + 2 + 3*9),\n        4 => \"-\" x ($file_len + 4*9),\n        5 => \"-\" x ($lang_len + $file_len + 2 + 4*9),\n    );\n    my %col_headings = (\n        1 => [\"Language\", \"files\", \"blank\", \"comment\", \"code\"],\n        2 => [\"Language\", \"files\", \"blank\", \"comment\", \"code\", \"Total\"],\n        3 => [\"File\", \"Language\", \"blank\", \"comment\", \"code\"],\n        4 => [\"File\", \"blank\", \"comment\", \"code\", \"Total\"],\n        5 => [\"File\", \"Language\", \"blank\", \"comment\", \"code\", \"Total\"],\n    );\n\n    push @prt_lines, \"$header\\n\";\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    push @prt_lines, sprintf $str_fmt{$format}, @{$col_headings{$format}};\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    my ($n_files, $n_blank, $n_comment, $n_code, $n_total) = (0, 0, 0, 0, 0);\n    my @out;\n    my $sum;\n    if ($format < 3) {\n        # by language\n        foreach my $lang (@lang_list) {\n            my ($nF, $nB, $nCm, $nCo) = ($language{$lang}{'files'},\n                                         $language{$lang}{'blank'},\n                                         $language{$lang}{'comment'},\n                                         $language{$lang}{'code'});\n            $n_files   += $nF;\n            $n_blank   += $nB;\n            $n_comment += $nCm;\n            $n_code    += $nCo;\n            $n_total   += $nB + $nCm + $nCo;\n            $sum = $nB + $nCm + $nCo;\n            if ($opt_thousands_delimiter) {\n                $sum = separate_thousands($sum, $opt_thousands_delimiter);\n                $nF  = separate_thousands($nF,  $opt_thousands_delimiter);\n                $nB  = separate_thousands($nB,  $opt_thousands_delimiter);\n                $nCm = separate_thousands($nCm, $opt_thousands_delimiter);\n                $nCo = separate_thousands($nCo, $opt_thousands_delimiter);\n            }\n            if      ($format == 1) {\n                @out = ($lang, $nF, $nB, $nCm, $nCo);\n            } else {\n                @out = ($lang, $nF, $nB, $nCm, $nCo, $sum);\n            }\n            push @prt_lines, sprintf $str_fmt{$format}, @out;\n        }\n    } else {\n        # by file\n        foreach my $file (@file_list) {\n            my ($nB, $nCm, $nCo) = ($contents{$file}{'blank'},\n                                    $contents{$file}{'comment'},\n                                    $contents{$file}{'code'});\n            $n_blank   += $nB;\n            $n_comment += $nCm;\n            $n_code    += $nCo;\n            $n_total   += $nB + $nCm + $nCo;\n            $sum = $nB + $nCm + $nCo;\n            if ($opt_thousands_delimiter) {\n                $sum = separate_thousands($sum, $opt_thousands_delimiter);\n                $nB  = separate_thousands($nB,  $opt_thousands_delimiter);\n                $nCm = separate_thousands($nCm, $opt_thousands_delimiter);\n                $nCo = separate_thousands($nCo, $opt_thousands_delimiter);\n            }\n            my $lang = $contents{$file}{'language'};\n            if      ($format == 1) {\n            } elsif ($format == 3) {\n                @out = ($file, $lang, $nB, $nCm, $nCo);\n            } elsif ($format == 4) {\n                @out = ($file, $nB, $nCm, $nCo, $sum);\n            } else {\n                @out = ($file, $lang, $nB, $nCm, $nCo, $sum);\n            }\n            push @prt_lines, sprintf $str_fmt{$format}, @out;\n        }\n    }\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    if (scalar @file_list > 1) {\n        if ($opt_thousands_delimiter) {\n            $n_files   = separate_thousands($n_files,   $opt_thousands_delimiter);\n            $n_blank   = separate_thousands($n_blank,   $opt_thousands_delimiter);\n            $n_comment = separate_thousands($n_comment, $opt_thousands_delimiter);\n            $n_code    = separate_thousands($n_code,    $opt_thousands_delimiter);\n            $n_total   = separate_thousands($n_total,   $opt_thousands_delimiter);\n        }\n        if      ($format == 1) {\n            @out = ( \"SUM\", $n_files, $n_blank, $n_comment, $n_code);\n        } elsif ($format == 2) {\n            @out = ( \"SUM\", $n_files, $n_blank, $n_comment, $n_code, $n_total);\n        } elsif ($format == 3) {\n            @out = ( \"SUM\", \" \", $n_blank, $n_comment, $n_code);\n        } elsif ($format == 4) {\n            @out = ( \"SUM\", $n_blank, $n_comment, $n_code, $n_total);\n        } else {\n            @out = ( \"SUM\", \" \", $n_blank, $n_comment, $n_code, $n_total);\n        }\n        push @prt_lines, sprintf $str_fmt{$format}, @out;\n        push @prt_lines, \"$hyphens{$format}\\n\";\n    }\n    return @prt_lines;\n    print \"<- print_format_n()\\n\" if $opt_v > 2;\n} # 1}}}\nsub parse_ignore_regex {                              # {{{1\n    #\n    # Convert the list of \"language(s)|regex\" into a hash\n    #   $ignore_regex{language} = [list of regex]\n\n    my ($ra_lang_regex           , # in, as given on command line\n        $rhaa_Filters_by_Language, # in, hash of filters by language\n        $rha_ignore_regex) = @_;\n    print \"-> parse_ignore_regex()\\n\" if $opt_v > 2;\n\n    foreach my $lang_regex (@{$ra_lang_regex}) {\n        die \"Missing '|' character in --ignore-regex '$lang_regex'\\n\"\n            unless $lang_regex =~ /\\|/;\n        my ($lang, $regex) = split(/\\|/, $lang_regex, 2);\n        die \"Invalid --ignore-regex: $lang_regex\\n\"\n            unless defined $lang and defined $regex;\n        my @languages = split(/,/, $lang);\n        foreach my $lang (@languages) {\n            if ($lang eq '*') {\n                foreach my $lang (keys %{$rhaa_Filters_by_Language}) {\n                    push @{$rha_ignore_regex->{$lang}}, $regex;\n                }\n            } else {\n                die \"Unknown language '$lang' in --ignore-regex '$lang_regex'\\n\"\n                    unless defined $rhaa_Filters_by_Language->{$lang};\n                push @{$rha_ignore_regex->{$lang}}, $regex;\n            }\n#print \"lang=$lang  regex=[$regex]\\n\";\n        }\n    }\n#use Data::Dumper;\n#print Dumper($rha_ignore_regex);\n    print \"<- parse_ignore_regex()\\n\" if $opt_v > 2;\n}\n# 1}}}\n# really_is_pascal, really_is_incpascal, really_is_php from SLOCCount\nmy %php_files    = ();  # really_is_php()\nsub really_is_pascal {                       # {{{1\n# Given filename, returns TRUE if its contents really are Pascal.\n\n# This isn't as obvious as it seems.\n# Many \".p\" files are Perl files\n# (such as /usr/src/redhat/BUILD/ispell-3.1/dicts/czech/glob.p),\n# others are C extractions\n# (such as /usr/src/redhat/BUILD/linux/include/linux/umsdos_fs.p\n# and some files in linuxconf).\n# However, test files in \"p2c\" really are Pascal, for example.\n\n# Note that /usr/src/redhat/BUILD/ucd-snmp-4.1.1/ov/bitmaps/UCD.20.p\n# is actually C code.  The heuristics determine that they're not Pascal,\n# but because it ends in \".p\" it's not counted as C code either.\n# I believe this is actually correct behavior, because frankly it\n# looks like it's automatically generated (it's a bitmap expressed as code).\n# Rather than guess otherwise, we don't include it in a list of\n# source files.  Let's face it, someone who creates C files ending in \".p\"\n# and expects them to be counted by default as C files in SLOCCount needs\n# their head examined.  I suggest examining their head\n# with a sucker rod (see syslogd(8) for more on sucker rods).\n\n# This heuristic counts as Pascal such files such as:\n#  /usr/src/redhat/BUILD/teTeX-1.0/texk/web2c/tangleboot.p\n# Which is hand-generated.  We don't count woven documents now anyway,\n# so this is justifiable.\n\n my $filename = shift;\n chomp($filename);\n\n# The heuristic is as follows: it's Pascal _IF_ it has all of the following\n# (ignoring {...} and (*...*) comments):\n# 1. \"^..program NAME\" or \"^..unit NAME\",\n# 2. \"procedure\", \"function\", \"^..interface\", or \"^..implementation\",\n# 3. a \"begin\", and\n# 4. it ends with \"end.\",\n#\n# Or it has all of the following:\n# 1. \"^..module NAME\" and\n# 2. it ends with \"end.\".\n#\n# Or it has all of the following:\n# 1. \"^..program NAME\",\n# 2. a \"begin\", and\n# 3. it ends with \"end.\".\n#\n# The \"end.\" requirements in particular filter out non-Pascal.\n#\n# Note (jgb): this does not detect Pascal main files in fpc, like\n# fpc-1.0.4/api/test/testterminfo.pas, which does not have \"program\" in\n# it\n\n my $is_pascal = 0;      # Value to determine.\n\n my $has_program = 0;\n my $has_unit = 0;\n my $has_module = 0;\n my $has_procedure_or_function = 0;\n my $found_begin = 0;\n my $found_terminating_end = 0;\n my $has_begin = 0;\n\n my $PASCAL_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's pascal.\\n\" if !defined $PASCAL_FILE;\n while(<$PASCAL_FILE>) {\n   s/\\{.*?\\}//g;  # Ignore {...} comments on this line; imperfect, but effective.\n   s/\\(\\*.*?\\*\\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.\n   if (m/\\bprogram\\s+[A-Za-z]/i)  {$has_program=1;}\n   if (m/\\bunit\\s+[A-Za-z]/i)     {$has_unit=1;}\n   if (m/\\bmodule\\s+[A-Za-z]/i)   {$has_module=1;}\n   if (m/\\bprocedure\\b/i)         { $has_procedure_or_function = 1; }\n   if (m/\\bfunction\\b/i)          { $has_procedure_or_function = 1; }\n   if (m/^\\s*interface\\s+/i)      { $has_procedure_or_function = 1; }\n   if (m/^\\s*implementation\\s+/i) { $has_procedure_or_function = 1; }\n   if (m/\\bbegin\\b/i) { $has_begin = 1; }\n   # Originally I said:\n   # \"This heuristic fails if there are multi-line comments after\n   # \"end.\"; I haven't seen that in real Pascal programs:\"\n   # But jgb found there are a good quantity of them in Debian, specially in\n   # fpc (at the end of a lot of files there is a multiline comment\n   # with the changelog for the file).\n   # Therefore, assume Pascal if \"end.\" appears anywhere in the file.\n   if (m/end\\.\\s*$/i) {$found_terminating_end = 1;}\n#   elsif (m/\\S/) {$found_terminating_end = 0;}\n }\n close($PASCAL_FILE);\n\n # Okay, we've examined the entire file looking for clues;\n # let's use those clues to determine if it's really Pascal:\n\n if ( ( ($has_unit || $has_program) && $has_procedure_or_function &&\n     $has_begin && $found_terminating_end ) ||\n      ( $has_module && $found_terminating_end ) ||\n      ( $has_program && $has_begin && $found_terminating_end ) )\n          {$is_pascal = 1;}\n\n return $is_pascal;\n} # 1}}}\nsub really_is_incpascal {                    # {{{1\n# Given filename, returns TRUE if its contents really are Pascal.\n# For .inc files (mainly seen in fpc)\n\n my $filename = shift;\n chomp($filename);\n\n# The heuristic is as follows: it is Pascal if any of the following:\n# 1. really_is_pascal returns true\n# 2. Any usual reserved word is found (program, unit, const, begin...)\n\n # If the general routine for Pascal files works, we have it\n if (really_is_pascal($filename)) {\n   return 1;\n }\n\n my $is_pascal = 0;      # Value to determine.\n my $found_begin = 0;\n\n my $PASCAL_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's pascal.\\n\" if !defined $PASCAL_FILE;\n while(<$PASCAL_FILE>) {\n   s/\\{.*?\\}//g;  # Ignore {...} comments on this line; imperfect, but effective.\n   s/\\(\\*.*?\\*\\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.\n   if (m/\\bprogram\\s+[A-Za-z]/i)  {$is_pascal=1;}\n   if (m/\\bunit\\s+[A-Za-z]/i)     {$is_pascal=1;}\n   if (m/\\bmodule\\s+[A-Za-z]/i)   {$is_pascal=1;}\n   if (m/\\bprocedure\\b/i)         {$is_pascal = 1; }\n   if (m/\\bfunction\\b/i)          {$is_pascal = 1; }\n   if (m/^\\s*interface\\s+/i)      {$is_pascal = 1; }\n   if (m/^\\s*implementation\\s+/i) {$is_pascal = 1; }\n   if (m/\\bconstant\\s+/i)         {$is_pascal=1;}\n   if (m/\\bbegin\\b/i) { $found_begin = 1; }\n   if ((m/end\\.\\s*$/i) && ($found_begin = 1)) {$is_pascal = 1;}\n   if ($is_pascal) {\n     last;\n   }\n }\n\n close($PASCAL_FILE);\n return $is_pascal;\n} # 1}}}\nsub really_is_php {                          # {{{1\n# Given filename, returns TRUE if its contents really is php.\n\n my $filename = shift;\n chomp($filename);\n\n my $is_php = 0;      # Value to determine.\n # Need to find a matching pair of surrounds, with ending after beginning:\n my $normal_surround = 0;  # <?; bit 0 = <?, bit 1 = ?>\n my $script_surround = 0;  # <script..>; bit 0 = <script language=\"php\">\n my $asp_surround = 0;     # <%; bit 0 = <%, bit 1 = %>\n\n # Return cached result, if available:\n if ($php_files{$filename}) { return $php_files{$filename};}\n\n my $PHP_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's php.\\n\" if !defined $PHP_FILE;\n while(<$PHP_FILE>) {\n   if (m/\\<\\?/)                           { $normal_surround |= 1; }\n   if (m/\\?\\>/ && ($normal_surround & 1)) { $normal_surround |= 2; }\n   if (m/\\<script.*language=\"?php\"?/i)    { $script_surround |= 1; }\n   if (m/\\<\\/script\\>/i && ($script_surround & 1)) { $script_surround |= 2; }\n   if (m/\\<\\%/)                           { $asp_surround |= 1; }\n   if (m/\\%\\>/ && ($asp_surround & 1)) { $asp_surround |= 2; }\n }\n close($PHP_FILE);\n\n if ( ($normal_surround == 3) || ($script_surround == 3) ||\n      ($asp_surround == 3)) {\n   $is_php = 1;\n }\n\n $php_files{$filename} = $is_php; # Store result in cache.\n\n return $is_php;\n} # 1}}}\nEND { # {{{1\n    # Temp files might have been created\n    #   - on Windows if running with --fmt\n    #   - on POSIX if using process substitution, eg, cloc <(cat cloc)\n    if ($tmp_file_to_delete) {\n        print \"-> END unlink $tmp_file_to_delete\\n\" if $opt_v > 2;\n        unlink($tmp_file_to_delete)\n    }\n} # 1}}}\n__END__\nmode values (stat $item)[2]\n       Unix    Windows\nfile:  33188   33206\ndir :  16832   16895\nlink:  33261   33206\npipe:   4544    null\n"
  },
  {
    "path": "Unix/cloc.1.pod",
    "content": "#   Copyright\n#\n#      Copyright (C) 2018-2026 Al Danial <al.danial@gmail.com>.\n#      Copyright (C) 2010-2017 Jari Aalto <jari.aalto@cante.net>\n#\n#   License\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#   Description\n#\n#       To learn what TOP LEVEL section to use in manual pages,\n#       see POSIX/Susv standard and \"Utility Description Defaults\" at\n#       http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap01.html#tag_01_11\n#\n#       This is manual page in Perl POD format. Read more at\n#       http://perldoc.perl.org/perlpod.html or run command:\n#\n#           perldoc perlpod | less\n#\n#       To check the syntax:\n#\n#           podchecker *.pod\n#\n#       Create manual page with command:\n#\n#           pod2man PAGE.N.pod > PAGE.N\n\n=pod\n\n=head1 NAME\n\ncloc - Count, or compute differences of, lines of source code and comments.\n\n=head1 SYNOPSIS\n\n  cloc [options] <FILE|DIR> ...\n\n=head1 DESCRIPTION\n\nCount, or compute differences of, physical lines of source code in the\ngiven files (may be archives such as compressed tarballs or zip files,\nor git commit hashes or branch names) and/or recursively below the given\ndirectories.  It is written entirely in Perl, using only modules from the\nstandard distribution.\n\n=head1 OPTIONS\n\n=head2 Input Options\n\nTo count standard input, use the special filename B<-> and either\nB<--stdin-name=FILE> to tell cloc the name of the file being\npiped in, or B<--force-lang=LANG> to apply the LANG counter to\nall input.\n\n=over 4\n\n=item B<--extract-with=CMD>\n\nThis option is only needed if cloc is unable to figure out how to\nextract the contents of the input file(s) by itself. Use CMD to\nextract binary archive files (e.g.: .tar.gz, .zip, .Z). Use the\nliteral 'E<gt>FILEE<lt>' as a stand-in for the actual file(s) to be\nextracted. For example, to count lines of code in the input files\ngcc-4.2.tar.gz perl-5.8.8.tar.gz on Unix use:\n\n    --extract-with='gzip -dc >FILE< | tar xf -\n\nor, if you have GNU tar:\n\n    --extract-with='tar zxf >FILE<'\n\nand on Windows, use, for example:\n\n    --extract-with=\"\\\"c:\\Program Files\\WinZip\\WinZip32.exe\\\" -e -o >FILE<\n\n=item B<--list-file=FILE>\n\nTake the list of file and/or directory names to\nprocess from FILE, which has one file/directory\nname per line.  Only exact matches are counted;\nrelative path names will be resolved starting from\nthe directory where cloc is invoked.\nSet FILE to - to read file names from a STDIN pipe.\nSee also\nB<--exclude-list-file>,\nB<--config>.\n\n=item B<--diff-list-file=FILE>\n\nTake the pairs of file names to be diff'ed from\nFILE, whose format matches the output of\nB<--diff-alignment>.  (Run with that option to\nsee a sample.)  The language identifier at the\nend of each line is ignored.  This enables B<--diff>\nmode and by-passes file pair alignment logic.\nSee also\nB<--config>.\n\n=item B<--vcs=VCS>\n\nInvoke a system call to VCS to obtain a list of\nfiles to work on.  If VCS is 'git', then will\ninvoke 'git ls-files' to get a file list and\n'git submodule status' to get a list of submodules\nwhose contents will be ignored.  See also B<--git>\nwhich accepts git commit hashes and branch names.\nIf VCS is 'svn' then will invoke 'svn list -R'.\nThe primary benefit is that cloc will then skip\nfiles explicitly excluded by the versioning tool\nin question, ie, those in .gitignore or have the\nsvn:ignore property.\nAlternatively VCS may be any system command\nthat generates a list of files.\nNote:  cloc must be in a directory which can read\nthe files as they are returned by VCS.  cloc will\nnot download files from remote repositories.\n'svn list -R' may refer to a remote repository\nto obtain file names (and therefore may require\nauthentication to the remote repository), but\nthe files themselves must be local.\nSetting VCS to 'auto' selects between 'git'\nand 'svn' (or neither) depending on the presence\nof a .git or .svn subdirectory below the directory\nwhere cloc is invoked.\n\n=item B<--unicode>\n\nCheck binary files to see if they contain Unicode expanded ASCII text.\nThis causes performance to drop noticeably.\n\n=back\n\n=head2 Processing Options\n\n=over 4\n\n=item B<--autoconf>\n\nCount .in files (as processed by GNU autoconf) of recognized languages.\nSee also B<--no-autogen>.\n\n=item B<--by-file>\n\nReport results for every source file encountered.\n\n=item B<--by-file-by-lang>\n\nReport results for every source file encountered in addition to\nreporting by language.\n\n=item B<--config FILE>\n\nRead command line switches from FILE instead of\nthe default location of ~/.config/cloc/options.txt.\nThe file should contain one switch, along with\narguments (if any), per line.  Blank lines and lines\nbeginning with '#' are skipped.  Options given on\nthe command line take priority over entries read from\nthe file.\nIf a directory is also given with any of these\nswitches: --list-file,\nB<--exclude-list-file>,\nB<--read-lang-def>,\nB<--force-lang-def>,\nB<--diff-list-file>\nand a config file exists in that directory, it will\ntake priority over ~/.config/cloc/options.txt.\n\n=item B<--count-and-diff SET1 SET2>\n\nFirst perform direct code counts of source file(s)\nof SET1 and SET2 separately, then perform a diff\nof these.  Inputs may be pairs of files, directories,\nor archives.  If --out or --report-file is given, three output\nfiles will be created, one for each of the two counts and\none for the diff.  See also B<--diff>, B<--diff-alignment>,\nB<--diff-timeout>, B<--ignore-case>, B<--ignore-whitespace>.\n\n=item B<--diff SET1 SET2>\n\nCompute differences in code and comments between source file(s) of\nSET1 and SET2.  The inputs may be pairs of files, directories, or\narchives.  Use B<--diff-alignment> to generate a list showing\nwhich file pairs where compared.  See also\nB<--count-and-diff>, B<--diff-alignment>, B<--diff-timeout>,\nB<--ignore-case>, B<--ignore-whitespace>.\n\n=item B<--diff-timeout N>\n\nIgnore files which take more than N seconds\nto process.  Default is 10 seconds.  Setting N\nto 0 allows unlimited time.\n(Large files with many repeated lines can cause\nAlgorithm::Diff::sdiff() to take hours.)\n\n=item B<--docstring-as-code>\n\ncloc considers docstrings to be comments, but this is\nnot always correct as docstrings represent regular\nstrings when they appear on the right hand side of an\nassignment or as function arguments.  This switch\nforces docstrings to be counted as code.\n\n=item B<--follow-links>\n\n[Unix only] Follow symbolic links to directories (sym links to files\nare always followed).\n\n=item B<--force-lang=LANG[,EXT]>\n\nProcess all files that have a EXT extension with the counter for\nlanguage LANG. For example, to count all .f files with the Fortran\n90 counter (which expects files to end with .f90) instead of the\ndefault Fortran 77 counter, use:\n\n\t--force-lang=\"Fortran 90\",f\n\nIf EXT is omitted, every file will be counted with the LANG counter.\nThis option can be specified multiple times (but that is only useful\nwhen EXT is given each time). See also B<--script-lang>,\nB<--lang-no-ext>.\n\n=item B<--force-lang-def=FILE>\n\nLoad language processing filters from FILE,\nthen use these filters instead of the built-in\nfilters.  Note:  languages which map to the same\nfile extension (for example:\nMATLAB/Objective-C/MUMPS;  Pascal/PHP;\nLisp/OpenCL; Lisp/Julia; Perl/Prolog) will be ignored as\nthese require additional processing that is not expressed in\nlanguage definition files.\nUse B<--read-lang-def> to define new language\nfilters without replacing built-in filters\n(see also B<--write-lang-def>, B<--write-lang-def-incl-dup>).\n\n=item B<--git>\n\nForces the inputs to be interpreted as git targets\n(commit hashes, branch names, et cetera) if these\nare not first identified as file or directory\nnames.  This option overrides the --vcs=git logic\nif this is given; in other words, --git gets its\nlist of files to work on directly from git using\nthe hash or branch name rather than from\n'git ls-files'.  This option can be used with\n--diff to perform line count diffs between git\ncommits, or between a git commit and a file,\ndirectory, or archive.  Use -v/--verbose to see\nthe git system commands cloc issues.\n\n=item B<--git-diff-rel>\n\nSame as B<--git --diff>, or just B<--diff> if the inputs\nare recognized as git targets.  Only files which\nhave changed in either commit are compared.\n\n=item B<--git-diff-all>\n\nGit diff strategy #2:  compare all files in the\nrepository between the two commits.\n\n=item B<--ignore-whitespace>\n\nIgnore horizontal white space when comparing files\nwith B<--diff>.  See also B<--ignore-case>.\n\n=item B<--ignore-case>\n\nIgnore changes in case within file contents;\nconsider upper- and lowercase letters equivalent\nwhen comparing files with B<--diff>.  See also\nB<--ignore-whitespace>.\n\n=item B<--ignore-case-ext>\n\nIgnore case of file name extensions.  This will\ncause problems counting some languages\n(specifically, .c and .C are associated with C and\nC++; this switch would count .C files as C rather\nthan C++ on *nix operating systems).  File name\ncase insensitivity is always true on Windows.\n\n=item B<--ignore-regex>\n\nIgnore lines in source files that match the given\nPerl regular expression for the given language(s).\nThis option can be specified multiple times.\nLanguage names are comma separated and are followed\nby the pipe character and the regular expression.\nUse * to match all languages.\nExamples:\n\n  --ignore-regex='C,Java,C++|^\\s*[{};]\\s*$'\n  --ignore-regex='*|DEBUG|TEST\\s+ONLY'\n\nThese filters are applied after comments are\nremoved.  Use --strip-comments=EXT to create\nnew files that show these filters applied.\nThe primary use case is to ignore lines\ncontaining only braces, brackets, or puctuation.\n\n=item B<--include-submodules>\n\nWhen using B<--vcs=git>, include files in git submodules.\n\n=item B<--lang-no-ext=LANG>\n\nCount files without extensions using the LANG counter.  This option\noverrides internal logic for files without extensions (where such files\nare checked against known scripting languages by examining the first\nline for C<#!>).  See also B<--force-lang>, B<--script-lang>.\n\n=item B<--max-file-size=MB>\n\nSkip files larger than C<MB> megabytes when\ntraversing directories.  By default, C<MB>=100.\ncloc's memory requirement is roughly twenty times\nlarger than the largest file so running with\nfiles larger than 100 MB on a computer with less\nthan 2 GB of memory will cause problems.\nNote:  this check does not apply to files\nexplicitly passed as command line arguments.\n\n=item B<--no-autogen[=list]>\n\nIgnore files generated by code-production systems\nsuch as GNU autoconf.  To see a list of these files\n(then exit), run with B<--no-autogen list>\nSee also B<--autoconf>.\n\n=item B<--no-recurse>\n\nCount files in the given directories without\nrecursively descending below them.\n\n=item B<--only-count-files>\n\nOnly count files by language.  Blank, comment, and\ncode counts will be zero.\n\n=item B<--original-dir>\n\nOnly effective in combination with\nB<--strip-comments>.  Write the stripped files\nto the same directory as the original files.\n\n=item B<--read-binary-files>\n\nProcess binary files in addition to text files. This is usually a bad\nidea and should only be attempted with text files that have embedded\nbinary data.\n\n=item B<--read-lang-def=FILE>\n\nLoad new language processing filters from FILE\nand merge them with those\nalready known to cloc.  If FILE defines a\nlanguage cloc already knows about, cloc's\ndefinition will take precedence.  Use\nB<--force-lang-def> to over-ride cloc's definitions.\n(see also B<--write-lang-def>).\n\n=item B<--script-lang=LANG,S>\n\nProcess all files that invoke C<S> as a C<#!> scripting language with the\ncounter for language LANG. For example, files that begin with\nC<#!/usr/local/bin/perl5.8.8> will be counted with the Perl counter by\nusing\n\n\t--script-lang=Perl,perl5.8.8\n\nThe language name is case insensitive but the name of the script\nlanguage executable, C<S>, must have the right case. This option can be\nspecified multiple times. See also B<--force-lang>.\n\n=item B<--sdir=DIR>\n\nUse DIR as the scratch directory instead of letting I<File::Temp> chose\nthe location. Files written to this location are not removed at the\nend of the run (as they are with I<File::Temp>).\n\n=item B<--skip-leading=N[,ext]>\n\n Skip the first <N> lines of each file.  If a\ncomma separated list of extensions is also given,\nonly skip lines from those file types.  Example:\n\n\t--skip-leading=10,cpp,h\n\nwill skip the first ten lines of *.cpp and *.h\nfiles.  This is useful for ignoring boilerplate\ntext.\n\n\n=item B<--skip-uniqueness>\n\nSkip the file uniqueness check. This will give a performance boost at\nthe expense of counting files with identical contents multiple times\n(if such duplicates exist).\n\n=item B<--stat>\n\nSome file systems (AFS, CD-ROM, FAT, HPFS, SMB)\ndo not have directory 'nlink' counts that match\nthe number of its subdirectories.  Consequently\ncloc may undercount or completely skip the\ncontents of such file systems.  This switch forces\nFile::Find to stat directories to obtain the\ncorrect count.  File search speed will decrease.\nSee also B<--follow-links>.\n\n=item B<--stdin-name=FILE>\n\nCount lines streamed via I<STDIN> as if they came from a file named FILE.\n\n=item B<--strip-code=EXT>\n\nFor each file processed, write to the current directory a version of\nthe file which has blank and code lines removed.\nThe name of each stripped file is the original file name with\nC<.EXT> appended to it. It is written to the current directory unless\nB<--original-dir> is on.\n\n=item B<--strip-comments=EXT>\n\nFor each file processed, write to the current directory a version of\nthe file which has blank and commented lines removed (in-line comments\npersist). The name of each stripped file is the original file name with\nC<.EXT> appended to it. It is written to the current directory unless\nB<--original-dir> is on.\n\n=item B<--strip-str-comments>\n\nReplace comment markers embedded in strings with\n'xx'.  This attempts to work around a limitation\nin Regexp::Common::Comment where comment markers\nembedded in strings are seen as actual comment\nmarkers and not strings, often resulting in a\n'Complex regular subexpression recursion limit'\nwarning and incorrect counts.  There are two\ndisadvantages to using this switch:  1/code count\nperformance drops, and 2/code generated with\nB<--strip-comments> will contain different strings\nwhere ever embedded comments are found.\n\n=item B<--sum-reports>\n\nInput arguments are report files previously created with the\nB<--report-file> option. Makes a cumulative set of results containing\nthe sum of data from the individual report files.\n\n=item B<--timeout=N>\n\nIgnore files which take more than <N> seconds\nto process at any of the language's filter stages.\nThe default maximum number of seconds spent on a\nfilter stage is the number of lines in the file\ndivided by one thousand.  Setting B<N> to 0 allows\nunlimited time.  See also B<--diff-timeout>.\n\n=item B<--processes=NUM>\n\n[Available only on systems with a recent version\nof the Parallel::ForkManager module.  Not\navailable on Windows.] Sets the maximum number of\ncores that cloc uses.  The default value of 0\ndisables multiprocessing.\n\n=item B<--unix>\n\nOver-ride the operating system detection logic and run in UNIX\nmode.  See also B<--windows>, B<--show-os>.\n\n=item B<--use-sloccount>\n\nIf SLOCCount is installed, use its compiled\nexecutables c_count, java_count, pascal_count,\nphp_count, and xml_count instead of cloc's\ncounters.  SLOCCount's compiled counters are\nsubstantially faster than cloc's and may give\na performance improvement when counting projects\nwith large files.  However, these cloc-specific\nfeatures will not be available: B<--diff>,\nB<--count-and-diff>, B<--strip-comments>, B<--unicode>.\n\n=item B<--windows>\n\nOver-ride the operating system detection logic and run in\nMicrosoft Windows mode.  See also B<--unix>, B<--show-os>.\n\n=back\n\n=head2 Filter Options\n\n=over 4\n\n=item B<--include-content=REGEX>\n\nOnly count files containing text that matches the given\nregular expression.\n\n=item B<--exclude-content=REGEX>\n\nExclude files containing text that matches the given\nregular expression.\n\n=item B<--exclude-dir=DIR1[,DIR2 ...]>\n\nExclude the given comma separated directories from being scanned. For\nexample:\n\n\t--exclude-dir=.cache,test\n\nwill skip all files that match C</.cache/> or C</test/> as part of\ntheir path. Directories named C<.bzr>, C<.cvs>, C<.hg>, C<.git>,\nand C<.svn> are always excluded.\nThis option only works with individual directory\nnames so including file path separators is not\nallowed.  Use B<--fullpath> and B<--not-match-d=REGEX>\nto supply a regex matching multiple subdirectories.\n\n=item B<--exclude-ext=EXT1[,EXT2 ...]>\n\nDo not count files having the given file name extensions.\n\n=item B<--exclude-lang=L1[,L2[...]]>\n\nExclude the given comma separated languages from being counted.\n\n=item B<--exclude-list-file=FILE>\n\nIgnore files and/or directories whose names\nappear in FILE.  FILE should have one file\nname per line.  Only exact matches are ignored;\nrelative path names will be resolved starting from\nthe directory where cloc is invoked.\nSee also B<--list-file>,\nB<--config>.\n\n=item B<--fullpath>\n\nModifies the behavior of B<--match-f> or\nB<--not-match-f> to include the file's path\nin the regex, not just the file's basename.\n(This does not expand each file to include its\nabsolute path, instead it uses as much of\nthe path as is passed in to cloc.)\n\n=item B<--include-ext=<ext1>[,ext2[...]]>\n\nCount only languages having the given comma\nseparated file extensions.  Use B<--show-ext> to\nsee the recognized extensions.\n\n=item B<--include-lang=L1[,L2 ...]>\n\nCount only the given comma separated, case-insensitive languages\nL1, L2, L3, et cetera.\n\n=item B<--match-d=REGEX>\n\nOnly count files in directories matching the Perl regex.  For example\n\n     --match-d='/(src|include)/'\n\nonly counts files in directory paths containing C</src/>\nor C</include/>.\n\n=item B<--not-match-d=REGEX>\n\nCount all files except in directories matching the Perl regex.\nOnly the trailing directory name is compared, for example, when\ncounting in C</usr/local/lib>, only C<lib> is\ncompared to the regex.\nAdd B<--fullpath> to compare parent directories to\nthe regex.\nDo not include file path separators at the beginning\nor end of the regex.\nThis switch may be repeated.\n\n=item B<--match-f=REGEX>\n\nOnly count files whose basenames match the Perl regex. For example\nthis only counts files at start with Widget or widget:\n\n     --match-f='^[Ww]idget'\n\nAdd B<--fullpath> to include parent directories\nin the regex instead of just the basename.\n\n=item B<--not-match-f=REGEX>\n\nCount all files except those whose basenames match the Perl regex.\nAdd B<--fullpath> to include parent directories\nin the regex instead of just the basename.\nThis switch may be repeated.\n\n=item B<--skip-archive=REGEX>\n\nIgnore files that end with the given Perl regular\nexpression.  For example, if given\n\n\t--skip-archive='(zip|tar(\\.(gz|Z|bz2|xz|7z))?)'\n\nthe code will skip files that end with .zip,\n.tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and\n.tar.7z.\n\n=item B<--skip-win-hidden>\n\nOn Windows, ignore hidden files.\n\n=back\n\n=head2 Debug Options\n\n=over 4\n\n=item B<--categorized=FILE>\n\nSave file sizes in bytes, identified languages and\nnames of categorized files to FILE.\n\n=item B<--counted=FILE>\n\nSave names of processed source files to FILE.\nSee also B<--found>, B<--ignored>, B<--unique>.\n\n=item B<--diff-alignment=FILE>\n\nWrite to FILE a list of files and file pairs\nshowing which files were added, removed, and/or\ncompared during a run with B<--diff>.  This switch\nforces the B<--diff> mode on.\n\n=item B<--explain=LANG>\n\nPrint the filters used to remove comments for\nlanguage LANG and exit.  In some cases the\nfilters refer to Perl subroutines rather than\nregular expressions.  An examination of the\nsource code may be needed for further explanation.\n\n=item B<--help>\n\nPrint cloc's internal usage information and exit.\n\n=item B<--found=FILE>\n\nSave names of every file found to FILE.  See also B<--counted>,\nB<--ignored>, B<--unique>.\n\n=item B<--ignored=FILE>\n\nSave names of ignored files and the reason they were ignored to FILE.\nSee also B<--counted>, B<--found>, B<--unique>.\n\n=item B<--print-filter-stages>\n\nPrint to I<STDOUT> processed source code before and after each filter is\napplied.\n\n=item B<--show-ext[=EXT]>\n\nPrint information about all known (or just the given) file extensions\nand exit.\n\n=item B<--show-errors[=EXT]>\n\nUsed with B<--quiet>, print error messages (if any).\n\n=item B<--show-lang[=LANG]>\n\nPrint information about all known (or just the given) languages and\nexit.\n\n=item B<--show-os>\n\nPrint the value of the operating system mode and exit.  See also\nB<--unix>, B<--windows>.\n\n=item B<--quiet>\n\nSuppress all information messages except the final output.\nSee also B<--shwow-errors>.\n\n=item B<--unique=FILE>\n\nSave names of ignored files and the reason they were ignored to FILE.\nSee also B<--counted>, B<--found>, B<--ignored>.\n\n=item B<-v[=N]>\n\nTurn on verbose with optional numeric value.\n\n=item B<--verbose[=N]>\n\nLong form of B<-v>.\n\n=item B<--version>\n\nPrint the version of this program and exit.\n\n=item B<--write-lang-def=FILE>\n\nWrites to FILE the language processing filters then exits. Useful as a\nfirst step to creating custom language definitions.\nNote: languages which map to the same file extension will be excluded.\nSee also B<--force-lang-def>, B<--read-lang-def>.\n\n=item B<--write-lang-def-incl-dup=FILE>\n\nSame as B<--write-lang-def>, but includes duplicated\nextensions.  This generates a problematic language\ndefinition file because cloc will refuse to use\nit until duplicates are removed.\n\n=back\n\n=head2 Output Options\n\n=over 4\n\n=item B<--3>\n\nPrint third-generation language output.  (This option can cause report\nsummation to fail if some reports were produced with this option while\nothers were produced without it.)\n\n=item B<--by-percent X>\n\nInstead of comment and blank line counts, show\nthese values as percentages based on the\nvalue of X in the denominator, where X is one of\n    c   meaning lines of code\n    cm  meaning lines of code + comments\n    cb  meaning lines of code + blanks\n    cmb meaning lines of code + comments + blanks\n\nFor example, if using method 'c' and your code\nhas twice as many lines of comments as lines\nof code, the value in the comment column will\nbe 200%.  The code column remains a line count.\n\n=item B<--csv>\n\nWrite the results as comma separated values.\n\n=item B<--csv-delimiter=C>\n\nUse the character C as the delimiter for comma separated files\ninstead of ,.  This switch forces B<--csv> to be on.\n\n=item B<--file-encoding=E>\n\nWrite output files using the B<E> encoding instead of\nthe default ASCII (B<E> = 'UTF-7').  Examples: 'UTF-16',\n'euc-kr', 'iso-8859-16'.  Known encodings can be\nprinted with\n  perl -MEncode -e 'print join(\"\\n\", Encode->encodings(\":all\")), \"\\n\"'\n\n=item B<--fmt=N>\n\nAlternate text output format where B<N> is a number\nfrom 1 to 5, or -1 to -5. 'total lines' means the\nsum of code, comment, and blank lines.  Negative\nvalues are the same as the positive values but retain,\ninstead of deleting, the intermediate JSON file that\nis written.  The JSON file name is randomly generated\nunless --out/--report-file is given.  The formats are:\n  1:  by language (same as cloc default output)\n  2:  by language with an extra column for total lines\n  3:  by file with language\n  4:  by file with a total lines column\n  5:  by file with language and a total lines column\n\n=item B<--hide-rate>\n\nDo not show line and file processing rates in the output\nheader. This makes output deterministic.\n\n=item B<--json>\n\nWrite the results in JavaScript Object Notation (JSON).\n\n=item B<--md>\n\nWrite the results as Markdown-formatted text.\n\n=item B<--out=FILE>\n\nSynonym for B<--report-file=FILE>.\n\n=item B<--progress-rate=N>\n\nShow progress update after every N files are processed (default\nN=100). Set N to 0 to suppress progress output; useful when\nredirecting output to I<STDOUT>.\n\n=item B<--quiet>\n\nSuppress all information messages except for the final report.\n\n=item B<--report-file=FILE>\n\nWrite the results to FILE instead of standard output.\n\n=item B<--summary-cutoff=X:N>\n\nAggregate to 'Other' results having X lines\nbelow N where X is one of\n    c   meaning lines of code\n    f   meaning files\n    m   meaning lines of comments\n    cm  meaning lines of code + comments\nAppending a percent sign to N changes\nthe calculation from straight count to\npercentage.\nIgnored with --diff or --by-file.\n\n=item B<--sql=FILE>\n\nWrite results as SQL CREATE and INSERT statements which can be read by\na database program such as SQLite. If FILE is B<->, output is sent to\nI<STDOUT>.\n\n=item B<--sql-append>\n\nAppend SQL insert statements to the file specified by B<--sql> and\ndo not generate table creation option.\n\n=item B<--sql-project=NAME>\n\nUse B<name> as the project identifier for the current run. Only valid\nwith the B<--sql> option.\n\n=item B<--sql-style=STYLE>\n\nWrite SQL statements in the given style instead of the default\nSQLite format.  Styles include B<Oracle> and B<Named_Columns>.\n\n=item B<--sum-one>\n\nFor plain text reports, show the SUM: output line even if only\none input file is processed.\n\n=item B<--xml>\n\nWrite the results in XML.\n\n=item B<--xsl[=FILE]>\n\nReference FILE as an XSL stylesheet within the XML output. If FILE is\nnot given, writes a default stylesheet, cloc.xsl. This switch forces\nB<--xml> to be on.\n\n=item B<--yaml>\n\nWrite the results in YAML.\n\n=back\n\n=head1 EXAMPLES\n\nCount the lines of code in the Perl 5.10.0 compressed tar file\non a UNIX-like operating system:\n\n  cloc perl-5.10.0.tar.gz\n\nCount the changes in files, code, and comments between Python\nreleases 2.6.6 and 2.7:\n\n  cloc --diff Python-2.6.6.tar.bz  Python-2.7.tar.bz2\n\nTo see how cloc aligns files for comparison between two code\nbases, use the B<--diff-alignment=FILE> option.  Here the\nalignment information is written to C<align.txt>:\n\n  cloc --diff-alignment=align.txt gcc-4.4.0.tar.bz2  gcc-4.5.0.tar.bz2\n\nCount file, code, and comment changes between two git commits:\n\n  cloc --git --diff b409850824 HEAD\n\nPrint the recognized languages:\n\n  cloc --show-lang\n\nRemove comments from C<foo.c> and save the result in C<foo.c.nc>\n(\"nc\" is an arbitrary extension; used here to denote \"no comments\"):\n\n  cloc --strip-comments=nc foo.c\n\nAdditional examples can be found at L<https://github.com/AlDanial/cloc>.\n\n=head1 ENVIRONMENT\n\nNone.\n\n=head1 FILES\n\nNone.\n\n=head1 SEE ALSO\n\nsloccount(1)\n\n=head1 AUTHORS\n\nThe cloc program was written by Al Danial <al.danial@gmail.com> and\nis Copyright (C) 2006-2026 <al.danial@gmail.com>.\n\nThe manual page was originally written by Jari Aalto <jari.aalto@cante.net>.\n\nBoth the code and documentation is released under the GNU GPL version 2\nor (at your option) any later version. For more information about\nlicense, visit <http://www.gnu.org/copyleft/gpl.html>.\n\n=cut\n"
  },
  {
    "path": "Unix/pod2man.mk",
    "content": "# pod2man.mk -- Makefile portion to convert *.pod files to manual pages\n#\n#   Copyright information\n#\n#\tCopyright (C) 2008-2012 Jari Aalto\n#\n#   License\n#\n#\tThis program is free software; you can redistribute it and/or modify\n#\tit under the terms of the GNU General Public License as published by\n#\tthe Free Software Foundation; either version 2 of the License, or\n#\t(at your option) any later version.\n#\n#\tThis program is distributed in the hope that it will be useful,\n#\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n#\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n#\tGNU General Public License for more details.\n#\n#\tYou should have received a copy of the GNU General Public License\n#\talong with this program. If not, see <http://www.gnu.org/licenses/>.\n#\n#   Description\n#\n#\tConvert *.pod files to manual pages. Add this to Makefile:\n#\n#\t    PACKAGE = package\n#\n#\t    man:\n#\t\t    make -f pod2man.mk PACKAGE=$(PACKAGE) makeman\n#\n#\t    build: man  \n\nifneq (,)\n    This makefile requires GNU Make.\nendif\n\n# This variable *must* be set when called\nPACKAGE\t\t?= package\n\n# Optional variables to set\nMANSECT\t\t?= 1\nPODCENTER\t?= User Commands\nPODDATE\t\t?= $$(date --utc --date=\"@$${SOURCE_DATE_EPOCH:-$$(date +%s)}\" \"+%Y-%m-%d\")\ndetected_OS = $(shell uname)\nifeq ($(detected_OS),Darwin)\n\t# macOS;  \"PODDATE ?=\" doesn't work\n\tPODDATE = $(shell date -u \"+%Y-%m-%d\")\nendif\n# add other OS exceptions as they arise\n\n# Directories\nMANSRC\t\t?=\nMANDEST\t\t?= $(MANSRC)\n\nMANPOD\t\t?= $(MANSRC)$(PACKAGE).$(MANSECT).pod\nMANPAGE\t\t?= $(MANDEST)$(PACKAGE).$(MANSECT)\n\nPOD2MAN\t\t?= pod2man\nPOD2MAN_FLAGS\t?= --utf8\n\nmakeman: $(MANPAGE)\n\n$(MANPAGE): $(MANPOD)\n\t# make target - create manual page from a *.pod page\n\tpodchecker $(MANPOD)\n\tLC_ALL= LANG=C $(POD2MAN) $(POD2MAN_FLAGS) \\\n\t\t--center=\"$(PODCENTER)\" \\\n\t\t--date=\"$(PODDATE)\" \\\n\t\t--name=\"$(PACKAGE)\" \\\n\t\t--section=\"$(MANSECT)\" \\\n\t\t$(MANPOD) \\\n\t| sed 's,[Pp]erl v[0-9.]\\+,$(PACKAGE),' \\\n\t  > $(MANPAGE) && \\\n\trm -f pod*.tmp\n\n# End of of Makefile part\n"
  },
  {
    "path": "Unix/t/00_C.t",
    "content": "#!/usr/bin/env perl\nuse warnings;\nuse strict;\nuse Test::More;\nuse Cwd;\nuse Getopt::Std;\nmy %opt;\ngetopts('u', \\%opt);  # -u to run Unix/cloc instead of ../cloc\nmy @Tests = (\n                {\n                    'name' => 'Activiti Business Process',\n                    'ref'  => '../tests/outputs/955.tld.yaml',\n                    'args' => '../tests/inputs/955.tld',\n                },\n                {\n                    'name' => 'Agda',\n                    'ref'  => '../tests/outputs/Lookup.agda.yaml',\n                    'args' => '../tests/inputs/Lookup.agda',\n                },\n                {\n                    'name' => 'AnsProlog',\n                    'ref'  => '../tests/outputs/AnsProlog.lp.yaml',\n                    'args' => '../tests/inputs/AnsProlog.lp',\n                },\n                {\n                    'name' => 'ANTLR Grammar 1',\n                    'ref'  => '../tests/outputs/ExprParser.g.yaml',\n                    'args' => '../tests/inputs/ExprParser.g',\n                },\n                {\n                    'name' => 'ANTLR Grammar 2',\n                    'ref'  => '../tests/outputs/C.g4.yaml',\n                    'args' => '../tests/inputs/C.g4',\n                },\n                {\n                    'name' => 'Apex Class',\n                    'ref'  => '../tests/outputs/RemoteSiteHelperTest.cls.yaml',\n                    'args' => '../tests/inputs/RemoteSiteHelperTest.cls',\n                },\n                {\n                    'name' => 'APL',\n                    'ref'  => '../tests/outputs/rand.apl.yaml',\n                    'args' => '../tests/inputs/rand.apl',\n                },\n                {\n                    'name' => 'AppleScript',\n                    'ref'  => '../tests/outputs/send_msg.applescript.yaml',\n                    'args' => '../tests/inputs/send_msg.applescript',\n                },\n                {\n                    'name' => 'Aria',\n                    'ref'  => '../tests/outputs/github_user.aria.yaml',\n                    'args' => '../tests/inputs/github_user.aria',\n                },\n                {\n                    'name' => 'ArkTs',\n                    'ref'  => '../tests/outputs/openharmony.ets.yaml',\n                    'args' => '../tests/inputs/openharmony.ets',\n                },\n                {\n                    'name' => 'Arturo',\n                    'ref'  => '../tests/outputs/Arturo.art.yaml',\n                    'args' => '../tests/inputs/Arturo.art',\n                },\n                {\n                    'name' => 'AsciiDoc',\n                    'ref'  => '../tests/outputs/asciidoctor.adoc.yaml',\n                    'args' => '../tests/inputs/asciidoctor.adoc',\n                },\n                {\n                    'name' => 'ASP.NET 1',\n                    'ref'  => '../tests/outputs/page_layout.aspx.yaml',\n                    'args' => '../tests/inputs/page_layout.aspx',\n                },\n                {\n                    'name' => 'ASP.NET 2',\n                    'ref'  => '../tests/outputs/server_side.aspx.yaml',\n                    'args' => '../tests/inputs/server_side.aspx',\n                },\n                {\n                    'name' => 'Assembly 1',\n                    'ref'  => '../tests/outputs/Assembler-Intel.asm.yaml',\n                    'args' => '../tests/inputs/Assembler-Intel.asm',\n                },\n                {\n                    'name' => 'Assembly 2',\n                    'ref'  => '../tests/outputs/Assembly-sysv.S.yaml',\n                    'args' => '../tests/inputs/Assembly-sysv.S',\n                },\n                {\n                    'name' => 'Assembly 3',\n                    'ref'  => '../tests/outputs/zos_assembly.s.yaml',\n                    'args' => '../tests/inputs/zos_assembly.s',\n                },\n                {\n                    'name' => 'Astro',\n                    'ref'  => '../tests/outputs/slug.astro.yaml',\n                    'args' => '../tests/inputs/slug.astro',\n                },\n                {\n                    'name' => 'Asymptote', \n                    'ref'  => '../tests/outputs/cad.asy.yaml',\n                    'args' => '../tests/inputs/cad.asy',\n                },\n                {\n                    'name' => 'AXAML', \n                    'ref'  => '../tests/outputs/HelpersView.axaml.yaml',\n                    'args' => '../tests/inputs/HelpersView.axaml',\n                },\n                {\n                    'name' => 'Bazel',\n                    'ref'  => '../tests/outputs/BUILD.yaml',\n                    'args' => '../tests/inputs/BUILD',\n                },\n                {\n                    'name' => 'Beluga',\n                    'ref'  => '../tests/outputs/beluga.bel.yaml',\n                    'args' => '../tests/inputs/beluga.bel',\n                },\n                {\n                    'name' => 'Bicep',\n                    'ref'  => '../tests/outputs/sample.bicep.yaml',\n                    'args' => '../tests/inputs/sample.bicep',\n                },\n                {\n                    'name' => 'BitBake',\n                    'ref'  => '../tests/outputs/bitbake.yaml',\n                    'args' => '../tests/inputs/hello_1.0.bb ' .\n                              '../tests/inputs/cpp-example.inc ' .\n                              '../tests/inputs/layer.conf ',\n                },\n                {\n                    'name' => 'BizTalk Orchestration',\n                    'ref'  => '../tests/outputs/ProcessPO.odx.yaml',\n                    'args' => '../tests/inputs/ProcessPO.odx',\n                },\n                {\n                    'name' => 'BizTalk Pipeline',\n                    'ref'  => '../tests/outputs/XmlToJSONSendPipeline.btp.yaml',\n                    'args' => '--unicode ../tests/inputs/XmlToJSONSendPipeline.btp',\n                },\n                {\n                    'name' => 'Blade',\n                    'ref'  => '../tests/outputs/master.blade.php.yaml',\n                    'args' => '../tests/inputs/master.blade.php',\n                },\n                {\n                    'name' => 'Blueprint',\n                    'ref'  => '../tests/outputs/window.blp.yaml',\n                    'args' => '../tests/inputs/window.blp',\n                },\n                {\n                    'name' => 'Brainfuck',\n                    'ref'  => '../tests/outputs/hello.bf.yaml',\n                    'args' => '../tests/inputs/hello.bf',\n                },\n                {\n                    'name' => 'BrightScript',\n                    'ref'  => '../tests/outputs/roku.brs.yaml',\n                    'args' => '../tests/inputs/roku.brs',\n                },\n                {\n                    'name' => 'C simple',\n                    'args' => '../tests/inputs/C-Ansi.c',\n                    'ref'  => '../tests/outputs/C-Ansi.c.yaml',\n                },\n                {\n                    'name' => 'C# 1',\n                    'ref'  => '../tests/outputs/C#.cs.yaml',\n                    'args' => '../tests/inputs/C#.cs',\n                },\n                {\n                    'name' => 'C# 2',\n                    'ref'  => '../tests/outputs/wokka.cs.yaml',\n                    'args' => '../tests/inputs/wokka.cs',\n                },\n                {\n                    'name' => 'C# 3',\n                    'ref'  => '../tests/outputs/assembly.cs.yaml',\n                    'args' => '../tests/inputs/assembly.cs',\n                },\n                {\n                    'name' => 'C# Designer',\n                    'ref'  => '../tests/outputs/csharp-designer.designer.cs.yaml',\n                    'args' => '../tests/inputs/csharp-designer.designer.cs',\n                },\n                {\n                    'name' => 'C/C++ header',\n                    'ref'  => '../tests/outputs/locale_facets.h.yaml',\n                    'args' => '../tests/inputs/locale_facets.h',\n                },\n                {\n                    'name' => 'Cairo',\n                    'ref'  => '../tests/outputs/ERC20.cairo.yaml',\n                    'args' => '../tests/inputs/ERC20.cairo',\n                },\n                {\n                    'name' => 'Cake Build Script',\n                    'ref'  => '../tests/outputs/build.cake.yaml',\n                    'args' => '../tests/inputs/build.cake',\n                },\n                {\n                    'name' => 'Cangjie',\n                    'ref'  => '../tests/outputs/functional.cj.yaml',\n                    'args' => '../tests/inputs/functional.cj',\n                },\n                {\n                    'name' => 'Clojure',\n                    'ref'  => '../tests/outputs/ch10-REPL-oriented-repl-interactions.cj.yaml',\n                    'args' => '../tests/inputs/ch10-REPL-oriented-repl-interactions.cj',\n                },\n                {\n                    'name' => 'Circom',\n                    'ref'  => '../tests/outputs/eddsa.circom.yaml',\n                    'args' => '../tests/inputs/eddsa.circom',\n                },\n                {\n                    'name' => 'Chapel',\n                    'ref'  => '../tests/outputs/Chapel.chpl.yaml',\n                    'args' => '../tests/inputs/Chapel.chpl',\n                },\n                {\n                    'name' => 'Clean',\n                    'ref'  => '../tests/outputs/iclean.icl.yaml',\n                    'args' => '../tests/inputs/iclean.icl',\n                },\n                {\n                    'name' => 'COBOL',\n                    'ref'  => '../tests/outputs/conditions.CBL.yaml',\n                    'args' => '../tests/inputs/conditions.CBL',\n                },\n                {\n                    'name' => 'COBOL 2',\n                    'ref'  => '../tests/outputs/wokka.cbl.yaml',\n                    'args' => '../tests/inputs/wokka.cbl',\n                },\n                {\n                    'name' => 'COBOL 3',\n                    'ref'  => '../tests/outputs/Cobol.cbl.yaml',\n                    'args' => '../tests/inputs/Cobol.cbl',\n                },\n                {\n                    'name' => 'CoCoA 5',\n                    'ref'  => '../tests/outputs/Buchberger.cocoa5.yaml',\n                    'args' => '../tests/inputs/Buchberger.cocoa5',\n                },\n                {\n                    'name' => 'CodeQL',\n                    'ref'  => '../tests/outputs/CodeQL.ql.yaml',\n                    'args' => '../tests/inputs/CodeQL.ql',\n                },\n                {\n                    'name' => 'ColdFusion',\n                    'ref'  => '../tests/outputs/ColdFusion.cfm.yaml',\n                    'args' => '../tests/inputs/ColdFusion.cfm',\n                },\n                {\n                    'name' => 'Containerfile',\n                    'ref'  => '../tests/outputs/Containerfile.yaml',\n                    'args' => '../tests/inputs/Containerfile',\n                },\n                {\n                    'name' => 'Context Grammar',\n                    'ref'  => '../tests/outputs/apertium-dan.dan.rlx.yaml',\n                    'args' => '../tests/inputs/apertium-dan.dan.rlx',\n                },\n                {\n                    'name' => 'C++ 1',\n                    'ref'  => '../tests/outputs/C++-MFC.cc.yaml',\n                    'args' => '../tests/inputs/C++-MFC.cc',\n                },\n                {\n                    'name' => 'C++ 2',\n                    'ref'  => '../tests/outputs/BasicPlane.Figures-Rectangle.ixx.yaml',\n                    'args' => '../tests/inputs/BasicPlane.Figures-Rectangle.ixx',\n                },\n                {\n                    'name' => 'C++ Uppercase extension',\n                    'ref'  => '../tests/outputs/C++-uppercase.CPP.yaml',\n                    'args' => '../tests/inputs/C++-uppercase.CPP',\n                },\n                {\n                    'name' => 'Cadence',\n                    'ref'  => '../tests/outputs/cadence_test.cdc.yaml',\n                    'args' => '../tests/inputs/cadence_test.cdc',\n                },\n                {\n                    'name' => 'Carbon',\n                    'ref'  => '../tests/outputs/variable_length.carbon.yaml',\n                    'args' => '../tests/inputs/variable_length.carbon',\n                },\n                {\n                    'name' => 'C simple',\n                    'ref'  => '../tests/outputs/C-Ansi.c.yaml',\n                    'args' => '../tests/inputs/C-Ansi.c',\n                },\n                {\n                    'name' => 'Civet',\n                    'ref'  => '../tests/outputs/parser_1.civet.yaml',\n                    'args' => '../tests/inputs/parser_1.civet',\n                },\n                {\n                    'name' => 'Civet (coffeeComment)',\n                    'ref'  => '../tests/outputs/parser_2.civet.yaml',\n                    'args' => '../tests/inputs/parser_2.civet',\n                },\n                {\n                    'name' => 'CSV',\n                    'ref'  => '../tests/outputs/cloc_counts.csv.yaml',\n                    'args' => '../tests/inputs/cloc_counts.csv',\n                },\n                {\n                    'name' => 'Cucumber',\n                    'ref'  => '../tests/outputs/cucumber.feature.yaml',\n                    'args' => '../tests/inputs/cucumber.feature',\n                },\n                {\n                    'name' => 'C3',\n                    'ref'  => '../tests/outputs/io.c3.yaml',\n                    'args' => '../tests/inputs/io.c3',\n                },\n                {\n                    'name' => 'Dafny',\n                    'ref'  => '../tests/outputs/fib.dfy.yaml',\n                    'args' => '../tests/inputs/fib.dfy',\n                },\n                {\n                    'name' => 'DAML',\n                    'ref'  => '../tests/outputs/Test.daml.yaml',\n                    'args' => '../tests/inputs/Test.daml',\n                },\n                {\n                    'name' => 'DenizenScript',\n                    'ref'  => '../tests/outputs/double_doors.dsc.yaml',\n                    'args' => '../tests/inputs/double_doors.dsc',\n                },\n                {\n                    'name' => 'Derw',\n                    'ref'  => '../tests/outputs/complex_union.derw.yaml',\n                    'args' => '../tests/inputs/complex_union.derw',\n                },\n                {\n                    'name' => 'dhall',\n                    'ref'  => '../tests/outputs/Prelude.dhall.yaml',\n                    'args' => '../tests/inputs/Prelude.dhall',\n                },\n                {\n                    'name' => 'DIET',\n                    'ref'  => '../tests/outputs/layout.dt.yaml',\n                    'args' => '../tests/inputs/layout.dt',\n                },\n                {\n                    'name' => 'dir 1',\n                    'ref'  => '../tests/outputs/foo_bar.yaml',\n                    'args' => '../tests/inputs/foo_bar',\n                },\n                {\n                    'name' => 'dir 2',\n                    'ref'  => '../tests/outputs/dd.yaml',\n                    'args' => '../tests/inputs/dd',\n                },\n                {\n                    'name' => 'dir 3',\n                    'ref'  => '../tests/outputs/aa.yaml',\n                    'args' => '../tests/inputs/aa',\n                },\n                {\n                    'name' => 'Dockerfile',\n                    'ref'  => '../tests/outputs/Dockerfile.yaml',\n                    'args' => '../tests/inputs/Dockerfile',\n                },\n                {\n                    'name' => 'DOS batch',\n                    'ref'  => '../tests/outputs/MSDOS.bat.yaml',\n                    'args' => '../tests/inputs/MSDOS.bat',\n                },\n                {\n                    'name' => 'Drools',\n                    'ref'  => '../tests/outputs/drools.drl.yaml',\n                    'args' => '../tests/inputs/drools.drl',\n                },\n                {\n                    'name' => 'ECPP',\n                    'ref'  => '../tests/outputs/comp.ecpp.yaml',\n                    'args' => '../tests/inputs/comp.ecpp',\n                },\n                {\n                    'name' => 'EJS',\n                    'ref'  => '../tests/outputs/sample.ejs.yaml',\n                    'args' => '../tests/inputs/sample.ejs',\n                },\n                {\n                    'name' => 'Elixir',\n                    'ref'  => '../tests/outputs/elixir.ex.yaml',\n                    'args' => '../tests/inputs/elixir.ex',\n                },\n                {\n                    'name' => 'Elixir Script',\n                    'ref'  => '../tests/outputs/dev.exs.yaml',\n                    'args' => '../tests/inputs/dev.exs',\n                },\n                {\n                    'name' => 'Embedded Crystal',\n                    'ref'  => '../tests/outputs/capture.ecr.yaml',\n                    'args' => '../tests/inputs/capture.ecr',\n                },\n                {\n                    'name' => 'Fennel',\n                    'ref'  => '../tests/outputs/generate.fnl.yaml',\n                    'args' => '../tests/inputs/generate.fnl',\n                },\n                {\n                    'name' => 'Finite State Language',\n                    'ref'  => '../tests/outputs/traffic_light.fsl.yaml',\n                    'args' => '../tests/inputs/traffic_light.fsl',\n                },\n                {\n                    'name' => 'Fish Shell',\n                    'ref'  => '../tests/outputs/git_helpers.fish.yaml',\n                    'args' => '../tests/inputs/git_helpers.fish',\n                },\n                {\n                    'name' => 'Focus',\n                    'ref'  => '../tests/outputs/FOCUS.focexec.yaml',\n                    'args' => '../tests/inputs/FOCUS.focexec',\n                },\n                {\n                    'name' => 'Fortran 77',\n                    'ref'  => '../tests/outputs/Fortran77.f.yaml',\n                    'args' => '../tests/inputs/Fortran77.f',\n                },\n                {\n                    'name' => 'Fortran 77 2',\n                    'ref'  => '../tests/outputs/hello.f.yaml',\n                    'args' => '../tests/inputs/hello.f',\n                },\n                {\n                    'name' => 'Fortran 90',\n                    'ref'  => '../tests/outputs/Fortran90.f90.yaml',\n                    'args' => '../tests/inputs/Fortran90.f90',\n                },\n                {\n                    'name' => 'Fortran 90 2',\n                    'ref'  => '../tests/outputs/hello.f90.yaml',\n                    'args' => '../tests/inputs/hello.f90',\n                },\n                {\n                    'name' => 'Fortran 2003',\n                    'ref'  => '../tests/outputs/main.f03.yaml',\n                    'args' => '../tests/inputs/main.f03',\n                },\n                {\n                    'name' => 'Freemarker Template',\n                    'ref'  => '../tests/outputs/FreemarkerTemplate.ftl.yaml',\n                    'args' => '../tests/inputs/FreemarkerTemplate.ftl',\n                },\n                {\n                    'name' => 'Futhark',\n                    'ref'  => '../tests/outputs/futhark.fut.yaml',\n                    'args' => '../tests/inputs/futhark.fut',\n                },\n                {\n                    'name' => 'FXML',\n                    'ref'  => '../tests/outputs/vbox.fxml.yaml',\n                    'args' => '../tests/inputs/vbox.fxml',\n                },\n                {\n                    'name' => 'F#',\n                    'ref'  => '../tests/outputs/fsharp.fs.yaml',\n                    'args' => '../tests/inputs/fsharp.fs',\n                },\n                {\n                    'name' => 'F# Script',\n                    'ref'  => '../tests/outputs/fsharp_script.fsx.yaml',\n                    'args' => '../tests/inputs/fsharp_script.fsx',\n                },\n                {\n                    'name' => 'Flatbuffers',\n                    'ref'  => '../tests/outputs/flatbuffers.fbs.yaml',\n                    'args' => '../tests/inputs/flatbuffers.fbs',\n                },\n                {\n                    'name' => 'Gencat NLS',\n                    'ref'  => '../tests/outputs/Gencat-NLS.msg.yaml',\n                    'args' => '../tests/inputs/Gencat-NLS.msg',\n                },\n                {\n                    'name' => 'Glade',\n                    'ref'  => '../tests/outputs/glade-search-popover.ui.yaml',\n                    'args' => '../tests/inputs/glade-search-popover.ui',\n                },\n                {\n                    'name' => 'Gleam',\n                    'ref'  => '../tests/outputs/string.gleam.yaml',\n                    'args' => '../tests/inputs/string.gleam',\n                },\n                {\n                    'name' => 'Glimmer JavaScript',\n                    'ref'  => '../tests/outputs/body.gjs.yaml',\n                    'args' => '../tests/inputs/body.gjs',\n                },\n                {\n                    'name' => 'Glimmer TypeScript',\n                    'ref'  => '../tests/outputs/input.gts.yaml',\n                    'args' => '../tests/inputs/input.gts',\n                },\n                {\n                    'name' => 'GLSL',\n                    'ref'  => '../tests/outputs/blur.glsl.yaml',\n                    'args' => '../tests/inputs/blur.glsl',\n                },\n                {\n                    'name' => 'Go',\n                    'ref'  => '../tests/outputs/hello_app.go-1.yaml',\n                    'args' => '../tests/inputs/hello_app*.go',\n                },\n                {\n                    'name' => 'Go --no-autogen',\n                    'ref'  => '../tests/outputs/hello_app.go-2.yaml',\n                    'args' => '--no-autogen ../tests/inputs/hello_app*.go',\n                },\n                {\n                    'name' => 'Go',\n                    'ref'  => '../tests/outputs/hello_app.go-1.yaml',\n                    'args' => '../tests/inputs/hello_app*.ʕ◔ϖ◔ʔ',\n                },\n                {\n                    'name' => 'Go --no-autogen',\n                    'ref'  => '../tests/outputs/hello_app.go-2.yaml',\n                    'args' => '--no-autogen ../tests/inputs/hello_app*.ʕ◔ϖ◔ʔ',\n                },\n                {\n                    'name' => 'Godot Scene',\n                    'ref'  => '../tests/outputs/GamePanel.tscn.yaml',\n                    'args' => '../tests/inputs/GamePanel.tscn',\n                },\n                {\n                    'name' => 'Godot Shaders',\n                    'ref'  => '../tests/outputs/example_2d.gdshader.yaml',\n                    'args' => '../tests/inputs/example_2d.gdshader',\n                },\n                {\n                    'name' => 'Godot Resource',\n                    'ref'  => '../tests/outputs/door.tres.yaml',\n                    'args' => '../tests/inputs/door.tres',\n                },\n                {\n                    'name' => 'Groovy',\n                    # issue #139; avoid\n                    # Complex regular subexpression recursion limit (32766) exceeded\n                    'ref'  => '../tests/outputs/regex_limit.gradle.yaml',\n                    'args' => '../tests/inputs/regex_limit.gradle',\n                },\n                {\n                    'name' => 'GraphQL',\n                    'ref'  => '../tests/outputs/graphql.gql.yaml',\n                    'args' => '../tests/inputs/graphql.gql',\n                },\n                {\n                    'name' => 'HAML',\n                    'ref'  => '../tests/outputs/just_stuff.haml.yaml',\n                    'args' => '../tests/inputs/just_stuff.haml',\n                },\n                {\n                    'name' => 'Hare',\n                    'ref'  => '../tests/outputs/fmt.ha.yaml',\n                    'args' => '../tests/inputs/fmt.ha',\n                },\n                {\n                    'name' => 'Haskell',\n                    'ref'  => '../tests/outputs/test2.lhs.yaml',\n                    'args' => '../tests/inputs/test2.lhs',\n                },\n                {\n                    'name' => 'Haskell 2',\n                    'ref'  => '../tests/outputs/test1.lhs.yaml',\n                    'args' => '../tests/inputs/test1.lhs',\n                },\n                {\n                    'name' => 'Haskell 3',\n                    'ref'  => '../tests/outputs/Haskell.hs.yaml',\n                    'args' => '../tests/inputs/Haskell.hs',\n                },\n                {\n                    'name' => 'Haskell 4',\n                    'ref'  => '../tests/outputs/test.hs.yaml',\n                    'args' => '../tests/inputs/test.hs',\n                },\n                {\n                    'name' => 'Haskell Boot',\n                    'ref'  => '../tests/outputs/Splice.hs-boot.yaml',\n                    'args' => '../tests/inputs/Splice.hs-boot',\n                },\n                {\n                    'name' => 'Haxe',\n                    'ref'  => '../tests/outputs/Sys.hx.yaml',\n                    'args' => '../tests/inputs/Sys.hx',\n                },\n                {\n                    'name' => 'HCL',\n                    'ref'  => '../tests/outputs/nomad_job.hcl.yaml',\n                    'args' => '../tests/inputs/nomad_job.hcl',\n                },\n                {\n                    'name' => 'Hibernate',\n                    'ref'  => '../tests/outputs/955.hbm.xml.yaml',\n                    'args' => '../tests/inputs/955.hbm.xml',\n                },\n                {\n                    'name' => 'HolyC',\n                    'ref'  => '../tests/outputs/Once.HC.yaml',\n                    'args' => '../tests/inputs/Once.HC',\n                },\n                {\n                    'name' => 'Hoon',\n                    'ref'  => '../tests/outputs/arvo.hoon.yaml',\n                    'args' => '../tests/inputs/arvo.hoon',\n                },\n                {\n                    'name' => 'HTML EEx',\n                    'ref'  => '../tests/outputs/html_heex_example.heex.yaml',\n                    'args' => '../tests/inputs/html_heex_example.heex',\n                },\n                {\n                    'name' => 'IDL 1',\n                    'ref'  => '../tests/outputs/IDL.idl.yaml',\n                    'args' => '../tests/inputs/IDL.idl',\n                },\n                {\n                    'name' => 'IDL 2',\n                    'ref'  => '../tests/outputs/streamlines.pro.yaml',\n                    'args' => '../tests/inputs/streamlines.pro',\n                },\n                {\n                    'name' => 'Idris',\n                    'ref'  => '../tests/outputs/Combinators.idr.yaml',\n                    'args' => '../tests/inputs/Combinators.idr',\n                },\n                {\n                    'name' => 'Idris (block comments)',\n                    'ref'  => '../tests/outputs/idris_block_comments.idr.yaml',\n                    'args' => '../tests/inputs/idris_block_comments.idr',\n                },\n                {\n                    'name' => 'Igor Pro',\n                    'ref'  => '../tests/outputs/igorpro.ipf.yaml',\n                    'args' => '../tests/inputs/igorpro.ipf',\n                },\n                {\n                    'name' => 'Imba',\n                    'ref'  => '../tests/outputs/class.imba.yaml',\n                    'args' => '../tests/inputs/class.imba',\n                },\n                {\n                    'name' => 'INI',\n                    'ref'  => '../tests/outputs/wpedia.ini.yaml',\n                    'args' => '../tests/inputs/wpedia.ini',\n                },\n                {\n                    'name' => 'IPL',\n                    'ref'  => '../tests/outputs/insertJournalEntry.ipl.yaml',\n                    'args' => '../tests/inputs/insertJournalEntry.ipl',\n                },\n                {\n                    'name' => 'Jai',\n                    'ref'  => '../tests/outputs/poly_constructor.jai.yaml',\n                    'args' => '../tests/inputs/poly_constructor.jai',\n                },\n                {\n                    'name' => 'Janet',\n                    'ref'  => '../tests/outputs/args.janet.yaml',\n                    'args' => '../tests/inputs/args.janet',\n                },\n                {\n                    'name' => 'Java',\n                    'ref'  => '../tests/outputs/Java.java.yaml',\n                    'args' => '../tests/inputs/Java.java',\n                },\n                {\n                    'name' => 'JCL',\n                    'ref'  => '../tests/outputs/offline.jcl.yaml',\n                    'args' => '../tests/inputs/offline.jcl',\n                },\n                {\n                    'name' => 'Jinja Templates',\n                    'ref'  => '../tests/outputs/child_template.jinja2.yaml',\n                    'args' => '../tests/inputs/child_template.jinja2',\n                },\n                {\n                    'name' => 'JSON',\n                    'ref'  => '../tests/outputs/glossary.json.yaml',\n                    'args' => '../tests/inputs/glossary.json',\n                },\n                {\n                    'name' => 'JSON5',\n                    'ref'  => '../tests/outputs/glossary.json5.yaml',\n                    'args' => '../tests/inputs/glossary.json5',\n                },\n                {\n                    'name' => 'Jsonnet',\n                    'ref'  => '../tests/outputs/inner_ref.jsonnet.yaml',\n                    'args' => '../tests/inputs/inner_ref.jsonnet',\n                },\n                {\n                    'name' => 'Jasper Report XML/Template',\n                    'ref'  => '../tests/outputs/955.jrxml.yaml',\n                    'args' => '../tests/inputs/955.jrxml',\n                },\n                {\n                    'name' => 'JSP Tag Library Definition',\n                    'ref'  => '../tests/outputs/955.tld.yaml',\n                    'args' => '../tests/inputs/955.tld',\n                },\n                {\n                    'name' => 'Jupyter Notebook',\n                    'ref'  => '../tests/outputs/Trapezoid_Rule.ipynb.yaml',\n                    'args' => '../tests/inputs/Trapezoid_Rule.ipynb',\n                },\n                {\n                    'name' => 'Julia',\n                    'ref'  => '../tests/outputs/julia.jl.yaml',\n                    'args' => '../tests/inputs/julia.jl',\n                },\n                {\n                    'name' => 'Juniper Junos',\n                    'ref'  => '../tests/outputs/config.junos.yaml',\n                    'args' => '../tests/inputs/config.junos',\n                },\n                {\n                    'name' => 'Justfile',\n                    'ref'  => '../tests/outputs/cross-platform.just.yaml',\n                    'args' => '../tests/inputs/cross-platform.just',\n                },\n                {\n                    'name' => 'kvlang',\n                    'ref'  => '../tests/outputs/kvlang.kv.yaml',\n                    'args' => '../tests/inputs/kvlang.kv',\n                },\n                {\n                    'name' => 'Kotlin',\n                    'ref'  => '../tests/outputs/hello.kt.yaml',\n                    'args' => '../tests/inputs/hello.kt',\n                },\n                {\n                    'name' => 'Lean',\n                    'ref'  => '../tests/outputs/dlist.lean.yaml',\n                    'args' => '../tests/inputs/dlist.lean',\n                },\n                {\n                    'name' => 'Lem',\n                    'ref'  => '../tests/outputs/machineDefFreshIds.lem.yaml',\n                    'args' => '../tests/inputs/machineDefFreshIds.lem',\n                },\n                {\n                    'name' => 'LFE',\n                    'ref'  => '../tests/outputs/ping_pong.lfe.yaml',\n                    'args' => '../tests/inputs/ping_pong.lfe',\n                },\n                {\n                    'name' => 'Linker Script',\n                    'ref'  => '../tests/outputs/linker.ld.yaml',\n                    'args' => '../tests/inputs/linker.ld',\n                },\n                {\n                    'name' => 'Liquibase',\n                    'ref'  => '../tests/outputs/955.lb.xml.yaml',\n                    'args' => '../tests/inputs/955.lb.xml',\n                },\n                {\n                    'name' => 'Lisp',\n                    'ref'  => '../tests/outputs/sharpsign.cl.yaml',\n                    'args' => '../tests/inputs/sharpsign.cl',\n                },\n                {\n                    'name' => 'Literate Idris',\n                    'ref'  => '../tests/outputs/Hello.lidr.yaml',\n                    'args' => '../tests/inputs/Hello.lidr',\n                },\n                {\n                    'name' => 'LLVM IR',\n                    'ref'  => '../tests/outputs/DIEnumerator-10.0.ll.yaml',\n                    'args' => '../tests/inputs/DIEnumerator-10.0.ll',\n                },\n                {\n                    'name' => 'Logos 1',\n                    'ref'  => '../tests/outputs/logos.x.yaml',\n                    'args' => '../tests/inputs/logos.x',\n                },\n                {\n                    'name' => 'Logos 2',\n                    'ref'  => '../tests/outputs/logos.xm.yaml',\n                    'args' => '../tests/inputs/logos.xm',\n                },\n                {\n                    'name' => 'Logtalk',\n                    'ref'  => '../tests/outputs/logtalk.lgt.yaml',\n                    'args' => '../tests/inputs/logtalk.lgt',\n                },\n                {\n                    'name' => 'Lua',\n                    'ref'  => '../tests/outputs/hello.lua.yaml',\n                    'args' => '../tests/inputs/hello.lua',\n                },\n                {\n                    'name' => 'Lua nested comments',\n                    'ref'  => '../tests/outputs/nested.lua.yaml',\n                    'args' => '../tests/inputs/nested.lua',\n                },\n                {\n                    'name' => 'Luau',\n                    'ref'  => '../tests/outputs/basic.luau.yaml',\n                    'args' => '../tests/inputs/basic.luau',\n                },\n                {\n                    'name' => 'Makefile',\n                    'ref'  => '../tests/outputs/Makefile.yaml',\n                    'args' => '../tests/inputs/Makefile',\n                },\n                {\n                    'name' => 'Makefile 2',\n                    'ref'  => '../tests/outputs/mfile.mk.yaml',\n                    'args' => '../tests/inputs/mfile.mk',\n                },\n                {\n                    'name' => 'Mako',\n                    'ref'  => '../tests/outputs/Mako.mako.yaml',\n                    'args' => '../tests/inputs/Mako.mako',\n                },\n                {\n                    'name' => 'Magik',\n                    'ref'  => '../tests/outputs/magikfile.magik.yaml',\n                    'args' => '../tests/inputs/magikfile.magik',\n                },\n                {\n                    'name' => 'Mathematica',\n                    'ref'  => '../tests/outputs/Mathematica_1.m.yaml',\n                    'args' => '../tests/inputs/Mathematica_1.m',\n                },\n                {\n                    'name' => 'Mathematica 2',\n                    'ref'  => '../tests/outputs/Mathematica_2.wlt.yaml',\n                    'args' => '../tests/inputs/Mathematica_2.wlt',\n                },\n                {\n                    'name' => 'MATLAB',\n                    'ref'  => '../tests/outputs/Octave.m.yaml',\n                    'args' => '../tests/inputs/Octave.m',\n                },\n                {\n                    'name' => 'MATLAB 2',\n                    'ref'  => '../tests/outputs/Lanczos.m.yaml',\n                    'args' => '../tests/inputs/Lanczos.m',\n                },\n                {\n                    'name' => 'MATLAB 3',\n                    'ref'  => '../tests/outputs/matlab_line_colors.m.yaml',\n                    'args' => '../tests/inputs/matlab_line_colors.m',\n                },\n                {\n                    'name' => 'Meson',\n                    'ref'  => '../tests/outputs/meson.build.yaml',\n                    'args' => '../tests/inputs/meson.build',\n                },\n                {\n                    'name' => 'Metal',\n                    'ref'  => '../tests/outputs/RenderTest.metal.yaml',\n                    'args' => '../tests/inputs/RenderTest.metal',\n                },\n                {\n                    'name' => 'Modelica',\n                    'ref'  => '../tests/outputs/SimpleODE.mo.yaml',\n                    'args' => '../tests/inputs/SimpleODE.mo',\n                },\n                {\n                    'name' => 'Mojom',\n                    'ref'  => '../tests/outputs/Mojo.mojom.yaml',\n                    'args' => '../tests/inputs/Mojo.mojom',\n                },\n                {\n                    'name' => 'Mojo',\n                    'ref'  => '../tests/outputs/hi.mojo.yaml',\n                    'args' => '../tests/inputs/hi.mojo',\n                },\n                {\n                    'name' => 'MoonBit',\n                    'ref'  => '../tests/outputs/moonbit.yaml',\n                    'args' => '../tests/inputs/moonbit.mbt ' .\n                              '../tests/inputs/moonbit.mbti ',\n                },\n                {\n                    'name' => 'Mumps',\n                    'ref'  => '../tests/outputs/Mumps.mps.yaml',\n                    'args' => '../tests/inputs/Mumps.mps',\n                },\n                {\n                    'name' => 'Mustache',\n                    'ref'  => '../tests/outputs/x.mustache.yaml',\n                    'args' => '../tests/inputs/x.mustache',\n                },\n                {\n                    'name' => 'Mustache 2',\n                    'ref'  => '../tests/outputs/includes_demo.mustache.yaml',\n                    'args' => '../tests/inputs/includes_demo.mustache',\n                },\n                {\n                    'name' => 'MXML',\n                    'ref'  => '../tests/outputs/drupal.mxml.yaml',\n                    'args' => '../tests/inputs/drupal.mxml',\n                },\n                {\n                    'name' => '.NET IL',\n                    'ref'  => '../tests/outputs/dotNET_intermediate.il.yaml',\n                    'args' => '../tests/inputs/dotNET_intermediate.il',\n                },\n                {\n                    'name' => 'NetLogo',\n                    'ref'  => '../tests/outputs/vinos.nlogo.yaml',\n                    'args' => '../tests/inputs/vinos.nlogo',\n                },\n                {\n                    'name' => 'Nextflow',\n                    'ref'  => '../tests/outputs/cli-args.nf.yaml',\n                    'args' => '../tests/inputs/cli-args.nf',\n                },\n                {\n                    'name' => 'Nickel',\n                    'ref'  => '../tests/outputs/fibonacci.ncl.yaml',\n                    'args' => '../tests/inputs/fibonacci.ncl',\n                },\n                {\n                    'name' => 'Nim',\n                    'ref'  => '../tests/outputs/statcsv.nim.yaml',\n                    'args' => '../tests/inputs/statcsv.nim',\n                },\n                {\n                    'name' => 'Nix',\n                    'ref'  => '../tests/outputs/darwin-configuration.nix.yaml',\n                    'args' => '../tests/inputs/darwin-configuration.nix',\n                },\n                {\n                    'name' => 'Nunjucks',\n                    'ref'  => '../tests/outputs/child_template.njk.yaml',\n                    'args' => '../tests/inputs/child_template.njk',\n                },\n                {\n                    'name' => 'Nushell',\n                    'ref'  => '../tests/outputs/nu-example.nu.yaml',\n                    'args' => '../tests/inputs/nu-example.nu',\n                },\n                {\n                    'name' => 'Nushell Object Notation',\n                    'ref'  => '../tests/outputs/nuon-example.nuon.yaml',\n                    'args' => '../tests/inputs/nuon-example.nuon',\n                },\n                {\n                    'name' => 'Objective-C',\n                    'ref'  => '../tests/outputs/qsort_demo.m.yaml',\n                    'args' => '../tests/inputs/qsort_demo.m',\n                },\n                {\n                    'name' => 'Odin',\n                    'ref'  => '../tests/outputs/demo.odin.yaml',\n                    'args' => '../tests/inputs/demo.odin',\n                },\n                {\n                    'name' => 'OpenSCAD',\n                    'ref'  => '../tests/outputs/Rounds.scad.yaml',\n                    'args' => '../tests/inputs/Rounds.scad',\n                },\n\n                {\n                    'name' => 'Oracle PL/SQL 1',\n                    'ref'  => '../tests/outputs/bubs_tak_ard.prc.yaml',\n                    'args' => '../tests/inputs/bubs_tak_ard.prc',\n                },\n\n                {\n                    'name' => 'Oracle PL/SQL 2',\n                    'ref'  => '../tests/outputs/issue_875.bdy.yaml',\n                    'args' => '../tests/inputs/issue_875.bdy',\n                },\n\n                {\n                    'name' => 'Org Mode',\n                    'ref'  => '../tests/outputs/orgmode.org.yaml',\n                    'args' => '../tests/inputs/orgmode.org',\n                },\n\n                {\n                    'name' => 'P4',\n                    'ref'  => '../tests/outputs/basic.p4.yaml',\n                    'args' => '../tests/inputs/basic.p4',\n                },\n                {\n                    'name' => 'Pawn',\n                    'ref'  => '../tests/outputs/pawn.yaml',\n                    'args' => '../tests/inputs/fortran.inc ' .\n                              '../tests/inputs/hanoi.inc ' .\n                              '../tests/inputs/pascal.inc ' .\n                              '../tests/inputs/test1.inc ' .\n                              '../tests/inputs/Pascal.p ' .\n                              '../tests/inputs/queue.p ',\n                },\n                {\n                    'name' => 'Pascal',\n                    'ref'  => '../tests/outputs/Pascal.pas.yaml',\n                    'args' => '../tests/inputs/Pascal.pas',\n                },\n                {\n                    'name' => 'Pascal 2',\n                    'ref'  => '../tests/outputs/Pascal.pp.yaml',\n                    'args' => '../tests/inputs/Pascal.pp',\n                },\n                {\n                    'name' => 'Pascal 3',\n                    'ref'  => '../tests/outputs/hello1.pas.yaml',\n                    'args' => '../tests/inputs/hello1.pas',\n                },\n                {\n                    'name' => 'Pascal 4',\n                    'ref'  => '../tests/outputs/hello.pas.yaml',\n                    'args' => '../tests/inputs/hello.pas',\n                },\n                {\n                    'name' => 'PEG',\n                    'ref'  => '../tests/outputs/sdp_parser.peg.yaml',\n                    'args' => '../tests/inputs/sdp_parser.peg',\n                },\n                {\n                    'name' => 'pegjs',\n                    'ref'  => '../tests/outputs/sdp_parser.pegjs.yaml',\n                    'args' => '../tests/inputs/sdp_parser.pegjs',\n                },\n                {\n                    'name' => 'peggy',\n                    'ref'  => '../tests/outputs/sdp_parser.peggy.yaml',\n                    'args' => '../tests/inputs/sdp_parser.peggy',\n                },\n                {\n                    'name' => 'Pek',\n                    'ref'  => '../tests/outputs/pek_example.pek.yaml',\n                    'args' => '../tests/inputs/pek_example.pek',\n                },\n                {\n                    'name' => 'Perl',\n                    'ref'  => '../tests/outputs/with_pod.pl.yaml',\n                    'args' => '../tests/inputs/with_pod.pl',\n                },\n                {\n                    'name' => 'Pest',\n                    'ref'  => '../tests/outputs/toml.pest.yaml',\n                    'args' => '../tests/inputs/toml.pest',\n                },\n                {\n                    'name' => 'PHP',\n                    'ref'  => '../tests/outputs/test1.inc.yaml',\n                    'args' => '../tests/inputs/test1.inc',\n                },\n                {\n                    'name' => 'PHP 2',\n                    'ref'  => '../tests/outputs/test1.php.yaml',\n                    'args' => '../tests/inputs/test1.php',\n                },\n                {\n                    'name' => 'Pig Latin',\n                    'ref'  => '../tests/outputs/script1-hadoop.pig.yaml',\n                    'args' => '../tests/inputs/script1-hadoop.pig',\n                },\n                {\n                    'name' => 'Pkl',\n                    'ref'  => '../tests/outputs/fib_class.pkl.yaml',\n                    'args' => '../tests/inputs/fib_class.pkl',\n                },\n                {\n                    'name' => 'PL/I',\n                    'ref'  => '../tests/outputs/hello.pl1.yaml',\n                    'args' => '../tests/inputs/hello.pl1',\n                },\n                {\n                    'name' => 'PL/M',\n                    'ref'  => '../tests/outputs/find.plm.yaml',\n                    'args' => '../tests/inputs/find.plm',\n                },\n                {\n                    'name' => 'PlantUML',\n                    'ref'  => '../tests/outputs/plantuml.puml.yaml',\n                    'args' => '../tests/inputs/plantuml.puml',\n                },\n                {\n                    'name' => 'PO File',\n                    'ref'  => '../tests/outputs/en_AU.po.yaml',\n                    'args' => '../tests/inputs/en_AU.po',\n                },\n                {\n                    'name' => 'Pony (--docstring-as-code)',\n                    'ref'  => '../tests/outputs/ring.pony.1.yaml',\n                    'args' => '--docstring-as-code ../tests/inputs/ring.pony',\n                },\n                {\n                    'name' => 'Pony',\n                    'ref'  => '../tests/outputs/ring.pony.2.yaml',\n                    'args' => '../tests/inputs/ring.pony',\n                },\n                {\n                    'name' => 'Prisma Schema',\n                    'ref'  => '../tests/outputs/schema.prisma.yaml',\n                    'args' => '../tests/inputs/schema.prisma',\n                },\n                {\n                    'name' => 'Processing',\n                    'ref'  => '../tests/outputs/pointillism.pde.yaml',\n                    'args' => '../tests/inputs/pointillism.pde',\n                },\n                {\n                    'name' => 'ProGuard',\n                    'ref'  => '../tests/outputs/proguard-project-app.pro.yaml',\n                    'args' => '../tests/inputs/proguard-project-app.pro',\n                },\n                {\n                    'name' => 'Prolog',\n                    'ref'  => '../tests/outputs/birds.pro.yaml',\n                    'args' => '../tests/inputs/birds.pro',\n                },\n                {\n                    'name' => 'Properties',\n                    'ref'  => '../tests/outputs/wiki.properties.yaml',\n                    'args' => '../tests/inputs/wiki.properties',\n                },\n                {\n                    'name' => 'PRQL',\n                    'ref'  => '../tests/outputs/invoices.prql.yaml',\n                    'args' => '../tests/inputs/invoices.prql',\n                },\n                {\n                    'name' => 'Puppet class',\n                    'ref'  => '../tests/outputs/modules1-ntp1.pp.yaml',\n                    'args' => '../tests/inputs/modules1-ntp1.pp',\n                },\n                {\n                    'name' => 'Puppet function without arguments',\n                    'ref'  => '../tests/outputs/modules1-func1.pp.yaml',\n                    'args' => '../tests/inputs/modules1-func1.pp',\n                },\n                {\n                    'name' => 'Puppet function with arguments',\n                    'ref'  => '../tests/outputs/modules1-func2.pp.yaml',\n                    'args' => '../tests/inputs/modules1-func2.pp',\n                },\n                {\n                    'name' => 'Puppet typealias',\n                    'ref'  => '../tests/outputs/modules1-typealias.pp.yaml',\n                    'args' => '../tests/inputs/modules1-typealias.pp',\n                },\n                {\n                    'name' => 'Python',\n                    'ref'  => '../tests/outputs/hi.py.yaml',\n                    'args' => '../tests/inputs/hi.py',\n                },\n                {\n                    'name' => 'Python wheel file',\n                    'ref'  => '../tests/outputs/test-1.0-py2.py3-none-win32.whl.yaml',\n                    'args' => '../tests/inputs/test-1.0-py2.py3-none-win32.whl',\n                },\n                {\n                    'name' => 'Qt Linguist',\n                    'ref'  => '../tests/outputs/i18n_de.ts.yaml',\n                    'args' => '../tests/inputs/i18n_de.ts',\n                },\n                {\n                    'name' => 'R 1',\n                    'ref'  => '../tests/outputs/sample.R.yaml',\n                    'args' => '../tests/inputs/sample.R',\n                },\n                {\n                    'name' => 'R 2',\n                    'ref'  => '../tests/outputs/utilities.R.yaml',\n                    'args' => '../tests/inputs/utilities.R',\n                },\n                {\n                    'name' => 'R 3',\n                    'ref'  => '../tests/outputs/acpclust.R.yaml',\n                    'args' => '../tests/inputs/acpclust.R',\n                },\n                {\n                    'name' => 'Racket',\n                    'ref'  => '../tests/outputs/md5.rkt.yaml',\n                    'args' => '../tests/inputs/md5.rkt',\n                },\n                {\n                    'name' => 'Ring',\n                    'ref'  => '../tests/outputs/tictactoe3d.ring.yaml',\n                    'args' => '../tests/inputs/tictactoe3d.ring',\n                },\n                {\n                    'name' => 'Raku',\n                    'ref'  => '../tests/outputs/prob060-andreoss.p6.yaml',\n                    'args' => '../tests/inputs/prob060-andreoss.p6',\n                },\n                {\n                    'name' => 'RAML',\n                    'ref'  => '../tests/outputs/helloworld.raml.yaml',\n                    'args' => '../tests/inputs/helloworld.raml',\n                },\n                {\n                    'name' => 'Razor',\n                    'ref'  => '../tests/outputs/razor.cshtml.yaml',\n                    'args' => '../tests/inputs/razor.cshtml',\n                },\n                {\n                    'name' => 'ReasonML',\n                    'ref'  => '../tests/outputs/LogMain.re.yaml',\n                    'args' => '../tests/inputs/LogMain.re',\n                },\n                {\n                    'name' => 'Rego',\n                    'ref'  => '../tests/outputs/test.rego.yaml',\n                    'args' => '../tests/inputs/test.rego',\n                },\n                {\n                    'name' => 'ReScript',\n                    'ref'  => '../tests/outputs/RedBlackTree.res.yaml',\n                    'args' => '../tests/inputs/RedBlackTree.res',\n                },\n                {\n                    'name' => 'reStructuredText',\n                    'ref'  => '../tests/outputs/reStructuredText.rst.yaml',\n                    'args' => '../tests/inputs/reStructuredText.rst',\n                },\n                {\n                    'name' => 'Rhai',\n                    'ref'  => '../tests/outputs/comments.rhai.yaml',\n                    'args' => '../tests/inputs/comments.rhai',\n                },\n                {\n                    'name' => 'RobotFramework',\n                    'ref'  => '../tests/outputs/robotframework.robot.yaml',\n                    'args' => '../tests/inputs/robotframework.robot',\n                },\n                {\n                    'name' => 'Rmd',\n                    'ref'  => '../tests/outputs/test.Rmd.yaml',\n                    'args' => '../tests/inputs/test.Rmd',\n                },\n                {\n                    'name' => 'Ruby',\n                    'ref'  => '../tests/outputs/messages.rb.yaml',\n                    'args' => '../tests/inputs/messages.rb',\n                },\n                {\n                    'name' => 'SaltStack',\n                    'ref'  => '../tests/outputs/certificates.sls.yaml',\n                    'args' => '../tests/inputs/certificates.sls',\n                },\n                {\n                    'name' => 'SCSS',\n                    'ref'  => '../tests/outputs/style.scss.yaml',\n                    'args' => '../tests/inputs/style.scss',\n                },\n                {\n                    'name' => 'Scheme',\n                    'ref'  => '../tests/outputs/scheme.sls.yaml',\n                    'args' => '../tests/inputs/scheme.sls',\n                },\n                {\n                    'name' => 'Clarity',\n                    'ref'  => '../tests/outputs/clarityfiles.clar.yaml',\n                    'args' => '../tests/inputs/clarityfiles.clar',\n                },\n                {\n                    'name' => 'SKILL',\n                    'ref'  => '../tests/outputs/ChangeProperties.il.yaml',\n                    'args' => '../tests/inputs/ChangeProperties.il',\n                },\n                {\n                    'name' => 'Starlark',\n                    'ref'  => '../tests/outputs/build.bzl.yaml',\n                    'args' => '../tests/inputs/build.bzl',\n                },\n                {\n                    'name' => 'Slim',\n                    'ref'  => '../tests/outputs/Slim.html.slim.yaml',\n                    'args' => '../tests/inputs/Slim.html.slim',\n                },\n                {\n                    'name' => 'Slint',\n                    'ref'  => '../tests/outputs/Slint-helloworld.slint.yaml',\n                    'args' => '../tests/inputs/Slint-helloworld.slint',\n                },\n                {\n                    'name' => 'Smalltalk 1',\n                    'ref'  => '../tests/outputs/chat.st.yaml',\n                    'args' => '../tests/inputs/chat.st',\n                },\n                {\n                    'name' => 'Smalltalk 2',\n                    'ref'  => '../tests/outputs/captcha.cs.yaml',\n                    'args' => '../tests/inputs/captcha.cs',\n                },\n                {\n                    'name' => 'Snakemake',\n                    'ref'  => '../tests/outputs/Snakefile.yaml',\n                    'args' => '../tests/inputs/Snakefile',\n                },\n                {\n                    'name' => 'Smarty',\n                    'ref'  => '../tests/outputs/guestbook.tpl.yaml',\n                    'args' => '../tests/inputs/guestbook.tpl',\n                },\n                {\n                    'name' => 'SparForte',\n                    'ref'  => '../tests/outputs/hello.sp.yaml',\n                    'args' => '../tests/inputs/hello.sp',\n                },\n                {\n                    'name' => 'Solidity',\n                    'ref'  => '../tests/outputs/solidity.sol.yaml',\n                    'args' => '../tests/inputs/solidity.sol',\n                },\n                {\n                    'name' => 'Specman e 1',\n                    'ref'  => '../tests/outputs/specman_e.e.yaml',\n                    'args' => '../tests/inputs/specman_e.e',\n                },\n                {\n                    'name' => 'Specman e 2',\n                    'ref'  => '../tests/outputs/specman_e2.e.yaml',\n                    'args' => '../tests/inputs/specman_e2.e',\n                },\n                {\n                    'name' => 'Squirrel',\n                    'ref'  => '../tests/outputs/squirrel_table.nut.yaml',\n                    'args' => '../tests/inputs/squirrel_table.nut',\n                },\n                {\n                    'name' => 'Stata',\n                    'ref'  => '../tests/outputs/stata.do.yaml',\n                    'args' => '../tests/inputs/stata.do',\n                },\n                {\n                    'name' => 'SugarSS',\n                    'ref'  => '../tests/outputs/rules.sss.yaml',\n                    'args' => '../tests/inputs/rules.sss',\n                },\n                {\n                    'name' => 'SurrealQL',\n                    'ref'  => '../tests/outputs/ranges.surql.yaml',\n                    'args' => '../tests/inputs/ranges.surql',\n                },\n                {\n                    'name' => 'Svelte (HTML comments)',\n                    'ref'  => '../tests/outputs/reactive.svelte.yaml',\n                    'args' => '../tests/inputs/reactive.svelte',\n                },\n                {\n                    'name' => 'Svelte (C++ comments)',\n                    'ref'  => '../tests/outputs/test_w_cpp_comments.svelte.yaml',\n                    'args' => '../tests/inputs/test_w_cpp_comments.svelte',\n                },\n                {\n                    'name' => 'Svelte (comments in strings)',\n                    'ref'  => '../tests/outputs/comments_in_str.svelte.yaml',\n                    'args' => '--strip-str-comments ../tests/inputs/comments_in_str.svelte',\n                },\n                {\n                    'name' => 'SVG',\n                    'ref'  => '../tests/outputs/SVG_logo.svg.yaml',\n                    'args' => '../tests/inputs/SVG_logo.svg',\n                },\n                {\n                    'name' => 'Swift',\n                    'ref'  => '../tests/outputs/tour.swift.yaml',\n                    'args' => '../tests/inputs/tour.swift',\n                },\n                {\n                    'name' => 'SWIG',\n                    'ref'  => '../tests/outputs/swig_example.i.yaml',\n                    'args' => '../tests/inputs/swig_example.i',\n                },\n                {\n                    'name' => 'TableGen',\n                    'ref'  => '../tests/outputs/TableGen-ARM.yaml',\n                    'args' => '../tests/inputs/TableGen-ARM.td',\n                },\n                {\n                    'name' => 'Tcl/Tk',\n                    'ref'  => '../tests/outputs/Tk.yaml',\n                    'args' => '../tests/inputs/Tk',\n                },\n                {\n                    'name' => 'TEAL',\n                    'ref'  => '../tests/outputs/htlc.teal.yaml',\n                    'args' => '../tests/inputs/htlc.teal',\n                },\n                {\n                    'name' => 'Templ',\n                    'ref'  => '../tests/outputs/templ_example.templ.yaml',\n                    'args' => '../tests/inputs/templ_example.templ'\n                },\n                {\n                    'name' => 'TeX',\n                    'ref'  => '../tests/outputs/LaTeX.tex.yaml',\n                    'args' => '../tests/inputs/LaTeX.tex',\n                },\n                {\n                    'name' => 'Text',\n                    'ref'  => '../tests/outputs/plain_text.txt.yaml',\n                    'args' => '../tests/inputs/plain_text.txt',\n                },\n                {\n                    'name' => 'Thrift',\n                    'ref'  => '../tests/outputs/DocTest.thrift.yaml',\n                    'args' => '../tests/inputs/DocTest.thrift',\n                },\n                {\n                    'name' => 'TLA+',\n                    'ref'  => '../tests/outputs/TLAExample.tla.yaml',\n                    'args' => '../tests/inputs/TLAExample.tla',\n                },\n                {\n                    'name' => 'TLA+/PlusCal',\n                    'ref'  => '../tests/outputs/PlusCalExample.tla.yaml',\n                    'args' => '../tests/inputs/PlusCalExample.tla',\n                },\n                {\n                    'name' => 'TLA+/PlusCal --no-autogen',\n                    'ref'  => '../tests/outputs/PlusCalExample-no-autogen.tla.yaml',\n                    'args' => '--no-autogen ../tests/inputs/PlusCalExample.tla',\n                },\n                {\n                    'name' => 'TOML',\n                    'ref'  => '../tests/outputs/toml_example.toml.yaml',\n                    'args' => '../tests/inputs/toml_example.toml',\n                },\n                {\n                    'name' => 'TNSDL',\n                    'ref'  => '../tests/outputs/tnsdl.sdl.yaml',\n                    'args' => '../tests/inputs/tnsdl.sdl',\n                },\n                {\n                    'name' => 'tspeg 1',\n                    'ref'  => '../tests/outputs/sdp_parser.tspeg.yaml',\n                    'args' => '../tests/inputs/sdp_parser.tspeg',\n                },\n                {\n                    'name' => 'tspeg 2',\n                    'ref'  => '../tests/outputs/sdp_parser.jspeg.yaml',\n                    'args' => '../tests/inputs/sdp_parser.jspeg',\n                },\n                {\n                    'name' => 'TTCN',\n                    'ref'  => '../tests/outputs/clusterConf.ttcn.yaml',\n                    'args' => '../tests/inputs/clusterConf.ttcn',\n                },\n                {\n                    'name' => 'TypeScript',\n                    'ref'  => '../tests/outputs/TypeScript.ts.yaml',\n                    'args' => '../tests/inputs/TypeScript.ts',\n                },\n                {\n                    'name' => 'TypeScript 2',\n                    'ref'  => '../tests/outputs/TypeScript_2.ts.yaml',\n                    'args' => '../tests/inputs/TypeScript_2.ts',\n                },\n                {\n                    'name' => 'TypeScript 3',\n                    'ref'  => '../tests/outputs/warship.ts.yaml',\n                    'args' => '../tests/inputs/warship.ts',\n                },\n                {\n                    'name' => 'TypeScript 4',\n                    'ref'  => '../tests/outputs/greeter.tsx.yaml',\n                    'args' => '../tests/inputs/greeter.tsx',\n                },\n                {\n                    'name' => 'Typst',\n                    'ref'  => '../tests/outputs/notes.typ.yaml',\n                    'args' => '../tests/inputs/notes.typ',\n                },\n\n                {\n                    'name' => 'Umka',\n                    'ref'  => '../tests/outputs/fractal.um.yaml',\n                    'args' => '../tests/inputs/fractal.um',\n                },\n\n                {\n                    'name' => 'Unknown',\n                    # No result will be produced, result.yaml will stay like the previous test\n                    'ref'  => '../tests/outputs/fractal.um.yaml',\n                    'args' => '../tests/inputs/xattr.conf',\n                },\n\n                {\n                    'name' => 'USS',\n                    'ref'  => '../tests/outputs/USS.uss.yaml',\n                    'args' => '../tests/inputs/USS.uss',\n                },\n\n                {\n                    'name' => 'UXML',\n                    'ref'  => '../tests/outputs/UXML.uxml.yaml',\n                    'args' => '../tests/inputs/UXML.uxml',\n                },\n\n                {\n                    'name' => 'Vala',\n                    'ref'  => '../tests/outputs/gnureadline.vala.yaml',\n                    'args' => '../tests/inputs/gnureadline.vala',\n                },\n                {\n                    'name' => 'VBA',\n                    'ref'  => '../tests/outputs/vba_test.vba.yaml',\n                    'args' => '../tests/inputs/vba_test.vba',\n                },\n                {\n                    'name' => 'VB.NET',\n                    'ref'  => '../tests/outputs/vbnet_test.vb.yaml',\n                    'args' => '../tests/inputs/vbnet_test.vb',\n                },\n                {\n                    'name' => 'Velocity Template Language',\n                    'ref'  => '../tests/outputs/vtl.vm.yaml',\n                    'args' => '../tests/inputs/vtl.vm',\n                },\n                {\n                    'name' => 'Verilog',\n                    'ref'  => '../tests/outputs/verilog.sv.yaml',\n                    'args' => '../tests/inputs/verilog.sv',\n                },\n                {\n                    'name' => 'Visual Basic',\n                    'ref'  => '../tests/outputs/JetCar.cls.yaml',\n                    'args' => '../tests/inputs/JetCar.cls',\n                },\n                {\n                    'name' => 'Visual Basic (Dsr)',\n                    'ref'  => '../tests/outputs/test.Dsr.yaml',\n                    'args' => '../tests/inputs/test.Dsr',\n                },\n                {\n                    'name' => 'Visual Basic .NET (vbhtml)',\n                    'ref'  => '../tests/outputs/test.vbhtml.yaml',\n                    'args' => '../tests/inputs/test.vbhtml',\n                },\n                {\n                    'name' => 'VBScript',\n                    'ref'  => '../tests/outputs/test.vbs.yaml',\n                    'args' => '../tests/inputs/test.vbs',\n                },\n                {\n                    'name' => 'Visual Studio Solution',\n                    'ref'  => '../tests/outputs/vs_solution.sln.yaml',\n                    'args' => '../tests/inputs/vs_solution.sln',\n                },\n\n                {\n                    'name' => 'Vuejs Component 1',\n                    'ref'  => '../tests/outputs/ItemView.vue.yaml',\n                    'args' => '../tests/inputs/ItemView.vue',\n                },\n\n                {\n                    'name' => 'VSCode Workspace',\n                    'ref'  => '../tests/outputs/cloc-dev.code-workspace.yaml',\n                    'args' => '../tests/inputs/cloc-dev.code-workspace',\n                },\n\n                {\n                    'name' => 'Vuejs Component 2',\n                    'ref'  => '../tests/outputs/issue_876.vue.yaml',\n                    'args' => '../tests/inputs/issue_876.vue',\n                },\n\n                {\n                    'name' => 'Vyper',\n                    'ref'  => '../tests/outputs/vyper.vy.yaml',\n                    'args' => '../tests/inputs/vyper.vy',\n                },\n                {\n                    'name' => 'WebAssembly',\n                    'ref'  => '../tests/outputs/type.wast.yaml',\n                    'args' => '../tests/inputs/type.wast',\n                },\n                {\n                    'name' => 'Web Services Description',\n                    'ref'  => '../tests/outputs/webservice.wsdl.yaml',\n                    'args' => '../tests/inputs/webservice.wsdl',\n                },\n                {\n                    'name' => 'WGSL',\n                    'ref'  => '../tests/outputs/updateSprites.wgsl.yaml',\n                    'args' => '../tests/inputs/updateSprites.wgsl',\n                },\n                {\n                    'name' => 'Windows Message',\n                    'ref'  => '../tests/outputs/ZosMsg.mc.yaml',\n                    'args' => '../tests/inputs/ZosMsg.mc',\n                },\n                {\n                    'name' => 'Windows Message 2',\n                    'ref'  => '../tests/outputs/Sample.mc.yaml',\n                    'args' => '../tests/inputs/Sample.mc',\n                },\n                {\n                    'name' => 'Windows Module',\n                    'ref'  => '../tests/outputs/ZosNp.def.yaml',\n                    'args' => '../tests/inputs/ZosNp.def',\n                },\n                {\n                    'name' => 'Windows Resource',\n                    'ref'  => '../tests/outputs/ZosNet.rc.yaml',\n                    'args' => '../tests/inputs/ZosNet.rc',\n                },\n                {\n                    'name' => 'WXML',\n                    'ref'  => '../tests/outputs/pages.wxml.yaml',\n                    'args' => '../tests/inputs/pages.wxml',\n                },\n                {\n                    'name' => 'WXSS',\n                    'ref'  => '../tests/outputs/pages.wxss.yaml',\n                    'args' => '../tests/inputs/pages.wxss',\n                },\n                {\n                    'name' => 'xBase',\n                    'ref'  => '../tests/outputs/harbour_xbase.prg.yaml',\n                    'args' => '../tests/inputs/harbour_xbase.prg',\n                },\n                {\n                    'name' => 'X++',\n                    'ref'  => '../tests/outputs/X++.xpo.yaml',\n                    'args' => '../tests/inputs/X++.xpo',\n                },\n                {\n                    'name' => 'XML',\n                    'ref'  => '../tests/outputs/XML.xml.yaml',\n                    'args' => '../tests/inputs/XML.xml',\n                },\n                {\n                    'name' => 'XML (Qt/GTK)',\n                    'ref'  => '../tests/outputs/BoxWidget.ui.yaml',\n                    'args' => '../tests/inputs/BoxWidget.ui',\n                },\n                {\n                    'name' => 'XQuery',\n                    'ref'  => '../tests/outputs/pop_by_country.xq.yaml',\n                    'args' => '../tests/inputs/pop_by_country.xq',\n                },\n                {\n                    'name' => 'XSLT',\n                    'ref'  => '../tests/outputs/XSL-FO.xsl.yaml',\n                    'args' => '../tests/inputs/XSL-FO.xsl',\n                },\n                {\n                    'name' => 'XSLT 2',\n                    'ref'  => '../tests/outputs/XSLT.xslt.yaml',\n                    'args' => '../tests/inputs/XSLT.xslt',\n                },\n                {\n                    'name' => 'Xtend',\n                    'ref'  => '../tests/outputs/Xtend.xtend.yaml',\n                    'args' => '../tests/inputs/Xtend.xtend',\n                },\n                {\n                    'name' => 'Yang',\n                    'ref'  => '../tests/outputs/bbf-device.yang.yaml',\n                    'args' => '../tests/inputs/bbf-device.yang',\n                },\n                {\n                    'name' => 'Yarn',\n                    'ref'  => '../tests/outputs/guard_talking.yarn.yaml',\n                    'args' => '../tests/inputs/guard_talking.yarn',\n                },\n                {\n                    'name' => 'Zig',\n                    'ref'  => '../tests/outputs/zir_sema.zig.yaml',\n                    'args' => '../tests/inputs/zir_sema.zig',\n                },\n            );\n\nmy $Verbose = 0;\n\nmy $results  = 'results.yaml';\nmy $work_dir = getcwd;\nmy $cloc     = \"$work_dir/../cloc\";                 # all-purpose version\n   $cloc     = \"$work_dir/cloc\" if defined $opt{u}; # Unix-tuned version\nmy $Run = \"$cloc --quiet --yaml --out $results \";\nforeach my $t (@Tests) {\n    print  $Run . $t->{'args'} if $Verbose;\n    system($Run . $t->{'args'});\n    ok(-e $results, $t->{'name'} . \" created output\");\n    my %ref  = load_yaml($t->{'ref'});\n    my %this = load_yaml($results);\n    is_deeply(\\%this, \\%ref, $t->{'name'} . \" results match\");\n}\ndone_testing();\nprint \"Finished testing $cloc\\n\";\n\nsub load_yaml { # {{{1\n    my ($file, ) = @_;\n    my %result = ();\n    if (!-r $file) {\n        warn \"File not found: $file\\n\";\n        return %result;\n    }\n    open IN, $file or return %result;\n    my $section = undef;\n    while (<IN>) {\n        next if /^\\s*#/ or /^--/;\n        if (/^\\s*'?(.*?)'?\\s*:\\s*$/) {\n            $section = $1;\n            next;\n        }\n        next unless defined $section;\n        next if $section eq 'header';\n        chomp;\n        s/\\s+//g;\n        my ($K, $V) = split(':');\n        $K =~ s/'//g;\n        $result{$section}{$K} = $V;\n    }\n    close IN;\n    return %result\n} # 1}}}\n"
  },
  {
    "path": "Unix/t/01_opts.t",
    "content": "#!/usr/bin/env perl\nuse warnings;\nuse strict;\nuse Test::More;\nuse File::Copy \"cp\";\nuse Cwd;\nuse Getopt::Std;\nmy %opt;\ngetopts('u', \\%opt);  # -u to run Unix/cloc instead of ../cloc\nmy @Tests = (\n\n               {\n                   'name' => '--exclude-dir 1 (baseline for github issue #82)',\n                   'args' => '--exclude-dir cc ../tests/inputs/dd',\n                   'ref'  => '../tests/outputs/exclude_dir_1.yaml',\n               },\n               {\n                   'name' => '--exclude-dir 2 (github issue #82)',\n                   'cd'   => '../tests/inputs/dd',\n                   'args' => '--exclude-dir cc *',\n                   'ref'  => '../tests/outputs/exclude_dir_1.yaml',\n               },\n               {\n                   'name' => '--not-match-d',\n                   'cd'   => '../tests/inputs/dd',\n                   'args' => '--not-match-d cc *',\n                   'ref'  => '../tests/outputs/exclude_dir_1.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T1)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T1.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T2)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --not-match-d bar issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T2.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T3)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --not-match-d bee issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T3.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T4)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --not-match-d bar/bee issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T4.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T5)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --fullpath --not-match-d   bar issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T5.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T6)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --fullpath --not-match-d ./bar issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T6.yaml',\n               },\n               {\n                   'name' => '--not-match-d (github issue #114 T7)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--by-file --fullpath --not-match-d bar/bee issues/114',\n                   'ref'  => '../tests/outputs/issues/114/T7.yaml',\n               },\n             # {\n             #     'name' => 'git submodule handling (github issue #131 T1)',\n             #     'cd'   => '../tests/inputs',\n             #     'args' => 'issues/131',\n             #     'ref'  => '../tests/outputs/issues/131/T1.yaml',\n             # },\n             # {\n             #     'name' => 'git submodule handling (github issue #131 T2)',\n             #     'cd'   => '../tests/inputs',\n             #     'args' => '--vcs git issues/131',\n             #     'ref'  => '../tests/outputs/issues/131/T2.yaml',\n             # },\n               {\n                   'name' => 'all files (github issue #132 T1)',\n                   'cd'   => '../tests/inputs',\n                   'args' => 'issues/132',\n                   'ref'  => '../tests/outputs/issues/132/T1.yaml',\n               },\n               {\n                   'name' => '--vcs git issues/132 (github issue #132 T2)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git issues/132',\n                   'ref'  => '../tests/outputs/issues/132/T2.yaml',\n               },\n               {\n                   'name' => '--vcs-git --exclude-dir ignore_dir (github issue #132 T3)',\n                   'cd'   => '../tests/inputs/issues/132',\n                   'args' => '--vcs git --exclude-dir ignore_dir .',\n                   'ref'  => '../tests/outputs/issues/132/T3.yaml',\n               },\n               {\n                   'name' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir (github issue #132 T4)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --fullpath --not-match-d issues/132/ignore_dir issues/132',\n                   'ref'  => '../tests/outputs/issues/132/T4.yaml',\n               },\n               {\n                   'name' => '--vcs git --match-f C-Ansi (github issue #132 T5)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --match-f C-Ansi issues/132',\n                   'ref'  => '../tests/outputs/issues/132/T5.yaml',\n               },\n               {\n                   'name' => '--vcs git --match-f \"\\.c$\" (github issue #132 T6)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --match-f \"\\.c$\" issues/132',\n                   'ref'  => '../tests/outputs/issues/132/T6.yaml',\n               },\n               {\n                   'name' => '--vcs \"find X\" (github issue #147)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs \"find foo_bar\"',\n                   'ref'  => '../tests/outputs/issues/147/T1.yaml',\n               },\n               {\n                   'name' => '--read-lang-def w/remove_between_general (github issue #166)',\n                   'cd'   => '../tests/inputs/issues/166',\n                   'args' => '--read-lang-def X fake.thy',\n                   'ref'  => '../tests/outputs/issues/166/fake.thy.yaml',\n               },\n               {\n                   'name' => '--read-lang-def w/triple_extension',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--read-lang-def triple_lang_def.txt custom.triple.extension.js',\n                   'ref'  => '../tests/outputs/custom.triple.extension.js.yaml',\n               },\n               {\n                   'name' => 'Forth balanced parentheses #1 (github issue #183)',\n                   'cd'   => '../tests/inputs/issues/183',\n                   'args' => 'file.fth',\n                   'ref'  => '../tests/outputs/issues/183/file.fth.yaml',\n               },\n               {\n                   'name' => 'Forth balanced parentheses #2 (github issue #183)',\n                   'cd'   => '../tests/inputs/issues/183',\n                   'args' => 'eval1957.SACunidir.fr',\n                   'ref'  => '../tests/outputs/issues/183/eval1957.SACunidir.fr.yaml',\n               },\n               {\n                   'name' => 'diff identical files (github issue #280)',\n                   'cd'   => '../tests/inputs/issues/280',\n                   'args' => '--diff L R',\n                   'ref'  => '../tests/outputs/issues/280/280.yaml',\n               },\n               {\n                   'name' => 'diff identical files by file (github issue #280)',\n                   'cd'   => '../tests/inputs/issues/280',\n                   'args' => '--by-file --diff L R',\n                   'ref'  => '../tests/outputs/issues/280/280_by_file.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  1/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '               --not-match-d ignore_subdir                    project',\n                   'ref'  => '../tests/outputs/issues/286/1.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  2/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '--follow-links --not-match-d ignore_subdir                    project',\n\n                   'ref'  => '../tests/outputs/issues/286/2.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  3/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '               --not-match-d ignore_subdir --fullpath         project',\n\n                   'ref'  => '../tests/outputs/issues/286/3.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  4/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '--follow-links --not-match-d ignore_subdir --fullpath         project',\n                   'ref'  => '../tests/outputs/issues/286/4.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  5/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '               --not-match-d project/ignore_subdir --fullpath project',\n                   'ref'  => '../tests/outputs/issues/286/5.yaml',\n               },\n\n               {\n                   'name' => '--follow-links, --not-match-d, --fullpath  6/6 (github issue #286)',\n                   'cd'   => '../tests/inputs/issues/286',\n                   'args' => '--follow-links --not-match-d project/ignore_subdir --fullpath project',\n                   'ref'  => '../tests/outputs/issues/286/6.yaml',\n               },\n\n               {\n                   'name' => '--include-ext m,lua (github issue #296)',\n                   'cd'   => '../tests/inputs/issues/296',\n                   'args' => '--include-ext m,lua .',\n                   'ref'  => '../tests/outputs/issues/296/results.yaml',\n               },\n\n               {\n                   'name' => '--strip-str-comments (github issue #245)',\n                   'cd'   => '../tests/inputs/issues/245',\n                   'args' => '--strip-str-comments .',\n                   'ref'  => '../tests/outputs/issues/245/CRS.scala.yaml',\n               },\n\n               {\n                   'name' => 'YAML --by-file output with unusual filename (github issue #312)',\n                   'cd'   => '../tests/inputs/issues/312',\n                   'args' => '--by-file .',\n                   'ref'  => '../tests/outputs/issues/312/results.yaml',\n               },\n\n               {\n                   'name' => 'custom Smarty definition (github issue #327)',\n                   'cd'   => '../tests/inputs/issues/327',\n                   'args' => '--force-lang-def=lang.config example.smarty2',\n                   'ref'  => '../tests/outputs/issues/327/results.yaml',\n               },\n\n               {\n                   'name' => 'UTF-8 output file encoding',\n                   'cd'   => '../tests/inputs/issues/318',\n                   'args' => '--by-file --file-encoding utf8 R*.cs',\n                   'ref'  => '../tests/inputs/issues/318/Rcs.yaml',  # results in input dir\n               },\n\n               {\n                   'name' => 'distinguish TeX from VB (github issue #341)',\n                   'cd'   => '../tests/inputs/issues/341',\n                   'args' => '.',\n                   'ref'  => '../tests/outputs/issues/341/results.yaml',\n               },\n\n               {\n                   'name' => '--strip-str-comments (github issue #350)',\n                   'cd'   => '../tests/inputs/issues/350',\n                   'args' => '--strip-str-comments .',\n                   'ref'  => '../tests/outputs/issues/350/fs.go.yaml',\n               },\n\n               {\n                   'name' => 'Java comments in strings, issue #365',\n                   'cd'   => '../tests/inputs/issues/365',\n                   'args' => 'RSpecTests.java',\n                   'ref'  => '../tests/outputs/issues/365/results.yaml',\n               },\n\n               {\n                   'name' => 'Arduino IDE 0xA0 characters',\n                   'cd'   => '../tests/inputs/issues/370',\n                   'args' => 'arduino_issue_370.ino',\n                   'ref'  => '../tests/outputs/issues/370/results.yaml',\n               },\n\n               {\n                   'name' => 'Python docstrings --docstring-as-code',\n                   'cd'   => '../tests/inputs/issues/375',\n                   'args' => '--docstring-as-code docstring.py',\n                   'ref'  => '../tests/outputs/issues/375/results.yaml',\n               },\n\n               {\n                   'name' => 'Perl v. Prolog',\n                   'cd'   => '../tests/inputs/issues/380',\n                   'args' => 'wrapper.pl',\n                   'ref'  => '../tests/outputs/issues/380/wrapper.pl.yaml',\n               },\n\n               {\n                   'name' => 'Java comments and continuation lines issue 381',\n                   'cd'   => '../tests/inputs/issues/381',\n                   'args' => 'issue381.java',\n                   'ref'  => '../tests/outputs/issues/381/issue381.java.yaml',\n               },\n\n               {\n                   'name' => 'C comments w/ backslashed quote in strings issue 381',\n                   'cd'   => '../tests/inputs/issues/381',\n                   'args' => '--strip-str-comments issue381.c',\n                   'ref'  => '../tests/outputs/issues/381/issue381.c.yaml',\n               },\n\n               {\n                   'name' => '--exclude-content issue 396',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--exclude-content Lambda acpclust.R sample.R utilities.R',\n                   'ref'  => '../tests/outputs/issues/396/excl.yaml',\n               },\n\n               {\n                   'name' => '--exclude-content w/--diff issue 396',\n                   'cd'   => '../tests/inputs/issues/280',\n                   'args' => '--exclude-content Copyright --diff L R',\n                   'ref'  => '../tests/outputs/issues/396/excl_diff.yaml',\n               },\n\n               {\n                   'name' => 'Python with /* in strings issue 405',\n                   'cd'   => '../tests/inputs/issues/405',\n                   'args' => 'globs.py',\n                   'ref'  => '../tests/outputs/issues/405/globs.py.yaml',\n               },\n\n               {\n                   'name' => '--exclude-dir and --follow-link, #407 1/3',\n                   'cd'   => '../tests/inputs/issues/407',\n                   'args' => '--follow-link --exclude-dir Test count_dir',\n                   'ref'  => '../tests/outputs/issues/407/results1.yaml',\n               },\n\n               {\n                   'name' => '--exclude-dir and --follow-link, #407 2/3',\n                   'cd'   => '../tests/inputs/issues/407',\n                   'args' => '--exclude-dir Test level2',\n                   'ref'  => '../tests/outputs/issues/407/results2.yaml',\n               },\n\n               {\n                   'name' => '--exclude-dir and --follow-link, #407 3/3',\n                   'cd'   => '../tests/inputs/issues/407',\n                   'args' => '--follow-link --exclude-dir Test level2',\n                   'ref'  => '../tests/outputs/issues/407/results3.yaml',\n               },\n\n               {\n                   'name' => 'doubly counted she-bang line, #408',\n                   'cd'   => '../tests/inputs/issues/408',\n                   'args' => 'badly_named_ruby.pl',\n                   'ref'  => '../tests/outputs/issues/408/badly_named_ruby.yaml',\n               },\n\n               {\n                   'name' => 'case insensitive file ext, #420',\n                   'cd'   => '../tests/inputs/issues/420',\n                   'args' => '--ignore-case-ext .',\n                   'ref'  => '../tests/outputs/issues/420/results.yaml',\n               },\n\n               {\n                   'name' => 'diff with --exclude-list-file, #433',\n                   'cd'   => '../tests/inputs/issues/433',\n                   'args' => '--exclude-list-file excl.txt --by-file --follow-links --diff L R\n                   ',\n                   'ref'  => '../tests/outputs/issues/433/results.yaml',\n               },\n               {\n                   'name' => 'JavaScript comment in string, #454',\n                   'cd'   => '../tests/inputs/issues/454',\n                   'args' => '--strip-str-comments createServer.js',\n                   'ref'  => '../tests/outputs/issues/454/createServer.js.yaml',\n               },\n               {\n                   'name' => 'XML with no extension, #456',\n                   'cd'   => '../tests/inputs/issues/456',\n                   'args' => 'XML_no_ext',\n                   'ref'  => '../tests/outputs/issues/456/XML_no_ext.yaml',\n               },\n               {\n                   'name' => 'XML with unusual extension, #456',\n                   'cd'   => '../tests/inputs/issues/456',\n                   'args' => 'XML_weird_ext.profile',\n                   'ref'  => '../tests/outputs/issues/456/XML_weird_ext.profile.yaml',\n               },\n               {\n                   'name' => 'ignore Algorithm::Diff::sdiff() failures, #463',\n                   'cd'   => '../tests/inputs/issues/463',\n                   'args' => '--diff left.C right.C',\n                   'ref'  => '../tests/outputs/issues/463/diff.yaml',\n               },\n               {\n                   'name' => 'diff list input format 1, #455',\n                   'cd'   => '../',\n                   'args' => '--diff-list-file tests/inputs/issues/455/list.txt',\n                   'ref'  => '../tests/outputs/issues/455/list.yaml',\n               },\n               {\n                   'name' => 'diff list input format 2, #455',\n                   'cd'   => '../',\n                   'args' => '--diff-list-file tests/inputs/issues/455/list_align.txt',\n                   'ref'  => '../tests/outputs/issues/455/list_align.yaml',\n               },\n               {\n                   'name' => 'replace_regex with null, #472',\n                   'cd'   => '../tests/inputs/issues/472',\n                   'args' => '--force-lang-def lua_def.txt not_really.lua',\n                   'ref'  => '../tests/outputs/issues/472/not_really.lua.yaml',\n               },\n               {\n                   'name' => '--exclude-lang --diff 1/3, #476',\n                   'cd'   => '../tests/inputs/issues/476',\n                   'args' => '--diff A B',\n                   'ref'  => '../tests/outputs/issues/476/all.yaml',\n               },\n               {\n                   'name' => '--exclude-lang --diff 2/3, #476',\n                   'cd'   => '../tests/inputs/issues/476',\n                   'args' => \"--exclude-lang 'Fortran 90' --diff A B\",\n                   'ref'  => '../tests/outputs/issues/476/no_fortran.yaml',\n               },\n               {\n                   'name' => '--exclude-lang --diff 3/3, #476',\n                   'cd'   => '../tests/inputs/issues/476',\n                   'args' => \"--exclude-lang C++ --diff A B\",\n                   'ref'  => '../tests/outputs/issues/476/no_cpp.yaml',\n               },\n               # Next test, 482, requires an empty directory B.  Git\n               # does not like this so create it at runtime.\n               {\n                   'name' => '--include-lang --diff, #482',\n                   'cd'   => '../tests/inputs/issues/482',\n                   'args' => '--include-lang C --diff A B',\n                   'ref'  => '../tests/outputs/issues/482/results.yaml',\n               },\n\n               {\n                   'name' => '--unicode #494',\n                   'cd'   => '../tests/inputs/issues/494',\n                   'args' => '--unicode --by-file P*.sql',\n                   'ref'  => '../tests/outputs/issues/494/results.yaml',\n               },\n\n               {\n                   'name' => '--diff-list-file #513',\n                   'cd'   => '../tests/inputs/issues/513',\n                   'args' => '--diff-list-file diff_list.txt',\n                   'ref'  => '../tests/outputs/issues/513/results.yaml',\n               },\n\n               {\n                   'name' => '--list-file BOM #502',\n                   'cd'   => '../tests/inputs/issues/502',\n                   'args' => '--list-file FileCounter20200715140433.txt',\n                   'ref'  => '../tests/outputs/issues/502/results.yaml',\n               },\n\n               {\n                   'name' => 'Julia with docstring as comment #520 1/2',\n                   'cd'   => '../tests/inputs/issues/520',\n                   'args' => 'julia_docstr.jl',\n                   'ref'  => '../tests/outputs/issues/520/doc_as_comment.yaml',\n               },\n\n               {\n                   'name' => 'Julia with docstring as comment #520 2/2',\n                   'cd'   => '../tests/inputs/issues/520',\n                   'args' => '--docstring-as-code julia_docstr.jl',\n                   'ref'  => '../tests/outputs/issues/520/doc_as_code.yaml',\n               },\n\n               {\n                   'name' => 'diff alignment on Windows #521 1/2',\n                   'cd'   => '../tests/inputs/issues/521',\n                   'args' => '--diff \"Test 188\" ../521/Test188New',\n                   'ref'  => '../tests/outputs/issues/521/uniq.yaml',\n               },\n\n               {\n                   'name' => 'diff alignment on Windows #521 2/2',\n                   'cd'   => '../tests/inputs/issues/521',\n                   'args' => '--skip-uniqueness --diff \"Test 188\" ../521/Test188New',\n                   'ref'  => '../tests/outputs/issues/521/skip_uniq.yaml',\n               },\n\n               {\n                   'name' => '--summary-cutoff (f:1) #528 1/3',\n                   'cd'   => '../tests/inputs/issues/528',\n                   'args' => '--summary-cutoff f:1 .',\n                   'ref'  => '../tests/outputs/issues/528/cutoff_files_1.yaml',\n               },\n\n               {\n                   'name' => '--summary-cutoff (c:10) #528 2/3',\n                   'cd'   => '../tests/inputs/issues/528',\n                   'args' => '--summary-cutoff c:10 .',\n                   'ref'  => '../tests/outputs/issues/528/cutoff_code_10.yaml',\n               },\n\n               {\n                   'name' => '--summary-cutoff (c:50%) #528 3/3',\n                   'cd'   => '../tests/inputs/issues/528',\n                   'args' => '--summary-cutoff c:50% .',\n                   'ref'  => '../tests/outputs/issues/528/cutoff_code_50pct.yaml',\n               },\n\n               {\n                   'name' => '--skip-leading 2 #530 1/4',\n                   'cd'   => '../tests/inputs/issues/530',\n                   'args' => '--skip-leading 2 .',\n                   'ref'  => '../tests/outputs/issues/530/case_1.yaml',\n               },\n\n               {\n                   'name' => '--skip-leading 100 #530 2/4',\n                   'cd'   => '../tests/inputs/issues/530',\n                   'args' => '--skip-leading 100 .',\n                   'ref'  => '../tests/outputs/issues/530/case_2.yaml',\n               },\n\n               {\n                   'name' => '--skip-leading 2,c,h #530 3/4',\n                   'cd'   => '../tests/inputs/issues/530',\n                   'args' => '--skip-leading 2,c,h .',\n                   'ref'  => '../tests/outputs/issues/530/case_3.yaml',\n               },\n\n               {\n                   'name' => '--skip-leading 2,C,H #530 4/4',\n                   'cd'   => '../tests/inputs/issues/530',\n                   'args' => '--skip-leading 2,C,H .',\n                   'ref'  => '../tests/outputs/issues/530/case_4.yaml',\n               },\n\n               {\n                   'name' => '--force-lang-def #537 1/2',\n                   'cd'   => '../tests/inputs/issues/537',\n                   'args' => '--force-lang-def my_define.txt sourceCounter.vsql',\n                   'ref'  => '../tests/outputs/issues/537/results_force.yaml',\n               },\n\n               {\n                   'name' => '--read-lang-def #537 2/2',\n                   'cd'   => '../tests/inputs/issues/537',\n                   'args' => '--read-lang-def my_define.txt sourceCounter.vsql',\n                   'ref'  => '../tests/outputs/issues/537/results_read.yaml',\n               },\n\n               {\n                   'name' => 'Elm empty comment, #538',\n                   'cd'   => '../tests/inputs/issues/538',\n                   'args' => 'add.elm',\n                   'ref'  => '../tests/outputs/issues/538/add.elm.yaml',\n               },\n\n               {\n                   'name' => 'Elm nested block comments, #539',\n                   'cd'   => '../tests/inputs/issues/539',\n                   'args' => 'nested_comments.elm',\n                   'ref'  => '../tests/outputs/issues/539/nested_comments.elm.yaml',\n               },\n\n               {\n                   'name' => 'preserve upper/lowercase filenames on Windows, #540',\n                   'cd'   => '../tests/inputs/issues/540',\n                   'args' => '--windows --by-file Hello.f',\n                   'ref'  => '../tests/outputs/issues/540/Hello.f.yaml',\n               },\n\n               {\n                   'name' => 'accept all file extensions in user-provided language definitions, #542',\n                   'cd'   => '../tests/inputs/issues/542',\n                   'args' => '--read-lang-def txt_lang_def.txtt txt_lang_def.txtt',\n                   'ref'  => '../tests/outputs/issues/542/results.yaml',\n               },\n\n               {\n                   'name' => 'small unicode files, #580',\n                   'cd'   => '../tests/inputs/issues/580',\n                   'args' => '--unicode encodingtest.cs',\n                   'ref'  => '../tests/outputs/issues/580/encodingtest.cs.yaml',\n               },\n\n               {\n                   'name' => 'identify autogenerated C#, #579',\n                   'cd'   => '../tests/inputs/issues/579',\n                   'args' => 'csharp-autogen.cs',\n                   'ref'  => '../tests/outputs/issues/579/csharp-autogen.cs.yaml',\n               },\n\n               {\n                   'name' => 'config file from list file directory, #577',\n                   'cd'   => '../tests/inputs/issues/577',\n                   'args' => '--diff-list-file diff_list_file.txt',\n                   'ref'  => '../tests/outputs/issues/577/diff_list.yaml',\n               },\n\n               {\n                   'name' => '--force-lang-def without XML definition, #596',\n                   'cd'   => '../tests/inputs/issues/596',\n                   'args' => '--force-lang-def def.txt .',\n                   'ref'  => '../tests/outputs/issues/596/results.yaml',\n               },\n\n               {\n                   'name' => '--csv-delimiter=\"#\", #597',\n                   'cd'   => '../tests/inputs/issues/597',\n                   'args' => '--csv-delimiter=\"#\" --exclude-lang=CSV hello.C',\n                   'ref'  => '../tests/outputs/issues/597/results.yaml',\n               },\n\n               {\n                   'name' => '--unicode (uninitialized value), #606',\n                   'cd'   => '../tests/inputs/issues/606',\n                   'args' => '--unicode in',\n                   'ref'  => '../tests/outputs/issues/606/results.yaml',\n               },\n\n               {\n                   'name' => 'CMakeLists.txt on Windows (lowercase file), #611',\n                   'cd'   => '../tests/inputs/issues/611',\n                   'args' => '.',\n                   'ref'  => '../tests/outputs/issues/611/cmakelists.txt.yaml',\n               },\n\n               {\n                   'name' => 'SCSS separate from Sass, #613',\n                   'cd'   => '../tests/inputs/issues/613',\n                   'args' => '.',\n                   'ref'  => '../tests/outputs/issues/613/nav.scss.yaml',\n               },\n\n               {\n                   'name' => 'sequence of Assembly filters, #619',\n                   'cd'   => '../tests/inputs/issues/619',\n                   'args' => '.',\n                   'ref'  => '../tests/outputs/issues/619/RA.s.yaml',\n               },\n\n               {\n                   'name' => 'GraphQL descriptions, #628',\n                   'cd'   => '../tests/inputs/issues/628',\n                   'args' => '.',\n                   'ref'  => '../tests/outputs/issues/628/results.yaml',\n               },\n\n               {\n                   'name' => 'diff with dir of excluded extensions, #625',\n                   'cd'   => '../tests/inputs/issues/625',\n                   'args' => '--diff old new',\n                   'ref'  => '../tests/outputs/issues/625/results.yaml',\n               },\n\n               {\n                   'name' => 'case insensitive --include-lang, #637',\n                   'cd'   => '../tests/inputs/issues/637',\n                   'args' => '--include-lang python,perl --follow-links A B',\n                   'ref'  => '../tests/outputs/issues/637/straight_incl_lang.yaml',\n               },\n\n               {\n                   'name' => 'case insensitive --include-lang --diff, #637',\n                   'cd'   => '../tests/inputs/issues/637',\n                   'args' => '--include-lang python,perl --follow-links --diff A B',\n                   'ref'  => '../tests/outputs/issues/637/diff_incl_lang.yaml',\n               },\n\n               {\n                   'name' => 'empty Unicode file w/only BOM, #644',\n                   'cd'   => '../tests/inputs/issues/644',\n                   'args' => 'UInt8.cs',\n                   'ref'  => '../tests/outputs/issues/644/results.yaml',\n               },\n\n               {\n                   'name' => '--no-recurse, #657',\n                   'cd'   => '../tests/inputs/issues/657',\n                   'args' => '--no-recurse .',\n                   'ref'  => '../tests/outputs/issues/657/results.yaml',\n               },\n\n               {\n                   'name' => '--csv-delimiter=\"|\", #670',\n                   'cd'   => '../tests/inputs/issues/670',\n                   'args' => '--csv-delimiter=\"|\" --exclude-lang=CSV hello.C hi.py',\n                   'ref'  => '../tests/outputs/issues/670/results.yaml',\n               },\n\n               {\n                   'name' => '--diff-list-files, #692',\n                   'cd'   => '../tests/inputs/issues/692',\n                   'args' => '--diff-list-files A.txt B.txt',\n                   'ref'  => '../tests/outputs/issues/692/results.yaml',\n               },\n\n               {\n                   'name' => 'comments in OCaml strings, #701',\n                   'cd'   => '../tests/inputs/issues/701',\n                   'args' => '--strip-str-comments demo.ml',\n                   'ref'  => '../tests/outputs/issues/701/results.yaml',\n               },\n\n               {\n                   'name' => '--only-count-files, #708',\n                   'cd'   => '../tests/inputs/dd',\n                   'args' => '--only-count-files .',\n                   'ref'  => '../tests/outputs/issues/708/results.yaml',\n               },\n\n               {\n                   'name' => '--diff-list-file w/unknown lang, #710',\n                   'cd'   => '../tests/inputs/issues/710',\n                   'args' => '--diff-list-file test_files.list',\n                   'ref'  => '../tests/outputs/issues/710/results.yaml',\n               },\n\n               {\n                   'name' => 'nondeterministic --diff, #712',\n                   'cd'   => '../tests/inputs/issues/712',\n                   'args' => \"--include-lang='C' --by-file --diff dir1/ dir2/\",\n                   'ref'  => '../tests/outputs/issues/712/results.yaml',\n               },\n\n               {\n                   'name' => '--hide-rate --yaml, #713',\n                   'cd'   => '../tests/inputs/issues/713',\n                   'args' => '--hide-rate --yaml .',\n                   'ref'  => '../tests/outputs/issues/713/results.yaml',\n               },\n\n               {\n                   'name' => '--include-content, #720',\n                   'cd'   => '../tests/inputs/issues/720',\n                   'args' => '--include-content=for --by-file ../../*.m',\n                   'ref'  => '../tests/outputs/issues/720/results.yaml',\n               },\n\n                {\n                    'name' => 'additive --not-match-f, #722',\n                    'cd'   => '../tests/inputs/issues/722',\n                    'args' => '--not-match-f lua --not-match-f 77 --by-file .',\n                    'ref'  => '../tests/outputs/issues/722/results_1.yaml',\n                },\n\n                {\n                    'name' => 'C# including autogenerated, #753',\n                    'cd'   => '../tests/inputs/issues/753',\n                    'args' => '.',\n                    'ref'  => '../tests/outputs/issues/753/all.yaml',\n                },\n\n                {\n                    'name' => '--exclude-list-file, #784',\n                    'cd'   => '../tests/inputs/issues/784',\n                    'args' => '--by-file --exclude-list-file=.cloc-ignore .',\n                    'ref'  => '../tests/outputs/issues/784/results.yaml',\n                },\n\n                {\n                    'name' => '--exclude-list-file, file path w/regex metacharacters, #785',\n                    'cd'   => '../tests/inputs/issues/785',\n                    'args' => '--exclude-list-file=.cloc-ignore .',\n                    'ref'  => '../tests/outputs/issues/785/results.yaml',\n                },\n\n                {\n                    'name' => '.inc as PHP, Pascal, or Fortran #781',\n                    'cd'   => '../tests/inputs/issues/781',\n                    'args' => '--by-file .',\n                    'ref'  => '../tests/outputs/issues/781/results.yaml',\n                },\n\n                {\n                    'name' => 'Java /* in string #804',\n                    'cd'   => '../tests/inputs/issues/804',\n                    'args' => 'infoSQL.java',\n                    'ref'  => '../tests/outputs/issues/804/infoSQL.java.yaml',\n                },\n\n                {\n                    'name' => 'comments in Java text blocks #805',\n                    'cd'   => '../tests/inputs/issues/805',\n                    'args' => 'text_block.java',\n                    'ref'  => '../tests/outputs/issues/805/text_block.java.yaml',\n                },\n\n                {\n                    'name' => 'Java text block start in comments #806',\n                    'cd'   => '../tests/inputs/issues/806',\n                    'args' => 'huffman.java',\n                    'ref'  => '../tests/outputs/issues/806/results.yaml',\n                },\n\n                {\n                    'name' => 'XML start block comment on line w/code #811',\n                    'cd'   => '../tests/inputs/issues/811',\n                    'args' => 'inline_comment.xml',\n                    'ref'  => '../tests/outputs/issues/811/inline_comment.xml.yaml',\n                },\n\n                {\n                    'name' => '\"*/*\", `*/*` in Go strings #816',\n                    'cd'   => '../tests/inputs/issues/816',\n                    'args' => '--strip-str-comments star_slash_star.go',\n                    'ref'  => '../tests/outputs/issues/816/results.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T1)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--fullpath --not-match-f \"^c.csv\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T1.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T2)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --fullpath --not-match-f \"^c.csv\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T2.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T3)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--fullpath --not-match-f \"b/c.csv\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T3.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T4)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --fullpath --not-match-f \"b/c.csv\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T4.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T5)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--fullpath --not-match-d \"^b\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T5.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T6)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --fullpath --not-match-d \"^b\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T6.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T7)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--fullpath --not-match-d \"a/b\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T7.yaml',\n                },\n\n                {\n                   'name' => '--fullpath issues/822 (github issue #822 T8)',\n                   'cd'   => '../tests/inputs',\n                   'args' => '--vcs git --fullpath --not-match-d \"a/b\" issues/822',\n                   'ref'  => '../tests/outputs/issues/822/T8.yaml',\n                },\n\n                {\n                   'name' => '--not-match-d with trailing slash (github issue #833)',\n                   'cd'   => '../tests/inputs/issues/833',\n                   'args' => '. --not-match-d=\"/foo/\"',\n                   'ref'  => '../tests/outputs/issues/833/results.yaml',\n                },\n\n                {\n                   'name' => '--match-f with --no-recurse (github issue #851)',\n                   'cd'   => '../tests/inputs/issues/851',\n                   'args' => \"--match-f '.lua\\$' --no-recurse level_1\",\n                   'ref'  => '../tests/outputs/issues/851/results.yaml',\n                },\n\n                {\n                   'name' => '--ignore-regex (github issues #862, #865, #868)',\n                   'cd'   => '../tests/inputs/issues/862',\n                   'args' => '--ignore-regex=\"C,Fortran 77|^\\\\s*([{};]|END)\\\\s*\\$\" *.f *.c',\n                   'ref'  => '../tests/outputs/issues/862/results.yaml',\n                },\n\n                {\n                   'name' => '--ignore-regex --diff (github issues #862, #865, #868)',\n                   'cd'   => '../tests/inputs/issues/862',\n                   'args' => '--ignore-regex=\"*|import\" --diff a.py b.py',\n                   'ref'  => '../tests/outputs/issues/862/diff_results.yaml',\n                },\n\n                # The filename tests/inputs/issues/898/irregular\"file2.md\n                # is not legal on Windows.  Only test it on Unix-like systems.\n                {\n                   'name' => '--by-file output for JSON/YAML with filenames having embedded quotes (#897, #898)',\n                   'cd'   => '../tests/inputs/issues/898',\n                   'args' => '--by-file .', # default is YAML\n                   'ref'  => '../tests/outputs/issues/898/results.yaml',\n                },\n\n                {\n                   'name' => '--percent (#886)',\n                   'cd'   => '../tests/inputs/dd',\n                   'args' => '--percent .',\n                   'ref'  => '../tests/outputs/issues/886/results.yaml',\n                },\n\n                {\n                   'name' => '--percent --by-file (#886)',\n                   'cd'   => '../tests/inputs/dd',\n                   'args' => '--percent --by-file .',\n                   'ref'  => '../tests/outputs/issues/886/results_by_file.yaml',\n                },\n\n                {\n                   'name' => 'Python docstring with embedded \"#\" (#906)',\n                   'cd'   => '../tests/inputs/issues/906',\n                   'args' => '--diff previous_version.py current_version.py',\n                   'ref'  => '../tests/outputs/issues/906/results.yaml',\n                },\n\n            );\n\nmy $ON_WINDOWS = 0;\n   $ON_WINDOWS = 1 if ($^O =~ /^MSWin/) or ($^O eq \"Windows_NT\");\nif ($ON_WINDOWS and $ENV{'SHELL'}) {\n    if ($ENV{'SHELL'} =~ m{^/}) {\n        $ON_WINDOWS = 0;  # make Cygwin look like Unix\n    } else {\n        $ON_WINDOWS = 1;  # MKS defines $SHELL but still acts like Windows\n    }\n}\nmy $ON_MINGW64 = 0; # git-bash on Windows has special needs\nif (!$ON_WINDOWS and defined $ENV{'SSH_ASKPASS'} and $ENV{'SSH_ASKPASS'} =~ m{^/mingw64/}) {\n    $ON_MINGW64 = 1;\n}\n\n# Special cases:\n\n# 132: Create test input which needs data not in the git repo.\n# Silently fail if file/dir already exists.\nmkdir \"../tests/inputs/issues/132/ignore_git\";\ncp    \"../tests/inputs/hi.py\", \"../tests/inputs/issues/132/ignore_git/\";\n\n# 898\nmake_898_weird_filename() unless $ON_WINDOWS;\n\n# Issues #540, #544 regarding case preservation on file systems\n# that are case insensitive:  git issues a warning about the\n# link hello.f -> Hello.f.  Per https://github.com/mitchblank,\n# remove it from git and make it at runtime.\nmy $work_dir = getcwd;\nchdir( \"../tests/inputs/issues/540/\" );\nsymlink(\"Hello.f\", \"hello.f\");\nchdir( $work_dir );\n\nmy $missing_dir = \"../tests/inputs/issues/482/B\";\nif (!-d $missing_dir) {\n    mkdir $missing_dir;\n}\n\nmy $Verbose = 0;\n\nmy $results = 'results.yaml';\nmy $cloc    = \"$work_dir/../cloc\";                 # all-purpose version\n   $cloc    = \"$work_dir/cloc\" if defined $opt{u}; # Unix-tuned version\nmy $Run = \"$cloc --quiet --yaml --out $results \";\nforeach my $t (@Tests) {\n    if ($t->{'name'} =~ /#898/ and $ON_WINDOWS) {\n        print \"Skipping test $t->{'name'} on Windows.\\n\";\n        next;\n    }\n    chdir($t->{'cd'}) if defined $t->{'cd'};\n    print \"Run  dir= \", cwd(), \"\\n\" if $Verbose;\n    print  $Run . $t->{'args'} if $Verbose;\n    system($Run . $t->{'args'});\n    ok(-e $results, $t->{'name'} . \" created output\");\n    my %this = load_yaml($results);\n    unlink $results unless $Verbose;\n    chdir($work_dir) if defined $t->{'cd'};\n    print \"Load dir= \", cwd(), \"\\n\" if $Verbose;\n    my %ref  = load_yaml($t->{'ref'});\n\n#   my $REF = LoadFile($t->{'ref'});  # using official YAML module\n#   is_deeply($REF , \\%this, $t->{'name'} . \" results match\");\n\n#   use Data::Dumper;\n#   print Dumper(\\%ref);\n#   print Dumper(\\%this);\n\n    is_deeply(\\%ref, \\%this, $t->{'name'} . \" results match\");\n}\ndone_testing();\nprint \"Finished testing $cloc\\n\";\n\nsub load_yaml { # {{{1\n    my ($file, ) = @_;\n    my %result = ();\n    if (!-r $file) {\n        warn \"File not found: $file\\n\";\n        return %result;\n    }\n    open IN, $file or return %result;\n    my $section = undef;\n    while (<IN>) {\n        next if /^\\s*#/ or /^--/;\n        if (/^\\s*'?(.*?)'?\\s*:\\s*$/) {\n            $section = $1;\n            next;\n        }\n        next unless defined $section;\n        next if $section eq 'header';\n        chomp;\n        s/\\s+//g;\n        my ($K, $V) = split(':');\n        $result{$section}{$K} = $V;\n    }\n    close IN;\n    return %result\n} # 1}}}\nsub make_898_weird_filename { # {{{1\n    my $parent_dir = \"../tests/inputs/issues/898\";\n    if (!-d $parent_dir) {\n        print \"Cannot find $parent_dir, skipping test 898.\\n\";\n        return 0;\n    }\n    my $weird_filename = 'irregular\"file2.md';\n    my $content = <<'EOF';\n---\nid: 5dc174fcf86c76b9248c6eb3\ntitle: Step 3\nchallengeType: 0\ndashedName: step-2\ndemoType: onLoad                                                                                                                 ---\n\n# --description--\n\nIn this workshop, you will learn how to work with basic HTML elements like\nheadings.\n\nEOF\n    open OUT , \">$parent_dir/$weird_filename\" or die \"Cannot write to  $weird_filename : $!\";\n    print OUT $content;\n    close OUT;\n\n    return 1;\n} # 1}}}\n"
  },
  {
    "path": "Unix/t/02_git.t",
    "content": "#!/usr/bin/env perl\nuse warnings;\nuse strict;\nuse Test::More;\nuse File::Copy \"cp\";\nuse Cwd;\nuse Getopt::Std;\nmy %opt;\ngetopts('u', \\%opt);  # -u to run Unix/cloc instead of ../cloc\nmy @Tests = (\n                {\n                    'name' => 'direct count git hash 1',\n                    'args' => 'd9b672643d',\n                    'ref'  => '../tests/outputs/git_tests/d9b672643d.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'direct count git hash 2',\n                    'args' => 'f647093e8be3',\n                    'ref'  => '../tests/outputs/git_tests/f647093e8be3.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'tar file f647093e8',\n                    'args' => '../../tests/inputs/git_tests/contents_f647093e8.tar.gz',\n                    'ref'  => '../tests/outputs/git_tests/contents_f647093e8.tar.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'diff f647093e8 to tar file f647093e8',\n                    'args' => '--git --diff f647093e8 ../../tests/inputs/git_tests/contents_f647093e8.tar.gz',\n                    'ref'  => '../tests/outputs/git_tests/diff_contents_f647093e8.tar.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'diff f15bf042b f647093e8b',\n                    'args' => '--git --diff f15bf042b f647093e8b',\n                    'ref'  => '../tests/outputs/git_tests/diff_f15bf042b_f647093e8b.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'diff commit with only deleted file',\n                    'args' => '--strip-str-comments --git --diff 04179b6 ae0d26e',\n                    'ref'  => '../tests/outputs/git_tests/04179b6_ae0d26e.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => 'diff commit with only added file',\n                    'args' => '--strip-str-comments --git --diff f15bf04 d9b6726',\n                    'ref'  => '../tests/outputs/git_tests/f15bf04_d9b6726.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                # cannot use HEAD~1 HEAD as the diff is not deterministic\n                {\n                    'name' => 'count and diff part I',\n                    'args' => '--strip-str-comments  --git --count-and-diff 3b359b4904 f647093e8be',\n                    'ref'  => '../tests/outputs/git_tests/count_and_diff.yaml.HEAD',\n                    'cd'   => 'cloc_submodule_test',\n                    'results'  => 'results.yaml.f647093e8be',\n                },\n\n                {\n                    'name' => 'count and diff part II',\n                    'args' => '--strip-str-comments  --git --count-and-diff 3b359b4904 f647093e8be',\n                    'ref'  => '../tests/outputs/git_tests/count_and_diff.yaml.HEAD~1',\n                    'cd'   => 'cloc_submodule_test',\n                    'results'  => 'results.yaml.3b359b4904',\n                },\n\n                {\n                    'name' => 'count and diff part III',\n                    'args' => '--strip-str-comments  --git --count-and-diff 3b359b4904 f647093e8be',\n                    'ref'  => '../tests/outputs/git_tests/count_and_diff.yaml.diff.HEAD~1.HEAD',\n                    'cd'   => 'cloc_submodule_test',\n                    'results'  => 'results.yaml.diff.3b359b4904.f647093e8be',\n                },\n\n                {\n                    'name' => 'file size filter with --vcs, #599',\n                    'args' => '--vcs=git --max-file-size 0.0001 .',\n                    'ref'  => '../tests/outputs/issues/599/results.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => '--git-diff-{rel,all} with --exclude-list-file, #735',\n                    'args' => '--exclude-list-file ../../tests/inputs/issues/735/excludes.txt --git --diff f15bf042b f647093e8b',\n                    'ref'  => '../tests/outputs/issues/735/results.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n                {\n                    'name' => '--vcs=git from non-git directory, #772',\n                    'args' => '--vcs=git cloc_submodule_test',\n                    'ref'  => '../tests/outputs/issues/772/results.yaml',\n                    'cd'   => '.',\n                },\n\n                {\n                    'name' => '--exclude-lang with --git --diff and all additions, #917',\n                    'args' => '--git --diff ../../tests/inputs/issues/917/empty.tar f647093e8b --exclude-lang=C',\n                    'ref'  => '../tests/outputs/issues/917/results.yaml',\n                    'cd'   => 'cloc_submodule_test',\n                },\n\n            );\n\nmy $Verbose = 0;\nmy $cloc;\n\nif (!-d 'cloc_submodule_test') {\n    print \"-\" x 79, \"\\n\";\n    print \"Directory 'cloc_submodule_test' is not found; git tests skipped.\\n\";\n    print \"To enable the tests, create the directory with\\n\";\n    print \"    git submodule add https://github.com/AlDanial/cloc_submodule_test.git\\n\";\n    ok( 0, \"git tests\");\n    print \"-\" x 79, \"\\n\";\n} else {\n    my $results  = 'results.yaml';\n    my $work_dir = getcwd;\n       $cloc     = \"$work_dir/../cloc\";                 # all-purpose version\n       $cloc     = \"$work_dir/cloc\" if defined $opt{u}; # Unix-tuned version\n\n    my $Run = \"$cloc --quiet --yaml --out $results \";\n    foreach my $t (@Tests) {\n        chdir($t->{'cd'}) if defined $t->{'cd'};\n        print  $Run . $t->{'args'} if $Verbose;\n        system($Run . $t->{'args'});\n        my %this = ();\n        if (defined $t->{'results'}) {\n            ok(-e $t->{'results'}, $t->{'name'} . \" created output\");\n            %this = load_yaml($t->{'results'});\n        } else {\n            ok(-e $results       , $t->{'name'} . \" created output\");\n            %this = load_yaml($results);\n        }\n        unlink $results;\n        chdir($work_dir) if defined $t->{'cd'};\n        my %ref  = load_yaml($t->{'ref'});\n\n        is_deeply(\\%ref, \\%this, $t->{'name'} . \" results match\");\n    }\n}\ndone_testing();\nprint \"Finished testing $cloc\\n\";\n\nsub load_yaml { # {{{1\n    my ($file, ) = @_;\n    my %result = ();\n    if (!-r $file) {\n        warn \"File not found: $file\\n\";\n        return %result;\n    }\n    open IN, $file or return %result;\n    my $section = undef;\n    while (<IN>) {\n        next if /^\\s*#/ or /^--/;\n        if (/^\\s*'?(.*?)'?\\s*:\\s*$/) {\n            $section = $1;\n            next;\n        }\n        next unless defined $section;\n        next if $section eq 'header';\n        chomp;\n        s/\\s+//g;\n        my ($K, $V) = split(':');\n        $result{$section}{$K} = $V;\n    }\n    close IN;\n    return %result\n} # 1}}}\n"
  },
  {
    "path": "Unix/why_this_directory_exists.txt",
    "content": "The contents of the cloc/Unix/ directory are intended for\ncloc package maintainers on distributions such as Ubuntu,\nDebian, Fedora, Gentoo, Mint, SUSE, FreeBSD, macOS.\n\nEach time cloc is released, the cloc executable in this\ndirectory is updated to the latest version, minus the\nbuilt-in installers for Rexexp::Common and\nAlgorithm::Diff code.  Instead this version of cloc will\nrely on the package definition to require these--as well\nas Digest::MD5--as dependencies.\n\nAlso included is Perl \"POD\" documentation that can be used\nto create a man page:\n  pod2man cloc.1.pod > cloc.1\n\n\nNote!  Updates are applied to this stripped down version of\ncloc only for packaged releases).  During development,\nthis version is not maintained.  Do not supply pull requests\nfor this file!  Only update the cloc in the parent directory.\n"
  },
  {
    "path": "cloc",
    "content": "#!/usr/bin/env perl\n# cloc -- Count Lines of Code                  {{{1\n# Copyright (C) 2006-2026 Al Danial <al.danial@gmail.com>\n# First release August 2006\n#\n# Includes code from:\n#   - SLOCCount v2.26\n#     http://www.dwheeler.com/sloccount/\n#     by David Wheeler.\n#   - Regexp::Common v2017060201\n#     https://metacpan.org/pod/Regexp::Common\n#     by Damian Conway and Abigail.\n#   - Win32::Autoglob 1.01\n#     https://metacpan.org/pod/Win32::Autoglob\n#     by Sean M. Burke.\n#   - Algorithm::Diff 1.1902\n#     https://metacpan.org/pod/Algorithm::Diff\n#     by Tye McQueen.\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# <http://www.gnu.org/licenses/gpl.txt>.\n#\n# 1}}}\nmy $VERSION = \"2.09\";  # odd number == beta; even number == stable\nmy $URL     = \"github.com/AlDanial/cloc\";  # 'https://' pushes header too wide\nrequire 5.10.0;\n# use modules                                  {{{1\nuse warnings;\nuse strict;\n\nuse Getopt::Long;\nuse File::Basename;\nuse File::Temp qw { tempfile tempdir };\nuse File::Find;\nuse File::Path;\nuse File::Spec;\nuse IO::File;\nuse List::Util qw( min max );\nuse Cwd;\nuse Encode qw( encode );\nuse POSIX qw { strftime ceil};\n# Parallel::ForkManager isn't in the standard distribution.\n# Use it only if installed, and only if --processes=N is given.\n# The module load happens in get_max_processes().\nmy $HAVE_Parallel_ForkManager = 0;\n\n# Digest::MD5 isn't in the standard distribution. Use it only if installed.\nmy $HAVE_Digest_MD5 = 0;\neval \"use Digest::MD5;\";\nif (defined $Digest::MD5::VERSION) {\n    $HAVE_Digest_MD5 = 1;\n} else {\n    warn \"Digest::MD5 not installed; will skip file uniqueness checks.\\n\";\n}\n\n# Time::HiRes became standard with Perl 5.8\nmy $HAVE_Time_HiRes = 0;\neval \"use Time::HiRes;\";\n$HAVE_Time_HiRes = 1 if defined $Time::HiRes::VERSION;\n\nmy $HAVE_Rexexp_Common;\n# Regexp::Common isn't in the standard distribution.  It will\n# be installed in a temp directory if necessary.\neval \"use Regexp::Common qw ( comment ) \";\nif (defined $Regexp::Common::VERSION) {\n    $HAVE_Rexexp_Common = 1;\n} else {\n    $HAVE_Rexexp_Common = 0;\n}\n\n# Uncomment next two lines when building Windows executable with perl2exe\n# or if running on a system that already has Regexp::Common.\n#use Regexp::Common;\n#$HAVE_Rexexp_Common = 1;\n\n#perl2exe_include \"Regexp/Common/whitespace.pm\"\n#perl2exe_include \"Regexp/Common/URI.pm\"\n#perl2exe_include \"Regexp/Common/URI/fax.pm\"\n#perl2exe_include \"Regexp/Common/URI/file.pm\"\n#perl2exe_include \"Regexp/Common/URI/ftp.pm\"\n#perl2exe_include \"Regexp/Common/URI/gopher.pm\"\n#perl2exe_include \"Regexp/Common/URI/http.pm\"\n#perl2exe_include \"Regexp/Common/URI/pop.pm\"\n#perl2exe_include \"Regexp/Common/URI/prospero.pm\"\n#perl2exe_include \"Regexp/Common/URI/news.pm\"\n#perl2exe_include \"Regexp/Common/URI/tel.pm\"\n#perl2exe_include \"Regexp/Common/URI/telnet.pm\"\n#perl2exe_include \"Regexp/Common/URI/tv.pm\"\n#perl2exe_include \"Regexp/Common/URI/wais.pm\"\n#perl2exe_include \"Regexp/Common/CC.pm\"\n#perl2exe_include \"Regexp/Common/SEN.pm\"\n#perl2exe_include \"Regexp/Common/number.pm\"\n#perl2exe_include \"Regexp/Common/delimited.pm\"\n#perl2exe_include \"Regexp/Common/profanity.pm\"\n#perl2exe_include \"Regexp/Common/net.pm\"\n#perl2exe_include \"Regexp/Common/zip.pm\"\n#perl2exe_include \"Regexp/Common/comment.pm\"\n#perl2exe_include \"Regexp/Common/balanced.pm\"\n#perl2exe_include \"Regexp/Common/lingua.pm\"\n#perl2exe_include \"Regexp/Common/list.pm\"\n#perl2exe_include \"File/Glob.pm\"\n\nuse Text::Tabs qw { expand };\nuse Cwd qw { cwd };\nuse File::Glob;\n# 1}}}\n# Usage information, options processing.       {{{1\nmy $ON_WINDOWS = 0;\n   $ON_WINDOWS = 1 if ($^O =~ /^MSWin/) or ($^O eq \"Windows_NT\");\nif ($ON_WINDOWS and $ENV{'SHELL'}) {\n    if ($ENV{'SHELL'} =~ m{^/}) {\n        $ON_WINDOWS = 0;  # make Cygwin look like Unix\n    } else {\n        $ON_WINDOWS = 1;  # MKS defines $SHELL but still acts like Windows\n    }\n}\nmy $ON_MINGW64 = 0; # git-bash on Windows has special needs\nif (!$ON_WINDOWS and defined $ENV{'SSH_ASKPASS'} and $ENV{'SSH_ASKPASS'} =~ m{^/mingw64/}) {\n    $ON_MINGW64 = 1;\n}\n\nuse Cwd \"abs_path\";\nuse File::Spec;\n# Fix for issues when runing cloc through a symlink on Windows\n# e.g. : it have been installed with Winget\n# See https://github.com/AlDanial/cloc/issues/849\nif ($ON_WINDOWS) {\n    my $exec_path = abs_path($0);\n    if (-l $0) {\n        $exec_path = abs_path(readlink($0));\n    }\n    $0 = $exec_path;\n}\n\nmy $HAVE_Win32_Long_Path = 0;\n# Win32::LongPath is an optional dependency that when available on\n# Windows will be used to support reading files past the 255 char\n# path length limit.\nif ($ON_WINDOWS) {\n    eval \"use Win32::LongPath;\";\n    if (defined $Win32::LongPath::VERSION) {\n        $HAVE_Win32_Long_Path = 1;\n    }\n}\nmy $config_file = '';\nif ( $ENV{'HOME'} ) {\n    $config_file = File::Spec->catfile( $ENV{'HOME'}, '.config', 'cloc', 'options.txt');\n} elsif ( $ENV{'APPDATA'} and $ON_WINDOWS ) {\n    $config_file = File::Spec->catfile( $ENV{'APPDATA'}, 'cloc');\n}\n# $config_file may be updated by check_alternate_config_files()\n\nmy $NN     = chr(27) . \"[0m\";  # normal\n   $NN     = \"\" if $ON_WINDOWS or !(-t STDOUT); # -t STDOUT:  is it a terminal?\nmy $BB     = chr(27) . \"[1m\";  # bold\n   $BB     = \"\" if $ON_WINDOWS or !(-t STDOUT);\nmy $script = basename $0;\n\n#  Intended for v1.88:\n#  --git-diff-simindex       Git diff strategy #3:  use git's similarity index\n#                            (git diff -M --name-status) to identify file pairs\n#                            to compare.  This is especially useful to compare\n#                            files that were renamed between the commits.\n\nmy $brief_usage = brief_usage();\nmy $usage  = long_usage();\n\n$| = 1;  # flush STDOUT\nmy $start_time = get_time();\nmy (\n    $opt_categorized          ,\n    $opt_found                ,\n    @opt_force_lang           ,\n    $opt_lang_no_ext          ,\n    @opt_script_lang          ,\n    $opt_count_diff           ,\n    $opt_diff                 ,\n    $opt_diff_alignment       ,\n    $opt_diff_list_file       ,\n    $opt_diff_list_files      ,\n    $opt_diff_timeout         ,\n    $opt_timeout              ,\n    $opt_html                 ,\n    $opt_ignored              ,\n    $opt_unique               ,\n    $opt_counted              ,\n    $opt_show_ext             ,\n    $opt_show_lang            ,\n    $opt_progress_rate        ,\n    $opt_print_filter_stages  ,\n    $opt_v                    ,\n    $opt_vcs                  ,\n    $opt_version              ,\n    $opt_include_submodules   ,\n    $opt_include_content      ,\n    $opt_exclude_content      ,\n    $opt_exclude_lang         ,\n    $opt_exclude_list_file    ,\n    $opt_exclude_dir          ,\n    $opt_explain              ,\n    $opt_include_ext          ,\n    $opt_include_lang         ,\n    $opt_force_lang_def       ,\n    $opt_read_lang_def        ,\n    $opt_write_lang_def       ,\n    $opt_write_lang_def_incl_dup,\n    $opt_strip_code           ,\n    $opt_strip_comments       ,\n    $opt_original_dir         ,\n    $opt_quiet                ,\n    $opt_report_file          ,\n    $opt_sdir                 ,\n    $opt_sum_reports          ,\n    $opt_hide_rate            ,\n    $opt_processes            ,\n    $opt_unicode              ,\n    $opt_no3                  ,   # accept it but don't use it\n    $opt_3                    ,\n    $opt_extract_with         ,\n    $opt_by_file              ,\n    $opt_by_file_by_lang      ,\n    $opt_by_percent           ,\n    $opt_percent              ,\n    $opt_xml                  ,\n    $opt_xsl                  ,\n    $opt_yaml                 ,\n    $opt_csv                  ,\n    $opt_csv_delimiter        ,\n    $opt_fullpath             ,\n    $opt_json                 ,\n    $opt_md                   ,\n    $opt_match_f              ,\n    @opt_not_match_f          ,\n    $opt_match_d              ,\n    @opt_not_match_d          ,\n    $opt_skip_uniqueness      ,\n    $opt_list_file            ,\n    $opt_help                 ,\n    $opt_skip_win_hidden      ,\n    $opt_read_binary_files    ,\n    $opt_sql                  ,\n    $opt_sql_append           ,\n    $opt_sql_project          ,\n    $opt_sql_style            ,\n    $opt_inline               ,\n    $opt_exclude_ext          ,\n    $opt_ignore_whitespace    ,\n    $opt_ignore_case          ,\n    $opt_ignore_case_ext      ,\n    @opt_ignore_regex         ,\n    $opt_follow_links         ,\n    $opt_autoconf             ,\n    $opt_sum_one              ,\n    $opt_stdin_name           ,\n    $opt_force_on_windows     ,\n    $opt_force_on_unix        ,   # actually forces !$ON_WINDOWS\n    $opt_show_os              ,\n    $opt_skip_archive         ,\n    $opt_max_file_size        ,   # in MB\n    $opt_use_sloccount        ,\n    $opt_no_autogen           ,\n    $opt_force_git            ,\n    $opt_git_diff_rel         ,\n    $opt_git_diff_all         ,\n    $opt_git_diff_simindex    ,\n    $opt_config_file          ,\n    $opt_strip_str_comments   ,\n    $opt_file_encoding        ,\n    $opt_docstring_as_code    ,\n    $opt_stat                 ,\n    $opt_summary_cutoff       ,\n    $opt_skip_leading         ,\n    $opt_no_recurse           ,\n    $opt_only_count_files     ,\n    $opt_fmt                  ,\n    $opt_encoding             ,\n    $opt_txt                  ,  # not associated with a command line option\n    $opt_thousands_delimiter  ,\n    $opt_show_errors          ,\n   );\n\nmy $getopt_success = GetOptions(             # {{{1\n   \"by_file|by-file\"                         => \\$opt_by_file             ,\n   \"by_file_by_lang|by-file-by-lang\"         => \\$opt_by_file_by_lang     ,\n   \"categorized=s\"                           => \\$opt_categorized         ,\n   \"counted=s\"                               => \\$opt_counted             ,\n   \"include_ext|include-ext=s\"               => \\$opt_include_ext         ,\n   \"include_lang|include-lang=s\"             => \\$opt_include_lang        ,\n   \"include_content|include-content=s\"       => \\$opt_include_content     ,\n   \"exclude_content|exclude-content=s\"       => \\$opt_exclude_content     ,\n   \"exclude_lang|exclude-lang=s\"             => \\$opt_exclude_lang        ,\n   \"exclude_dir|exclude-dir=s\"               => \\$opt_exclude_dir         ,\n   \"exclude_list_file|exclude-list-file=s\"   => \\$opt_exclude_list_file   ,\n   \"explain=s\"                               => \\$opt_explain             ,\n   \"extract_with|extract-with=s\"             => \\$opt_extract_with        ,\n   \"found=s\"                                 => \\$opt_found               ,\n   \"count_and_diff|count-and-diff\"           => \\$opt_count_diff          ,\n   \"diff\"                                    => \\$opt_diff                ,\n   \"diff-alignment|diff_alignment=s\"         => \\$opt_diff_alignment      ,\n   \"diff-timeout|diff_timeout=i\"             => \\$opt_diff_timeout        ,\n   \"diff-list-file|diff_list_file=s\"         => \\$opt_diff_list_file      ,\n   \"diff-list-files|diff_list_files\"         => \\$opt_diff_list_files     ,\n   \"timeout=i\"                               => \\$opt_timeout             ,\n   \"html\"                                    => \\$opt_html                ,\n   \"ignored=s\"                               => \\$opt_ignored             ,\n   \"unique=s\"                                => \\$opt_unique             ,\n   \"quiet\"                                   => \\$opt_quiet               ,\n   \"force_lang_def|force-lang-def=s\"         => \\$opt_force_lang_def      ,\n   \"read_lang_def|read-lang-def=s\"           => \\$opt_read_lang_def       ,\n   \"show_ext|show-ext:s\"                     => \\$opt_show_ext            ,\n   \"show_lang|show-lang:s\"                   => \\$opt_show_lang           ,\n   \"progress_rate|progress-rate=i\"           => \\$opt_progress_rate       ,\n   \"print_filter_stages|print-filter-stages\" => \\$opt_print_filter_stages ,\n   \"report_file|report-file=s\"               => \\$opt_report_file         ,\n   \"out=s\"                                   => \\$opt_report_file         ,\n   \"script_lang|script-lang=s\"               => \\@opt_script_lang         ,\n   \"sdir=s\"                                  => \\$opt_sdir                ,\n   \"skip_uniqueness|skip-uniqueness\"         => \\$opt_skip_uniqueness     ,\n   \"strip_code|strip-code=s\"                 => \\$opt_strip_code          ,\n   \"strip_comments|strip-comments=s\"         => \\$opt_strip_comments      ,\n   \"original_dir|original-dir\"               => \\$opt_original_dir        ,\n   \"sum_reports|sum-reports\"                 => \\$opt_sum_reports         ,\n   \"hide_rate|hide-rate\"                     => \\$opt_hide_rate           ,\n   \"processes=n\"                             => \\$opt_processes           ,\n   \"unicode\"                                 => \\$opt_unicode             ,\n   \"no3\"                                     => \\$opt_no3                 ,  # ignored\n   \"3\"                                       => \\$opt_3                   ,\n   \"v|verbose:i\"                             => \\$opt_v                   ,\n   \"vcs=s\"                                   => \\$opt_vcs                 ,\n   \"files-from=s\"                            => \\$opt_vcs                 ,  # synonym\n   \"include-submodules\"                      => \\$opt_include_submodules  ,\n   \"version\"                                 => \\$opt_version             ,\n   \"write_lang_def|write-lang-def=s\"         => \\$opt_write_lang_def      ,\n   \"write_lang_def_incl_dup|write-lang-def-incl-dup=s\" => \\$opt_write_lang_def_incl_dup,\n   \"xml\"                                     => \\$opt_xml                 ,\n   \"xsl=s\"                                   => \\$opt_xsl                 ,\n   \"force_lang|force-lang=s\"                 => \\@opt_force_lang          ,\n   \"lang_no_ext|lang-no-ext=s\"               => \\$opt_lang_no_ext         ,\n   \"yaml\"                                    => \\$opt_yaml                ,\n   \"csv\"                                     => \\$opt_csv                 ,\n   \"csv_delimiter|csv-delimiter=s\"           => \\$opt_csv_delimiter       ,\n   \"json\"                                    => \\$opt_json                ,\n   \"md\"                                      => \\$opt_md                  ,\n   \"fullpath\"                                => \\$opt_fullpath            ,\n   \"match_f|match-f=s\"                       => \\$opt_match_f             ,\n   \"not_match_f|not-match-f=s\"               => \\@opt_not_match_f         ,\n   \"match_d|match-d=s\"                       => \\$opt_match_d             ,\n   \"not_match_d|not-match-d=s\"               => \\@opt_not_match_d         ,\n   \"list_file|list-file=s\"                   => \\$opt_list_file           ,\n   \"help\"                                    => \\$opt_help                ,\n   \"skip_win_hidden|skip-win-hidden\"         => \\$opt_skip_win_hidden     ,\n   \"read_binary_files|read-binary-files\"     => \\$opt_read_binary_files   ,\n   \"sql=s\"                                   => \\$opt_sql                 ,\n   \"sql_project|sql-project=s\"               => \\$opt_sql_project         ,\n   \"sql_append|sql-append\"                   => \\$opt_sql_append          ,\n   \"sql_style|sql-style=s\"                   => \\$opt_sql_style           ,\n   \"inline\"                                  => \\$opt_inline              ,\n   \"exclude_ext|exclude-ext=s\"               => \\$opt_exclude_ext         ,\n   \"ignore_whitespace|ignore-whitespace\"     => \\$opt_ignore_whitespace   ,\n   \"ignore_case|ignore-case\"                 => \\$opt_ignore_case         ,\n   \"ignore_case_ext|ignore-case-ext\"         => \\$opt_ignore_case_ext     ,\n   \"ignore_regex|ignore-regex=s\"             => \\@opt_ignore_regex        ,\n   \"follow_links|follow-links\"               => \\$opt_follow_links        ,\n   \"autoconf\"                                => \\$opt_autoconf            ,\n   \"sum_one|sum-one\"                         => \\$opt_sum_one             ,\n   \"percent\"                                 => \\$opt_percent             ,\n   \"by_percent|by-percent=s\"                 => \\$opt_by_percent          ,\n   \"stdin_name|stdin-name=s\"                 => \\$opt_stdin_name          ,\n   \"windows\"                                 => \\$opt_force_on_windows    ,\n   \"unix\"                                    => \\$opt_force_on_unix       ,\n   \"show_os|show-os\"                         => \\$opt_show_os             ,\n   \"skip_archive|skip-archive=s\"             => \\$opt_skip_archive        ,\n   \"max_file_size|max-file-size=f\"           => \\$opt_max_file_size       ,\n   \"use_sloccount|use-sloccount\"             => \\$opt_use_sloccount       ,\n   \"no_autogen|no-autogen\"                   => \\$opt_no_autogen          ,\n   \"git\"                                     => \\$opt_force_git           ,\n   \"git_diff_rel|git-diff-rel\"               => \\$opt_git_diff_rel        ,\n   \"git_diff_all|git-diff-all\"               => \\$opt_git_diff_all        ,\n#  \"git_diff_simindex|git-diff-simindex\"     => \\$opt_git_diff_simindex   ,\n   \"config=s\"                                => \\$opt_config_file         ,\n   \"strip_str_comments|strip-str-comments\"   => \\$opt_strip_str_comments  ,\n   \"file_encoding|file-encoding=s\"           => \\$opt_file_encoding       ,\n   \"docstring_as_code|docstring-as-code\"     => \\$opt_docstring_as_code   ,\n   \"stat\"                                    => \\$opt_stat                ,\n   \"summary_cutoff|summary-cutoff=s\"         => \\$opt_summary_cutoff      ,\n   \"skip_leading|skip-leading:s\"             => \\$opt_skip_leading        ,\n   \"no_recurse|no-recurse\"                   => \\$opt_no_recurse          ,\n   \"only_count_files|only-count-files\"       => \\$opt_only_count_files    ,\n   \"fmt=i\"                                   => \\$opt_fmt                 ,\n   \"encoding=s\"                              => \\$opt_encoding            , # not production ready #880\n   \"ksep|thousands-delimiter=s\"              => \\$opt_thousands_delimiter ,\n   \"show-errors\"                             => \\$opt_show_errors         ,\n  );\n$opt_txt = 0;\nmy $tmp_file_to_delete = \"\";\n# 1}}}\n$config_file = $opt_config_file if defined $opt_config_file;\nload_from_config_file($config_file,          # {{{2\n                                                \\$opt_by_file             ,\n                                                \\$opt_by_file_by_lang     ,\n                                                \\$opt_categorized         ,\n                                                \\$opt_counted             ,\n                                                \\$opt_include_ext         ,\n                                                \\$opt_include_lang        ,\n                                                \\$opt_include_content     ,\n                                                \\$opt_exclude_content     ,\n                                                \\$opt_exclude_lang        ,\n                                                \\$opt_exclude_dir         ,\n                                                \\$opt_exclude_list_file   ,\n                                                \\$opt_explain             ,\n                                                \\$opt_extract_with        ,\n                                                \\$opt_found               ,\n                                                \\$opt_count_diff          ,\n                                                \\$opt_diff_list_files     ,\n                                                \\$opt_diff                ,\n                                                \\$opt_diff_alignment      ,\n                                                \\$opt_diff_timeout        ,\n                                                \\$opt_timeout             ,\n                                                \\$opt_html                ,\n                                                \\$opt_ignored             ,\n                                                \\$opt_unique              ,\n                                                \\$opt_quiet               ,\n                                                \\$opt_force_lang_def      ,\n                                                \\$opt_read_lang_def       ,\n                                                \\$opt_show_ext            ,\n                                                \\$opt_show_lang           ,\n                                                \\$opt_progress_rate       ,\n                                                \\$opt_print_filter_stages ,\n                                                \\$opt_report_file         ,\n                                                \\@opt_script_lang         ,\n                                                \\$opt_sdir                ,\n                                                \\$opt_skip_uniqueness     ,\n                                                \\$opt_strip_code          ,\n                                                \\$opt_strip_comments      ,\n                                                \\$opt_original_dir        ,\n                                                \\$opt_sum_reports         ,\n                                                \\$opt_hide_rate           ,\n                                                \\$opt_processes           ,\n                                                \\$opt_unicode             ,\n                                                \\$opt_3                   ,\n                                                \\$opt_v                   ,\n                                                \\$opt_vcs                 ,\n                                                \\$opt_include_submodules  ,\n                                                \\$opt_version             ,\n                                                \\$opt_write_lang_def      ,\n                                                \\$opt_write_lang_def_incl_dup,\n                                                \\$opt_xml                 ,\n                                                \\$opt_xsl                 ,\n                                                \\@opt_force_lang          ,\n                                                \\$opt_lang_no_ext         ,\n                                                \\$opt_yaml                ,\n                                                \\$opt_csv                 ,\n                                                \\$opt_csv_delimiter       ,\n                                                \\$opt_json                ,\n                                                \\$opt_md                  ,\n                                                \\$opt_fullpath            ,\n                                                \\$opt_match_f             ,\n                                                \\@opt_not_match_f         ,\n                                                \\$opt_match_d             ,\n                                                \\@opt_not_match_d         ,\n                                                \\$opt_list_file           ,\n                                                \\$opt_help                ,\n                                                \\$opt_skip_win_hidden     ,\n                                                \\$opt_read_binary_files   ,\n                                                \\$opt_sql                 ,\n                                                \\$opt_sql_project         ,\n                                                \\$opt_sql_append          ,\n                                                \\$opt_sql_style           ,\n                                                \\$opt_inline              ,\n                                                \\$opt_exclude_ext         ,\n                                                \\$opt_ignore_whitespace   ,\n                                                \\$opt_ignore_case         ,\n                                                \\$opt_ignore_case_ext     ,\n                                                \\@opt_ignore_regex        ,\n                                                \\$opt_follow_links        ,\n                                                \\$opt_autoconf            ,\n                                                \\$opt_sum_one             ,\n                                                \\$opt_by_percent          ,\n                                                \\$opt_stdin_name          ,\n                                                \\$opt_force_on_windows    ,\n                                                \\$opt_force_on_unix       ,\n                                                \\$opt_show_os             ,\n                                                \\$opt_skip_archive        ,\n                                                \\$opt_max_file_size       ,\n                                                \\$opt_use_sloccount       ,\n                                                \\$opt_no_autogen          ,\n                                                \\$opt_force_git           ,\n                                                \\$opt_strip_str_comments  ,\n                                                \\$opt_file_encoding       ,\n                                                \\$opt_docstring_as_code   ,\n                                                \\$opt_stat                ,\n                                                \\$opt_thousands_delimiter ,\n                                                \\$opt_show_errors         ,\n);  # 2}}} Not pretty.  Not at all.\nif ($opt_version) {\n    printf \"$VERSION\\n\";\n    exit;\n}\nmy $opt_git = 0;\n$opt_git = 1 if defined($opt_git_diff_all) or\n                defined($opt_git_diff_rel) or\n                (defined($opt_vcs) and ($opt_vcs eq \"git\"));\n$opt_by_file  = 1 if defined  $opt_by_file_by_lang;\n$opt_fmt = 0 unless defined $opt_fmt;\nif ($opt_fmt) {\n    $opt_by_file = 1;\n    $opt_json = 1;\n}\nmy $CLOC_XSL = \"cloc.xsl\"; # created with --xsl\n   $CLOC_XSL = \"cloc-diff.xsl\" if $opt_diff;\ndie \"\\n\" unless $getopt_success;\nprint $usage and exit if $opt_help;\nmy %Exclude_Language = ();\n   %Exclude_Language = map { $_ => 1 } split(/,/, $opt_exclude_lang)\n        if $opt_exclude_lang;\nmy %Exclude_Dir      = ();\n   %Exclude_Dir      = map { $_ => 1 } split(/,/, $opt_exclude_dir )\n        if $opt_exclude_dir ;\ndie unless exclude_dir_validates(\\%Exclude_Dir);\nmy %Include_Ext = ();\n   %Include_Ext = map { $_ => 1 } split(/,/, $opt_include_ext)\n        if $opt_include_ext;\nmy %Include_Language = (); # keys are lower case language names\n   %Include_Language = map { lc($_) => 1 } split(/,/, $opt_include_lang)\n        if $opt_include_lang;\n# Forcibly exclude .svn, .cvs, .hg, .git, .bzr directories.  The contents of these\n# directories often conflict with files of interest.\n$opt_exclude_dir       = 1;\n$Exclude_Dir{\".svn\"}   = 1;\n$Exclude_Dir{\".cvs\"}   = 1;\n$Exclude_Dir{\".hg\"}    = 1;\n$Exclude_Dir{\".git\"}   = 1;\n$Exclude_Dir{\".bzr\"}   = 1;\n$Exclude_Dir{\".snapshot\"} = 1;  # NetApp backups\n$Exclude_Dir{\".config\"} = 1;\n$Exclude_Dir{\".venv\"}  = 1; # Python virtual environment\n$opt_count_diff        = defined $opt_count_diff ? 1 : 0;\n$opt_diff              = 1  if $opt_diff_alignment    or\n                               $opt_diff_list_file    or\n                               $opt_diff_list_files   or\n                               $opt_git_diff_rel      or\n                               $opt_git_diff_all      or\n                               $opt_git_diff_simindex;\n$opt_force_git         = 1  if $opt_git_diff_rel      or\n                               $opt_git_diff_all      or\n                               $opt_git_diff_simindex;\n$opt_diff_alignment    = 0  if $opt_diff_list_file;\n$opt_exclude_ext       = \"\" unless $opt_exclude_ext;\n$opt_ignore_whitespace = 0  unless $opt_ignore_whitespace;\n$opt_ignore_case       = 0  unless $opt_ignore_case;\n$opt_ignore_case_ext   = 0  unless $opt_ignore_case_ext;\nmy %ignore_regex       = ();\n$opt_lang_no_ext       = 0  unless $opt_lang_no_ext;\n$opt_follow_links      = 0  unless $opt_follow_links;\nif (defined $opt_diff_timeout) {\n    # if defined but with a value of <= 0, set to 2^31-1 seconds = 68 years\n    $opt_diff_timeout = 2**31-1 unless $opt_diff_timeout > 0;\n} else {\n    $opt_diff_timeout  =10; # seconds\n}\n$opt_thousands_delimiter = 0 unless defined $opt_thousands_delimiter;\nif (defined $opt_timeout) {\n    # if defined but with a value of <= 0, set to 2^31-1 seconds = 68 years\n    $opt_timeout = 2**31-1 unless $opt_timeout > 0;\n    # else is computed dynamically, ref $max_duration_sec\n}\n$opt_csv               = 0  unless defined $opt_csv;\n$opt_csv               = 1  if $opt_csv_delimiter;\n$ON_WINDOWS            = 1  if $opt_force_on_windows;\n$ON_WINDOWS            = 0  if $opt_force_on_unix;\n$opt_max_file_size     = 100 unless $opt_max_file_size;\nmy $HAVE_SLOCCOUNT_c_count = 0;\nif (!$ON_WINDOWS and $opt_use_sloccount) {\n    # Only bother doing this kludgey test is user explicitly wants\n    # to use SLOCCount.  Debian based systems will hang if just doing\n    #  external_utility_exists(\"c_count\")\n    # if c_count is in $PATH; c_count expects to have input.\n    $HAVE_SLOCCOUNT_c_count = external_utility_exists(\"c_count /bin/sh\");\n}\nif ($opt_use_sloccount) {\n    if (!$HAVE_SLOCCOUNT_c_count) {\n        warn \"c_count could not be found; ignoring --use-sloccount\\n\";\n        $opt_use_sloccount = 0;\n    } else {\n        warn \"Using c_count, php_count, xml_count, pascal_count from SLOCCount\\n\";\n        warn \"--diff is disabled with --use-sloccount\\n\" if $opt_diff;\n        warn \"--count-and-diff is disabled with --use-sloccount\\n\" if $opt_count_diff;\n        warn \"--unicode is disabled with --use-sloccount\\n\" if $opt_unicode;\n        warn \"--strip-comments is disabled with --use-sloccount\\n\" if $opt_strip_comments;\n        warn \"--strip-code is disabled with --use-sloccount\\n\" if $opt_strip_code;\n        $opt_diff           = 0;\n        $opt_count_diff     = undef;\n        $opt_unicode        = 0;\n        $opt_strip_comments = 0;\n        $opt_strip_code     = 0;\n    }\n}\ndie \"--strip-comments and --strip-code are mutually exclusive\\n\" if\n    $opt_strip_comments and $opt_strip_code;\n$opt_vcs = 0 if $opt_force_git;\n\n# replace Windows path separators with /\nif ($ON_WINDOWS) {\n    map { s{\\\\}{/}g } @ARGV;\n    if ($opt_git) {\n        # PowerShell tab expansion automatically prefixes local directories\n        # with \".\\\" (now mapped to \"./\").   git ls-files output does not\n        # include this.  Strip this prefix to permit clean matches.\n        map { s{^\\./}{} } @ARGV;\n    }\n}\n\nmy @COUNT_DIFF_ARGV        = undef;\nmy $COUNT_DIFF_report_file = undef;\nif ($opt_count_diff and !$opt_diff_list_file) {\n    die \"--count-and-diff requires two arguments; got \", scalar @ARGV, \"\\n\"\n        if scalar @ARGV != 2;\n    # prefix with a dummy term so that $opt_count_diff is the\n    # index into @COUNT_DIFF_ARGV to work on at each pass\n    @COUNT_DIFF_ARGV = (undef, $ARGV[0],\n                               $ARGV[1],\n                              [$ARGV[0], $ARGV[1]]);  # 3rd pass: diff them\n    $COUNT_DIFF_report_file = $opt_report_file if $opt_report_file;\n}\n\n# Options defaults:\n$opt_quiet         =   1 if ($opt_md or $opt_json or !(-t STDOUT))\n                            and !defined $opt_report_file;\n$opt_progress_rate = 100 unless defined $opt_progress_rate;\n$opt_progress_rate =   0 if     defined $opt_quiet;\nif (!defined $opt_v) {\n    $opt_v  = 0;\n} elsif (!$opt_v) {\n    $opt_v  = 1;\n}\nif (defined $opt_xsl) {\n    $opt_xsl = $CLOC_XSL if $opt_xsl eq \"1\";\n    $opt_xml = 1;\n}\nmy $skip_generate_report = 0;\n$opt_sql_style = 0 unless defined $opt_sql_style;\n$opt_sql = 0 unless $opt_sql_style or defined $opt_sql;\nif ($opt_sql eq \"-\" || $opt_sql eq \"1\") { # stream SQL output to STDOUT\n    $opt_quiet            = 1;\n    $skip_generate_report = 1;\n    $opt_by_file          = 1;\n    $opt_sum_reports      = 0;\n    $opt_progress_rate    = 0;\n} elsif ($opt_sql)  { # write SQL output to a file\n    $opt_by_file          = 1;\n    $skip_generate_report = 1;\n    $opt_sum_reports      = 0;\n}\nif ($opt_sql_style) {\n    $opt_sql_style = lc $opt_sql_style;\n    if (!grep { lc $_ eq $opt_sql_style } qw ( Oracle Named_Columns )) {\n        die \"'$opt_sql_style' is not a recognized SQL style.\\n\";\n    }\n}\n$opt_by_percent = '' unless defined $opt_by_percent;\nif ($opt_by_percent and $opt_by_percent !~ m/^(c|cm|cb|cmb|t)$/i) {\n    die \"--by-percent must be either 'c', 'cm', 'cb', 'cmb', or 't'\\n\";\n}\n$opt_by_percent = lc $opt_by_percent;\n$opt_by_percent = 't' if $opt_percent;\n\n$opt_txt = 1 if $opt_report_file;\nmy $N_OUTPUT_FORMATS = 0;\nmy %OUTFILE_EXT      = (\n    \"txt\"  => $opt_txt ,\n    \"csv\"  => $opt_csv ,\n    \"xml\"  => 0        ,\n    \"yaml\" => 0        ,\n    \"json\" => 0        ,\n    \"md\"   => 0        ,\n);\n$OUTFILE_EXT{\"xml\" } = 1 if defined($opt_xml );\n$OUTFILE_EXT{\"yaml\"} = 1 if defined($opt_yaml);\n$OUTFILE_EXT{\"json\"} = 1 if defined($opt_json);\n$OUTFILE_EXT{\"md\"  } = 1 if defined($opt_md  );\n# $OUTFILE_EXT{\"sql\" } = 1 if defined($opt_sql ); # doesn't work; --sql needs an argument\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    ++$N_OUTPUT_FORMATS if $OUTFILE_EXT{$out_style};\n}\nif ($N_OUTPUT_FORMATS >= 2 and $OUTFILE_EXT{\"txt\"}) {\n    --$N_OUTPUT_FORMATS;\n    $OUTFILE_EXT{\"txt\"} = 0;\n}\nif (!$N_OUTPUT_FORMATS) {\n    $N_OUTPUT_FORMATS = 1;\n    $OUTFILE_EXT{\"txt\"} = 1;\n    $opt_txt = 1;\n}\n\nif (defined $opt_vcs) {\n    if ($opt_vcs eq \"auto\") {\n        if      (is_dir(\".git\")) {\n            $opt_vcs = \"git\";\n        } elsif (is_dir(\".svn\")) {\n            $opt_vcs = \"svn\";\n        } else {\n            warn \"--vcs auto:  unable to determine versioning system\\n\";\n        }\n    }\n    if      ($opt_vcs eq \"git\") {\n        $opt_vcs = \"git -c \\\"safe.directory=*\\\" ls-files\";\n        $opt_vcs .= \" --recurse-submodules\" if $opt_include_submodules;\n        my @submodules = invoke_generator(\"git -c \\\"safe.directory=*\\\" submodule status\", \\@ARGV);\n        foreach my $SM (@submodules) {\n            $SM =~ s/^\\s+//;        # may have leading space\n            $SM =~ s/\\(\\S+\\)\\s*$//; # may end with something like (heads/master)\n            my ($checksum, $dir) = split(' ', $SM, 2);\n            $dir =~ s/\\s+$//;\n            $Exclude_Dir{$dir} = 1;\n        }\n    } elsif ($opt_vcs eq \"svn\") {\n        $opt_vcs = \"svn list -R\";\n    }\n}\n\nmy $list_no_autogen = 0;\nif (defined $opt_no_autogen and scalar @ARGV == 1 and $ARGV[0] eq \"list\") {\n    $list_no_autogen = 1;\n}\nif ($opt_summary_cutoff) {\n    my $error = summary_cutoff_error($opt_summary_cutoff);\n    die \"$error\\n\" if $error;\n}\n\nif (!$opt_config_file) {\n    # if not explicitly given, look for a config file in other\n    # possible locations\n    my $other_loc = check_alternate_config_files($opt_list_file,\n        $opt_exclude_list_file, $opt_read_lang_def, $opt_force_lang_def,\n        $opt_diff_list_file);\n    $opt_config_file = $other_loc if $other_loc;\n}\n\n# --match-d and --not-match-d: if end with a trailing slash, update the\n# regex to be either slash or end of line since File::Find::find() will\n# not see the trailing slash in leaf directories (#732, #833).\nif ($opt_match_d and $opt_match_d =~ m{/$}) {\n    $opt_match_d =~ s{/$}{(/|\\$)};\n}\nforeach my $nmd (@opt_not_match_d) {\n    if ($nmd =~ m{/$}) {\n        $nmd =~ s{/$}{(/|\\$)};\n    }\n}\n\ndie $brief_usage unless defined $opt_version         or\n                        defined $opt_show_lang       or\n                        defined $opt_show_ext        or\n                        defined $opt_show_os         or\n                        defined $opt_write_lang_def  or\n                        defined $opt_write_lang_def_incl_dup  or\n                        defined $opt_list_file       or\n                        defined $opt_diff_list_file  or\n                        defined $opt_vcs             or\n                        defined $opt_xsl             or\n                        defined $opt_explain         or\n                        $list_no_autogen             or\n                        scalar @ARGV >= 1;\nif (!$opt_diff_list_file) {\n    die \"--diff requires two arguments; got \", scalar @ARGV, \"\\n\"\n        if $opt_diff and !$opt_sum_reports and scalar @ARGV != 2;\n    die \"--diff arguments are identical; nothing done\", \"\\n\"\n        if $opt_diff and !$opt_sum_reports and scalar @ARGV == 2\n                                           and $ARGV[0] eq $ARGV[1];\n}\n\nmy $HAVE_Algorithm_Diff = 0;\n# Algorithm::Diff isn't in the standard distribution.  It will\n# be installed in a temp directory if necessary.\neval \"use Algorithm::Diff qw ( sdiff ) \";\nif (defined $Algorithm::Diff::VERSION) {\n    $HAVE_Algorithm_Diff = 1;\n} else {\n    Install_Algorithm_Diff();\n}\n\ntrick_pp_packer_encode() if $ON_WINDOWS and $opt_file_encoding;\n$File::Find::dont_use_nlink = 1 if $opt_stat or top_level_SMB_dir(\\@ARGV);\nmy @git_similarity = (); # only populated with --git-diff-simindex\nmy %git_metadata   = (); # key is hash, tag, or other git reference;\n                         # this has two keys if doing git diff and\n                         # both L and R are git references\nget_git_metadata(\\@ARGV, \\%git_metadata) if $opt_force_git;\n#use Data::Dumper;\n#print Dumper(\\%git_metadata);\nreplace_git_hash_with_tarfile(\\@ARGV, \\@git_similarity);\n# 1}}}\n# Step 1:  Initialize global constants.        {{{1\n#\nmy $nFiles_Found = 0;  # updated in make_file_list\nmy (%Language_by_Extension, %Language_by_Script,\n    %Filters_by_Language, %Not_Code_Extension, %Not_Code_Filename,\n    %Language_by_File_Type, %Language_by_Filename,\n    %Scale_Factor, %Known_Binary_Archives,\n    %Language_by_Prefix, %EOL_Continuation_re,\n   );\nmy $ALREADY_SHOWED_HEADER = 0;\nmy $ALREADY_SHOWED_XML_SECTION = 0;\nmy %Error_Codes = ( 'Unable to read'                => -1,\n                    'Neither file nor directory'    => -2,\n                    'Diff error (quoted comments?)' => -3,\n                    'Diff error, exceeded timeout'  => -4,\n                    'Line count, exceeded timeout'  => -5,\n                  );\nmy %Extension_Collision = (\n    'ADSO/IDSM'                                     => [ 'adso' ] ,\n    'C#/Smalltalk'                                  => [ 'cs'   ] ,\n    'D/dtrace'                                      => [ 'd'    ] ,\n    'F#/Forth'                                      => [ 'fs'   ] ,\n    'Fortran 77/Forth'                              => [ 'f', 'for' ] ,\n    'IDL/Qt Project/Prolog/ProGuard'                => [ 'pro'  ] ,\n    'Lisp/Julia'                                    => [ 'jl'   ] ,\n    'Lisp/OpenCL'                                   => [ 'cl'   ] ,\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury'  => [ 'm'    ] ,\n    'Pascal/Pawn'                                   => [ 'p'    ] ,\n    'Pascal/Puppet'                                 => [ 'pp'   ] ,\n    'Perl/Prolog'                                   => [ 'pl', 'PL'  ] ,\n    'PHP/Pascal/Fortran/Pawn/BitBake'               => [ 'inc'  ] ,\n    'Raku/Prolog'                                   => [ 'p6', 'P6'  ] ,\n    'XML-Qt-GTK/Glade'                              => [ 'ui'   ] ,\n    'TypeScript/Qt Linguist'                        => [ 'ts'   ] ,\n    'Verilog-SystemVerilog/Coq'                     => [ 'v'    ] ,\n    'Visual Basic/TeX/Apex Class'                   => [ 'cls'  ] ,\n    'Scheme/SaltStack'                              => [ 'sls'  ] ,\n    'SKILL/.NET IL'                                 => [ 'il'   ] ,\n    'Clojure/Cangjie'                               => [ 'cj'   ] ,\n    'Unknown/BitBake'                               => [ 'conf' ] ,\n);\nmy @Autogen_to_ignore = no_autogen_files($list_no_autogen);\nif ($opt_force_lang_def) {\n    # replace cloc's definitions\n    read_lang_def(\n        $opt_force_lang_def    , #        Sample values:\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n} else {\n    set_constants(               #\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Language_by_Prefix   , # Language_by_Prefix{Dockerfile}  = 'Dockerfile'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%Known_Binary_Archives, # Known_Binary_Archives{.tar} = 1\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n        if ($opt_no_autogen) {\n            foreach my $F (@Autogen_to_ignore) { $Not_Code_Filename{ $F } = 1; }\n        }\n}\nif ($opt_read_lang_def) {\n    # augment cloc's definitions (keep cloc's where there are overlaps)\n    merge_lang_def(\n        $opt_read_lang_def     , #        Sample values:\n        \\%Language_by_Extension, # Language_by_Extension{f}    = 'Fortran 77'\n        \\%Language_by_Script   , # Language_by_Script{sh}      = 'Bourne Shell'\n        \\%Language_by_File_Type     , # Language_by_File_Type{makefile}  = 'make'\n        \\%Filters_by_Language  , # Filters_by_Language{Bourne Shell}[0] =\n                                 #      [ 'remove_matches' , '^\\s*#'  ]\n        \\%Not_Code_Extension   , # Not_Code_Extension{jpg}     = 1\n        \\%Not_Code_Filename    , # Not_Code_Filename{README}   = 1\n        \\%Scale_Factor         , # Scale_Factor{Perl}          = 4.0\n        \\%EOL_Continuation_re  , # EOL_Continuation_re{C++}    = '\\\\$'\n        );\n}\nif ($opt_lang_no_ext and !defined $Filters_by_Language{$opt_lang_no_ext}) {\n    die_unknown_lang($opt_lang_no_ext, \"--lang-no-ext\")\n}\ncheck_scale_existence(\\%Filters_by_Language, \\%Language_by_Extension,\n                      \\%Scale_Factor);\nparse_ignore_regex(\\@opt_ignore_regex, \\%Filters_by_Language, \\%ignore_regex)\n    if @opt_ignore_regex;\n\nmy $nCounted = 0;\n\n# Process command line provided extension-to-language mapping overrides.\n# Make a hash of known languages in lower case for easier matching.\nmy %Recognized_Language_lc = (); # key = language name in lc, value = true name\nforeach my $language (keys %Filters_by_Language) {\n    my $lang_lc = lc $language;\n    $Recognized_Language_lc{$lang_lc} = $language;\n}\nmy %Forced_Extension = (); # file name extensions which user wants to count\nmy $All_One_Language = 0;  # set to !0 if --force-lang's <ext> is missing\nforeach my $pair (@opt_force_lang) {\n    my ($lang, $extension) = split(',', $pair);\n    my $lang_lc = lc $lang;\n    if (defined $extension) {\n        $Forced_Extension{$extension} = $lang;\n\n        die_unknown_lang($lang, \"--force-lang\")\n            unless $Recognized_Language_lc{$lang_lc};\n\n        $Language_by_Extension{$extension} = $Recognized_Language_lc{$lang_lc};\n    } else {\n        # the scary case--count everything as this language\n        $All_One_Language = $Recognized_Language_lc{$lang_lc};\n    }\n}\n\nforeach my $pair (@opt_script_lang) {\n    my ($lang, $script_name) = split(',', $pair);\n    my $lang_lc = lc $lang;\n    if (!defined $script_name) {\n        die \"The --script-lang option requires a comma separated pair of \".\n            \"strings.\\n\";\n    }\n\n    die_unknown_lang($lang, \"--script-lang\")\n        unless $Recognized_Language_lc{$lang_lc};\n\n    $Language_by_Script{$script_name} = $Recognized_Language_lc{$lang_lc};\n}\n\n# If user provided a language definition file, make sure those\n# extensions aren't rejected.\nforeach my $ext (%Language_by_Extension) {\n    next unless defined $Not_Code_Extension{$ext};\n    delete $Not_Code_Extension{$ext};\n}\n\n# If user provided file extensions to ignore, add these to\n# the exclusion list.\nforeach my $ext (map { $_ => 1 } split(/,/, $opt_exclude_ext ) ) {\n    $ext = lc $ext if $ON_WINDOWS or $opt_ignore_case_ext;\n    $Not_Code_Extension{$ext} = 1;\n}\n\n# If SQL or --by-file output is requested, keep track of directory names\n# generated by File::Temp::tempdir and used to temporarily hold the results\n# of compressed archives.  Contents of the SQL table 't' will be much\n# cleaner if these meaningless directory names are stripped from the front\n# of files pulled from the archives.\nmy %TEMP_DIR = ();\nmy $TEMP_OFF =  0;  # Needed for --sdir; keep track of the number of\n                    # scratch directories made in this run to avoid\n                    # file overwrites by multiple extractions to same\n                    # sdir.\n# Also track locations where temporary installations, if necessary, of\n# Algorithm::Diff and/or Regexp::Common are done.  Make sure these\n# directories are not counted as inputs (ref bug #80 2012-11-23).\nmy %TEMP_INST = ();\n\n# invert %Language_by_Script hash to get an easy-to-look-up list of known\n# scripting languages\nmy %Script_Language = map { $_ => 1 } values %Language_by_Script ;\n# 1}}}\n# Step 2:  Early exits for display, summation. {{{1\n#\nprint_extension_info(   $opt_show_ext     ) if defined $opt_show_ext ;\nprint_language_info(    $opt_show_lang, '') if defined $opt_show_lang;\nprint_language_filters( $opt_explain      ) if defined $opt_explain  ;\nexit if (defined $opt_show_ext)  or\n        (defined $opt_show_lang) or\n        (defined $opt_explain)   or\n        $list_no_autogen;\n\nTop_of_Processing_Loop:\n# Sorry, coding purists.  Using a goto to implement --count-and-diff\n# which has to do three passes over the main code, starting with\n# a clean slate each time.\nif ($opt_count_diff) {\n    @ARGV = ( $COUNT_DIFF_ARGV[ $opt_count_diff ] );\n    if ($opt_count_diff == 3) {\n        $opt_diff = 1;\n        @ARGV = @{$COUNT_DIFF_ARGV[ $opt_count_diff ]}; # last arg is list of list\n    } elsif ($opt_diff_list_files) {\n        $opt_diff = 0;\n    }\n    if ($opt_report_file) {\n        # Instead of just one output file, will have three.\n        # Keep their names unique otherwise results are clobbered.\n        # Replace file path separators with underscores otherwise\n        # may end up with illegal file names.\n        my ($fn_0, $fn_1) = (undef, undef);\n        if ($ON_WINDOWS) {\n            ($fn_0 = $ARGV[0]) =~ s{\\\\}{_}g;\n             $fn_0 =~ s{:}{_}g;\n             $fn_0 =~ s{/}{_}g;\n            ($fn_1 = $ARGV[1]) =~ s{\\\\}{_}g if defined $ARGV[1];\n             $fn_1 =~ s{:}{_}g              if defined $ARGV[1];\n             $fn_1 =~ s{/}{_}g              if defined $ARGV[1];\n        } else {\n            ($fn_0 = $ARGV[0]) =~ s{/}{_}g;\n            ($fn_1 = $ARGV[1]) =~ s{/}{_}g  if defined $ARGV[1];\n        }\n\n        if      ($opt_count_diff == 3) {\n            $opt_report_file = $COUNT_DIFF_report_file . \".diff.$fn_0.$fn_1\";\n        } else {\n            $opt_report_file = $COUNT_DIFF_report_file . \".$fn_0\";\n        }\n    } else {\n        # STDOUT; print a header showing what it's working on\n        if ($opt_count_diff == 3) {\n            print \"\\ndiff $ARGV[0] $ARGV[1]::\\n\";\n        } else {\n            print \"\\n\" if $opt_count_diff > 1;\n            print \"$ARGV[0]::\\n\";\n        }\n    }\n    $ALREADY_SHOWED_HEADER      = 0;\n    $ALREADY_SHOWED_XML_SECTION = 0;\n}\n\n#print \"Before glob have [\", join(\",\", @ARGV), \"]\\n\";\n@ARGV = windows_glob(@ARGV) if $ON_WINDOWS;\n#print \"after  glob have [\", join(\",\", @ARGV), \"]\\n\";\n\n# filter out archive files if requested to do so\nif (defined $opt_skip_archive) {\n    my @non_archive = ();\n    foreach my $candidate (@ARGV) {\n        if ($candidate !~ m/${opt_skip_archive}$/) {\n            push @non_archive, $candidate;\n\n        }\n    }\n    @ARGV = @non_archive;\n}\n\nif ($opt_sum_reports and $opt_diff) {\n    my @results = ();\n    if ($opt_csv and !defined($opt_csv_delimiter)) {\n        $opt_csv_delimiter = \",\";\n    }\n    if ($opt_list_file) { # read inputs from the list file\n        my @list = read_list_file($opt_list_file);\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@list);\n        } else {\n            @results = combine_diffs(\\@list);\n        }\n    } elsif ($opt_vcs) { # read inputs from the VCS generator\n        my @list = invoke_generator($opt_vcs, \\@ARGV);\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@list);\n        } else {\n            @results = combine_diffs(\\@list);\n        }\n    } else { # get inputs from the command line\n        if ($opt_csv) {\n            @results = combine_csv_diffs($opt_csv_delimiter, \\@ARGV);\n        } else {\n            @results = combine_diffs(\\@ARGV);\n        }\n    }\n    if ($opt_report_file) {\n        write_file($opt_report_file, {}, @results);\n    } else {\n        print \"\\n\", join(\"\\n\", @results), \"\\n\";\n    }\n    exit;\n}\nif ($opt_sum_reports) {\n    my %Results = ();\n    foreach my $type( \"by language\", \"by report file\" ) {\n        my $found_lang = undef;\n        if ($opt_list_file or $opt_vcs) {\n            # read inputs from the list file\n            my @list;\n            if ($opt_vcs) {\n                @list = invoke_generator($opt_vcs, \\@ARGV);\n            } else {\n                @list = read_list_file($opt_list_file);\n            }\n            $found_lang = combine_results(\\@list,\n                                           $type,\n                                          \\%{$Results{ $type }},\n                                          \\%Filters_by_Language );\n        } else { # get inputs from the command line\n            $found_lang = combine_results(\\@ARGV,\n                                           $type,\n                                          \\%{$Results{ $type }},\n                                          \\%Filters_by_Language );\n        }\n        next unless %Results;\n        my $end_time = get_time();\n        my @results  = generate_report($VERSION, $end_time - $start_time,\n                                       $type,\n                                      \\%{$Results{ $type }}, \\%Scale_Factor,\n                                       \"txt\");\n        if ($opt_report_file) {\n            my $ext  = \".lang\";\n               $ext  = \".file\" unless $type eq \"by language\";\n            next if !$found_lang and  $ext  eq \".lang\";\n            write_file($opt_report_file . $ext, {}, @results);\n        } else {\n            print \"\\n\", join(\"\\n\", @results), \"\\n\";\n        }\n    }\n    exit;\n}\nif ($opt_write_lang_def or $opt_write_lang_def_incl_dup) {\n    my $file = $opt_write_lang_def          if $opt_write_lang_def;\n       $file = $opt_write_lang_def_incl_dup if $opt_write_lang_def_incl_dup;\n    write_lang_def($file                 ,\n                  \\%Language_by_Extension,\n                  \\%Language_by_Script   ,\n                  \\%Language_by_File_Type     ,\n                  \\%Filters_by_Language  ,\n                  \\%Not_Code_Extension   ,\n                  \\%Not_Code_Filename    ,\n                  \\%Scale_Factor         ,\n                  \\%EOL_Continuation_re  ,\n                  );\n    exit;\n}\nif ($opt_show_os) {\n    if ($ON_WINDOWS) {\n        print \"Windows\\n\";\n    } else {\n        print \"UNIX\\n\";\n    }\n    exit;\n}\n\nmy $max_processes = get_max_processes();\n\n# 1}}}\n# Step 3:  Create a list of files to consider. {{{1\n#  a) If inputs are binary archives, first cd to a temp\n#     directory, expand the archive with the user-given\n#     extraction tool, then add the temp directory to\n#     the list of dirs to process.\n#  b) Create a list of every file that might contain source\n#     code.  Ignore binary files, zero-sized files, and\n#     any file in a directory the user says to exclude.\n#  c) Determine the language for each file in the list.\n#\nmy @binary_archive = ();\nmy $cwd            = cwd();\nif ($opt_extract_with) {\n#print \"cwd main = [$cwd]\\n\";\n    my @extract_location = ();\n    foreach my $bin_file (@ARGV) {\n        my $extract_dir = undef;\n        if ($opt_sdir) {\n            ++$TEMP_OFF;\n            $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n            File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n            File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n        } else {\n            $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n        }\n        $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n        print \"mkdir $extract_dir\\n\"  if $opt_v;\n        print \"cd    $extract_dir\\n\"  if $opt_v;\n        chdir $extract_dir;\n        my $bin_file_full_path = \"\";\n        if (File::Spec->file_name_is_absolute( $bin_file )) {\n            $bin_file_full_path = $bin_file;\n#print \"bin_file_full_path (was ful) = [$bin_file_full_path]\\n\";\n        } else {\n            $bin_file_full_path = File::Spec->catfile( $cwd, $bin_file );\n#print \"bin_file_full_path (was rel) = [$bin_file_full_path]\\n\";\n        }\n        my     $extract_cmd = uncompress_archive_cmd($bin_file_full_path);\n        print  $extract_cmd, \"\\n\" if $opt_v;\n        system $extract_cmd;\n        push @extract_location, $extract_dir;\n        chdir $cwd;\n    }\n    # It is possible that the binary archive itself contains additional\n    # files compressed the same way (true for Java .ear files).  Go\n    # through all the files that were extracted, see if they are binary\n    # archives and try to extract them.  Lather, rinse, repeat.\n    my $binary_archives_exist = 1;\n    my $count_binary_archives = 0;\n    my $previous_count        = 0;\n    my $n_pass                = 0;\n    while ($binary_archives_exist) {\n        @binary_archive = ();\n        foreach my $dir (@extract_location) {\n            find(\\&archive_files, $dir);  # populates global @binary_archive\n        }\n        foreach my $archive (@binary_archive) {\n            my $extract_dir = undef;\n            if ($opt_sdir) {\n                ++$TEMP_OFF;\n                $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n            } else {\n                $extract_dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n            }\n            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n            print \"mkdir $extract_dir\\n\"  if $opt_v;\n            print \"cd    $extract_dir\\n\"  if $opt_v;\n            chdir  $extract_dir;\n\n            my     $extract_cmd = uncompress_archive_cmd($archive);\n            print  $extract_cmd, \"\\n\" if $opt_v;\n            system $extract_cmd;\n            push @extract_location, $extract_dir;\n            unlink $archive;  # otherwise will be extracting it forever\n        }\n        $count_binary_archives = scalar @binary_archive;\n        if ($count_binary_archives == $previous_count) {\n            $binary_archives_exist = 0;\n        }\n        $previous_count = $count_binary_archives;\n    }\n    chdir $cwd;\n\n    @ARGV = @extract_location;\n} else {\n    # see if any of the inputs need to be auto-uncompressed &/or expanded\n    my @updated_ARGS = ();\n    replace_git_hash_with_tarfile(\\@ARGV, \\@git_similarity) if $opt_force_git;\n    foreach my $Arg (@ARGV) {\n        if (is_dir($Arg)) {\n            push @updated_ARGS, $Arg;\n            next;\n        }\n        my $full_path = \"\";\n        if (File::Spec->file_name_is_absolute( $Arg )) {\n            $full_path = $Arg;\n        } else {\n            $full_path = File::Spec->catfile( $cwd, $Arg );\n        }\n#print \"full_path = [$full_path]\\n\";\n        my $extract_cmd = uncompress_archive_cmd($full_path);\n        if ($extract_cmd) {\n            my $extract_dir = undef;\n            if ($opt_sdir) {\n                ++$TEMP_OFF;\n                $extract_dir = \"$opt_sdir/$TEMP_OFF\";\n                File::Path::rmtree($extract_dir) if     is_dir($extract_dir);\n                File::Path::mkpath($extract_dir) unless is_dir($extract_dir);\n            } else {\n                $extract_dir = tempdir( CLEANUP => 1 ); # 1 = delete on exit\n            }\n            $TEMP_DIR{ $extract_dir } = 1 if $opt_sql or $opt_by_file;\n            print \"mkdir $extract_dir\\n\"  if $opt_v;\n            print \"cd    $extract_dir\\n\"  if $opt_v;\n            chdir  $extract_dir;\n            print  $extract_cmd, \"\\n\" if $opt_v;\n            system $extract_cmd;\n            push @updated_ARGS, $extract_dir;\n            chdir $cwd;\n        } else {\n            # this is a conventional, uncompressed, unarchived file\n            # or a directory; keep as-is\n            push @updated_ARGS, $Arg;\n        }\n    }\n    @ARGV = @updated_ARGS;\n\n    # make sure we're not counting any directory containing\n    # temporary installations of Regexp::Common, Algorithm::Diff\n    foreach my $d (sort keys %TEMP_INST) {\n        foreach my $a (@ARGV) {\n            next unless is_dir($a);\n            if ($opt_v > 2) {\n                printf \"Comparing %s (location of %s) to input [%s]\\n\",\n                        $d, $TEMP_INST{$d}, $a;\n            }\n            if ($a eq $d) {\n                die \"File::Temp::tempdir chose directory \",\n                    $d, \" to install \", $TEMP_INST{$d}, \" but this \",\n                    \"matches one of your input directories.  Rerun \",\n                    \"with --sdir and supply a different temporary \",\n                    \"directory for \", $TEMP_INST{$d}, \"\\n\";\n            }\n        }\n    }\n}\n# 1}}}\nmy @Errors    = ();\nmy @file_list = ();  # global variable updated in files()\nmy %Ignored   = ();  # files that are not counted (language not recognized or\n                     # problems reading the file)\nmy %upper_lower_map = ();  # global variable (needed only on Windows) to\n                           # track case of original filename, populated in\n                           # make_file_list() if $ON_WINDOWS\nif ($opt_diff) {\n# Step 4:  Separate code from non-code files.  {{{1\nmy @fh            = ();\nmy @files_for_set = ();\nmy @files_added_tot = ();\nmy @files_removed_tot = ();\nmy @file_pairs_tot = ();\n# make file lists for each separate argument\nif ($opt_diff_list_file) {\n    @files_for_set = ( (), () );\n    file_pairs_from_file($opt_diff_list_file, # in\n                        \\@files_added_tot   , # out\n                        \\@files_removed_tot , # out\n                        \\@file_pairs_tot    , # out\n                       );\n    foreach my $F (@files_added_tot) {\n        if ($ON_WINDOWS) {\n            (my $lc = lc $F) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $F;\n            $F = $lc;\n        }\n        push @{$files_for_set[1]}, $F;\n    }\n    foreach my $F (@files_removed_tot) {\n        if ($ON_WINDOWS) {\n            (my $lc = lc $F) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $F;\n            $F = $lc;\n        }\n        push @{$files_for_set[0]}, $F;\n    }\n    foreach my $pair (@file_pairs_tot) {\n        if ($ON_WINDOWS) {\n            push @{$files_for_set[0]}, lc $pair->[0];\n            push @{$files_for_set[1]}, lc $pair->[1];\n        } else {\n            push @{$files_for_set[0]}, $pair->[0];\n            push @{$files_for_set[1]}, $pair->[1];\n        }\n    }\n    @ARGV = (1, 2); # place holders\n}\nfor (my $i = 0; $i < scalar @ARGV; $i++) {\n    if ($opt_diff_list_file) {\n        push @fh, make_file_list($files_for_set[$i], $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    } elsif ($opt_diff_list_files) {\n        my @list_files = read_list_file($ARGV[$i]);\n        push @fh, make_file_list(\\@list_files, $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    } else {\n        push @fh, make_file_list([ $ARGV[$i] ], $i+1,\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n        @{$files_for_set[$i]} = @file_list;\n    }\n    if ($opt_exclude_list_file) {\n        # note: process_exclude_list_file() references global @file_list\n        process_exclude_list_file($opt_exclude_list_file,\n                                 \\%Exclude_Dir,\n                                 \\%Ignored);\n    }\n    if ($opt_no_autogen) {\n        exclude_autogenerated_files(\\@{$files_for_set[$i]},  # in/out\n                                    \\%Error_Codes, \\@Errors, \\%Ignored);\n    }\n    @file_list = ();\n}\n# 1}}}\n# Step 5:  Remove duplicate files.             {{{1\n#\nmy %Language           = ();\nmy %unique_source_file = ();\nmy $n_set = 0;\nforeach my $FH (@fh) {  # loop over each pair of file sets\n    ++$n_set;\n    remove_duplicate_files($FH,\n                               \\%{$Language{$FH}}               ,\n                               \\%{$unique_source_file{$FH}}     ,\n                          \\%Error_Codes                         ,\n                               \\@Errors                         ,\n                               \\%Ignored                        );\n    if ($opt_exclude_content) {\n        exclude_by_regex($opt_exclude_content,              # in\n                        \\%{$unique_source_file{$FH}},       # in/out\n                        \\%Ignored);                         # out\n    } elsif ($opt_include_content) {\n        include_by_regex($opt_include_content,              # in\n                        \\%{$unique_source_file{$FH}},       # in/out\n                        \\%Ignored);                         # out\n    }\n\n    if ($opt_include_lang) {\n        # remove files associated with languages not\n        # specified by --include-lang\n        my @delete_file = ();\n        foreach my $file (keys %{$unique_source_file{$FH}}) {\n            my $keep_file = 0;\n            foreach my $keep_lang (keys %Include_Language) {\n                if (lc($Language{$FH}{$file}) eq $keep_lang) {\n                    $keep_file = 1;\n                    last;\n                }\n            }\n            next if $keep_file;\n            push @delete_file, $file;\n        }\n        foreach my $file (@delete_file) {\n            delete $Language{$FH}{$file};\n        }\n    }\n\n    printf \"%2d: %8d unique file%s.                          \\r\",\n        $n_set,\n        plural_form(scalar keys %unique_source_file)\n        unless $opt_quiet;\n    my $suffix = $n_set == 1 ? \"L\" : \"R\";\n    write_file(\"${opt_unique}_${suffix}\", {}, sort keys %unique_source_file) if $opt_unique;\n}\n# 1}}}\n# Step 6:  Count code, comments, blank lines.  {{{1\n#\nmy %Results_by_Language = ();\nmy %Results_by_File     = ();\nmy %Delta_by_Language   = ();\nmy %Delta_by_File       = ();\nmy %Renamed             = ();\n\nmy %alignment = ();\n\nmy $fset_a = $fh[0];\nmy $fset_b = $fh[1];\n\nmy $n_filepairs_compared = 0;\nmy $tot_counted = 0;\n\nif ( scalar @fh != 2 ) {\n    print \"Error: incorrect length fh array when preparing diff at step 6.\\n\";\n    exit 1;\n}\n\nif ($opt_git_diff_rel and (scalar(keys %git_metadata) == 2)) {\n    # --git --diff with both L and R as git references\n    align_from_git($ARGV[0]                              , # in, before tag\n                   $ARGV[1]                              , # in, after  tag\n                   \\@files_added_tot                     , # out\n                   \\@files_removed_tot                   , # out\n                   \\@file_pairs_tot                      , # out\n                   \\%Renamed                             , # out\n                  );\n} elsif (!$opt_diff_list_file) {\n    align_by_pairs(\\%{$unique_source_file{$fset_a}}      , # in\n                   \\%{$unique_source_file{$fset_b}}      , # in\n                   \\@files_added_tot                     , # out\n                   \\@files_removed_tot                   , # out\n                   \\@file_pairs_tot                      , # out\n                  );\n}\n\n#use Data::Dumper;\n#print \"in files L : \", Dumper($unique_source_file{$fset_a});\n#print \"in files R : \", Dumper($unique_source_file{$fset_b});\n#print \"added : \", Dumper(\\@files_added_tot);\n#print \"removed : \", Dumper(\\@files_removed_tot);\n#print \"pairs : \", Dumper(\\@file_pairs_tot);\n\nif ( $max_processes == 0) {\n    # Multiprocessing is disabled\n    my $part = count_filesets ( $fset_a, $fset_b, \\@files_added_tot,\n                               \\@files_removed_tot, \\@file_pairs_tot,\n                               0, \\%Language, \\%ignore_regex, \\%Ignored);\n    %Results_by_File = %{$part->{'results_by_file'}};\n    %Results_by_Language= %{$part->{'results_by_language'}};\n    %Delta_by_File = %{$part->{'delta_by_file'}};\n    %Delta_by_Language= %{$part->{'delta_by_language'}};\n    %Ignored = ( %Ignored, %{$part->{'ignored'}});\n    %alignment = %{$part->{'alignment'}};\n    $n_filepairs_compared = $part->{'n_filepairs_compared'};\n    push ( @Errors, @{$part->{'errors'}});\n} else {\n    # Multiprocessing is enabled\n    # Do not create more processes than the amount of data to be processed\n    my $num_processes = min(max(scalar @files_added_tot,\n                                scalar @files_removed_tot,\n                                scalar @file_pairs_tot),\n                            $max_processes);\n    # ... but use at least one process.\n       $num_processes = 1\n            if $num_processes == 0;\n    # Start processes for counting\n    my $pm = Parallel::ForkManager->new($num_processes);\n    # When processes finish, they will use the embedded subroutine for\n    # merging the data into global variables.\n    $pm->run_on_finish ( sub {\n        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $part) = @_;\n        my $part_ignored = $part->{'ignored'};\n        my $part_result_by_file = $part->{'results_by_file'};\n        my $part_result_by_language = $part->{'results_by_language'};\n        my $part_delta_by_file = $part->{'delta_by_file'};\n        my $part_delta_by_language = $part->{'delta_by_language'};\n        my $part_alignment = $part->{'alignment'};\n        my $part_errors = $part->{'errors'};\n           $tot_counted += scalar keys %$part_result_by_file;\n           $n_filepairs_compared += $part->{'n_filepairs_compared'};\n        # Since files are processed by multiple processes, we can't measure\n        # the number of processed files exactly. We approximate this by showing\n        # the number of files counted by finished processes.\n        printf \"Counting:  %d\\r\", $tot_counted\n                 if $opt_progress_rate;\n\n        foreach my $this_language ( keys %$part_result_by_language ) {\n            my $counts = $part_result_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                $Results_by_Language{$this_language}{$inner_key} +=\n                    $counts->{$inner_key};\n            }\n        }\n\n        foreach my $this_language ( keys %$part_delta_by_language ) {\n            my $counts = $part_delta_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                my $statuses = $counts->{$inner_key};\n                foreach my $inner_status ( keys %$statuses ) {\n                    $Delta_by_Language{$this_language}{$inner_key}{$inner_status} +=\n                          $counts->{$inner_key}->{$inner_status};\n                }\n            }\n        }\n\n        foreach my $label ( keys %$part_alignment ) {\n            my $inner = $part_alignment->{$label};\n            foreach my $key ( keys %$inner ) {\n                $alignment{$label}{$key} = 1;\n            }\n        }\n\n        %Results_by_File = ( %Results_by_File, %$part_result_by_file );\n        %Delta_by_File = ( %Delta_by_File, %$part_delta_by_file );\n        %Ignored = (%Ignored, %$part_ignored );\n        push ( @Errors, @$part_errors );\n    } );\n\n    my $num_filepairs_per_part = ceil ( ( scalar @file_pairs_tot ) / $num_processes );\n    my $num_filesremoved_per_part = ceil ( ( scalar @files_removed_tot ) / $num_processes );\n    my $num_filesadded_per_part = ceil ( ( scalar @files_added_tot ) / $num_processes );\n\n    while ( 1 ) {\n        my @files_added_part = splice @files_added_tot, 0, $num_filesadded_per_part;\n        my @files_removed_part = splice @files_removed_tot, 0, $num_filesremoved_per_part;\n        my @filepairs_part = splice @file_pairs_tot, 0, $num_filepairs_per_part;\n        if ( scalar @files_added_part == 0 and scalar @files_removed_part == 0 and\n             scalar @filepairs_part == 0 ) {\n            last;\n        }\n\n        $pm->start() and next;\n        my $count_result = count_filesets ( $fset_a, $fset_b,\n            \\@files_added_part, \\@files_removed_part,\n            \\@filepairs_part, 1, \\%Language, \\%ignore_regex, \\%Ignored );\n        $pm->finish(0 , $count_result);\n    }\n    # Wait for processes to finish\n    $pm->wait_all_children();\n}\n\n# Write alignment data if needed requested\nif ($opt_diff_alignment) {\n    write_alignment_data ( $opt_diff_alignment, $n_filepairs_compared, \\%alignment ) ;\n}\n\nmy $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \": \";\nmy @ignored_reasons = map { \"${_}${separator} $Ignored{$_}\" } sort keys %Ignored;\nwrite_file($opt_ignored, {\"file_type\" => \"ignored\",\n                          \"separator\" => \": \",\n                          \"columns\"   => [\"file\", \"reason\"],\n                         }, @ignored_reasons   ) if $opt_ignored;\nwrite_file($opt_counted, {}, sort keys %Results_by_File) if $opt_counted;\n# 1}}}\n# Step 7:  Assemble results.                   {{{1\n#\nmy $end_time = get_time();\nprintf \"%8d file%s ignored.                           \\n\",\n    plural_form(scalar keys %Ignored) unless $opt_quiet;\nprint_errors(\\%Error_Codes, \\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\nif (!%Delta_by_Language) {\n    foreach my $out_style (sort keys %OUTFILE_EXT) {\n        next unless $OUTFILE_EXT{$out_style};\n        produce_null_output($opt_report_file, $out_style);\n        exit;\n    }\n}\ngenerate_diff_sql($end_time - $start_time, \\%Delta_by_File) if $opt_sql;\n\nexit if $skip_generate_report;\n\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    next unless $OUTFILE_EXT{$out_style};\n    my @Lines_Out = ();\n    if ($opt_by_file) {\n        @Lines_Out = diff_report($VERSION, $end_time - $start_time,\n                                \"by file\",\n                                \\%Delta_by_File, \\%Scale_Factor, \\%Renamed);\n    } else {\n        @Lines_Out = diff_report($VERSION, $end_time - $start_time,\n                                \"by language\",\n                                \\%Delta_by_Language, \\%Scale_Factor, undef);\n    }\n    my $outfile = $opt_report_file;\n    produce_output(\\@Lines_Out, $opt_report_file, $out_style);\n}\n\n# 1}}}\n} else {\n# Step 4:  Separate code from non-code files.  {{{1\nmy $fh = 0;\nif ($opt_list_file or $opt_diff_list_files or $opt_vcs) {\n    my @list;\n    if ($opt_vcs) {\n        @list = invoke_generator($opt_vcs, \\@ARGV);\n    } elsif ($opt_list_file) {\n        @list = read_list_file($opt_list_file);\n    } else {\n        @list = read_list_file($ARGV[0]);\n    }\n    $fh = make_file_list(\\@list, 0, \\%Error_Codes, \\@Errors, \\%Ignored);\n} else {\n    $fh = make_file_list(\\@ARGV, 0, \\%Error_Codes, \\@Errors, \\%Ignored);\n    #     make_file_list populates global variable @file_list via call to\n    #     File::Find's find() which in turn calls files()\n}\nif ($opt_exclude_list_file) {\n    # note: process_exclude_list_file() references global @file_list\n    process_exclude_list_file($opt_exclude_list_file,\n                             \\%Exclude_Dir,\n                             \\%Ignored);\n}\nif ($opt_skip_win_hidden and $ON_WINDOWS) {\n    my @file_list_minus_hidden = ();\n    # eval code to run on Unix without 'missing Win32::File module' error.\n    my $win32_file_invocation = '\n        use Win32::File;\n        foreach my $F (@file_list) {\n            my $attr = undef;\n            Win32::File::GetAttributes($F, $attr);\n            if ($attr & HIDDEN) {\n                $Ignored{$F} = \"Windows hidden file\";\n                print \"Ignoring $F since it is a Windows hidden file\\n\"\n                    if $opt_v > 1;\n            } else {\n                push @file_list_minus_hidden, $F;\n            }\n        }';\n    eval $win32_file_invocation;\n    @file_list = @file_list_minus_hidden;\n}\nif ($opt_no_autogen) {\n    exclude_autogenerated_files(\\@file_list,  # in/out\n                                \\%Error_Codes, \\@Errors, \\%Ignored);\n}\n#printf \"%8d file%s excluded.                     \\n\",\n#   plural_form(scalar keys %Ignored)\n#   unless $opt_quiet;\n# die print \": \", join(\"\\n: \", @file_list), \"\\n\";\n# 1}}}\n# Step 5:  Remove duplicate files.             {{{1\n#\nmy %Language           = ();\nmy %unique_source_file = ();\nremove_duplicate_files($fh                          ,   # in\n                           \\%Language               ,   # out\n                           \\%unique_source_file     ,   # out\n                      \\%Error_Codes                 ,   # in\n                           \\@Errors                 ,   # out\n                           \\%Ignored                );  # out\nif ($opt_exclude_content) {\n    exclude_by_regex($opt_exclude_content,              # in\n                    \\%unique_source_file ,              # in/out\n                    \\%Ignored);                         # out\n} elsif ($opt_include_content) {\n    include_by_regex($opt_include_content,              # in\n                    \\%unique_source_file ,              # in/out\n                    \\%Ignored);                         # out\n}\nprintf \"%8d unique file%s.                              \\n\",\n    plural_form(scalar keys %unique_source_file)\n    unless $opt_quiet;\nwrite_file($opt_unique, {}, sort keys %unique_source_file) if $opt_unique;\n# 1}}}\n# Step 6:  Count code, comments, blank lines.  {{{1\n#\nmy %Results_by_Language = ();\nmy %Results_by_File     = ();\nmy @results_parts  = ();\nmy @sorted_files = sort keys %unique_source_file;\n\nif ( $max_processes == 0) {\n    # Multiprocessing is disabled\n    my $part = count_files ( \\@sorted_files , 0, \\%ignore_regex, \\%Language);\n    %Results_by_File = %{$part->{'results_by_file'}};\n    %Results_by_Language= %{$part->{'results_by_language'}};\n    %Ignored = ( %Ignored, %{$part->{'ignored'}});\n    push ( @Errors, @{$part->{'errors'}});\n} else {\n    # Do not create more processes than the number of files to be processed\n    my $num_files = scalar @sorted_files;\n    my $num_processes = $num_files >= $max_processes ? $max_processes : $num_files;\n    # Use at least one process.\n       $num_processes = 1\n            if $num_processes == 0;\n    # Start processes for counting\n    my $pm = Parallel::ForkManager->new($num_processes);\n    # When processes finish, they will use the embedded subroutine for\n    # merging the data into global variables.\n    $pm->run_on_finish ( sub {\n        my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $part) = @_;\n        my $part_ignored = $part->{'ignored'};\n        my $part_result_by_file = $part->{'results_by_file'};\n        my $part_result_by_language = $part->{'results_by_language'};\n        my $part_errors = $part->{'errors'};\n        my $nCounted+= scalar keys %$part_result_by_file;\n        # Since files are processed by multiple processes, we can't measure\n        # the number of processed files exactly. We approximate this by showing\n        # the number of files counted by finished processes.\n        printf \"Counting:  %d\\r\", $nCounted\n                 if $opt_progress_rate;\n\n        foreach my $this_language ( keys %$part_result_by_language ) {\n            my $counts = $part_result_by_language->{$this_language};\n            foreach my $inner_key ( keys %$counts ) {\n                $Results_by_Language{$this_language}{$inner_key} +=\n                    $counts->{$inner_key};\n            }\n        }\n        %Results_by_File = ( %Results_by_File, %$part_result_by_file );\n        %Ignored = (%Ignored, %$part_ignored);\n        push ( @Errors, @$part_errors);\n    } );\n    my $num_files_per_part = ceil ( ( scalar @sorted_files ) / $num_processes );\n    while ( my @part = splice @sorted_files, 0 , $num_files_per_part ) {\n        $pm->start() and next;\n        my $count_result = count_files ( \\@part, 1, \\%ignore_regex, \\%Language );\n        $pm->finish(0 , $count_result);\n    }\n    # Wait for processes to finish\n    $pm->wait_all_children();\n}\n\nmy $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \": \";\nmy @ignored_reasons = map { \"${_}${separator} $Ignored{$_}\" } sort keys %Ignored;\nwrite_file($opt_ignored, {\"file_type\" => \"ignored\",\n                          \"separator\" => $separator,\n                          \"columns\"   => [\"file\", \"reason\"],\n                         }, @ignored_reasons   ) if $opt_ignored;\nif ($opt_summary_cutoff) {\n    %Results_by_Language = apply_cutoff($opt_summary_cutoff,\n                                       \\%Results_by_Language);\n}\nwrite_file($opt_counted, {}, sort keys %Results_by_File) if $opt_counted;\n# 1}}}\n# Step 7:  Assemble results.                   {{{1\n#\nmy $end_time = get_time();\nprintf \"%8d file%s ignored.\\n\", plural_form(scalar keys %Ignored)\n    unless $opt_quiet;\nprint_errors(\\%Error_Codes, \\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\nif (!%Results_by_Language) {\n    write_null_results($opt_json, $opt_xml, $opt_report_file);\n    exit;\n}\n\ngenerate_sql($end_time - $start_time,\n            \\%Results_by_File, \\%Scale_Factor) if $opt_sql;\nexit if $skip_generate_report;\n\nforeach my $out_style (sort keys %OUTFILE_EXT) {\n    next unless $OUTFILE_EXT{$out_style};\n    my @Lines_Out = ();\n\n    if      ($opt_by_file_by_lang) {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by file\",\n                                          \\%Results_by_File,    \\%Scale_Factor,\n                                          $out_style);\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by language\",\n                                          \\%Results_by_Language, \\%Scale_Factor,\n                                          $out_style);\n    } elsif ($opt_by_file) {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by file\",\n                                          \\%Results_by_File,    \\%Scale_Factor,\n                                          $out_style);\n    } else {\n        push @Lines_Out, generate_report( $VERSION, $end_time - $start_time,\n                                          \"by language\",\n                                          \\%Results_by_Language, \\%Scale_Factor,\n                                          $out_style);\n    }\n    produce_output(\\@Lines_Out, $opt_report_file, $out_style);\n}\n# 1}}}\n}\n\nif ($opt_count_diff) {\n    ++$opt_count_diff;\n    exit if $opt_count_diff > 3;\n    goto Top_of_Processing_Loop;\n}\n\nsuggest_remedies_for_errors(\\@Errors)\n    if @Errors and !($opt_quiet and !$opt_show_errors);\n# - - - - - - - - - - - - - - - end of main - - - - - - - - - - - - - - - #\nsub produce_output {                         # {{{1\n    my ($ra_Lines_Out, $outfile, $out_style) = @_;\n    if ($opt_fmt) {\n        my $json_string = \"\";\n        write_file(\\$json_string, {}, @{$ra_Lines_Out});\n        my ($file_len, $lang_len, $header, %contents) = load_json($json_string);\n        @{$ra_Lines_Out} = print_format_n(abs($opt_fmt), $file_len, $lang_len, $header, %contents);\n    }\n    if ($outfile) {\n        my $adjusted_outfile = $outfile;\n        if ($N_OUTPUT_FORMATS > 1 and\n            ($opt_report_file !~ /\\.${out_style}$/)) {\n            # ensure the output filename has a suitable extension\n            $adjusted_outfile .=  \".\" . $out_style;\n        }\n        write_file($adjusted_outfile, {}, @{$ra_Lines_Out});\n    } else {\n        if ($opt_fmt) {\n            print join(\"\", @{$ra_Lines_Out});\n        } else {\n            print \"\\n\" unless $opt_quiet;\n            print join(\"\\n\", @{$ra_Lines_Out}), \"\\n\";\n        }\n    }\n}\n# 1}}}\nsub produce_null_output {                    # {{{1\n    my ($outfile, $out_style) = @_;\n    print \"-> produce_null_output($outfile, $out_style)\\n\" if $opt_v > 2;\n    my @Lines_Out = ( \"Nothing to count.\" );\n    if ($out_style eq \"json\") {\n        @Lines_Out = ( \"{}\" );\n    } elsif ($out_style eq \"xml\") {\n        @Lines_Out = ( '<?xml version=\"1.0\" encoding=\"UTF-8\"?><results/>' );\n    } elsif ($out_style eq \"csv\") {\n        @Lines_Out = ( '' );\n    } elsif ($out_style eq \"md\" or $out_style eq \"yaml\") {\n        @Lines_Out = ( \"# Nothing to count.\" );\n    }\n    if ($outfile) {\n        write_file($outfile, {}, @Lines_Out);\n    } else {\n        print \"@Lines_Out\\n\";\n    }\n    print \"<- produce_null_output()\\n\" if $opt_v > 2;\n}\n# 1}}}\nsub suggest_remedies_for_errors {            # {{{1\n    my ($raa_errors) = @_; #  [ [ numeric error code, filename], .. ]\n    my $hit_timeout = 0;\n    foreach my $pair (@{$raa_errors}) {\n        my ($code, $file) = @{$pair};\n        $hit_timeout = $code == -5 ? 1 : $hit_timeout;\n    }\n    if ($hit_timeout) {\n        print \"\\n\";\n        print \"One or more files took longer to process than expected.\\n\";\n        print \"Try rerunning without timeout guards by adding  --timeout=0\\n\";\n        print \"to your command line arguments.  See the documentation on\\n\";\n        print \"the --timeout switch for more information.\\n\";\n        print \"\\n\";\n    }\n}\n# 1}}}\nsub brief_usage {                            # {{{1\n    return \"\n                       cloc -- Count Lines of Code\n\nUsage:\n    $script [options] <file(s)/dir(s)/git hash(es)>\n        Count physical lines of source code and comments in the given files\n        (may be archives such as compressed tarballs or zip files) and/or\n        recursively below the given directories or git commit hashes.\n        Example:    cloc src/ include/ main.c\n\n    $script [options] --diff <set1>  <set2>\n        Compute differences of physical lines of source code and comments\n        between any pairwise combination of directory names, archive\n        files or git commit hashes.\n        Example:    cloc --diff Python-3.5.tar.xz python-3.6/\n\n$script --help  shows full documentation on the options.\nhttps://$URL has numerous examples and more information.\n\";\n}\n# 1}}}\nsub long_usage {                             # {{{1\n    return \"\nUsage: $script [options] <file(s)/dir(s)/git hash(es)> | <set 1> <set 2> | <report files>\n\n Count, or compute differences of, physical lines of source code in the\n given files (may be archives such as compressed tarballs or zip files,\n or git commit hashes or branch names) and/or recursively below the\n given directories.\n\n ${BB}Input Options${NN}\n   --extract-with=<cmd>      This option is only needed if cloc is unable\n                             to figure out how to extract the contents of\n                             the input file(s) by itself.\n                             Use <cmd> to extract binary archive files (e.g.:\n                             .tar.gz, .zip, .Z).  Use the literal '>FILE<' as\n                             a stand-in for the actual file(s) to be\n                             extracted.  For example, to count lines of code\n                             in the input files\n                                gcc-4.2.tar.gz  perl-5.8.8.tar.gz\n                             on Unix use\n                               --extract-with='gzip -dc >FILE< | tar xf -'\n                             or, if you have GNU tar,\n                               --extract-with='tar zxf >FILE<'\n                             and on Windows use, for example:\n                               --extract-with=\\\"\\\\\\\"c:\\\\Program Files\\\\WinZip\\\\WinZip32.exe\\\\\\\" -e -o >FILE< .\\\"\n                             (if WinZip is installed there).\n   --list-file=<file>        Take the list of file and/or directory names to\n                             process from <file>, which has one file/directory\n                             name per line.  Only exact matches are counted;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.  Set <file>\n                             to - to read file names from a STDIN pipe.\n                             See also --exclude-list-file, --config.\n   --diff-list-file=<file>   Take the pairs of file names to be diff'ed from\n                             <file>, whose format matches the output of\n                             --diff-alignment.  (Run with that option to\n                             see a sample.)  The language identifier at the\n                             end of each line is ignored.  This enables --diff\n                             mode and bypasses file pair alignment logic.\n                             Use --diff-list-files to define the file name\n                             pairs in separate files. See also --config.\n   --diff-list-files <file1> <file2>\n                             Compute differences in code and comments between\n                             the files and directories listed in <file1> and\n                             <file2>.  Each input file should use the same\n                             format as --list-file, where there is one file or\n                             directory name per line.  Only exact matches are\n                             counted; relative path names will be resolved\n                             starting from the directory where cloc is invoked.\n                             This enables --diff mode.  See also --list-file,\n                             --diff-list-file, --diff.\n   --files-from=<CMD>        Synonym for --vcs=<CMD>.\n   --vcs=<CMD>               Invoke a system call to <CMD> to obtain a list of\n                             files to work on.  If <CMD> is 'git', then will\n                             invoke 'git ls-files' to get a file list.  Submodules\n                             are ignored unless --include-submodules is also\n                             given. See also --git which accepts git commit hashes\n                             and branch names. If <VCS> is 'svn' then will invoke\n                             'svn list -R'. The primary benefit is that cloc will\n                             then skip files explicitly excluded by the versioning\n                             tool in question, ie, those in .gitignore or have the\n                             svn:ignore property.\n                             Alternatively <CMD> may be any system command\n                             that generates a list of files.\n                             Note:  cloc must be in a directory which can read\n                             the files as they are returned by <CMD>.  cloc will\n                             not download files from remote repositories.\n                             'svn list -R' may refer to a remote repository\n                             to obtain file names (and therefore may require\n                             authentication to the remote repository), but\n                             the files themselves must be local.\n                             Setting <CMD> to 'auto' selects between 'git'\n                             and 'svn' (or neither) depending on the presence\n                             of a .git or .svn subdirectory below the directory\n                             where cloc is invoked.\n                             --files-from is a synonym for --vcs.\n   --unicode                 Check binary files to see if they contain Unicode\n                             expanded ASCII text.  This causes performance to\n                             drop noticeably.\n\n ${BB}Processing Options${NN}\n   --autoconf                Count .in files (as processed by GNU autoconf) of\n                             recognized languages.  See also --no-autogen.\n   --by-file                 Report results for every source file encountered.\n                             See also --fmt under 'Output Options'.\n   --by-file-by-lang         Report results for every source file encountered\n                             in addition to reporting by language.\n   --config <file>           Read command line switches from <file> instead of\n                             the default location of $config_file.\n                             The file should contain one switch, along with\n                             arguments (if any), per line.  Blank lines and lines\n                             beginning with '#' are skipped.  Options given on\n                             the command line take priority over entries read from\n                             the file.\n                             If a directory is also given with any of these\n                             switches: --list-file, --exclude-list-file,\n                             --read-lang-def, --force-lang-def, --diff-list-file\n                             and a config file exists in that directory, it will\n                             take priority over $config_file.\n   --count-and-diff <set1> <set2>\n                             First perform direct code counts of source file(s)\n                             of <set1> and <set2> separately, then perform a diff\n                             of these.  Inputs may be pairs of files, directories,\n                             or archives.  If --out or --report-file is given,\n                             three output files will be created, one for each\n                             of the two counts and one for the diff.  See also\n                             --diff, --diff-alignment, --diff-timeout,\n                             --ignore-case, --ignore-whitespace.\n   --diff <set1> <set2>      Compute differences in code and comments between\n                             source file(s) of <set1> and <set2>.  The inputs\n                             may be any mix of files, directories, archives,\n                             or git commit hashes.  Use --diff-alignment to\n                             generate a list showing which file pairs where\n                             compared.  File pairs are aligned by matching file\n                             names.  If --git is also given, a more sophisticated\n                             pairing algorithm which additionally attempts to pair\n                             renamed file is used.  When comparing git branches,\n                             only files which have changed in either commit are\n                             compared. See also --git, --count-and-diff,\n                             --diff-alignment, --diff-list-file, --diff-timeout,\n                             --ignore-case, --ignore-whitespace.\n   --diff-timeout <N>        Ignore files which take more than <N> seconds\n                             to process.  Default is 10 seconds.  Setting <N>\n                             to 0 allows unlimited time.  (Large files with many\n                             repeated lines can cause Algorithm::Diff::sdiff()\n                             to take hours.) See also --timeout.\n   --docstring-as-code       cloc considers docstrings to be comments, but this is\n                             not always correct as docstrings represent regular\n                             strings when they appear on the right hand side of an\n                             assignment or as function arguments.  This switch\n                             forces docstrings to be counted as code.\n   --follow-links            [Unix only] Follow symbolic links to directories\n                             (sym links to files are always followed).\n                             See also --stat.\n   --force-lang=<lang>[,<ext>]\n                             Process all files that have a <ext> extension\n                             with the counter for language <lang>.  For\n                             example, to count all .f files with the\n                             Fortran 90 counter (which expects files to\n                             end with .f90) instead of the default Fortran 77\n                             counter, use\n                               --force-lang=\\\"Fortran 90,f\\\"\n                             If <ext> is omitted, every file will be counted\n                             with the <lang> counter.  This option can be\n                             specified multiple times (but that is only\n                             useful when <ext> is given each time).\n                             See also --script-lang, --lang-no-ext.\n   --force-lang-def=<file>   Load language processing filters from <file>,\n                             then use these filters instead of the built-in\n                             filters.  Note:  languages which map to the same\n                             file extension (for example:\n                             MATLAB/Mathematica/Objective-C/MUMPS/Mercury;\n                             Pascal/PHP; Lisp/OpenCL; Lisp/Julia; Perl/Prolog)\n                             will be ignored as these require additional\n                             processing that is not expressed in language\n                             definition files.  Use --read-lang-def to define\n                             new language filters without replacing built-in\n                             filters (see also --write-lang-def,\n                             --write-lang-def-incl-dup, --config).\n   --git                     Forces the inputs to be interpreted as git targets\n                             (commit hashes, branch names, et cetera) if these\n                             are not first identified as file or directory\n                             names.  This option overrides the --vcs=git logic\n                             if this is given; in other words, --git gets its\n                             list of files to work on directly from git using\n                             the hash or branch name rather than from\n                             'git ls-files'.  This option can be used with\n                             --diff to perform line count diffs between git\n                             commits, or between a git commit and a file,\n                             directory, or archive.  Use -v/--verbose to see\n                             the git system commands cloc issues.\n   --git-diff-rel            Same as --git --diff, or just --diff if the inputs\n                             are recognized as git targets.  Only files which\n                             have changed in either commit are compared.\n   --git-diff-all            Git diff strategy #2:  compare all files in the\n                             repository between the two commits.\n   --ignore-whitespace       Ignore horizontal white space when comparing files\n                             with --diff.  See also --ignore-case.\n   --ignore-case             Ignore changes in case within file contents;\n                             consider upper- and lowercase letters equivalent\n                             when comparing files with --diff.  See also\n                             --ignore-whitespace.\n   --ignore-case-ext         Ignore case of file name extensions.  This will\n                             cause problems counting some languages\n                             (specifically, .c and .C are associated with C and\n                             C++; this switch would count .C files as C rather\n                             than C++ on *nix operating systems).  File name\n                             case insensitivity is always true on Windows.\n   --ignore-regex            Ignore lines in source files that match the given\n                             Perl regular expression for the given language(s).\n                             This option can be specified multiple times.\n                             Language names are comma separated and are followed\n                             by the pipe character and the regular expression.\n                             Use * to match all languages.\n                             Examples:\n                               --ignore-regex=\\\"C,Java,C++|^\\\\s*[{};]\\\\s*\\$\\\"\n                               --ignore-regex=\\\"*|DEBUG|TEST\\\\s+ONLY\\\"\n                             These filters are applied after comments are\n                             removed.  Use --strip-comments=EXT to create\n                             new files that show these filters applied.\n                             The primary use case is to ignore lines\n                             containing only braces, brackets, or puctuation.\n   --lang-no-ext=<lang>      Count files without extensions using the <lang>\n                             counter.  This option overrides internal logic\n                             for files without extensions (where such files\n                             are checked against known scripting languages\n                             by examining the first line for #!).  See also\n                             --force-lang, --script-lang.\n   --max-file-size=<MB>      Skip files larger than <MB> megabytes when\n                             traversing directories.  By default, <MB>=100.\n                             cloc's memory requirement is roughly twenty times\n                             larger than the largest file so running with\n                             files larger than 100 MB on a computer with less\n                             than 2 GB of memory will cause problems.\n                             Note:  this check does not apply to files\n                             explicitly passed as command line arguments.\n   --no-autogen[=list]       Ignore files generated by code-production systems\n                             such as GNU autoconf.  To see a list of these files\n                             (then exit), run with --no-autogen list\n                             See also --autoconf.\n   --no-recurse              Count files in the given directories without\n                             recursively descending below them.\n   --original-dir            [Only effective in combination with\n                             --strip-comments or --strip-code]  Write the stripped\n                             files to the same directory as the original files.\n   --only-count-files        Only count files by language.  Blank, comment, and\n                             code counts will be zero.\n   --read-binary-files       Process binary files in addition to text files.\n                             This is usually a bad idea and should only be\n                             attempted with text files that have embedded\n                             binary data.\n   --read-lang-def=<file>    Load new language processing filters from <file>\n                             and merge them with those already known to cloc.\n                             If <file> defines a language cloc already knows\n                             about, cloc's definition will take precedence.\n                             Use --force-lang-def to over-ride cloc's\n                             definitions (see also --write-lang-def,\n                             --write-lang-def-incl-dup, --config).\n   --script-lang=<lang>,<s>  Process all files that invoke <s> as a #!\n                             scripting language with the counter for language\n                             <lang>.  For example, files that begin with\n                                #!/usr/local/bin/perl5.8.8\n                             will be counted with the Perl counter by using\n                                --script-lang=Perl,perl5.8.8\n                             The language name is case insensitive but the\n                             name of the script language executable, <s>,\n                             must have the right case.  This option can be\n                             specified multiple times.  See also --force-lang,\n                             --lang-no-ext.\n   --sdir=<dir>              Use <dir> as the scratch directory instead of\n                             letting File::Temp chose the location.  Files\n                             written to this location are not removed at\n                             the end of the run (as they are with File::Temp).\n   --skip-leading=<N[,ext]>  Skip the first <N> lines of each file.  If a\n                             comma separated list of extensions is also given,\n                             only skip lines from those file types.  Example:\n                               --skip-leading=10,cpp,h\n                             will skip the first ten lines of *.cpp and *.h\n                             files.  This is useful for ignoring boilerplate\n                             text.\n   --skip-uniqueness         Skip the file uniqueness check.  This will give\n                             a performance boost at the expense of counting\n                             files with identical contents multiple times\n                             (if such duplicates exist).\n   --stat                    Some file systems (AFS, CD-ROM, FAT, HPFS, SMB)\n                             do not have directory 'nlink' counts that match\n                             the number of its subdirectories.  Consequently\n                             cloc may undercount or completely skip the\n                             contents of such file systems.  This switch forces\n                             File::Find to stat directories to obtain the\n                             correct count.  File search speed will decrease.\n                             See also --follow-links.\n   --stdin-name=<file>       Give a file name to use to determine the language\n                             for standard input.  (Use - as the input name to\n                             receive source code via STDIN.)\n   --strip-code=<ext>        For each file processed, write to the current\n                             directory a version of the file which has blank\n                             and code lines, including code with (in-line\n                             comments) removed. The name of each stripped file\n                             is the original file name with .<ext> appended to\n                             it. It is written to the current directory unless\n                             --original-dir is on.\n   --strip-comments=<ext>    For each file processed, write to the current\n                             directory a version of the file which has blank\n                             and commented lines removed (in-line comments\n                             persist).  The name of each stripped file is the\n                             original file name with .<ext> appended to it.\n                             It is written to the current directory unless\n                             --original-dir is on.\n   --strip-str-comments      Replace comment markers embedded in strings with\n                             'xx'.  This attempts to work around a limitation\n                             in Regexp::Common::Comment where comment markers\n                             embedded in strings are seen as actual comment\n                             markers and not strings, often resulting in a\n                             'Complex regular subexpression recursion limit'\n                             warning and incorrect counts.  There are two\n                             disadvantages to using this switch:  1/code count\n                             performance drops, and 2/code generated with\n                             --strip-comments will contain different strings\n                             where ever embedded comments are found.\n   --sum-reports             Input arguments are report files previously\n                             created with the --report-file option in plain\n                             format (eg. not JSON, YAML, XML, or SQL).\n                             Makes a cumulative set of results containing the\n                             sum of data from the individual report files.\n   --timeout <N>             Ignore files which take more than <N> seconds\n                             to process at any of the language's filter stages.\n                             The default maximum number of seconds spent on a\n                             filter stage is the number of lines in the file\n                             divided by one thousand.  Setting <N> to 0 allows\n                             unlimited time.  See also --diff-timeout.\n   --processes=NUM           [Available only on systems with a recent version\n                             of the Parallel::ForkManager module.  Not\n                             available on Windows.] Sets the maximum number of\n                             cores that cloc uses.  The default value of 0\n                             disables multiprocessing.\n   --unix                    Override the operating system autodetection\n                             logic and run in UNIX mode.  See also\n                             --windows, --show-os.\n   --use-sloccount           If SLOCCount is installed, use its compiled\n                             executables c_count, java_count, pascal_count,\n                             php_count, and xml_count instead of cloc's\n                             counters.  SLOCCount's compiled counters are\n                             substantially faster than cloc's and may give\n                             a performance improvement when counting projects\n                             with large files.  However, these cloc-specific\n                             features will not be available: --diff,\n                             --count-and-diff, --strip-code, --strip-comments,\n                             --unicode.\n   --windows                 Override the operating system autodetection\n                             logic and run in Microsoft Windows mode.\n                             See also --unix, --show-os.\n\n ${BB}Filter Options${NN}\n   --include-content=<regex> Only count files containing text that matches the\n                             given regular expression.\n   --exclude-content=<regex> Exclude files containing text that matches the given\n                             regular expression.\n   --exclude-dir=<D1>[,D2,]  Exclude the given comma separated directories\n                             D1, D2, D3, et cetera, from being scanned.  For\n                             example  --exclude-dir=.cache,test  will skip\n                             all files and subdirectories that have /.cache/\n                             or /test/ as their parent directory.\n                             Directories named .bzr, .cvs, .hg, .git, .svn,\n                             and .snapshot are always excluded.\n                             This option only works with individual directory\n                             names so including file path separators is not\n                             allowed.  Use --fullpath and --not-match-d=<regex>\n                             to supply a regex matching multiple subdirectories.\n   --exclude-ext=<ext1>[,<ext2>[...]]\n                             Do not count files having the given file name\n                             extensions.\n   --exclude-lang=<L1>[,L2[...]]\n                             Exclude the given comma separated languages\n                             L1, L2, L3, et cetera, from being counted.\n   --exclude-list-file=<file>  Ignore files and/or directories whose names\n                             appear in <file>.  <file> should have one file\n                             name per line.  Only exact matches are ignored;\n                             relative path names will be resolved starting from\n                             the directory where cloc is invoked.\n                             See also --list-file, --config.\n   --fullpath                Modifies the behavior of --match-f, --not-match-f,\n                             and --not-match-d to include the file's path--\n                             relative to the directory from which cloc is\n                             invoked--in the regex, not just the file's basename.\n                             (This does not expand each filename to include its\n                             fully qualified absolute path; instead, it uses as\n                             much of the path as is passed in to cloc.)\n   --include-ext=<ext1>[,ext2[...]]\n                             Count only languages having the given comma\n                             separated file extensions.  Use --show-ext to\n                             see the recognized extensions.\n   --include-lang=<L1>[,L2[...]]\n                             Count only the given comma separated, case-\n                             insensitive languages L1, L2, L3, et cetera.  Use\n                             --show-lang to see the list of recognized languages.\n   --include-submodules      When using --vcs=git, include files in git\n                             submodules.\n   --match-d=<regex>         Only count files in directories matching the Perl\n                             regex.  For example\n                               --match-d='/(src|include)/'\n                             only counts files in directories containing\n                             /src/ or /include/.  Unlike --not-match-d,\n                             --match-f, and --not-match-f, --match-d always\n                             anchors the regex to the directory from which\n                             cloc is invoked.\n   --not-match-d=<regex>     Count all files except those in directories\n                             matching the Perl regex.  Only the trailing\n                             directory name is compared, for example, when\n                             counting in /usr/local/lib, only 'lib' is\n                             compared to the regex.\n                             Add --fullpath to compare parent directories, beginning\n                             from the directory where cloc is invoked, to the regex.\n                             Do not include file path separators at the beginning\n                             or end of the regex. This option may be repeated.\n   --match-f=<regex>         Only count files whose basenames match the Perl\n                             regex.  For example\n                               --match-f='^[Ww]idget'\n                             only counts files that start with Widget or widget.\n                             Add --fullpath to include parent directories\n                             in the regex instead of just the basename.\n   --not-match-f=<regex>     Count all files except those whose basenames\n                             match the Perl regex.  Add --fullpath to include\n                             parent directories in the regex instead of just\n                             the basename. This option may be repeated.\n   --skip-archive=<regex>    Ignore files that end with the given Perl regular\n                             expression.  For example, if given\n                               --skip-archive='(zip|tar(\\.(gz|Z|bz2|xz|7z))?)'\n                             the code will skip files that end with .zip,\n                             .tar, .tar.gz, .tar.Z, .tar.bz2, .tar.xz, and\n                             .tar.7z.\n   --skip-win-hidden         On Windows, ignore hidden files.\n\n ${BB}Debug Options${NN}\n   --categorized=<file>      Save file sizes in bytes, identified languages\n                             and names of categorized files to <file>.\n   --counted=<file>          Save names of processed source files to <file>.\n                             See also --found, --ignored, --unique.\n   --diff-alignment=<file>   Write to <file> a list of files and file pairs\n                             showing which files were added, removed, and/or\n                             compared during a run with --diff.  This switch\n                             forces the --diff mode on.\n   --explain=<lang>          Print the filters used to remove comments for\n                             language <lang> and exit.  In some cases the\n                             filters refer to Perl subroutines rather than\n                             regular expressions.  An examination of the\n                             source code may be needed for further explanation.\n   --help                    Print this usage information and exit.\n   --found=<file>            Save names of every file found to <file>.  See\n                             also --counted, --ignored, --unique.\n   --ignored=<file>          Save names of ignored files and the reason they\n                             were ignored to <file>.  See also --counted,\n                             --found, --unique.\n   --print-filter-stages     Print processed source code before and after\n                             each filter is applied.\n   --show-ext[=<ext>]        Print information about all known (or just the\n                             given) file extensions and exit.\n   --show-lang[=<lang>]      Print information about all known (or just the\n                             given) languages and exit.\n   --show-os                 Print the value of the operating system mode\n                             and exit.  See also --unix, --windows.\n   --unique=<file>           Save names of unique files found to <file>.  See\n                             also --counted, --found, --ignored.\n   -v[=<n>]                  Verbose switch (optional numeric value).\n   -verbose[=<n>]            Long form of -v.\n   --version                 Print the version of this program and exit.\n   --write-lang-def=<file>   Writes to <file> the language processing filters\n                             then exits.  Useful as a first step to creating\n                             custom language definitions. Note: languages which\n                             map to the same file extension will be excluded.\n                             (See also --force-lang-def, --read-lang-def).\n   --write-lang-def-incl-dup=<file>\n                             Same as --write-lang-def, but includes duplicated\n                             extensions.  This generates a problematic language\n                             definition file because cloc will refuse to use\n                             it until duplicates are removed.\n\n ${BB}Output Options${NN}\n   --3                       Print third-generation language output.\n                             (This option can cause report summation to fail\n                             if some reports were produced with this option\n                             while others were produced without it.)\n   --by-percent  X           Instead of comment and blank line counts, show\n                             these values as percentages based on the value\n                             of X in the denominator, where X is\n                                 c    meaning lines of code\n                                 cm   meaning lines of code + comments\n                                 cb   meaning lines of code + blanks\n                                 cmb  meaning lines of code + comments + blanks\n                                 t    meaning sum of values in that column\n                             For example, if using method 'c' and your code\n                             has twice as many lines of comments as lines\n                             of code, the value in the comment column will\n                             be 200%.  Method 't' computes percentages\n                             based on totals for each column.  Another way of\n                             looking at this is that 't' computes percentages\n                             vertically while the other methods compute them\n                             horizontally.\n   --csv                     Write the results as comma separated values.\n   --csv-delimiter=<C>       Use the character <C> as the delimiter for comma\n                             separated files instead of ,.  This switch forces\n   --file-encoding=<E>       Write output files using the <E> encoding instead of\n                             the default ASCII (<E> = 'UTF-7').  Examples: 'UTF-16',\n                             'euc-kr', 'iso-8859-16'.  Known encodings can be\n                             printed with\n                               perl -MEncode -e 'print join(\\\"\\\\n\\\", Encode->encodings(\\\":all\\\")), \\\"\\\\n\\\"'\n   --fmt=<N>                 Alternate text output format where <N> is a number\n                             from 1 to 5. 'total lines' means the sum of code,\n                             comment, and blank lines.  The formats are:\n                               1:  by language (same as cloc default output)\n                               2:  by language with an extra column for total lines\n                               3:  by file with language\n                               4:  by file with a total lines column\n                               5:  by file with language and a total lines column\n   --hide-rate               Do not show elapsed time, line processing rate, or\n                             file processing rates in the output header. This\n                             makes output deterministic.\n   --json                    Write the results as JavaScript Object Notation\n                             (JSON) formatted output.\n   --md                      Write the results as Markdown-formatted text.\n   --out=<file>              Synonym for --report-file=<file>.\n   --percent                 Show counts as percentages of sums for each column.\n                             Same as '--by-percent t'.\n   --progress-rate=<n>       Show progress update after every <n> files are\n                             processed (default <n>=100).  Set <n> to 0 to\n                             suppress progress output (useful when redirecting\n                             output to STDOUT).\n   --quiet                   Suppress all information messages, including errors,\n                             except for the final report.  Add --show-errors to\n                             see errors.\n   --report-file=<file>      Write the results to <file> instead of STDOUT.\n   --show-errors             Show error messages, if any, when running with --quiet.\n   --sql=<file>              Write results as SQL create and insert statements\n                             which can be read by a database program such as\n                             SQLite.  If <file> is -, output is sent to STDOUT.\n   --sql-append              Append SQL insert statements to the file specified\n                             by --sql and do not generate table creation\n                             statements.  Only valid with the --sql option.\n   --sql-project=<name>      Use <name> as the project identifier for the\n                             current run.  Only valid with the --sql option.\n   --sql-style=<style>       Write SQL statements in the given style instead\n                             of the default SQLite format.  Styles include\n                             'Oracle' and 'Named_Columns'.\n   --sum-one                 For plain text reports, show the SUM: output line\n                             even if only one input file is processed.\n   --summary-cutoff=X:N      Aggregate to 'Other' results having X lines\n                             below N where X is one of\n                                c   meaning lines of code\n                                f   meaning files\n                                m   meaning lines of comments\n                                cm  meaning lines of code + comments\n                             Appending a percent sign to N changes\n                             the calculation from straight count to\n                             percentage.\n                             Ignored with --diff or --by-file.\n   --thousands-delimiter=<C> Divides numbers with many digits (i.e. numbers\n                             over 999) into groups using the character <C> as\n                             delimiter (e.g. for <C> = '.': 12345 -> 12.345).\n                             Only works with the '--fmt' option.\n                             Sample values: '.', ',', '_', ' '\n                             Synonym:  --ksep\n   --xml                     Write the results in XML.\n   --xsl=<file>              Reference <file> as an XSL stylesheet within\n                             the XML output.  If <file> is 1 (numeric one),\n                             writes a default stylesheet, cloc.xsl (or\n                             cloc-diff.xsl if --diff is also given).\n                             This switch forces --xml on.\n   --yaml                    Write the results in YAML.\n\";\n}\n# 1}}}\nsub separate_thousands {\n    my ($number, $separator,) = @_;\n    while ($number =~ s/(\\d+)(\\d\\d\\d)/$1\\=$2/) { };\n    $number =~ s/=/${separator}/g;\n    return $number;\n}\nsub summary_cutoff_error {                   # {{{\n    my ($parameter) = @_;\n    print \"-> summary_cutoff_is_ok($parameter)\\n\" if $opt_v > 2;\n    my %known_keys = ( 'c' => 1, 'f' => 1, 'm' => 1, 'cm' => 1 );\n    my $result = \"\";\n    my $by_pct = 0;\n    my ($key, $value);\n    if ($parameter !~ /:/) {\n        $result = \"expected a colon in --summary-cutoff argument\";\n    } else {\n        ($key, $value) = split(':', $parameter, 2);\n        if ($value =~ /%$/) {\n            $by_pct = 1;\n            $value =~ s/%$//;\n        }\n        if (!$known_keys{$key}) {\n            $result = \"--summary-cutoff argument:  '$key' is not 'c', 'f', 'm' or 'cm'\";\n        }\n        if ($value !~ /^\\d+(\\.\\d*)?$/) {\n            $result = \"--summary-cutoff argument:  '$value' is not a number\";\n        }\n    }\n    print \"<- summary_cutoff_is_ok($result)\\n\" if $opt_v > 2;\n    return $result;\n} # 1}}}\nsub apply_cutoff {                           # {{{1\n    my ($criterion,\n        $rhh_by_lang) = @_;\n\n    my %aggregated_Results_by_Language = ();\n    my $by_pct = 0;\n    my ($key, $value) = split(':', $criterion, 2);\n    if ($value =~ /%$/) {\n        $by_pct = 1;\n        $value =~ s/%$//;\n    }\n\n    my %sum = ();\n    if ($by_pct) {\n        foreach my $lang (keys %{$rhh_by_lang}) {\n            foreach my $category (qw(nFiles comment blank code)) {\n                $sum{$category} += $rhh_by_lang->{$lang}{$category};\n            }\n        }\n        if      ($key eq 'c') {\n            $value *= $sum{'code'}/100;\n        } elsif ($key eq 'f') {\n            $value *= $sum{'nFiles'}/100;\n        } elsif ($key eq 'm') {\n            $value *= $sum{'comment'}/100;\n        } elsif ($key eq 'cm') {\n            $value *= ($sum{'code'} + $sum{'comment'})/100;\n        }\n    }\n\n    foreach my $lang (keys %{$rhh_by_lang}) {\n        my %sum = ();\n        my $agg_lang = $lang;\n        if      ($key eq 'c') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'code'}    <= $value;\n        } elsif ($key eq 'f') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'nFiles'}  <= $value;\n        } elsif ($key eq 'm') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'comment'} <= $value;\n        } elsif ($key eq 'cm') {\n            $agg_lang = 'Other' if $rhh_by_lang->{$lang}{'code'} +\n                                      $rhh_by_lang->{$lang}{'comment'} <= $value;\n        }\n        foreach my $category (qw(nFiles comment blank code)) {\n            $aggregated_Results_by_Language{$agg_lang}{$category} +=\n                $rhh_by_lang->{$lang}{$category};\n        }\n    }\n\n    return %aggregated_Results_by_Language;\n} # 1}}}\nsub exclude_by_regex {                       # {{{1\n    my ($regex,\n        $rh_unique_source_file, # in/out\n        $rh_ignored           , # out\n       ) = @_;\n    my @exclude = ();\n    foreach my $file (keys %{$rh_unique_source_file}) {\n        my $line_num = 0;\n        foreach my $line (read_file($file)) {\n            ++$line_num;\n            if ($line =~ /$regex/) {\n                $rh_ignored->{$file} = \"line $line_num match for --exclude-content=$regex\";\n                push @exclude, $file;\n                last;\n            }\n        }\n    }\n    foreach my $file (@exclude) {\n        delete $rh_unique_source_file->{$file};\n    }\n} # 1}}}\nsub include_by_regex {                       # {{{1\n    my ($regex,\n        $rh_unique_source_file, # in/out\n        $rh_ignored           , # out\n       ) = @_;\n    my @exclude = ();\n    foreach my $file (keys %{$rh_unique_source_file}) {\n        my $keep_this_one = 0;\n        foreach my $line (read_file($file)) {\n            if ($line =~ /$regex/) {\n                $keep_this_one = 1;\n                last;\n            }\n        }\n        if (!$keep_this_one) {\n            $rh_ignored->{$file} = \"does not satisfy --include-content=$regex\";\n            push @exclude, $file;\n        }\n    }\n    foreach my $file (@exclude) {\n        delete $rh_unique_source_file->{$file};\n    }\n} # 1}}}\nsub get_max_processes {                      # {{{1\n    # If user has specified valid number of processes, use that.\n    if (defined $opt_processes) {\n        eval \"use Parallel::ForkManager 0.7.6;\";\n        if ( defined $Parallel::ForkManager::VERSION ) {\n            $HAVE_Parallel_ForkManager = 1;\n        }\n        if ( $opt_processes !~ /^\\d+$/ ) {\n            print \"Error: processes option argument must be numeric.\\n\";\n            exit 1;\n        }\n        elsif ( $opt_processes >0 and ! $HAVE_Parallel_ForkManager ) {\n            print \"Error: cannot use multiple processes, because \" .\n                  \"Parallel::ForkManager is not installed, or the version is too old.\\n\";\n            exit 1;\n        }\n    elsif ( $opt_processes >0 and $ON_WINDOWS ) {\n            print \"Error: cannot use multiple processes on Windows systems.\\n\";\n            exit 1;\n        }\n        else {\n            return $opt_processes;\n        }\n    }\n\n    # Disable multiprocessing on Windows - does not work reliably\n    if ($ON_WINDOWS) {\n        return 0;\n    }\n\n    # Disable multiprocessing if Parallel::ForkManager is not available\n    if ( ! $HAVE_Parallel_ForkManager ) {\n        return 0;\n    }\n\n    # Set to number of cores on Linux\n    if ( $^O =~ /linux/i and -x '/usr/bin/nproc' ) {\n        my $numavcores_linux = `/usr/bin/nproc`;\n        chomp $numavcores_linux;\n        if ( $numavcores_linux =~ /^\\d+$/ ) {\n            return $numavcores_linux;\n        }\n    }\n\n    # Set to number of cores on macOS\n    if ( $^O =~ /darwin/i and -x '/usr/sbin/sysctl') {\n       my $numavcores_macos = `/usr/sbin/sysctl -n hw.physicalcpu`;\n       chomp $numavcores_macos;\n       if ($numavcores_macos =~ /^\\d+$/ ) {\n           return $numavcores_macos;\n       }\n    }\n\n    # Disable multiprocessing in other cases\n    return 0;\n} # 1}}}\nsub exclude_autogenerated_files {            # {{{1\n    my ($ra_file_list, # in/out\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rh_Ignored  , # out\n       ) = @_;\n    print \"-> exclude_autogenerated_files()\\n\" if $opt_v > 2;\n    my @file_list_minus_autogen = ();\n    foreach my $file (@{$ra_file_list}) {\n        if ($file !~ /\\.go$/ && $file !~ /\\.ʕ◔ϖ◔ʔ$/) {\n            # at the moment, only know Go autogenerated files\n            push @file_list_minus_autogen, $file;\n            next;\n        }\n        my $first_line = first_line($file, 1, $rh_Err, $raa_errors);\n        if ($first_line =~ m{^//\\s+Code\\s+generated\\s+.*?\\s+DO\\s+NOT\\s+EDIT\\.$}) {\n            $rh_Ignored->{$file} = 'Go autogenerated file';\n        } else {\n            # Go, but not autogenerated\n            push @file_list_minus_autogen, $file;\n        }\n    }\n    @{$ra_file_list} = @file_list_minus_autogen;\n\n    if ($opt_force_git) {\n        my $repo_dir = git_root_dir();\n        my @file_list_minus_linguist = ();\n        # if there's a .gitattributes file, look for linguist-generated\n        # and linguist-vendored entries to ignore\n        my $GA = \".gitattributes\";\n        if (-f $GA) {\n            foreach my $line (read_file($GA)) {\n                next unless $line =~ /^(.*?)\\s+(linguist-(vendored|generated))/;\n                my $re = glob2regex($1);\n                foreach my $file (@{$ra_file_list}) {\n                    my $full_path = File::Spec->catfile($repo_dir, $file);\n                    my $rel_file  = File::Spec->abs2rel($full_path, $cwd);\n                    my $match = undef;\n                    if ($ON_WINDOWS) {\n                        $rel_file =~ s{\\\\}{/}g;\n                        $match = $rel_file =~ m{$re}i;\n                    } else {\n                        $match = $rel_file =~ m{$re};\n                    }\n                    if ($match) {\n#print \"RULE [$rel_file] v [$re]\\n\";\n                        $rh_Ignored->{$file} = \"matches $GA rule '$line'\";\n                    } else {\n                        push @file_list_minus_linguist, $file;\n                    }\n                }\n            }\n        }\n    }\n    print \"<- exclude_autogenerated_files()\\n\" if $opt_v > 2;\n} # 1}}}\nsub git_root_dir {                           # {{{1\n    # if in a git repo, return the repo's top level directory\n    my $cmd = \"git -c \\\"safe.directory=*\\\" rev-parse --show-toplevel\";\n    print $cmd, \"\\n\" if $opt_v > 1;\n    my $dir = undef;\n    chomp($dir = `$cmd`);\n    die \"Not in a git repository\" unless $dir\n} # 1}}}\nsub file_extension {                         # {{{1\n    my ($fname, ) = @_;\n    $fname =~ m/\\.(\\w+)$/;\n    if ($1) {\n        return $1;\n    } else {\n        return \"\";\n    }\n} # 1}}}\nsub count_files {                            # {{{1\n    my ($filelist, $counter_type, $rha_ignore_regex, $language_hash) = @_;\n    print \"-> count_files()\\n\" if $opt_v > 2;\n    my @p_errors = ();\n    my %p_ignored = ();\n    my %p_rbl = ();\n    my %p_rbf = ();\n    my %Language = %{$language_hash};\n\n    foreach my $file (@$filelist) {\n        if ( ! $counter_type ) {\n            # Multithreading disabled\n            $nCounted++;\n\n            printf \"Counting:  %d\\r\", $nCounted\n                 unless (!$opt_progress_rate or ($nCounted % $opt_progress_rate));\n        }\n\n        next if $Ignored{$file};\n        if ($opt_include_ext and not $Include_Ext{ file_extension($file) }) {\n            $p_ignored{$file} = \"not in --include-ext=$opt_include_ext\";\n            next;\n        }\n        if ($opt_include_lang and not $Include_Language{lc($Language{$file})}) {\n            $p_ignored{$file} = \"not in --include-lang=$opt_include_lang\";\n            next;\n        }\n        if ($Exclude_Language{$Language{$file}}) {\n            $p_ignored{$file} = \"--exclude-lang=$Language{$file}\";\n            next;\n        }\n        if ($opt_force_lang_def and ($Language{$file} eq \"XML\") and\n            !defined $Filters_by_Language{XML}) {\n            # XML check is attempted for all unidentified text files.\n            # This can't be done if user forces language definition\n            # that excludes XML.  GH #596\n            next;\n        }\n\n        my $Filters_by_Language_Language_file = ! @{$Filters_by_Language{$Language{$file}} };\n        if ($Filters_by_Language_Language_file) {\n            if ($Language{$file} eq \"(unknown)\") {\n                $p_ignored{$file} = \"language unknown (#1)\";\n            } else {\n                $p_ignored{$file} = \"missing Filters_by_Language{$Language{$file}}\";\n            }\n            next;\n        }\n\n        my ($all_line_count, $blank_count, $comment_count, $code_count) = (0, 0, 0, 0);\n        if (!$opt_only_count_files) {\n            if ($opt_use_sloccount and $Language{$file} =~ /^(C|C\\+\\+|XML|PHP|Pascal|Java)$/) {\n                chomp ($blank_count     = `grep -cv \\\"[^[:space:]]\\\" '$file'`);\n                chomp ($all_line_count  = `cat '$file' | wc -l`);\n                if      ($Language{$file} =~ /^(C|C\\+\\+)$/) {\n                    $code_count = `cat '$file' | c_count      | head -n 1`;\n                } elsif ($Language{$file} eq \"XML\") {\n                    $code_count = `cat '$file' | xml_count    | head -n 1`;\n                } elsif ($Language{$file} eq \"PHP\") {\n                    $code_count = `cat '$file' | php_count    | head -n 1`;\n                } elsif ($Language{$file} eq \"Pascal\") {\n                    $code_count = `cat '$file' | pascal_count | head -n 1`;\n                } elsif ($Language{$file} eq \"Java\") {\n                    $code_count = `cat '$file' | java_count   | head -n 1`;\n                } else {\n                    die \"SLOCCount match failure: file=[$file] lang=[$Language{$file}]\";\n                }\n                $code_count = substr($code_count, 0, -2);\n                $comment_count = $all_line_count - $code_count - $blank_count;\n            } else {\n                ($all_line_count,\n                $blank_count   ,\n                $comment_count ,) = call_counter($file, $Language{$file},\n                                                 $rha_ignore_regex, \\@Errors);\n                $code_count = $all_line_count - $blank_count - $comment_count;\n            }\n        }\n\n        if ($opt_by_file) {\n            $p_rbf{$file}{'code'   } = $code_count     ;\n            $p_rbf{$file}{'blank'  } = $blank_count    ;\n            $p_rbf{$file}{'comment'} = $comment_count  ;\n            $p_rbf{$file}{'lang'   } = $Language{$file};\n            $p_rbf{$file}{'nFiles' } = 1;\n        } else {\n            $p_rbf{$file} = 1;  # just keep track of counted files\n        }\n\n        $p_rbl{$Language{$file}}{'nFiles'}++;\n        $p_rbl{$Language{$file}}{'code'}    += $code_count   ;\n        $p_rbl{$Language{$file}}{'blank'}   += $blank_count  ;\n        $p_rbl{$Language{$file}}{'comment'} += $comment_count;\n\n    }\n    print \"<- count_files()\\n\" if $opt_v > 2;\n    return {\n        \"ignored\" => \\%p_ignored,\n        \"errors\"  => \\@p_errors,\n        \"results_by_file\" => \\%p_rbf,\n        \"results_by_language\" => \\%p_rbl,\n    }\n} # 1}}}\nsub count_filesets {                         # {{{1\n    my ($fset_a,\n        $fset_b,\n        $files_added,\n        $files_removed,\n        $file_pairs,\n        $counter_type,\n        $language_hash,\n        $rha_ignore_regex,\n        $rh_Ignored) = @_;\n    print \"-> count_filesets()\\n\" if $opt_v > 2;\n    my @p_errors = ();\n    my %p_alignment = ();\n    my %p_ignored = ();\n    my %p_rbl = ();\n    my %p_rbf = ();\n    my %p_dbl = ();\n    my %p_dbf = ();\n    my %Language = %$language_hash;\n\n    my $nCounted = 0;\n\n    my %already_counted = (); # already_counted{ filename } = 1\n\n    if (!@$file_pairs) {\n        # Special case where all files were either added or deleted.\n        # In this case, one of these arrays will be empty:\n        #   @files_added, @files_removed\n        # so loop over both to cover both cases.\n        my $status = @$files_added ? 'added' : 'removed';\n        my $fset = @$files_added ? $fset_b : $fset_a;\n        foreach my $file (@$files_added, @$files_removed) {\n            next unless defined $Language{$fset}{$file};\n            my $Lang = $Language{$fset}{$file};\n            next if $Lang eq '(unknown)';\n            if ($Exclude_Language{$Lang}) {\n                $p_ignored{$file} = \"--exclude-lang=$Lang\";\n                next;\n            }\n\n            my ($all_line_count,\n                $blank_count   ,\n                $comment_count ,\n                ) = call_counter($file, $Lang, $rha_ignore_regex, \\@p_errors);\n            $already_counted{$file} = 1;\n            my $code_count = $all_line_count-$blank_count-$comment_count;\n            if ($opt_by_file) {\n                $p_dbf{$file}{'code'   }{$status} += $code_count   ;\n                $p_dbf{$file}{'blank'  }{$status} += $blank_count  ;\n                $p_dbf{$file}{'comment'}{$status} += $comment_count;\n                $p_dbf{$file}{'lang'   }{$status}  = $Lang         ;\n                $p_dbf{$file}{'nFiles' }{$status} += 1             ;\n            }\n            $p_dbl{$Lang}{'code'   }{$status} += $code_count   ;\n            $p_dbl{$Lang}{'blank'  }{$status} += $blank_count  ;\n            $p_dbl{$Lang}{'comment'}{$status} += $comment_count;\n            $p_dbl{$Lang}{'nFiles' }{$status} += 1             ;\n        }\n    }\n\n    #use Data::Dumper::Simple;\n    #use Data::Dumper;\n    #print Dumper(\\@files_added, \\@files_removed, \\@file_pairs);\n    #print \"after align_by_pairs:\\n\";\n    #print \"added:\\n\";\n\n    foreach my $f (@$files_added) {\n        next if $already_counted{$f};\n        #printf \"%10s -> %s\\n\", $f, $Language{$fh[$F+1]}{$f};\n        # Don't proceed unless the file (both L and R versions)\n        # is in a known language.\n        next if $opt_include_ext\n            and not $Include_Ext{ file_extension($f) };\n        if (!defined $Language{$fset_b}{$f}) {\n            $p_ignored{$f} = \"excluded or unknown language\";\n            next;\n        }\n        next if $opt_include_lang\n            and not $Include_Language{lc($Language{$fset_b}{$f})};\n        my $this_lang = $Language{$fset_b}{$f};\n        if (!defined  $Language{$fset_b}{$f}) {\n            # shouldn't happen but could get here if using\n            # --diff-list-file which bypasses earlier checks\n            $p_ignored{$f} = \"empty or uncharacterizeable file\";\n            next;\n        }\n        if ($this_lang eq \"(unknown)\") {\n            $p_ignored{$f} = \"unknown language\";\n            next;\n        }\n        if ($Exclude_Language{$this_lang}) {\n            $p_ignored{$f} = \"--exclude-lang=$this_lang\";\n            next;\n        }\n        $p_alignment{\"added\"}{sprintf \"  + %s ; %s\\n\", $f, $this_lang} = 1;\n        ++$p_dbl{ $this_lang }{'nFiles'}{'added'};\n        # Additionally, add contents of file $f to\n        # Delta_by_File{$f}{comment/blank/code}{'added'}\n        # Delta_by_Language{$lang}{comment/blank/code}{'added'}\n        # via the $p_dbl and $p_dbf variables.\n        my ($all_line_count,\n            $blank_count   ,\n            $comment_count ,\n           ) = call_counter($f, $this_lang, $rha_ignore_regex, \\@p_errors);\n        $p_dbl{ $this_lang }{'comment'}{'added'} += $comment_count;\n        $p_dbl{ $this_lang }{'blank'}{'added'}   += $blank_count;\n        $p_dbl{ $this_lang }{'code'}{'added'}    +=\n           $all_line_count - $blank_count - $comment_count;\n        $p_dbf{ $f }{'comment'}{'added'} = $comment_count;\n        $p_dbf{ $f }{'blank'}{'added'}   = $blank_count;\n        $p_dbf{ $f }{'code'}{'added'}    =\n           $all_line_count - $blank_count - $comment_count;\n    }\n\n    #print \"removed:\\n\";\n    foreach my $f (@$files_removed) {\n        next if $already_counted{$f};\n        # Don't proceed unless the file (both L and R versions)\n        # is in a known language.\n        next if $opt_include_ext\n            and not $Include_Ext{ file_extension($f) };\n        next if $opt_include_lang\n            and (not defined $Language{$fset_a}{$f}\n             or  not defined $Include_Language{lc($Language{$fset_a}{$f})});\n        my $this_lang = $Language{$fset_a}{$f};\n        if ((not defined $this_lang) or ($this_lang eq \"(unknown)\")) {\n            $p_ignored{$f} = \"unknown language\";\n            next;\n        }\n        if ($Exclude_Language{$this_lang}) {\n            $p_ignored{$f} = \"--exclude-lang=$this_lang\";\n            next;\n        }\n        ++$p_dbl{ $this_lang }{'nFiles'}{'removed'};\n        $p_alignment{\"removed\"}{sprintf \"  - %s ; %s\\n\", $f, $this_lang} = 1;\n        #printf \"%10s -> %s\\n\", $f, $Language{$fh[$F  ]}{$f};\n        # Additionally, add contents of file $f to\n        #        Delta_by_File{$f}{comment/blank/code}{'removed'}\n        #        Delta_by_Language{$lang}{comment/blank/code}{'removed'}\n        # via the $p_dbl and $p_dbf variables.\n        my ($all_line_count,\n            $blank_count   ,\n            $comment_count ,\n           ) = call_counter($f, $this_lang, $rha_ignore_regex, \\@p_errors);\n        $p_dbl{ $this_lang}{'comment'}{'removed'} += $comment_count;\n        $p_dbl{ $this_lang}{'blank'}{'removed'}   += $blank_count;\n        $p_dbl{ $this_lang}{'code'}{'removed'}    +=\n             $all_line_count - $blank_count - $comment_count;\n        $p_dbf{ $f }{'comment'}{'removed'} = $comment_count;\n        $p_dbf{ $f }{'blank'}{'removed'}   = $blank_count;\n        $p_dbf{ $f }{'code'}{'removed'}    =\n            $all_line_count - $blank_count - $comment_count;\n    }\n\n    my $n_file_pairs_compared = 0;\n    # Don't know ahead of time how many file pairs will be compared\n    # since duplicates are weeded out below.  The answer is\n    # scalar @file_pairs only if there are no duplicates.\n\n    foreach my $pair (@$file_pairs) {\n        my $file_L = $pair->[0];\n        my $file_R = $pair->[1];\n        if ($ON_WINDOWS) {\n            $file_L = lc $file_L;\n            $file_R = lc $file_R;\n        }\n        my $Lang_L = $Language{$fset_a}{$file_L};\n        my $Lang_R = $Language{$fset_b}{$file_R};\n#use Data::Dumper;\n#print \"Language: \", Dumper(\\%Language);\n#die \"L undefined\" unless defined $Language{$fset_a}{$file_L};\n#die \"R undefined\" unless defined $Language{$fset_b}{$file_R};\n#print \"file_L=$file_L  file_R=$file_R\\n\";\n#print \"fset_a=$fset_a  $Language{$fset_a}{$file_L}\\n\";\n#print \"fset_b=$fset_b  $Language{$fset_b}{$file_R}\\n\";\n        # handle cases where one side of the pair couldn't be identified\n        if      ( defined($Lang_L) and !defined($Lang_R)) {\n            $Lang_R = $Lang_L;\n            $Language{$fset_b}{$file_R} = $Lang_R;\n        } elsif (!defined($Lang_L) and  defined($Lang_R)) {\n            $Lang_L = $Lang_R;\n            $Language{$fset_a}{$file_L} = $Lang_L;\n        } elsif (!defined($Lang_L) or  !defined($Lang_R)) {\n            print \" -> count_filesets skipping $file_L, $file_R \",\n                  \"because language cannot be inferred\\n\" if $opt_v;\n            next;\n        }\n#print \"main step 6 file_L=$file_L ($Lang_L)   file_R=$file_R ($Lang_R)\\n\";\n        ++$nCounted;\n        printf \"Counting:  %d\\r\", $nCounted\n             unless ($counter_type or !$opt_progress_rate or ($nCounted % $opt_progress_rate));\n        next if $p_ignored{$file_L} or $p_ignored{$file_R};\n\n        # filter out non-included extensions\n        if ($opt_include_ext  and not $Include_Ext{ file_extension($file_L) }\n                              and not $Include_Ext{ file_extension($file_R) }) {\n            $p_ignored{$file_L} = \"not in --include-ext=$opt_include_ext\";\n            $p_ignored{$file_R} = \"not in --include-ext=$opt_include_ext\";\n            next;\n        }\n        # filter out non-included languages\n        if ($opt_include_lang and not $Include_Language{lc($Lang_L)}\n                              and not $Include_Language{lc($Lang_R)}) {\n            $p_ignored{$file_L} = \"not in --include-lang=$opt_include_lang\";\n            $p_ignored{$file_R} = \"not in --include-lang=$opt_include_lang\";\n            next;\n        }\n        # filter out excluded or unrecognized languages\n        if ($Exclude_Language{$Lang_L} or $Exclude_Language{$Lang_R}) {\n            $p_ignored{$file_L} = \"--exclude-lang=$Lang_L\";\n            $p_ignored{$file_R} = \"--exclude-lang=$Lang_R\";\n            next;\n        }\n\n        my $not_Filters_by_Language_Lang_LR = 0;\n        #print \"file_LR = [$file_L] [$file_R]\\n\";\n        #print \"Lang_LR = [$Lang_L] [$Lang_R]\\n\";\n        if (($Lang_L eq \"(unknown)\") or\n            ($Lang_R eq \"(unknown)\") or\n            !(@{$Filters_by_Language{$Lang_L} }) or\n            !(@{$Filters_by_Language{$Lang_R} })) {\n            $not_Filters_by_Language_Lang_LR = 1;\n        }\n        if ($not_Filters_by_Language_Lang_LR) {\n            if (($Lang_L eq \"(unknown)\") or ($Lang_R eq \"(unknown)\")) {\n                $p_ignored{$fset_a}{$file_L} = \"language unknown (#1)\";\n                $p_ignored{$fset_b}{$file_R} = \"language unknown (#1)\";\n            } else {\n                $p_ignored{$fset_a}{$file_L} = \"missing Filters_by_Language{$Lang_L}\";\n                $p_ignored{$fset_b}{$file_R} = \"missing Filters_by_Language{$Lang_R}\";\n            }\n            next;\n        }\n\n        # filter out explicitly excluded files\n        if ($opt_exclude_list_file and\n            ($rh_Ignored->{$file_L} or $rh_Ignored->{$file_R})) {\n            my $msg_2;\n            if ($rh_Ignored->{$file_L}) {\n                $msg_2 = \"$file_L (paired to $file_R)\";\n            } else {\n                $msg_2 = \"$file_R (paired to $file_L)\";\n            }\n            my $msg_1 = \"in --exclude-list-file=$opt_exclude_list_file\";\n            $p_ignored{$file_L} = \"$msg_1, $msg_2\";\n            $p_ignored{$file_R} = \"$msg_1, $msg_2\";\n            next;\n        }\n\n        #print \"DIFF($file_L, $file_R)\\n\";\n        # step 0: compare the two files' contents\n        chomp ( my @lines_L = read_file($file_L) );\n        chomp ( my @lines_R = read_file($file_R) );\n        my $language_file_L = \"\";\n        if (defined $Language{$fset_a}{$file_L}) {\n            $language_file_L = $Language{$fset_a}{$file_L};\n        } else {\n            # files $file_L and $file_R do not contain known language\n            next;\n        }\n\n        my $contents_are_same = 1;\n        if (scalar @lines_L == scalar @lines_R) {\n            # same size, must compare line-by-line\n            for (my $i = 0; $i < scalar @lines_L; $i++) {\n               if ($lines_L[$i] ne $lines_R[$i]) {\n                   $contents_are_same = 0;\n                   last;\n               }\n            }\n            if ($contents_are_same) {\n                ++$p_dbl{$language_file_L}{'nFiles'}{'same'};\n            } else {\n                ++$p_dbl{$language_file_L}{'nFiles'}{'modified'};\n            }\n        } else {\n            $contents_are_same = 0;\n            # different sizes, contents have changed\n            ++$p_dbl{$language_file_L}{'nFiles'}{'modified'};\n        }\n\n        if ($opt_diff_alignment) {\n            my $str =  \"$file_L | $file_R ; $language_file_L\";\n            if ($contents_are_same) {\n                $p_alignment{\"pairs\"}{\"  == $str\"} = 1;\n            } else {\n                $p_alignment{\"pairs\"}{\"  != $str\"} = 1;\n            }\n            ++$n_file_pairs_compared;\n        }\n\n        my ($all_line_count_L, $blank_count_L   , $comment_count_L ,\n            $all_line_count_R, $blank_count_R   , $comment_count_R , )  = (0,0,0,0,0,0,);\n        if (!$contents_are_same) {\n            # step 1: identify comments in both files\n            #print \"Diff blank removal L language= $Lang_L\";\n            #print \" scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n            my @original_minus_blanks_L\n                    = rm_blanks(  \\@lines_L, $Lang_L, \\%EOL_Continuation_re);\n            #print \"1: scalar(original_minus_blanks_L)=\", scalar @original_minus_blanks_L, \"\\n\";\n            @lines_L    = @original_minus_blanks_L;\n            #print \"2: scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n            @lines_L    = add_newlines(\\@lines_L); # compensate for rm_comments()\n            @lines_L    = rm_comments( \\@lines_L, $Lang_L, $file_L,\n                                       \\%EOL_Continuation_re);\n            #print \"3: scalar(lines_L)=\", scalar @lines_L, \"\\n\";\n\n            #print \"Diff blank removal R language= $Lang_R\\n\";\n            my @original_minus_blanks_R\n                    = rm_blanks(  \\@lines_R, $Lang_R, \\%EOL_Continuation_re);\n            @lines_R    = @original_minus_blanks_R;\n            @lines_R    = add_newlines(\\@lines_R); # taken away by rm_comments()\n            @lines_R    = rm_comments( \\@lines_R, $Lang_R, $file_R,\n                                       \\%EOL_Continuation_re);\n\n            my (@diff_LL, @diff_LR, );\n                   array_diff( $file_L                  ,   # in\n                       \\@original_minus_blanks_L ,   # in\n                       \\@lines_L                 ,   # in\n                       \"comment\"                 ,   # in\n                       \\@diff_LL, \\@diff_LR      ,   # out\n                       \\@p_errors);                    # in/out\n\n            my (@diff_RL, @diff_RR, );\n                    array_diff( $file_R                  ,   # in\n                       \\@original_minus_blanks_R ,   # in\n                       \\@lines_R                 ,   # in\n                       \"comment\"                 ,   # in\n                       \\@diff_RL, \\@diff_RR      ,   # out\n                       \\@p_errors);                    # in/out\n            # each line of each file is now classified as\n            # code or comment\n            #use Data::Dumper;\n            #print Dumper(\"diff_LL\", \\@diff_LL, \"diff_LR\", \\@diff_LR, );\n            #print Dumper(\"diff_RL\", \\@diff_RL, \"diff_RR\", \\@diff_RR, );\n            #die;\n\n            # step 2: separate code from comments for L and R files\n            my @code_L = ();\n            my @code_R = ();\n            my @comm_L = ();\n            my @comm_R = ();\n            foreach my $line_info (@diff_LL) {\n                if      ($line_info->{'type'} eq \"code\"   ) {\n                    push @code_L, $line_info->{char};\n                } elsif ($line_info->{'type'} eq \"comment\") {\n                    push @comm_L, $line_info->{char};\n                } else {\n                    die \"Diff unexpected line type \",\n                        $line_info->{'type'}, \"for $file_L line \",\n                        $line_info->{'lnum'};\n                }\n            }\n\n            foreach my $line_info (@diff_RL) {\n                if      ($line_info->{type} eq \"code\"   ) {\n                    push @code_R, $line_info->{'char'};\n                } elsif ($line_info->{type} eq \"comment\") {\n                    push @comm_R, $line_info->{'char'};\n                } else {\n                    die \"Diff unexpected line type \",\n                        $line_info->{'type'}, \"for $file_R line \",\n                        $line_info->{'lnum'};\n                }\n            }\n\n            if ($opt_ignore_whitespace) {\n                # strip all whitespace from each line of source code\n                # and comments then use these stripped arrays in diffs\n                foreach (@code_L) { s/\\s+//g }\n                foreach (@code_R) { s/\\s+//g }\n                foreach (@comm_L) { s/\\s+//g }\n                foreach (@comm_R) { s/\\s+//g }\n            }\n            if ($opt_ignore_case) {\n                # change all text to lowercase in diffs\n                foreach (@code_L) { $_ = lc }\n                foreach (@code_R) { $_ = lc }\n                foreach (@comm_L) { $_ = lc }\n                foreach (@comm_R) { $_ = lc }\n            }\n            my $n_code_removed_L = 0;\n            my $n_code_removed_R = 0;\n            @code_L = apply_ignores(\\@code_L, $Lang_L, $file_L, $rha_ignore_regex,\n                                    \\$n_code_removed_L);\n            @code_R = apply_ignores(\\@code_R, $Lang_R, $file_R, $rha_ignore_regex,\n                                    \\$n_code_removed_R);\n            # step 3: compute code diffs\n            array_diff(\"$file_L v. $file_R\"   ,   # in\n                       \\@code_L               ,   # in\n                       \\@code_R               ,   # in\n                       \"revision\"             ,   # in\n                       \\@diff_LL, \\@diff_LR   ,   # out\n                       \\@p_errors);                 # in/out\n            #print Dumper(\"diff_LL\", \\@diff_LL, \"diff_LR\", \\@diff_LR, );\n            #print Dumper(\"diff_LR\", \\@diff_LR);\n            foreach my $line_info (@diff_LR) {\n                my $status = $line_info->{'desc'}; # same|added|removed|modified\n                ++$p_dbl{$Lang_L}{'code'}{$status};\n                if ($opt_by_file) {\n                    ++$p_dbf{$file_L}{'code'}{$status};\n                }\n            }\n            #use Data::Dumper;\n            #print Dumper(\"code diffs:\", \\@diff_LL, \\@diff_LR);\n\n            # step 4: compute comment diffs\n            array_diff(\"$file_L v. $file_R\"   ,   # in\n                       \\@comm_L               ,   # in\n                       \\@comm_R               ,   # in\n                       \"revision\"             ,   # in\n                       \\@diff_LL, \\@diff_LR   ,   # out\n                       \\@Errors);                 # in/out\n            #print Dumper(\"comment diff_LR\", \\@diff_LR);\n            foreach my $line_info (@diff_LR) {\n                my $status = $line_info->{'desc'}; # same|added|removed|modified\n                ++$p_dbl{$Lang_L}{'comment'}{$status};\n                if ($opt_by_file) {\n                    ++$p_dbf{$file_L}{'comment'}{$status};\n                }\n            }\n            #print Dumper(\"comment diffs:\", \\@diff_LL, \\@diff_LR);\n\n            # step 5: compute difference in blank lines (kind of pointless)\n            next if $Lang_L eq '(unknown)' or\n                    $Lang_R eq '(unknown)';\n            ($all_line_count_L,\n             $blank_count_L   ,\n             $comment_count_L ,\n            ) = call_counter($file_L, $Lang_L, $rha_ignore_regex, \\@Errors);\n\n            ($all_line_count_R,\n             $blank_count_R   ,\n             $comment_count_R ,\n            ) = call_counter($file_R, $Lang_R, $rha_ignore_regex, \\@Errors);\n        } else {\n            # L and R file contents are identical, no need to diff\n            ($all_line_count_L,\n             $blank_count_L   ,\n             $comment_count_L ,\n            ) = call_counter($file_L, $Lang_L, $rha_ignore_regex, \\@Errors);\n            $all_line_count_R = $all_line_count_L;\n            $blank_count_R    = $blank_count_L   ;\n            $comment_count_R  = $comment_count_L ;\n            my $code_lines_R  = $all_line_count_R - ($blank_count_R + $comment_count_R);\n            $p_dbl{$Lang_L}{'blank'}{'same'}   += $blank_count_R;\n            $p_dbl{$Lang_L}{'comment'}{'same'} += $comment_count_R;\n            $p_dbl{$Lang_L}{'code'}{'same'}    += $code_lines_R;\n            if ($opt_by_file) {\n                $p_dbf{$file_L}{'blank'}{'same'}   += $blank_count_R;\n                $p_dbf{$file_L}{'comment'}{'same'} += $comment_count_R;\n                $p_dbf{$file_L}{'code'}{'same'}    += $code_lines_R;\n            }\n        }\n\n        if ($blank_count_L <  $blank_count_R) {\n            my $D = $blank_count_R - $blank_count_L;\n            $p_dbl{$Lang_L}{'blank'}{'added'}   += $D;\n        } else {\n            my $D = $blank_count_L - $blank_count_R;\n            $p_dbl{$Lang_L}{'blank'}{'removed'} += $D;\n        }\n        if ($opt_by_file) {\n            if ($blank_count_L <  $blank_count_R) {\n                my $D = $blank_count_R - $blank_count_L;\n                $p_dbf{$file_L}{'blank'}{'added'}   += $D;\n            } else {\n                my $D = $blank_count_L - $blank_count_R;\n                $p_dbf{$file_L}{'blank'}{'removed'} += $D;\n            }\n        }\n\n        my $code_count_L = $all_line_count_L-$blank_count_L-$comment_count_L;\n        if ($opt_by_file) {\n            $p_rbf{$file_L}{'code'   } = $code_count_L    ;\n            $p_rbf{$file_L}{'blank'  } = $blank_count_L   ;\n            $p_rbf{$file_L}{'comment'} = $comment_count_L ;\n            $p_rbf{$file_L}{'lang'   } = $Lang_L          ;\n            $p_rbf{$file_L}{'nFiles' } = 1                ;\n        } else {\n            $p_rbf{$file_L} = 1;  # just keep track of counted files\n        }\n\n        $p_rbl{$Lang_L}{'nFiles'}++;\n        $p_rbl{$Lang_L}{'code'}    += $code_count_L   ;\n        $p_rbl{$Lang_L}{'blank'}   += $blank_count_L  ;\n        $p_rbl{$Lang_L}{'comment'} += $comment_count_L;\n    }\n\n    print \"<- count_filesets()\\n\" if $opt_v > 2;\n    return {\n        \"ignored\" => \\%p_ignored,\n        \"errors\"  => \\@p_errors,\n        \"results_by_file\" => \\%p_rbf,\n        \"results_by_language\" => \\%p_rbl,\n        \"delta_by_file\" => \\%p_dbf,\n        \"delta_by_language\" => \\%p_dbl,\n        \"alignment\" => \\%p_alignment,\n        \"n_filepairs_compared\" => $n_file_pairs_compared\n    }\n} # 1}}}\nsub apply_ignores {                          # {{{1\n    my ($ra_lines             , # in\n        $language             , # in\n        $file                 , # in\n        $rha_ignore_regex     , # in\n        $rs_lines_code_removed, # out\n       ) = @_;\n    my @output = ();\n    print \"-> apply_ignores($file, $language)\\n\" if $opt_v > 2;\n\n    if (%{$rha_ignore_regex} and defined($rha_ignore_regex->{$language})) {\n        foreach my $line (@{$ra_lines}) {\n            my $keep = 1;\n            foreach my $regex (@{$rha_ignore_regex->{$language}}) {\n                if ($line =~ m{$regex}) {\n                    print \"apply_ignores reject '$line' in $file because of '$regex'\\n\"\n                        if $opt_v > 4;\n                    $keep = 0;\n                    ++${$rs_lines_code_removed};\n                    last;\n                }\n            }\n            push @output, $line if $keep;\n        }\n    } else {\n        @output = @{$ra_lines};\n    }\n\n    print \"<- apply_ignores(${$rs_lines_code_removed})\\n\" if $opt_v > 2;\n    return @output;\n} # 1}}}\nsub write_alignment_data {                   # {{{1\n    my ($filename, $n_filepairs_compared, $data ) = @_;\n    print \"-> write_alignment_data($filename)\\n\" if $opt_v > 2;\n    my @output = ();\n    if ( $data->{'added'} ) {\n        my %added_lines = %{$data->{'added'}};\n        push (@output, \"Files added: \" . (scalar keys %added_lines) . \"\\n\");\n        foreach my $line ( sort keys %added_lines ) {\n            push (@output, $line);\n        }\n        push (@output, \"\\n\" );\n    }\n    if ( $data->{'removed'} ) {\n        my %removed_lines = %{$data->{'removed'}};\n        push (@output, \"Files removed: \" . (scalar keys %removed_lines) . \"\\n\");\n        foreach my $line ( sort keys %removed_lines ) {\n            push (@output, $line);\n        }\n        push (@output, \"\\n\");\n    }\n    if ( $data->{'pairs'} ) {\n        my %pairs = %{$data->{'pairs'}};\n        push (@output, \"File pairs compared: \" . $n_filepairs_compared . \"\\n\");\n        foreach my $pair ( sort keys %pairs ) {\n            push (@output, $pair);\n        }\n    }\n    write_file($filename, {}, @output);\n    print \"<- write_alignment_data\\n\" if $opt_v > 2;\n} # 1}}}\nsub exclude_dir_validates {                  # {{{1\n    my ($rh_Exclude_Dir) = @_;\n    # $opt_v hasn't been set yet\n    # print \"-> exclude_dir_validates\\n\" if $opt_v > 2;\n    my $is_OK = 1;\n    foreach my $dir (keys %{$rh_Exclude_Dir}) {\n        if (($ON_WINDOWS and $dir =~ m{\\\\}) or ($dir =~ m{/})) {\n            $is_OK = 0;\n            warn \"--exclude-dir '$dir' :  cannot specify directory paths\\n\";\n        }\n    }\n    if (!$is_OK) {\n        warn \"Use '--fullpath --not-match-d=REGEX' instead\\n\";\n    }\n    # print \"<- exclude_dir_validates\\n\" if $opt_v > 2;\n    return $is_OK;\n} # 1}}}\nsub process_exclude_list_file {              # {{{1\n    my ($list_file      , # in\n        $rh_exclude_dir , # out\n        $rh_ignored     , # out\n       ) = @_;\n    # note: references global @file_list\n    print \"-> process_exclude_list_file($list_file)\\n\" if $opt_v > 2;\n    # reject a specific set of files and/or directories\n    my @reject_list   = ($list_file); # don't count the exclude list file itself\n    push @reject_list, read_list_file($list_file);\n    my @file_reject_list = ();\n    foreach my $F_or_D (@reject_list) {\n        if (is_dir($F_or_D)) {\n            $rh_exclude_dir->{$F_or_D} = 1;\n        } elsif (is_file($F_or_D)) {\n            push @file_reject_list, $F_or_D;\n        }\n    }\n\n    # Normalize file names for better comparison.\n    my %normalized_input   = normalize_file_names(@file_list);\n    my %normalized_reject  = normalize_file_names(@file_reject_list);\n    my %normalized_exclude = normalize_file_names(keys %{$rh_exclude_dir});\n    foreach my $F (keys %normalized_input) {\n        if ($normalized_reject{$F} or is_excluded($F, \\%normalized_exclude)) {\n            my $orig_F = $normalized_input{$F};\n            $rh_ignored->{$orig_F} = \"listed in exclusion file $opt_exclude_list_file\";\n            print \"Ignoring $orig_F because it appears in $opt_exclude_list_file\\n\"\n                if $opt_v > 1;\n        }\n    }\n\n    print \"<- process_exclude_list_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub combine_results {                        # {{{1\n    # returns 1 if the inputs are categorized by language\n    #         0 if no identifiable language was found\n    my ($ra_report_files, # in\n        $report_type    , # in  \"by language\" or \"by report file\"\n        $rhh_count      , # out count{TYPE}{nFiles|code|blank|comment|scaled}\n        $rhaa_Filters_by_Language , # in\n       ) = @_;\n\n    print \"-> combine_results(report_type=$report_type)\\n\" if $opt_v > 2;\n    my $found_language = 0;\n\n    foreach my $file (@{$ra_report_files}) {\n        my $n_results_found = 0;\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n        while (<$IN>) {\n            next if /^(http|Language|SUM|-----)/;\n            if (!$opt_by_file  and\n                m{^(.*?)\\s+         # language\n                   (\\d+)\\s+         # files\n                   (\\d+)\\s+         # blank\n                   (\\d+)\\s+         # comments\n                   (\\d+)\\s+         # code\n                   (                #    next four entries missing with -no3\n                   x\\s+             # x\n                   \\d+\\.\\d+\\s+      # scale\n                   =\\s+             # =\n                   (\\d+\\.\\d+)\\s*    # scaled code\n                   )?\n                   $}x) {\n                if ($report_type eq \"by language\") {\n                    if (!defined $rhaa_Filters_by_Language->{$1}) {\n                        warn \"Unrecognized language '$1' in $file ignored\\n\";\n                        next;\n                    }\n                    # above test necessary to avoid trying to sum reports\n                    # of reports (which have no language breakdown).\n                    $found_language = 1;\n                    $rhh_count->{$1   }{'nFiles' } += $2;\n                    $rhh_count->{$1   }{'blank'  } += $3;\n                    $rhh_count->{$1   }{'comment'} += $4;\n                    $rhh_count->{$1   }{'code'   } += $5;\n                    $rhh_count->{$1   }{'scaled' } += $7 if $opt_3;\n                } else {\n                    $rhh_count->{$file}{'nFiles' } += $2;\n                    $rhh_count->{$file}{'blank'  } += $3;\n                    $rhh_count->{$file}{'comment'} += $4;\n                    $rhh_count->{$file}{'code'   } += $5;\n                    $rhh_count->{$file}{'scaled' } += $7 if $opt_3;\n                }\n                ++$n_results_found;\n            } elsif ($opt_by_file  and\n                m{^(.*?)\\s+         # language\n                   (\\d+)\\s+         # blank\n                   (\\d+)\\s+         # comments\n                   (\\d+)\\s+         # code\n                   (                #    next four entries missing with -no3\n                   x\\s+             # x\n                   \\d+\\.\\d+\\s+      # scale\n                   =\\s+             # =\n                   (\\d+\\.\\d+)\\s*    # scaled code\n                   )?\n                   $}x) {\n                if ($report_type eq \"by language\") {\n                    next unless %{$rhaa_Filters_by_Language->{$1}};\n                    # above test necessary to avoid trying to sum reports\n                    # of reports (which have no language breakdown).\n                    $found_language = 1;\n                    $rhh_count->{$1   }{'nFiles' } +=  1;\n                    $rhh_count->{$1   }{'blank'  } += $2;\n                    $rhh_count->{$1   }{'comment'} += $3;\n                    $rhh_count->{$1   }{'code'   } += $4;\n                    $rhh_count->{$1   }{'scaled' } += $6 if $opt_3;\n                } else {\n                    $rhh_count->{$file}{'nFiles' } +=  1;\n                    $rhh_count->{$file}{'blank'  } += $2;\n                    $rhh_count->{$file}{'comment'} += $3;\n                    $rhh_count->{$file}{'code'   } += $4;\n                    $rhh_count->{$file}{'scaled' } += $6 if $opt_3;\n                }\n                ++$n_results_found;\n            }\n        }\n        warn \"No counts found in $file--is the file format correct?\\n\"\n            unless $n_results_found;\n    }\n    print \"<- combine_results\\n\" if $opt_v > 2;\n    return $found_language;\n} # 1}}}\nsub compute_denominator {                    # {{{1\n    my ($method, $nCode, $nComment, $nBlank, ) = @_;\n    print \"-> compute_denominator\\n\" if $opt_v > 2;\n    my %den        = ( \"c\" => $nCode );\n       $den{\"cm\"}  = $den{\"c\"}  + $nComment;\n       $den{\"cmb\"} = $den{\"cm\"} + $nBlank;\n       $den{\"cb\"}  = $den{\"c\"}  + $nBlank;\n\n    print \"<- compute_denominator\\n\" if $opt_v > 2;\n    return $den{ $method };\n} # 1}}}\nsub yaml_to_json_separators {                # {{{1\n    # YAML and JSON are closely related.  Their differences can be captured\n    # by trailing commas ($C), braces ($open_B, $close_B), and\n    # quotes around text ($Q).\n    print \"-> yaml_to_json_separators()\\n\" if $opt_v > 2;\n    my ($Q, $open_B, $close_B, $start, $C);\n    if ($opt_json) {\n       $C       = ',';\n       $Q       = '\"';\n       $open_B  = '{';\n       $close_B = '}';\n       $start   = '{';\n    } else {\n       $C       = '';\n       $Q       = '' ;\n       $open_B  = '' ;\n       $close_B = '';\n       $start   = \"---\\n# $URL\\n\";\n    }\n    print \"<- yaml_to_json_separators()\\n\" if $opt_v > 2;\n    return ($Q, $open_B, $close_B, $start, $C);\n} # 1}}}\nsub diff_report     {                        # {{{1\n    # returns an array of lines containing the results\n    print \"-> diff_report\\n\" if $opt_v > 2;\n\n    if ($opt_xml) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_xml_report(@_)\n    } elsif ($opt_yaml) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_yaml_report(@_)\n    } elsif ($opt_json) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_json_report(@_)\n    } elsif ($opt_csv or $opt_md) {\n        print \"<- diff_report\\n\" if $opt_v > 2;\n        return diff_csv_report(@_)\n    }\n\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n        $rh_renamed , # in\n       ) = @_;\n    my %orig_case = ();\n    if ($ON_WINDOWS and $report_type eq \"by file\") {\n        # restore the original upper/lowercase version of the file name\n        foreach my $lc_file (sort keys %{$rhhh_count}) {\n          foreach my $cat (sort keys %{$rhhh_count->{$lc_file}}) {\n            foreach my $S (qw(added same modified removed)) {\n                $orig_case{ $upper_lower_map{$lc_file} }{$cat}{$S} =\n                           $rhhh_count->{$lc_file}{$cat}{$S};\n            }\n          }\n        }\n        $rhhh_count = \\%orig_case;\n    }\n\n#use Data::Dumper;\n#print \"diff_report: \", Dumper($rhhh_count), \"\\n\";\n    my @results       = ();\n\n    my $languages     = ();\n    my %sum           = (); # sum{nFiles|blank|comment|code}{same|modified|added|removed}\n    my $max_len       = 0;\n    foreach my $language (keys %{$rhhh_count}) {\n        foreach my $V (qw(nFiles blank comment code)) {\n            foreach my $S (qw(added same modified removed)) {\n                $rhhh_count->{$language}{$V}{$S} = 0 unless\n                    defined $rhhh_count->{$language}{$V}{$S};\n                $sum{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};\n            }\n        }\n        $max_len      = length($language) if length($language) > $max_len;\n    }\n    my $column_1_offset = 0;\n       $column_1_offset = $max_len - 17 if $max_len > 17;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $spacing_0 = 23;\n    my $spacing_1 = 13;\n    my $spacing_2 =  9;\n    my $spacing_3 = 17;\n    if (!$opt_3) {\n        $spacing_1 = 19;\n        $spacing_2 = 14;\n        $spacing_3 = 27;\n    }\n    $spacing_0 += $column_1_offset;\n    $spacing_1 += $column_1_offset;\n    $spacing_3 += $column_1_offset;\n    my %Format = (\n        '1' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_0}s \",\n               },\n        '2' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_3}s \",\n               },\n        '3' => { 'xml' => 'files_count=\"%d\" ',\n                 'txt' => '%6d ',\n               },\n        '4' => { 'xml' => 'blank=\"%d\" comment=\"%d\" code=\"%d\" ',\n                 'txt' => \"\\%${spacing_2}d \\%${spacing_2}d \\%${spacing_2}d\",\n               },\n        '5' => { 'xml' => 'blank=\"%.2f\" comment=\"%.2f\" code=\"%d\" ',\n                 'txt' => \"\\%3.2f \\%3.2f \\%${spacing_2}d\",\n               },\n        '6' => { 'xml' => 'factor=\"%.2f\" scaled=\"%.2f\" ',\n                 'txt' => ' x %6.2f = %14.2f',\n               },\n    );\n    my $Style = \"txt\";\n       $Style = \"xml\" if $opt_xml ;\n       $Style = \"xml\" if $opt_yaml;  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $opt_json;  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $opt_csv ;  # not a typo; just set to anything but txt\n\n    my $hyphen_line = sprintf \"%s\", '-' x (79 + $column_1_offset);\n       $hyphen_line = sprintf \"%s\", '-' x (68 + $column_1_offset)\n            if (!$opt_3) and (68 + $column_1_offset) > 79;\n    my $data_line  = \"\";\n    my $first_column;\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $first_column = \"Language\";\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $first_column = \"File\";\n        $BY_FILE      = 1;\n    } else {\n        $first_column = \"Report File\";\n    }\n\n    # column headers\n    if (!$opt_3 and $BY_FILE) {\n        my $spacing_n = $spacing_1 - 11;\n        $data_line  = sprintf \"%-${spacing_n}s\" , $first_column;\n    } else {\n        $data_line  = sprintf \"%-${spacing_1}s \", $first_column;\n    }\n    if ($BY_FILE) {\n        $data_line .= sprintf \"%${spacing_2}s\"   , \"\"     ;\n    } else {\n        $data_line .= sprintf \"%${spacing_2}s \"  , \"files\";\n    }\n    my $PCT_symbol = \"\";\n       $PCT_symbol = \" \\%\" if $opt_by_percent;\n    $data_line .= sprintf \"%${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n        \"blank${PCT_symbol}\"         ,\n        \"comment${PCT_symbol}\"       ,\n        \"code${PCT_symbol}\"          ;\n\n    if ($Style eq \"txt\") {\n        push @results, $data_line;\n        push @results, $hyphen_line;\n    }\n\n#use Data::Dumper;\n#print \"diff_report.Renamed:\\n\", Dumper($rh_renamed);\n\n    # sort diff output in descending order of cumulative entries\n    foreach my $lang_or_file (sort {\n                                ($rhhh_count->{$b}{'code'}{'added'}    +\n                                 $rhhh_count->{$b}{'code'}{'same'}     +\n                                 $rhhh_count->{$b}{'code'}{'modified'} +\n                                 $rhhh_count->{$b}{'code'}{'removed'}  )  <=>\n                                ($rhhh_count->{$a}{'code'}{'added'}    +\n                                 $rhhh_count->{$a}{'code'}{'same'}     +\n                                 $rhhh_count->{$a}{'code'}{'modified'} +\n                                 $rhhh_count->{$a}{'code'}{'removed'})\n                              or $a cmp $b }\n                                    keys %{$rhhh_count}) {\n\n        if ($BY_FILE) {\n            my $file = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n#print \"diff_report.file=$file (orig $lang_or_file)\\n\";\n            $file .= \" -> \" . $rh_renamed->{$file} if defined $rh_renamed->{$file};\n            push @results, $file;\n        } else {\n            push @results, $lang_or_file;\n        }\n        foreach my $S (qw(same modified added removed)) {\n            my $indent = $spacing_1 - 2;\n            my $line .= sprintf \" %-${indent}s\", $S;\n            if ($BY_FILE) {\n                $line .= sprintf \"   \";\n            } else {\n                $line .= sprintf \"  %${spacing_2}s\", $rhhh_count->{$lang_or_file}{'nFiles'}{$S};\n            }\n            if ($opt_by_percent) {\n                my $DEN = compute_denominator($opt_by_percent  ,\n                    $rhhh_count->{$lang_or_file}{'code'}{$S}   ,\n                    $rhhh_count->{$lang_or_file}{'comment'}{$S},\n                    $rhhh_count->{$lang_or_file}{'blank'}{$S}  );\n                if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {\n                    $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                        $rhhh_count->{$lang_or_file}{'blank'}{$S}   / $DEN * 100,\n                        $rhhh_count->{$lang_or_file}{'comment'}{$S} / $DEN * 100,\n                        $rhhh_count->{$lang_or_file}{'code'}{$S}    / $DEN * 100;\n                } else {\n                    $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                        0.0, 0.0, $rhhh_count->{$lang_or_file}{'code'}{$S}    ;\n                }\n            } else {\n                $line .= sprintf \" %${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n                    $rhhh_count->{$lang_or_file}{'blank'}{$S}   ,\n                    $rhhh_count->{$lang_or_file}{'comment'}{$S} ,\n                    $rhhh_count->{$lang_or_file}{'code'}{$S}    ;\n            }\n            push @results, $line;\n        }\n    }\n    push @results, $hyphen_line;\n    push @results, \"SUM:\";\n    my $sum_files    = 0;\n    my $sum_lines    = 0;\n    foreach my $S (qw(same modified added removed)) {\n        my $indent = $spacing_1 - 2;\n        my $line .= sprintf \" %-${indent}s\", $S;\n            if ($BY_FILE) {\n                $line .= sprintf \"   \";\n                $sum_files += 1;\n            } else {\n                $line .= sprintf \"  %${spacing_2}s\", $sum{'nFiles'}{$S};\n                $sum_files += $sum{'nFiles'}{$S};\n            }\n        if ($opt_by_percent) {\n            my $DEN = compute_denominator($opt_by_percent,\n                $sum{'code'}{$S}, $sum{'comment'}{$S}, $sum{'blank'}{$S});\n            if ($sum{'code'}{$S} > 0) {\n                $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                    $sum{'blank'}{$S}   / $DEN * 100,\n                    $sum{'comment'}{$S} / $DEN * 100,\n                    $sum{'code'}{$S}    / $DEN * 100;\n            } else {\n                $line .= sprintf \" %14.2f %14.2f %${spacing_2}s\",\n                    0.0, 0.0, $sum{'code'}{$S}    ;\n            }\n        } else {\n            $line .= sprintf \" %${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n                $sum{'blank'}{$S}   ,\n                $sum{'comment'}{$S} ,\n                $sum{'code'}{$S}    ;\n        }\n        $sum_lines += $sum{'blank'}{$S} + $sum{'comment'}{$S} + $sum{'code'}{$S};\n        push @results, $line;\n    }\n\n    my $header_line  = sprintf \"%s v %s\", $URL, $version;\n       $header_line .= sprintf(\"  T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                        $elapsed_sec           ,\n                        $sum_files/$elapsed_sec,\n                        $sum_lines/$elapsed_sec) unless $opt_sum_reports or $opt_hide_rate;\n    if ($Style eq \"txt\") {\n        unshift @results, output_header($header_line, $hyphen_line, $BY_FILE);\n    }\n\n    push @results, $hyphen_line;\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    print \"<- diff_report\\n\" if $opt_v > 2;\n\n    return @results;\n} # 1}}}\nsub xml_yaml_or_json_header {                # {{{1\n    my ($URL, $version, $elapsed_sec, $sum_files, $sum_lines, $by_file) = @_;\n    print \"-> xml_yaml_or_json_header\\n\" if $opt_v > 2;\n    my $header      = \"\";\n    my $file_rate   = $sum_files/$elapsed_sec;\n    my $line_rate   = $sum_lines/$elapsed_sec;\n    my $type        = \"\";\n       $type        = \"diff_\" if $opt_diff;\n    my $report_file = \"\";\n    if ($opt_report_file) {\n        my $Fname = $opt_report_file;\n        $Fname =~ s{\\\\}{\\\\\\\\}g if $ON_WINDOWS;\n        if ($opt_sum_reports) {\n            if ($by_file) {\n                $report_file = \"  <report_file>$Fname.file</report_file>\"\n            } else {\n                $report_file = \"  <report_file>$Fname.lang</report_file>\"\n            }\n        } else {\n            $report_file = \"  <report_file>$Fname</report_file>\"\n        }\n    }\n    if ($opt_xml) {\n        $header = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\";\n        $header .= \"\\n<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" . $opt_xsl . \"\\\"?>\" if $opt_xsl;\n        if ($opt_hide_rate) {\n            $header .= \"<${type}results>\n<header>\n  <cloc_url>$URL</cloc_url>\n  <cloc_version>$version</cloc_version>\n  <n_files>$sum_files</n_files>\n  <n_lines>$sum_lines</n_lines>\";\n        } else {\n            $header .= \"<${type}results>\n<header>\n  <cloc_url>$URL</cloc_url>\n  <cloc_version>$version</cloc_version>\n  <elapsed_seconds>$elapsed_sec</elapsed_seconds>\n  <n_files>$sum_files</n_files>\n  <n_lines>$sum_lines</n_lines>\n  <files_per_second>$file_rate</files_per_second>\n  <lines_per_second>$line_rate</lines_per_second>\";\n        }\n        $header .= \"\\n$report_file\"\n            if $opt_report_file;\n        $header .= \"\\n</header>\";\n        if (%git_metadata) {\n            foreach my $target (keys %git_metadata) {\n                $header .= \"\\n<source>\";\n                $header .= \"\\n  <target>$target</target>\";\n                $header .= \"\\n  <origin>$git_metadata{$target}{'origin'}</origin>\";\n                $header .= \"\\n  <branch>$git_metadata{$target}{'branch'}</branch>\";\n                $header .= \"\\n  <commit>$git_metadata{$target}{'commit'}</commit>\";\n                $header .= \"\\n</source>\";\n            }\n        }\n    } elsif ($opt_yaml or $opt_json) {\n        my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n        if ($opt_hide_rate) {\n            $header = \"${start}${Q}header${Q} : $open_B\n  ${Q}cloc_url${Q}           : ${Q}$URL${Q}${C}\n  ${Q}cloc_version${Q}       : ${Q}$version${Q}${C}\n  ${Q}n_files${Q}            : $sum_files${C}\n  ${Q}n_lines${Q}            : $sum_lines\";\n        } else {\n            $header = \"${start}${Q}header${Q} : $open_B\n  ${Q}cloc_url${Q}           : ${Q}$URL${Q}${C}\n  ${Q}cloc_version${Q}       : ${Q}$version${Q}${C}\n  ${Q}elapsed_seconds${Q}    : $elapsed_sec${C}\n  ${Q}n_files${Q}            : $sum_files${C}\n  ${Q}n_lines${Q}            : $sum_lines${C}\n  ${Q}files_per_second${Q}   : $file_rate${C}\n  ${Q}lines_per_second${Q}   : $line_rate\";\n        }\n        if ($opt_report_file) {\n            my $Fname = $opt_report_file;\n            $Fname =~ s{\\\\}{\\\\\\\\}g if $ON_WINDOWS;\n            if ($opt_sum_reports) {\n                if ($by_file) {\n                    $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname.file${Q}\"\n                } else {\n                    $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname.lang${Q}\"\n                }\n            } else {\n                $header .= \"$C\\n  ${Q}report_file${Q}        : ${Q}$Fname${Q}\";\n            }\n        }\n        $header .= \"${close_B}${C}\";\n    }\n    print \"<- xml_yaml_or_json_header\\n\" if $opt_v > 2;\n    return $header;\n} # 1}}}\nsub diff_yaml_report {                       # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_yaml_report\\n\" if $opt_v > 2;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"$S :\";\n        foreach my $F_or_L (keys %{$rhhh_count}) {\n            # force quoted language or filename in case these\n            # have embedded funny characters, issue #312\n            push @results, \"  '\" . rm_leading_tempdir($F_or_L, \\%TEMP_DIR) . \"' :\";\n            foreach my $k (keys %{$rhhh_count->{$F_or_L}}) {\n                next if $k eq \"lang\"; # present only in those cases\n                                      # where code exists for action $S\n                $rhhh_count->{$F_or_L}{$k}{$S} = 0 unless\n                    defined $rhhh_count->{$F_or_L}{$k}{$S};\n                push @results,\n                    \"    $k : $rhhh_count->{$F_or_L}{$k}{$S}\";\n            }\n        }\n    }\n\n    push @results, \"SUM :\";\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"  $S :\";\n        foreach my $topic (keys %sum) {\n            push @results, \"    $topic : $sum{$topic}{$S}\";\n        }\n    }\n\n    print \"<- diff_yaml_report\\n\" if $opt_v > 2;\n\n    return @results;\n} # 1}}}\nsub diff_json_report {                       # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_json_report\\n\" if $opt_v > 2;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \" \\\"$S\\\" : {\";\n        foreach my $F_or_L (keys %{$rhhh_count}) {\n            push @results, \"  \\\"\" . rm_leading_tempdir($F_or_L, \\%TEMP_DIR) . \"\\\" : {\";\n            foreach my $k (keys %{$rhhh_count->{$F_or_L}}) {\n                next if $k eq \"lang\"; # present only in those cases\n                                      # where code exists for action $S\n                $rhhh_count->{$F_or_L}{$k}{$S} = 0 unless\n                    defined $rhhh_count->{$F_or_L}{$k}{$S};\n                push @results,\n                    \"    \\\"$k\\\" : $rhhh_count->{$F_or_L}{$k}{$S},\";\n            }\n            $results[-1] =~ s/,\\s*$//;\n            push @results, \"  },\"\n        }\n        $results[-1] =~ s/,\\s*$//;\n        push @results, \"  },\"\n    }\n\n    push @results, \"  \\\"SUM\\\" : {\";\n    foreach my $S (qw(added same modified removed)) {\n        push @results, \"  \\\"$S\\\" : {\";\n        foreach my $topic (keys %sum) {\n            push @results, \"    \\\"$topic\\\" : $sum{$topic}{$S},\";\n        }\n        $results[-1] =~ s/,\\s*$//;\n        push @results, \"},\";\n    }\n\n    $results[-1] =~ s/,\\s*$//;\n    push @results, \"} }\";\n    print \"<- diff_json_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub diff_header_sum {                        # {{{1\n    my ($report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rhh_sum    , # out sum{nFiles|blank|comment|code}{same|modified|added|removed}\n       ) = @_;\n\n    my $sum_files = 0;\n    my $sum_lines = 0;\n    foreach my $language (keys %{$rhhh_count}) {\n        foreach my $V (qw(nFiles blank comment code)) {\n            foreach my $S (qw(added same modified removed)) {\n                $rhhh_count->{$language}{$V}{$S} = 0 unless\n                    defined $rhhh_count->{$language}{$V}{$S};\n                $rhh_sum->{$V}{$S}  += $rhhh_count->{$language}{$V}{$S};\n                if ($V eq \"nFiles\") {\n                    $sum_files += $rhhh_count->{$language}{$V}{$S};\n                } else {\n                    $sum_lines += $rhhh_count->{$language}{$V}{$S};\n                }\n            }\n        }\n    }\n\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $BY_FILE      = 1;\n    }\n    return $sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE;\n} # 1}}}\nsub diff_xml_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> diff_xml_report\\n\" if $opt_v > 2;\n    my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n\n#print \"diff_report: \", Dumper($rhhh_count), \"\\n\";\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n    my @results       = ();\n    my %sum           = ();\n    my $languages     = ();\n\n    my ($sum_lines, $sum_files, $BY_FILE, $BY_LANGUAGE) =\n        diff_header_sum($report_type, $rhhh_count, \\%sum);\n\n    my $data_line   = \"\";\n\n    if (!$ALREADY_SHOWED_HEADER) {\n        push @results,\n              xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                 $sum_files, $sum_lines, $BY_FILE);\n        $ALREADY_SHOWED_HEADER = 1;\n    }\n\n    foreach my $S (qw(same modified added removed)) {\n        push @results, \"  <$S>\";\n        foreach my $lang_or_file (sort {\n                                     $rhhh_count->{$b}{'code'} <=>\n                                     $rhhh_count->{$a}{'code'}\n                                   }\n                              keys %{$rhhh_count}) {\n            my $L = \"\";\n\n            if ($BY_FILE) {\n                $L .= sprintf \"    <file name=\\\"%s\\\" files_count=\\\"1\\\" \",\n                    xml_metachars(\n                        rm_leading_tempdir($lang_or_file, \\%TEMP_DIR));\n            } else {\n                $L .= sprintf \"    <language name=\\\"%s\\\" files_count=\\\"%d\\\" \",\n                        $lang_or_file ,\n                        $rhhh_count->{$lang_or_file}{'nFiles'}{$S};\n            }\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent            ,\n                            $rhhh_count->{$lang_or_file}{'code'}{$S}   ,\n                            $rhhh_count->{$lang_or_file}{'comment'}{$S},\n                            $rhhh_count->{$lang_or_file}{'blank'}{$S}  );\n              foreach my $T (qw(blank comment code)) {\n                  if ($rhhh_count->{$lang_or_file}{'code'}{$S} > 0) {\n                    $L .= sprintf \"%s=\\\"%.2f\\\" \",\n                            $T, $rhhh_count->{$lang_or_file}{$T}{$S} / $DEN * 100;\n                  } else {\n                    $L .= sprintf \"%s=\\\"0.0\\\" \", $T;\n                  }\n              }\n            } else {\n              foreach my $T (qw(blank comment code)) {\n                  $L .= sprintf \"%s=\\\"%d\\\" \",\n                          $T, $rhhh_count->{$lang_or_file}{$T}{$S};\n              }\n            }\n            push @results, $L . \"/>\";\n        }\n\n\n        my $L = sprintf \"    <total sum_files=\\\"%d\\\" \", $sum{'nFiles'}{$S};\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent,\n                        $sum{'code'}{$S}   ,\n                        $sum{'comment'}{$S},\n                        $sum{'blank'}{$S}  );\n          foreach my $V (qw(blank comment code)) {\n              if ($sum{'code'}{$S} > 0) {\n                  $L .= sprintf \"%s=\\\"%.2f\\\" \", $V, $sum{$V}{$S} / $DEN * 100;\n              } else {\n                  $L .= sprintf \"%s=\\\"0.0\\\" \", $V;\n              }\n          }\n        } else {\n          foreach my $V (qw(blank comment code)) {\n              $L .= sprintf \"%s=\\\"%d\\\" \", $V, $sum{$V}{$S};\n          }\n        }\n        push @results, $L . \"/>\";\n        push @results, \"  </$S>\";\n    }\n\n    push @results, \"</diff_results>\";\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    print \"<- diff_xml_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub diff_csv_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhhh_count , # in  count{TYPE}{nFiles|code|blank|comment}{a|m|r|s}\n        $rh_scale   , # in  unused\n       ) = @_;\n    print \"-> diff_csv_report\\n\" if $opt_v > 2;\n\n    my @results       = ();\n    my $languages     = ();\n\n    my $data_line   = \"\";\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $BY_FILE      = 1;\n    }\n    my $DELIM = \",\";\n       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;\n       $DELIM = \"|\" if defined $opt_md;\n\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $line = \"Language${DELIM} \";\n       $line = \"File${DELIM} \" if $BY_FILE;\n    foreach my $item (qw(files blank comment code)) {\n        next if $BY_FILE and $item eq 'files';\n        foreach my $symbol ( '==', '!=', '+', '-', ) {\n            $line .= \"$symbol $item${DELIM} \";\n        }\n    }\n\n    my $T_elapsed_sec = \"T=$elapsed_sec s\";\n       $T_elapsed_sec = \"\" if $opt_hide_rate;\n\n    if ($opt_md) {\n        push @results, \"cloc|$URL v $version $T_elapsed_sec\";\n        push @results, \"--- | ---\";\n        push @results, \"\";\n        push @results, $line;\n        my @col_header  = ();\n        push @col_header, \":-------\";\n        foreach (1..16) {\n            push @col_header, \"-------:\";\n        }\n        push @results, join(\"|\", @col_header) . \"|\";\n    } else {\n        $line .= \"\\\"$URL v $version $T_elapsed_sec\\\"\";\n        push @results, $line;\n    }\n\n    foreach my $lang_or_file (keys %{$rhhh_count}) {\n        $rhhh_count->{$lang_or_file}{'code'}{'added'} = 0 unless\n            defined $rhhh_count->{$lang_or_file}{'code'};\n    }\n    foreach my $lang_or_file (sort {\n                                 $rhhh_count->{$b}{'code'} <=>\n                                 $rhhh_count->{$a}{'code'}\n                               }\n                          keys %{$rhhh_count}) {\n        if ($BY_FILE) {\n            $line = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR) . \"$DELIM \";\n        } else {\n            $line = $lang_or_file . \"${DELIM} \";\n        }\n        if ($opt_by_percent) {\n          foreach my $item (qw(nFiles)) {\n              next if $BY_FILE and $item eq 'nFiles';\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {\n                      $line .= \"$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} \";\n                  } else {\n                      $line .= \"0${DELIM} \";\n                  }\n              }\n          }\n          foreach my $item (qw(blank comment code)) {\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol} and\n                      defined $rhhh_count->{$lang_or_file}{'code'}{$symbol} and\n                      $rhhh_count->{$lang_or_file}{'code'}{$symbol} > 0) {\n                      $line .= sprintf(\"%.2f\", $rhhh_count->{$lang_or_file}{$item}{$symbol} / $rhhh_count->{$lang_or_file}{'code'}{$symbol} * 100).${DELIM};\n                  } else {\n                      $line .= \"0.00${DELIM} \";\n                  }\n              }\n          }\n        } else {\n          foreach my $item (qw(nFiles blank comment code)) {\n              next if $BY_FILE and $item eq 'nFiles';\n              foreach my $symbol (qw(same modified added removed)) {\n                  if (defined $rhhh_count->{$lang_or_file}{$item}{$symbol}) {\n                      $line .= \"$rhhh_count->{$lang_or_file}{$item}{$symbol}${DELIM} \";\n                  } else {\n                      $line .= \"0${DELIM} \";\n                  }\n              }\n          }\n        }\n        push @results, $line;\n    }\n\n    print \"<- diff_csv_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub rm_leading_tempdir {                     # {{{1\n    my ($in_file, $rh_temp_dirs, ) = @_;\n    my $clean_filename = $in_file;\n    foreach my $temp_d (keys %{$rh_temp_dirs}) {\n        if ($ON_WINDOWS) {\n        # \\ -> / necessary to allow the next if test's\n        # m{} to work in the presence of spaces in file names\n            $temp_d         =~ s{\\\\}{/}g;\n            $clean_filename =~ s{\\\\}{/}g;\n        }\n        if ($clean_filename =~ m{^$temp_d/}) {\n            $clean_filename =~ s{^$temp_d/}{};\n            last;\n        }\n    }\n    if ($ON_WINDOWS and $opt_by_file) { # then go back from / to \\\n        if ($opt_json) {\n            $clean_filename =~ s{/}{\\\\\\\\}g;\n        } else {\n            $clean_filename =~ s{/}{\\\\}g;\n        }\n    }\n    return $clean_filename;\n} # 1}}}\nsub generate_sql    {                        # {{{1\n    my ($elapsed_sec, # in\n        $rhh_count  , # in  count{TYPE}{lang|code|blank|comment|scaled}\n        $rh_scale   , # in\n       ) = @_;\n    print \"-> generate_sql\\n\" if $opt_v > 2;\n\n#print \"generate_sql A [$opt_sql_project]\\n\";\n    $opt_sql_project = cwd() unless defined $opt_sql_project;\n    $opt_sql_project = '' unless defined $opt_sql_project; # have seen cwd() fail\n#print \"generate_sql B [$opt_sql_project]\\n\";\n    $opt_sql_project =~ s{/}{\\\\}g if $ON_WINDOWS;\n#print \"generate_sql C [$opt_sql_project]\\n\";\n\n    my $schema = undef;\n    if ($opt_sql_style eq \"oracle\") {\n        $schema = \"\nCREATE TABLE metadata\n(\n  id          INTEGER PRIMARY KEY,\n  timestamp   TIMESTAMP,\n  project     VARCHAR2(500 CHAR),\n  elapsed_s   NUMBER(10, 6)\n)\n/\n\nCREATE TABLE t\n(\n  id             INTEGER           ,\n  project        VARCHAR2(500 CHAR),\n  language       VARCHAR2(500 CHAR),\n  file_fullname  VARCHAR2(500 CHAR),\n  file_dirname   VARCHAR2(500 CHAR),\n  file_basename  VARCHAR2(500 CHAR),\n  nblank         INTEGER,\n  ncomment       INTEGER,\n  ncode          INTEGER,\n  nscaled        NUMBER(10, 6),\nFOREIGN KEY (id)\n    REFERENCES metadata (id)\n)\n/\n\n\";\n    } else {\n        $schema = \"\ncreate table metadata (          -- $URL v $VERSION\n                id        integer primary key,\n                timestamp varchar(500),\n                Project   varchar(500),\n                elapsed_s real);\ncreate table t        (\n                id            integer        ,\n                Project       varchar(500)   ,\n                Language      varchar(500)   ,\n                File          varchar(500)   ,\n                File_dirname  varchar(500)   ,\n                File_basename varchar(500)   ,\n                nBlank        integer        ,\n                nComment      integer        ,\n                nCode         integer        ,\n                nScaled       real           ,\n        foreign key (id)\n            references metadata (id));\n\";\n    }\n    $opt_sql = \"-\" if $opt_sql eq \"1\";\n\n    my $open_mode = \">\";\n       $open_mode = \">>\" if $opt_sql_append;\n\n    my $fh;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne \"-\") {\n        # only use the Win32::LongPath wrapper here when needed,\n        # and only when not writing to STDOUT.\n        $fh = open_file($open_mode, $opt_sql, 1);\n        die \"Unable to write to $opt_sql\\n\" if !defined $fh;\n    } else {\n        $fh = new IO::File; # $opt_sql, \"w\";\n        if (!$fh->open(\"${open_mode}${opt_sql}\")) {\n            die \"Unable to write to $opt_sql  $!\\n\";\n        }\n    }\n    print $fh $schema unless defined $opt_sql_append;\n\n    my $id = int(time());\n    my $insert_into_t = \"insert into t \";\n    if ($opt_sql_style eq \"oracle\") {\n        printf $fh \"insert into metadata values(%d, TO_TIMESTAMP('%s','yyyy-mm-dd hh24:mi:ss'), '%s', %f);\\n\",\n                    $id,\n                    strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    } elsif ($opt_sql_style eq \"named_columns\") {\n        print $fh \"begin transaction;\\n\";\n        $insert_into_t .= \"(id, Project, Language, File, File_dirname, File_basename, nBlank, nComment, nCode, nScaled )\";\n    } else {\n        print $fh \"begin transaction;\\n\";\n        printf $fh \"insert into metadata values(%d, '%s', '%s', %f);\\n\",\n                    $id, strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    }\n\n    my $nIns = 0;\n    foreach my $file (keys %{$rhh_count}) {\n        my $language = $rhh_count->{$file}{'lang'};\n        my $clean_filename = $file;\n        # If necessary (that is, if the input contained an\n        # archive file [.tar.gz, etc]), strip the temporary\n        # directory name which was used to expand the archive\n        # from the file name.\n\n        $clean_filename = rm_leading_tempdir($clean_filename, \\%TEMP_DIR);\n        $clean_filename =~ s/\\'/''/g;  # double embedded single quotes\n                                       # to escape them\n\n        printf $fh \"$insert_into_t values(%d, '%s', '%s', '%s', '%s', '%s', \" .\n                   \"%d, %d, %d, %f);\\n\",\n                    $id                        ,\n                    $opt_sql_project           ,\n                    $language                  ,\n                    $clean_filename            ,\n                    dirname( $clean_filename)  ,\n                    basename($clean_filename)  ,\n                    $rhh_count->{$file}{'blank'},\n                    $rhh_count->{$file}{'comment'},\n                    $rhh_count->{$file}{'code'}   ,\n                    $rhh_count->{$file}{'code'}*$rh_scale->{$language};\n\n        ++$nIns;\n        if (!($nIns % 10_000) and ($opt_sql_style ne \"oracle\")) {\n            print $fh \"commit;\\n\";\n            print $fh \"begin transaction;\\n\";\n        }\n    }\n    if ($opt_sql_style ne \"oracle\") {\n        print $fh \"commit;\\n\";\n    }\n\n    $fh->close unless $opt_sql eq \"-\"; # don't try to close STDOUT\n    print \"<- generate_sql\\n\" if $opt_v > 2;\n\n    # sample query:\n    #\n    #   select project, language,\n    #          sum(nCode)     as Code,\n    #          sum(nComment)  as Comments,\n    #          sum(nBlank)    as Blank,\n    #          sum(nCode)+sum(nComment)+sum(nBlank) as All_Lines,\n    #          100.0*sum(nComment)/(sum(nCode)+sum(nComment)) as Comment_Pct\n    #          from t group by Project, Language order by Project, Code desc;\n    #\n} # 1}}}\nsub generate_diff_sql {                      # {{{1\n    my ($elapsed_sec, # in\n        $rhhh_delta , # in  delta{file}{comment/blank/code}{added/same/modified/removed}\n       ) = @_;\n    print \"-> generate_diff_sql\\n\" if $opt_v > 2;\n\n    $opt_sql_project = cwd() unless defined $opt_sql_project;\n    $opt_sql_project = '' unless defined $opt_sql_project; # have seen cwd() fail\n    $opt_sql_project =~ s{/}{\\\\}g if $ON_WINDOWS;\n\n    my $schema = undef;\n    if ($opt_sql_style eq \"oracle\") {\n        $schema = \"\nCREATE TABLE metadata\n(\n  id          INTEGER PRIMARY KEY,\n  timestamp   TIMESTAMP,\n  project     VARCHAR2(500 CHAR),\n  elapsed_s   NUMBER(10, 6)\n)\n/\n\nCREATE TABLE t_diff\n(\n  id                INTEGER           ,\n  project           VARCHAR2(500 CHAR),\n  language          VARCHAR2(500 CHAR),\n  file_fullname     VARCHAR2(500 CHAR),\n  file_dirname      VARCHAR2(500 CHAR),\n  file_basename     VARCHAR2(500 CHAR),\n  nblank_same       INTEGER,\n  nblank_modified   INTEGER,\n  nblank_added      INTEGER,\n  nblank_removed    INTEGER,\n  ncomment_same     INTEGER,\n  ncomment_modified INTEGER,\n  ncomment_added    INTEGER,\n  ncomment_removed  INTEGER,\n  ncode_same        INTEGER,\n  ncode_modified    INTEGER,\n  ncode_added       INTEGER,\n  ncode_removed     INTEGER,\nFOREIGN KEY (id)\n    REFERENCES metadata (id)\n)\n/\n\n\";\n    } else {\n        $schema = \"\ncreate table metadata (          -- $URL v $VERSION\n                id        integer primary key,\n                timestamp varchar(500),\n                Project   varchar(500),\n                elapsed_s real);\ncreate table t_diff   (\n                id                integer        ,\n                Project           varchar(500)   ,\n                Language          varchar(500)   ,\n                File              varchar(500)   ,\n                File_dirname      varchar(500)   ,\n                File_basename     varchar(500)   ,\n                nBlank_same       integer        ,\n                nBlank_modified   integer        ,\n                nBlank_added      integer        ,\n                nBlank_removed    integer        ,\n                nComment_same     integer        ,\n                nComment_modified integer        ,\n                nComment_added    integer        ,\n                nComment_removed  integer        ,\n                nCode_same        integer        ,\n                nCode_modified    integer        ,\n                nCode_added       integer        ,\n                nCode_removed     integer        ,\n        foreign key (id)\n            references metadata (id));\n\";\n    }\n    $opt_sql = \"-\" if $opt_sql eq \"1\";\n\n    my $open_mode = \">\";\n       $open_mode = \">>\" if $opt_sql_append;\n\n    my $fh;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path and $opt_sql ne \"-\") {\n        # only use the Win32::LongPath wrapper here when needed,\n        # and only when not writing to STDOUT.\n        $fh = open_file($open_mode, $opt_sql, 1);\n        die \"Unable to write to $opt_sql\\n\" if !defined $fh;\n    } else {\n        $fh = new IO::File; # $opt_sql, \"w\";\n        if (!$fh->open(\"${open_mode}${opt_sql}\")) {\n            die \"Unable to write to $opt_sql  $!\\n\";\n        }\n    }\n    print $fh $schema unless defined $opt_sql_append;\n\n    my $id = int(time());\n    my $insert_into_t = \"insert into t_diff \";\n    if ($opt_sql_style eq \"oracle\") {\n        printf $fh \"insert into metadata values(%d, TO_TIMESTAMP('%s',\" .\n                   \"'yyyy-mm-dd hh24:mi:ss'), '%s', %f);\\n\",\n                    $id,\n                    strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    } elsif ($opt_sql_style eq \"named_columns\") {\n        print $fh \"begin transaction;\\n\";\n        $insert_into_t .= \"(id, Project, Language, File, File_dirname, File_basename, \" .\n                          \"nBlank_same, nBlank_modified, nBlank_added, nBlank_removed, \" .\n                          \"nComment_same, nComment_modified, nComment_added, nComment_removed, \" .\n                          \"nCode_same, nCode_modified, nCode_added, nCode_removed )\";\n    } else {\n        print $fh \"begin transaction;\\n\";\n        printf $fh \"insert into metadata values(%d, '%s', '%s', %f);\\n\",\n                    $id, strftime(\"%Y-%m-%d %H:%M:%S\", localtime(time())),\n                    $opt_sql_project, $elapsed_sec;\n    }\n\n    my $nIns = 0;\n    foreach my $file (keys %{$rhhh_delta}) {\n        my $language = $Language_by_Filename{$file};\n        my $clean_filename = $file;\n        # If necessary (that is, if the input contained an\n        # archive file [.tar.gz, etc]), strip the temporary\n        # directory name which was used to expand the archive\n        # from the file name.\n\n        $clean_filename = rm_leading_tempdir($clean_filename, \\%TEMP_DIR);\n        $clean_filename =~ s/\\'/''/g;  # double embedded single quotes\n                                       # to escape them\n\nif (1) {\n        $rhhh_delta->{$file}{'blank'}{'same'}       = 0 unless defined $rhhh_delta->{$file}{'blank'}{'same'}      ;\n        $rhhh_delta->{$file}{'blank'}{'modified'}   = 0 unless defined $rhhh_delta->{$file}{'blank'}{'modified'}  ;\n        $rhhh_delta->{$file}{'blank'}{'added'}      = 0 unless defined $rhhh_delta->{$file}{'blank'}{'added'}     ;\n        $rhhh_delta->{$file}{'blank'}{'removed'}    = 0 unless defined $rhhh_delta->{$file}{'blank'}{'removed'}   ;\n        $rhhh_delta->{$file}{'comment'}{'same'}     = 0 unless defined $rhhh_delta->{$file}{'comment'}{'same'}    ;\n        $rhhh_delta->{$file}{'comment'}{'modified'} = 0 unless defined $rhhh_delta->{$file}{'comment'}{'modified'};\n        $rhhh_delta->{$file}{'comment'}{'added'}    = 0 unless defined $rhhh_delta->{$file}{'comment'}{'added'}   ;\n        $rhhh_delta->{$file}{'comment'}{'removed'}  = 0 unless defined $rhhh_delta->{$file}{'comment'}{'removed'} ;\n        $rhhh_delta->{$file}{'code'}{'same'}        = 0 unless defined $rhhh_delta->{$file}{'code'}{'same'}       ;\n        $rhhh_delta->{$file}{'code'}{'modified'}    = 0 unless defined $rhhh_delta->{$file}{'code'}{'modified'}   ;\n        $rhhh_delta->{$file}{'code'}{'added'}       = 0 unless defined $rhhh_delta->{$file}{'code'}{'added'}      ;\n        $rhhh_delta->{$file}{'code'}{'removed'}     = 0 unless defined $rhhh_delta->{$file}{'code'}{'removed'}    ;\nuse Data::Dumper;\n#print Dumper($rhhh_delta->{$file});\n#die;\n        printf $fh \"$insert_into_t values(%d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d);\\n\",\n                    $id                        ,\n                    $opt_sql_project           ,\n                    $language                  ,\n                    $clean_filename            ,\n                    dirname( $clean_filename)  ,\n                    basename($clean_filename)  ,\n                    $rhhh_delta->{$file}{'blank'}{'same'}      ,\n                    $rhhh_delta->{$file}{'blank'}{'modified'}  ,\n                    $rhhh_delta->{$file}{'blank'}{'added'}     ,\n                    $rhhh_delta->{$file}{'blank'}{'removed'}   ,\n                    $rhhh_delta->{$file}{'comment'}{'same'}    ,\n                    $rhhh_delta->{$file}{'comment'}{'modified'},\n                    $rhhh_delta->{$file}{'comment'}{'added'}   ,\n                    $rhhh_delta->{$file}{'comment'}{'removed'} ,\n                    $rhhh_delta->{$file}{'code'}{'same'}       ,\n                    $rhhh_delta->{$file}{'code'}{'modified'}   ,\n                    $rhhh_delta->{$file}{'code'}{'added'}      ,\n                    $rhhh_delta->{$file}{'code'}{'removed'}    ;\n}\n\n        ++$nIns;\n        if (!($nIns % 10_000) and ($opt_sql_style ne \"oracle\")) {\n            print $fh \"commit;\\n\";\n            print $fh \"begin transaction;\\n\";\n        }\n    }\n    if ($opt_sql_style ne \"oracle\") {\n        print $fh \"commit;\\n\";\n    }\n\n    $fh->close unless $opt_sql eq \"-\"; # don't try to close STDOUT\n    print \"<- generate_diff_sql\\n\" if $opt_v > 2;\n\n} # 1}}}\nsub output_header   {                        # {{{1\n    my ($header_line,\n        $hyphen_line,\n        $BY_FILE    ,)    = @_;\n    print \"-> output_header\\n\" if $opt_v > 2;\n    my @R = ();\n    if      ($opt_xml) {\n        if (!$ALREADY_SHOWED_XML_SECTION) {\n            push @R, \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\";\n            push @R, '<?xml-stylesheet type=\"text/xsl\" href=\"' .\n                            $opt_xsl . '\"?>' if $opt_xsl;\n            push @R, \"<results>\";\n            push @R, \"<header>$header_line</header>\";\n            $ALREADY_SHOWED_XML_SECTION = 1;\n        }\n        if ($BY_FILE) {\n            push @R, \"<files>\";\n        } else {\n            push @R, \"<languages>\";\n        }\n    } elsif ($opt_yaml) {\n        push @R, \"---\\n# $header_line\";\n    } elsif ($opt_csv or $opt_md) {\n        # append the header to the end of the column headers\n        # to keep the output a bit cleaner from a spreadsheet\n        # perspective\n    } else {\n        if ($ALREADY_SHOWED_HEADER) {\n            push @R, \"\";\n        } else {\n            push @R, $header_line;\n            $ALREADY_SHOWED_HEADER = 1;\n        }\n        push @R, $hyphen_line;\n    }\n    print \"<- output_header\\n\" if $opt_v > 2;\n    return @R;\n} # 1}}}\nsub generate_report {                        # {{{1\n    # returns an array of lines containing the results\n    my ($version    , # in\n        $elapsed_sec, # in\n        $report_type, # in  \"by language\" | \"by report file\" | \"by file\"\n        $rhh_count  , # in  count{TYPE}{nFiles|code|blank|comment|scaled}\n                      #       where TYPE = name of language, source file,\n                      #                    or report file\n        $rh_scale   , # in\n        $out_style  , # in  \"txt\" | \"xml\" | \"yaml\" | \"json\" | \"csv\" | \"md\"\n       ) = @_;\n\n    my %orig_case = ();\n    if ($ON_WINDOWS and $report_type eq \"by file\") {\n        # restore the original upper/lowercase version of the file name\n        foreach my $lc_file (sort keys %{$rhh_count}) {\n            foreach my $cat (sort keys %{$rhh_count->{$lc_file}}) {\n                $orig_case{ $upper_lower_map{$lc_file} }{$cat} =\n                           $rhh_count->{$lc_file}{$cat};\n            }\n        }\n        $rhh_count = \\%orig_case;\n    }\n    print \"-> generate_report\\n\" if $opt_v > 2;\n    my $DELIM = \",\";\n       $DELIM = $opt_csv_delimiter if defined $opt_csv_delimiter;\n       $DELIM = \"|\" if $out_style eq \"md\";\n\n    my @results       = ();\n\n    my $languages     = ();\n\n    my $sum_files     = 0;\n    my $sum_code      = 0;\n    my $sum_blank     = 0;\n    my $sum_comment   = 0;\n    my $max_len       = 0;\n    foreach my $language (keys %{$rhh_count}) {\n        $sum_files   += $rhh_count->{$language}{'nFiles'} ;\n        $sum_blank   += $rhh_count->{$language}{'blank'}  ;\n        $sum_comment += $rhh_count->{$language}{'comment'};\n        $sum_code    += $rhh_count->{$language}{'code'}   ;\n        $max_len      = length($language) if length($language) > $max_len;\n    }\n    my $column_1_offset = 0;\n       $column_1_offset = $max_len - 17 if $max_len > 17;\n    my $sum_lines = $sum_blank + $sum_comment + $sum_code;\n    $elapsed_sec = 0.5 unless $elapsed_sec;\n\n    my $spacing_0 = 23;\n    my $spacing_1 = 13;\n    my $spacing_2 =  9;\n    my $spacing_3 = 17;\n    if (!$opt_3) {\n        $spacing_1 = 19;\n        $spacing_2 = 14;\n        $spacing_3 = 27;\n    }\n    $spacing_0 += $column_1_offset;\n    $spacing_1 += $column_1_offset;\n    $spacing_3 += $column_1_offset;\n    my %Format = (\n        '1' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_0}s \",\n               },\n        '2' => { 'xml' => 'name=\"%s\" ',\n                 'txt' => \"\\%-${spacing_3}s \",\n               },\n        '3' => { 'xml' => 'files_count=\"%d\" ',\n                 'txt' => '%6d ',\n               },\n        '4' => { 'xml' => 'blank=\"%d\" comment=\"%d\" code=\"%d\" ',\n                 'txt' => \"\\%${spacing_2}d \\%${spacing_2}d \\%${spacing_2}d\",\n               },\n        '5' => { 'xml' => 'blank=\"%3.2f\" comment=\"%3.2f\" code=\"%3.2f\" ',\n                 'txt' => \"\\%14.2f \\%14.2f  \\%13.2f\",\n               },\n        '6' => { 'xml' => 'factor=\"%.2f\" scaled=\"%.2f\" ',\n                 'txt' => ' x %6.2f = %14.2f',\n               },\n    );\n    my $Style = \"txt\";\n       $Style = \"xml\" if $out_style eq \"xml\" ;\n       $Style = \"xml\" if $out_style eq \"yaml\";  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $out_style eq \"json\";  # not a typo; just set to anything but txt\n       $Style = \"xml\" if $out_style eq \"csv\" ;  # not a typo; just set to anything but txt\n\n    my $hyphen_line = sprintf \"%s\", '-' x (79 + $column_1_offset);\n       $hyphen_line = sprintf \"%s\", '-' x (68 + $column_1_offset)\n            if (!$opt_sum_reports) and (!$opt_3) and (68 + $column_1_offset) > 79;\n    my $data_line  = \"\";\n    my $first_column;\n    my $BY_LANGUAGE = 0;\n    my $BY_FILE     = 0;\n    if      ($report_type eq \"by language\") {\n        $first_column = \"Language\";\n        $BY_LANGUAGE  = 1;\n    } elsif ($report_type eq \"by file\")     {\n        $first_column = \"File\";\n        $BY_FILE      = 1;\n    } elsif ($report_type eq \"by report file\")     {\n        $first_column = \"File\";\n    } else {\n        $first_column = \"Report File\";\n    }\n\n    my $header_line  = sprintf \"%s v %s\", $URL, $version;\n       $header_line .= sprintf(\"  T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                        $elapsed_sec           ,\n                        $sum_files/$elapsed_sec,\n                        $sum_lines/$elapsed_sec) unless $opt_sum_reports or $opt_hide_rate;\n    if ($out_style eq \"xml\" or $out_style eq \"yaml\" or $out_style eq \"json\") {\n        if (!$ALREADY_SHOWED_HEADER) {\n            if ($opt_by_file_by_lang and $out_style eq \"json\") {\n                push @results, '{ \"by_file\" : ';\n            }\n            push @results, xml_yaml_or_json_header($URL, $version, $elapsed_sec,\n                                                   $sum_files, $sum_lines, $BY_FILE);\n#           $ALREADY_SHOWED_HEADER = 1 unless $opt_sum_reports;\n            # --sum-reports yields two xml or yaml files, one by\n            # language and one by report file, each of which needs a header\n        }\n        if ($out_style eq \"xml\") {\n            if ($BY_FILE or ($report_type eq \"by report file\")) {\n                push @results, \"<files>\";\n            } else {\n                push @results, \"<languages>\";\n            }\n        }\n    } else {\n        $header_line =~ s/,// if $out_style eq \"csv\";\n        push @results, output_header($header_line, $hyphen_line, $BY_FILE);\n    }\n\n    if ($Style eq \"txt\") {\n        # column headers\n        if (!$opt_3 and $BY_FILE) {\n            my $spacing_n = $spacing_1 - 11;\n            $data_line  = sprintf \"%-${spacing_n}s \", $first_column;\n        } else {\n            $data_line  = sprintf \"%-${spacing_1}s \", $first_column;\n        }\n        if ($BY_FILE) {\n            $data_line .= sprintf \"%${spacing_2}s \"  , \" \"    ;\n        } else {\n            $data_line .= sprintf \"%${spacing_2}s \"  , \"files\";\n        }\n        my $PCT_symbol = \"\";\n           $PCT_symbol = \" \\%\" if $opt_by_percent;\n        $data_line .= sprintf \"%${spacing_2}s %${spacing_2}s %${spacing_2}s\",\n            \"blank${PCT_symbol}\"   ,\n            \"comment${PCT_symbol}\" ,\n            \"code${PCT_symbol}\";\n        $data_line .= sprintf \" %8s   %14s\",\n            \"scale\"         ,\n            \"3rd gen. equiv\"\n              if $opt_3;\n        if ($out_style eq \"md\") {\n            my @col_header  = ();\n            if ($data_line =~ m{\\s%}) {\n                $data_line =~ s{\\s%}{_%}g;\n                foreach my $w ( split(' ', $data_line) ) {\n                    $w =~ s{_%}{ %};\n                    push @col_header, $w;\n                }\n            } else {\n                push @col_header, split(' ', $data_line);\n            }\n            my @col_hyphens    = ( '-------:') x scalar(@col_header);\n               $col_hyphens[0] =   ':-------'; # first column left justified\n            push @results, join(\"|\", @col_header );\n            push @results, join(\"|\", @col_hyphens);\n        } else {\n            push @results, $data_line;\n            push @results, $hyphen_line;\n        }\n    }\n\n    if ($out_style eq \"csv\")  {\n        my $header2;\n        if ($BY_FILE) {\n            $header2 = \"language${DELIM}filename\";\n        } else {\n            $header2 = \"files${DELIM}language\";\n        }\n        $header2 .= \"${DELIM}blank${DELIM}comment${DELIM}code\";\n        $header2 .= \"${DELIM}scale${DELIM}3rd gen. equiv\" if $opt_3;\n        $header2 .= ${DELIM} . '\"' . $header_line . '\"';\n        push @results, $header2;\n    }\n\n    my $sum_scaled = 0;\n    foreach my $lang_or_file (sort {\n                                 $rhh_count->{$b}{'code'} <=>\n                                 $rhh_count->{$a}{'code'}\n                              or $a cmp $b\n                                        }\n                                   keys %{$rhh_count}) {\n        next if $lang_or_file eq \"by report file\";\n        my $clean_lang_or_file = $lang_or_file;   # later, if by-file protect ' and \"\n        my ($factor, $scaled);\n        if ($BY_LANGUAGE or $BY_FILE) {\n            $factor = 1;\n            if ($BY_LANGUAGE) {\n                if (defined $rh_scale->{$lang_or_file}) {\n                    $factor = $rh_scale->{$lang_or_file};\n                } else {\n                    warn \"No scale factor for $lang_or_file; using 1.00\";\n                }\n            } else { # by individual code file\n                if ($report_type ne \"by report file\") {\n                    next unless defined $rhh_count->{$lang_or_file}{'lang'};\n                    next unless defined $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};\n                    $factor = $rh_scale->{$rhh_count->{$lang_or_file}{'lang'}};\n                }\n            }\n            $scaled = $factor*$rhh_count->{$lang_or_file}{'code'};\n        } else {\n            if (!defined $rhh_count->{$lang_or_file}{'scaled'}) {\n                $opt_3 = 0;\n                # If we're summing together files previously generated\n                # with --no3 then rhh_count->{$lang_or_file}{'scaled'}\n                # this variable will be undefined.  That should only\n                # happen when summing together by file however.\n            } elsif ($BY_LANGUAGE) {\n                warn \"Missing scaled language info for $lang_or_file\\n\";\n            }\n            if ($opt_3) {\n                $scaled =         $rhh_count->{$lang_or_file}{'scaled'};\n                $factor = $scaled/$rhh_count->{$lang_or_file}{'code'};\n            }\n        }\n\n        if ($BY_FILE) {\n            $clean_lang_or_file = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n            $clean_lang_or_file = xml_metachars($clean_lang_or_file) if $out_style eq \"xml\";\n            if ($out_style eq \"yaml\")  {\n                # YAML does not allow protected single quotes in keys\n                $clean_lang_or_file =~ s/'/0x27/g;\n            } elsif ($out_style eq \"json\")  {\n                # JSON does not allow protected double quotes in keys\n                $clean_lang_or_file =~ s/\"/0x2b/g;\n            } elsif ($out_style ne \"txt\")  {\n                # text output is allowed to keep its quotes as they are\n                $clean_lang_or_file =~ s/'/\\\\'/g;\n                $clean_lang_or_file =~ s/\"/\\\\\"/g;\n            }\n            $data_line  = sprintf $Format{'1'}{$Style}, $clean_lang_or_file;\n        } else {\n            $data_line  = sprintf $Format{'2'}{$Style}, $lang_or_file;\n        }\n        $data_line .= sprintf $Format{3}{$Style}  ,\n                        $rhh_count->{$lang_or_file}{'nFiles'} unless $BY_FILE;\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent       ,\n                        $rhh_count->{$lang_or_file}{'code'}   ,\n                        $rhh_count->{$lang_or_file}{'comment'},\n                        $rhh_count->{$lang_or_file}{'blank'}  );\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{5}{$Style}  ,\n                $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100,\n                $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100,\n                $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100;\n          } else {\n            $data_line .= sprintf $Format{5}{$Style}  ,\n                $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100,\n                $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100,\n                $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{4}{$Style}  ,\n              $rhh_count->{$lang_or_file}{'blank'}  ,\n              $rhh_count->{$lang_or_file}{'comment'},\n              $rhh_count->{$lang_or_file}{'code'}   ;\n        }\n        $data_line .= sprintf $Format{6}{$Style}  ,\n            $factor                               ,\n            $scaled if $opt_3;\n        $sum_scaled  += $scaled if $opt_3;\n\n        if ($out_style eq \"xml\") {\n            if (defined $rhh_count->{$lang_or_file}{'lang'}) {\n                my $lang = $rhh_count->{$lang_or_file}{'lang'};\n                if (!defined $languages->{$lang}) {\n                    $languages->{$lang} = $lang;\n                }\n                $data_line.=' language=\"' . $lang . '\" ';\n            }\n            if ($BY_FILE or ($report_type eq \"by report file\")) {\n                push @results, \"  <file \" . $data_line . \"/>\";\n            } else {\n                push @results, \"  <language \" . $data_line . \"/>\";\n            }\n        } elsif ($out_style eq \"yaml\" or $out_style eq \"json\") {\n            my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n            if ($out_style eq \"yaml\") {\n                # YAML: force quoted language or filename in case these\n                #       have embedded funny characters, issue #312\n                push @results,\"'\" . rm_leading_tempdir($clean_lang_or_file, \\%TEMP_DIR). \"' :$open_B\";\n            } else {\n                push @results,\"${Q}\" . rm_leading_tempdir($clean_lang_or_file, \\%TEMP_DIR). \"${Q} :$open_B\";\n            }\n            push @results,\"  ${Q}nFiles${Q}: \" . $rhh_count->{$lang_or_file}{'nFiles'} . $C\n                unless $BY_FILE;\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent       ,\n                            $rhh_count->{$lang_or_file}{'code'}   ,\n                            $rhh_count->{$lang_or_file}{'comment'},\n                            $rhh_count->{$lang_or_file}{'blank'}  );\n            if ($opt_by_percent eq 't') {\n              push @results,\"  ${Q}blank_pct${Q}: \"   .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100) . $C;\n              push @results,\"  ${Q}comment_pct${Q}: \" .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100) . $C;\n              push @results,\"  ${Q}code_pct${Q}: \"    .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100) . $C;\n            } else {\n              push @results,\"  ${Q}blank_pct${Q}: \"     .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100) . $C;\n              push @results,\"  ${Q}comment_pct${Q}: \" .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . $C;\n              push @results,\"  ${Q}code_pct${Q}: \"    .\n                sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100) . $C;\n            }\n            } else {\n              push @results,\"  ${Q}blank${Q}: \"   . $rhh_count->{$lang_or_file}{'blank'}   . $C;\n              push @results,\"  ${Q}comment${Q}: \" . $rhh_count->{$lang_or_file}{'comment'} . $C;\n              push @results,\"  ${Q}code${Q}: \"    . $rhh_count->{$lang_or_file}{'code'}    . $C;\n            }\n            push @results,\"  ${Q}language${Q}: \"  . $Q . $rhh_count->{$lang_or_file}{'lang'} . $Q . $C\n                if $BY_FILE;\n            if ($opt_3) {\n                push @results, \"  ${Q}scaled${Q}: \" . $scaled . $C;\n                push @results, \"  ${Q}factor${Q}: \" . $factor . $C;\n            }\n            if ($out_style eq \"json\") { # replace the trailing comma with }, on the last line\n                $results[-1] =~ s/,\\s*$/},/;\n            }\n        } elsif ($out_style eq \"csv\" or $out_style eq \"md\") {\n            my $extra_3 = \"\";\n               $extra_3 = \"${DELIM}$factor${DELIM}$scaled\" if $opt_3;\n            my $first_column = undef;\n            my $clean_name   = $lang_or_file;\n            my $str;\n            if ($out_style eq \"csv\") {\n                if ($BY_FILE) {\n                    $first_column = $rhh_count->{$lang_or_file}{'lang'};\n                    $clean_name   = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n                } else {\n                    $first_column = $rhh_count->{$lang_or_file}{'nFiles'};\n                }\n                $str = $first_column   . ${DELIM} .\n                       $clean_name     . ${DELIM};\n            } else {\n                if ($BY_FILE) {\n                    $first_column = $rhh_count->{$lang_or_file}{'lang'};\n                    $clean_name   = rm_leading_tempdir($lang_or_file, \\%TEMP_DIR);\n                    $str = $clean_name . ${DELIM};\n                } else {\n                    $first_column = $rhh_count->{$lang_or_file}{'nFiles'};\n                    $str = $clean_name     . ${DELIM} .\n                           $first_column   . ${DELIM};\n                }\n            }\n            if ($opt_by_percent) {\n              my $DEN = compute_denominator($opt_by_percent               ,\n                            $rhh_count->{$lang_or_file}{'code'}   ,\n                            $rhh_count->{$lang_or_file}{'comment'},\n                            $rhh_count->{$lang_or_file}{'blank'}  );\n              if ($opt_by_percent eq 't') {\n                $str .= sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $sum_blank   * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $sum_comment * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $sum_code    * 100) . ${DELIM} ;\n              } else {\n                $str .= sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'blank'}   / $DEN * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'comment'} / $DEN * 100) . ${DELIM} .\n                        sprintf(\"%3.2f\", $rhh_count->{$lang_or_file}{'code'}    / $DEN * 100) . ${DELIM} ;\n              }\n            } else {\n              $str .= $rhh_count->{$lang_or_file}{'blank'}  . ${DELIM} .\n                      $rhh_count->{$lang_or_file}{'comment'}. ${DELIM} .\n                      $rhh_count->{$lang_or_file}{'code'};\n            }\n            $str .= $extra_3;\n            push @results, $str;\n\n        } else {\n            push @results, $data_line;\n        }\n    }\n\n    my $avg_scale = 1;  # weighted average of scale factors\n       $avg_scale = sprintf(\"%.2f\", $sum_scaled / $sum_code)\n            if $sum_code and $opt_3;\n\n    if ($out_style eq \"xml\") {\n        $data_line = \"\";\n        if (!$BY_FILE) {\n            $data_line .= sprintf \"sum_files=\\\"%d\\\" \", $sum_files;\n        }\n        if ($opt_by_percent) {\n          my $DEN = compute_denominator($opt_by_percent    ,\n                        $sum_code, $sum_comment, $sum_blank);\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $sum_blank   * 100,\n                $sum_comment / $sum_comment * 100,\n                $sum_code    / $sum_code    * 100;\n          } else {\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $DEN * 100,\n                $sum_comment / $DEN * 100,\n                $sum_code    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{'4'}{$Style},\n              $sum_blank   ,\n              $sum_comment ,\n              $sum_code    ;\n        }\n        $data_line .= sprintf $Format{'6'}{$Style},\n            $avg_scale   ,\n            $sum_scaled  if $opt_3;\n        push @results, \"  <total \" . $data_line . \"/>\";\n\n        if ($BY_FILE or ($report_type eq \"by report file\")) {\n            push @results, \"</files>\";\n        } else {\n            foreach my $language (keys %{$languages}) {\n                push @results, '  <language name=\"' . $language . '\"/>';\n            }\n            push @results, \"</languages>\";\n        }\n\n        if (!$opt_by_file_by_lang or $ALREADY_SHOWED_XML_SECTION) {\n            push @results, \"</results>\";\n        } else {\n            $ALREADY_SHOWED_XML_SECTION = 1;\n        }\n    } elsif ($out_style eq \"yaml\" or $out_style eq \"json\") {\n        my ($Q, $open_B, $close_B, $start, $C) = yaml_to_json_separators();\n        push @results, \"${Q}SUM${Q}: ${open_B}\";\n        if ($opt_by_percent eq 't') {\n          push @results, \"  ${Q}blank${Q}: \"  . sprintf(\"%.2f\", 100) . $C;\n          push @results, \"  ${Q}comment${Q}: \". sprintf(\"%.2f\", 100) . $C;\n          push @results, \"  ${Q}code${Q}: \"   . sprintf(\"%.2f\", 100) . $C;\n        } else {\n          my $DEN = compute_denominator($opt_by_percent    ,\n                        $sum_code, $sum_comment, $sum_blank);\n          push @results, \"  ${Q}blank${Q}: \"  . $sum_blank   . $C;\n          push @results, \"  ${Q}comment${Q}: \". $sum_comment . $C;\n          push @results, \"  ${Q}code${Q}: \"   . $sum_code    . $C;\n        }\n        push @results, \"  ${Q}nFiles${Q}: \" . $sum_files   . $C;\n        if ($opt_3) {\n            push @results, \"  ${Q}scaled${Q}: \" . $sum_scaled . $C;\n            push @results, \"  ${Q}factor${Q}: \" . $avg_scale  . $C;\n        }\n        if ($out_style eq \"json\") {\n            $results[-1] =~ s/,\\s*$/} }/;\n            if ($opt_by_file_by_lang) {\n                if ($ALREADY_SHOWED_HEADER) {\n                    $results[-1] .= ' }';\n                } else {\n                    $results[-1] .= ', \"by_lang\" : {';\n                }\n            }\n        }\n    } elsif ($out_style eq \"csv\") {\n        my @entries = ();\n        if ($opt_by_file) {\n            push @entries, \"SUM\";\n            push @entries, \"\";\n        } else {\n            push @entries, $sum_files;\n            push @entries, \"SUM\";\n        }\n        if ($opt_by_percent) {\n          if ($opt_by_percent eq 't') {\n            push @entries, sprintf(\"%.2f\", 100);\n            push @entries, sprintf(\"%.2f\", 100);\n            push @entries, sprintf(\"%.2f\", 100);\n          } else {\n            my $DEN = compute_denominator($opt_by_percent    ,\n                          $sum_code, $sum_comment, $sum_blank);\n            push @entries, sprintf(\"%.2f\", $sum_blank   / $DEN * 100);\n            push @entries, sprintf(\"%.2f\", $sum_comment / $DEN * 100);\n            push @entries, sprintf(\"%.2f\", $sum_code    / $DEN * 100);\n          }\n        } else {\n            push @entries, $sum_blank;\n            push @entries, $sum_comment;\n            push @entries, $sum_code;\n        }\n        if ($opt_3) {\n            push @entries, $sum_scaled;\n            push @entries, $avg_scale ;\n        }\n        my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n        push @results, join($separator, @entries);\n    } else {\n\n        if ($BY_FILE) {\n            $data_line  = sprintf \"%-${spacing_0}s \", \"SUM:\"  ;\n        } else {\n            $data_line  = sprintf \"%-${spacing_1}s \", \"SUM:\"  ;\n            $data_line .= sprintf \"%${spacing_2}d \", $sum_files;\n        }\n        if ($opt_by_percent) {\n          if ($opt_by_percent eq 't') {\n            $data_line .= sprintf $Format{'5'}{$Style}, 100, 100, 100;\n          } else {\n            my $DEN = compute_denominator($opt_by_percent    ,\n                          $sum_code, $sum_comment, $sum_blank);\n            $data_line .= sprintf $Format{'5'}{$Style},\n                $sum_blank   / $DEN * 100,\n                $sum_comment / $DEN * 100,\n                $sum_code    / $DEN * 100;\n          }\n        } else {\n          $data_line .= sprintf $Format{'4'}{$Style},\n              $sum_blank   ,\n              $sum_comment ,\n              $sum_code    ;\n        }\n        $data_line .= sprintf $Format{'6'}{$Style},\n            $avg_scale   ,\n            $sum_scaled if $opt_3;\n        if ($out_style eq \"md\") {\n            my @words = split(' ', $data_line);\n            my $n_cols = scalar(@words);\n#           my $n_cols = scalar(split(' ', $data_line));  # deprecated\n            $data_line =~ s/\\s+/\\|/g;\n            my @col_hyphens    = ( '--------') x $n_cols;\n            push @results, join(\"|\", @col_hyphens);\n            push @results, $data_line   if $sum_files > 1 or $opt_sum_one;\n            unshift @results, ( \"cloc|$header_line\", \"--- | ---\", \"\", );\n        } else {\n            push @results, $hyphen_line if $sum_files > 1 or $opt_sum_one;\n            push @results, $data_line   if $sum_files > 1 or $opt_sum_one;\n            push @results, $hyphen_line;\n        }\n    }\n    write_xsl_file() if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n    $ALREADY_SHOWED_HEADER = 1 unless $opt_sum_reports;\n    print \"<- generate_report\\n\" if $opt_v > 2;\n    return @results;\n} # 1}}}\nsub print_errors {                           # {{{1\n    my ($rh_Error_Codes, # in\n        $raa_errors    , # in\n       ) = @_;\n\n    print \"-> print_errors\\n\" if $opt_v > 2;\n    my %error_string = reverse(%{$rh_Error_Codes});\n    my $nErrors      = scalar @{$raa_errors};\n    warn sprintf \"\\n%d error%s:\\n\", plural_form(scalar @Errors);\n    for (my $i = 0; $i < $nErrors; $i++) {\n        warn sprintf \"%s:  %s\\n\",\n                     $error_string{ $raa_errors->[$i][0] },\n                     $raa_errors->[$i][1] ;\n    }\n    print \"<- print_errors\\n\" if $opt_v > 2;\n\n} # 1}}}\nsub write_lang_def {                         # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # in\n        $rh_Language_by_Script    , # in\n        $rh_Language_by_File_Type      , # in\n        $rhaa_Filters_by_Language , # in\n        $rh_Not_Code_Extension    , # in\n        $rh_Not_Code_Filename     , # in\n        $rh_Scale_Factor          , # in\n        $rh_EOL_Continuation_re   , # in\n       ) = @_;\n\n    print \"-> write_lang_def($file)\\n\" if $opt_v > 2;\n    my @outlines = ();\n\n    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {\n        next if $language =~ /(Brain|\\(unknown\\))/;\n        next if defined $Extension_Collision{$language};\n        push @outlines, $language;\n        foreach my $filter (@{$rhaa_Filters_by_Language->{$language}}) {\n            my $line = \"\";\n            $line .= sprintf \"    filter %s\", $filter->[0];\n            $line .= sprintf \" %s\", $filter->[1] if defined $filter->[1];\n            # $filter->[0] == 'remove_between_general',\n            #                 'remove_between_regex', and\n            #                 'remove_matches_2re' have two args\n            $line .= sprintf \" %s\", $filter->[2] if defined $filter->[2];\n            # $filter->[0] == 'replace_between_regex' has three or four args\n            $line .= sprintf \" %s\", $filter->[3] if defined $filter->[3];\n            $line .= sprintf \" %s\", $filter->[4] if defined $filter->[4];\n            push @outlines, $line;\n        }\n\n        # file extension won't appear if the extension maps to\n        # multiple languages; work around this\n        my $found = 0;\n        foreach my $ext (sort keys %{$rh_Language_by_Extension}) {\n            if ($language eq $rh_Language_by_Extension->{$ext}) {\n                push @outlines, sprintf \"    extension %s\\n\", $ext;\n                $found = 1;\n            }\n        }\n        if (!$found and $opt_write_lang_def_incl_dup) {\n            foreach my $multilang (sort keys %Extension_Collision) {\n                my %Languages = map { $_ => 1 } split('/', $multilang);\n                next unless $Languages{$language};\n                foreach my $ext (@{$Extension_Collision{$multilang}}) {\n                    push @outlines, sprintf \"    extension %s\\n\", $ext;\n                }\n            }\n        }\n\n        foreach my $filename (sort keys %{$rh_Language_by_File_Type}) {\n            if ($language eq $rh_Language_by_File_Type->{$filename}) {\n                push @outlines, sprintf \"    filename %s\\n\", $filename;\n            }\n        }\n        foreach my $script_exe (sort keys %{$rh_Language_by_Script}) {\n            if ($language eq $rh_Language_by_Script->{$script_exe}) {\n                push @outlines, sprintf \"    script_exe %s\\n\", $script_exe;\n            }\n        }\n        push @outlines, sprintf \"    3rd_gen_scale %.2f\\n\", $rh_Scale_Factor->{$language};\n        if (defined $rh_EOL_Continuation_re->{$language}) {\n            push @outlines, sprintf \"    end_of_line_continuation %s\\n\",\n                $rh_EOL_Continuation_re->{$language};\n        }\n    }\n\n    write_file($file, {}, @outlines);\n    print \"<- write_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub read_lang_def {                          # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # out\n        $rh_Language_by_Script    , # out\n        $rh_Language_by_File_Type      , # out\n        $rhaa_Filters_by_Language , # out\n        $rh_Not_Code_Extension    , # out\n        $rh_Not_Code_Filename     , # out\n        $rh_Scale_Factor          , # out\n        $rh_EOL_Continuation_re   , # out\n        $rh_EOL_abc,\n       ) = @_;\n\n\n    print \"-> read_lang_def($file)\\n\" if $opt_v > 2;\n\n    my $language = \"\";\n    my @lines = read_file($file);\n    my $line_num = 0;\n    foreach (@lines) {\n        ++$line_num;\n        next if /^\\s*#/ or /^\\s*$/;\n\n        $_ = lc $_ if $ON_WINDOWS and /^\\s+(filename|extension)\\s/;\n\n        if (/^(\\.?\\w+.*?)\\s*$/) {\n            $language = $1;\n            next;\n        }\n        die \"Missing computer language name, line $line_num of $file\\n\"\n            unless $language;\n\n        if      (/^\\s{4}filter\\s+(remove_between_(general|2re|regex))\n                       \\s+(\\S+)\\s+(\\S+)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                   \\s+(\\S+)\\s+(\\S+)\\s+(\\S+|\\\".*\\\")\\s+(\\S+)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 , $5]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                       \\s+(\\S+)\\s+(\\S+)\\s+(.*?)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\\s+(\\S+)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , '' ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\n                       \\s+(\\S+)\\s+(.+?)\\s*$/x) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s+(.*?)\\s*$/) {\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]\n\n        } elsif (/^\\s{4}extension\\s+(\\S+)\\s*$/) {\n            if (defined $rh_Language_by_Extension->{$1}) {\n                die \"File extension collision:  $1 \",\n                    \"maps to languages '$rh_Language_by_Extension->{$1}' \",\n                    \"and '$language'\\n\" ,\n                    \"Edit $file and remove $1 from one of these two \",\n                    \"language definitions.\\n\";\n            }\n            $rh_Language_by_Extension->{$1} = $language;\n\n        } elsif (/^\\s{4}filename\\s+(\\S+)\\s*$/) {\n            $rh_Language_by_File_Type->{$1} = $language;\n\n        } elsif (/^\\s{4}script_exe\\s+(\\S+)\\s*$/) {\n            $rh_Language_by_Script->{$1} = $language;\n\n        } elsif (/^\\s{4}3rd_gen_scale\\s+(\\S+)\\s*$/) {\n            $rh_Scale_Factor->{$language} = $1;\n\n        } elsif (/^\\s{4}end_of_line_continuation\\s+(\\S+)\\s*$/) {\n            $rh_EOL_Continuation_re->{$language} = $1;\n\n        } else {\n            die \"Unexpected data line $line_num of $file:\\n$_\\n\";\n        }\n\n    }\n    print \"<- read_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub merge_lang_def {                         # {{{1\n    my ($file                     ,\n        $rh_Language_by_Extension , # in/out\n        $rh_Language_by_Script    , # in/out\n        $rh_Language_by_File_Type      , # in/out\n        $rhaa_Filters_by_Language , # in/out\n        $rh_Not_Code_Extension    , # in/out\n        $rh_Not_Code_Filename     , # in/out\n        $rh_Scale_Factor          , # in/out\n        $rh_EOL_Continuation_re   , # in/out\n        $rh_EOL_abc,\n       ) = @_;\n\n\n    print \"-> merge_lang_def($file)\\n\" if $opt_v > 2;\n\n    my $language        = \"\";\n    my $already_know_it = undef;\n    my @lines = read_file($file);\n    my $line_num = 0;\n    foreach (@lines) {\n        ++$line_num;\n        next if /^\\s*#/ or /^\\s*$/;\n\n        $_ = lc $_ if $ON_WINDOWS and /^\\s+(filename|extension)\\s/;\n\n        if (/^(\\.?\\w+.*?)\\s*$/) {\n            $language = $1;\n            $already_know_it = defined $rh_Scale_Factor->{$language};\n            next;\n        }\n        die \"Missing computer language name, line $line_num of $file\\n\"\n            unless $language;\n\n        if      (/^\\s{4}filter\\s+(remove_between_(general|2re|regex))\n                       \\s+(\\S+)\\s+(\\S+)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                   \\s+(\\S+)\\s+(\\S+)\\s+(\\S+|\\\".*\\\")\\s+(\\S+)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 , $5]\n\n        } elsif (/^\\s{4}filter\\s+(replace_between_regex)\n                       \\s+(\\S+)\\s+(\\S+)\\s+(.*?)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 , $4 ]\n\n        } elsif (/^\\s{4}filter\\s+(replace_regex)\n                       \\s+(\\S+)\\s+(.+?)\\s*$/x) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [\n                  $1 , $2 , $3 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s*$/) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 ]\n\n        } elsif (/^\\s{4}filter\\s+(\\w+)\\s+(.*?)\\s*$/) {\n            next if $already_know_it;\n            push @{$rhaa_Filters_by_Language->{$language}}, [ $1 , $2 ]\n\n        } elsif (/^\\s{4}extension\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            if (defined $rh_Language_by_Extension->{$1}) {\n                die \"File extension collision:  $1 \",\n                    \"maps to languages '$rh_Language_by_Extension->{$1}' \",\n                    \"and '$language'\\n\" ,\n                    \"Edit $file and remove $1 from one of these two \",\n                    \"language definitions.\\n\";\n            }\n            $rh_Language_by_Extension->{$1} = $language;\n\n        } elsif (/^\\s{4}filename\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Language_by_File_Type->{$1} = $language;\n\n        } elsif (/^\\s{4}script_exe\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Language_by_Script->{$1} = $language;\n\n        } elsif (/^\\s{4}3rd_gen_scale\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_Scale_Factor->{$language} = $1;\n\n        } elsif (/^\\s{4}end_of_line_continuation\\s+(\\S+)\\s*$/) {\n            next if $already_know_it;\n            $rh_EOL_Continuation_re->{$language} = $1;\n\n        } else {\n            die \"Unexpected data line $line_num of $file:\\n$_\\n\";\n        }\n\n    }\n    print \"<- merge_lang_def\\n\" if $opt_v > 2;\n} # 1}}}\nsub print_extension_info {                   # {{{1\n    my ($extension,) = @_;\n    printf \"%-15s %s\\n\", \"Extension\", \"Language\";\n    printf \"%-15s %s\\n\", \"---------\", \"-\" x 20;\n    if ($extension) {  # show information on this extension\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            next if $Language_by_Extension{$ext} =~ /Brain/;\n            printf \"%-15s %s\\n\", $ext, $Language_by_Extension{$ext}\n                if $ext =~ m{$extension}i;\n        }\n    } else {           # show information on all  extensions\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            next if $Language_by_Extension{$ext} =~ /Brain/;\n            # Language_by_Extension{f}    = 'Fortran 77'\n            printf \"%-15s %s\\n\", $ext, $Language_by_Extension{$ext};\n        }\n    }\n} # 1}}}\nsub print_language_info {                    # {{{1\n    my ($language,\n        $prefix ,) = @_;\n    my %extensions = (); # the subset matched by the given $language value\n    if ($language) {  # show information on this language\n        foreach my $ext (sort {lc $a cmp lc $b or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            push @{$extensions{$Language_by_Extension{$ext}} }, $ext\n                if lc $Language_by_Extension{$ext} eq lc $language;\n#               if $Language_by_Extension{$ext} =~ m{$language}i;\n        }\n    } else {          # show information on all  languages\n        foreach my $ext (sort {lc $a cmp lc $b  or $a cmp $b } keys %Language_by_Extension) {\n            # Language_by_Extension{f}    = 'Fortran 77'\n            push @{$extensions{$Language_by_Extension{$ext}} }, $ext\n        }\n    }\n\n    # add exceptions (one file extension mapping to multiple languages)\n    if (!$language or $language =~ /^(Objective-C|MATLAB|Mathematica|MUMPS|Mercury)$/i) {\n        push @{$extensions{'Objective-C'}}, \"m\";\n        push @{$extensions{'MATLAB'}}     , \"m\";\n        push @{$extensions{'Mathematica'}}, \"m\";\n        push @{$extensions{'MUMPS'}}      , \"m\";\n        delete $extensions{'MATLAB/Mathematica/Objective-C/MUMPS/Mercury'};\n    }\n    if (!$language or $language =~ /^(Lisp|OpenCL)$/i) {\n        push @{$extensions{'Lisp'}}  , \"cl\";\n        push @{$extensions{'OpenCL'}}, \"cl\";\n        delete $extensions{'Lisp/OpenCL'};\n    }\n    if (!$language or $language =~ /^(Lisp|Julia)$/i) {\n        push @{$extensions{'Lisp'}}  , \"jl\";\n        push @{$extensions{'Julia'}} , \"jl\";\n        delete $extensions{'Lisp/Julia'};\n    }\n    if (!$language or $language =~ /^(Perl|Prolog)$/i) {\n        push @{$extensions{'Perl'}}  , \"pl\";\n        push @{$extensions{'Prolog'}}, \"pl\";\n        delete $extensions{'Perl/Prolog'};\n    }\n    if (!$language or $language =~ /^(Raku|Prolog)$/i) {\n        push @{$extensions{'Perl'}}  , \"p6\";\n        push @{$extensions{'Prolog'}}, \"p6\";\n        delete $extensions{'Perl/Prolog'};\n    }\n    if (!$language or $language =~ /^(IDL|Qt Project|Prolog|ProGuard)$/i) {\n        push @{$extensions{'IDL'}}       , \"pro\";\n        push @{$extensions{'Qt Project'}}, \"pro\";\n        push @{$extensions{'Prolog'}}    , \"pro\";\n        push @{$extensions{'ProGuard'}}  , \"pro\";\n        delete $extensions{'IDL/Qt Project/Prolog/ProGuard'};\n    }\n    if (!$language or $language =~ /^(D|dtrace)$/i) {\n        push @{$extensions{'D'}}       , \"d\";\n        push @{$extensions{'dtrace'}}  , \"d\";\n        delete $extensions{'D/dtrace'};\n    }\n    if (!$language or $language =~ /^Forth$/) {\n        push @{$extensions{'Forth'}}     , \"fs\";\n        push @{$extensions{'Forth'}}     , \"f\";\n        push @{$extensions{'Forth'}}     , \"for\";\n        delete $extensions{'Fortran 77/Forth'};\n        delete $extensions{'F#/Forth'};\n    }\n    if (!$language or $language =~ /^Fortran 77$/) {\n        push @{$extensions{'Fortran 77'}}, \"f\";\n        push @{$extensions{'Fortran 77'}}, \"for\";\n        push @{$extensions{'F#'}}        , \"fs\";\n        delete $extensions{'Fortran 77/Forth'};\n    }\n    if (!$language or $language =~ /^F#$/) {\n        push @{$extensions{'F#'}}        , \"fs\";\n        delete $extensions{'F#/Forth'};\n    }\n    if (!$language or $language =~ /^(Verilog-SystemVerilog|Coq)$/) {\n        push @{$extensions{'Coq'}}                   , \"v\";\n        push @{$extensions{'Verilog-SystemVerilog'}} , \"v\";\n        delete $extensions{'Verilog-SystemVerilog/Coq'};\n    }\n    if (!$language or $language =~ /^(TypeScript|Qt Linguist)$/) {\n        push @{$extensions{'TypeScript'}}  , \"ts\";\n        push @{$extensions{'Qt Linguist'}} , \"ts\";\n        delete $extensions{'TypeScript/Qt Linguist'};\n    }\n    if (!$language or $language =~ /^(Qt|Glade)$/) {\n        push @{$extensions{'Glade'}}       , \"ui\";\n        push @{$extensions{'XML-Qt-GTK'}}  , \"ui\";\n        delete $extensions{'XML-Qt-GTK/Glade'};\n    }\n    if (!$language or $language =~ /^(C#|Smalltalk)$/) {\n        push @{$extensions{'C#'}}           , \"cs\";\n        push @{$extensions{'Smalltalk'}}    , \"cs\";\n        delete $extensions{'C#/Smalltalk'};\n    }\n    if (!$language or $language =~ /^(Visual\\s+Basic|TeX|Apex\\s+Class)$/i) {\n        push @{$extensions{'Visual Basic'}} , \"cls\";\n        push @{$extensions{'TeX'}}          , \"cls\";\n        push @{$extensions{'Apex Class'}}   , \"cls\";\n        delete $extensions{'Visual Basic/TeX/Apex Class'};\n    }\n    if (!$language or $language =~ /^(Ant)$/i) {\n        push @{$extensions{'Ant'}}  , \"build.xml\";\n        delete $extensions{'Ant/XML'};\n    }\n    if (!$language or $language =~ /^(Scheme|SaltStack)$/i) {\n        push @{$extensions{'Scheme'}}    , \"sls\";\n        push @{$extensions{'SaltStack'}} , \"sls\";\n        delete $extensions{'Scheme/SaltStack'};\n    }\n    if (!$language or $language =~ /^(Clojure|Cangjie)$/i) {\n        push @{$extensions{'Clojure'}} , \"cj\";\n        push @{$extensions{'Cangjie'}} , \"cj\";\n        delete $extensions{'Clojure/Cangjie'};\n    }\n    printf \"%-26s %s\\n\", \"Language\", \"Extension(s)\";\n    printf \"%-26s %s\\n\", \"-\" x 20, \"-\" x 40;\n    if ($opt_explain) {\n        return unless $extensions{$language};\n        if ($prefix) {\n            printf \"%s %s\\n\", $prefix, join(\", \", @{$extensions{$language}});\n        } else {\n            printf \"%-26s (%s)\\n\", $language, join(\", \", @{$extensions{$language}});\n        }\n    } else {\n        if (%extensions) {\n            foreach my $lang (sort {lc $a cmp lc $b } keys %extensions) {\n                next if $lang =~ /Brain/;\n                if ($prefix) {\n                    printf \"%s %s\\n\", $prefix, join(\", \", @{$extensions{$lang}});\n                } else {\n                    printf \"%-26s (%s)\\n\", $lang, join(\", \", @{$extensions{$lang}});\n                }\n            }\n        }\n    }\n} # 1}}}\nsub print_language_filters {                 # {{{1\n    my ($language,) = @_;\n    if (!$Filters_by_Language{$language} or\n        !@{$Filters_by_Language{$language}}) {\n        warn \"Unknown language: $language\\n\";\n        warn \"Use --show-lang to list all defined languages.\\n\";\n        return;\n    }\n    printf \"%s\\n\", $language;\n    foreach my $filter (@{$Filters_by_Language{$language}}) {\n        printf \"    filter %s\", $filter->[0];\n        printf \"  %s\", $filter->[1] if defined $filter->[1];\n        printf \"  %s\", $filter->[2] if defined $filter->[2];\n        printf \"  %s\", $filter->[3] if defined $filter->[3];\n        printf \"  %s\", $filter->[4] if defined $filter->[4];\n        print  \"\\n\";\n    }\n    print_language_info($language, \"    extensions:\");\n} # 1}}}\nsub top_level_SMB_dir {                      # {{{1\n    # Ref https://github.com/AlDanial/cloc/issues/392, if the\n    # user supplies a directory name which is an SMB mount\n    # point, this directory will appear to File::Find as\n    # though it is empty unless $File::Find::dont_use_nlink\n    # is set to 1.  This subroutine checks to see if any SMB\n    # mounts (identified from stat()'s fourth entry, nlink,\n    # having a value of 2) were passed in on the command line.\n\n    my ($ra_arg_list,) = @_;  # in user supplied file name, directory name, git hash, etc\n    foreach my $entry (@{$ra_arg_list}) {\n        next unless is_dir($entry);\n        # gets here if $entry is a directory; now get its nlink value\n        my $nlink;\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            my $stats = statL($entry);\n            $nlink = $stats->{nlink} if defined $stats;\n        } else {\n            my @stats = stat($entry);\n            $nlink = $stats[3];\n        }\n        return 1 if $nlink == 2;  # meaning it is an SMB mount\n    }\n    return 0;\n}\n# 1}}}\nsub get_git_metadata {                       # {{{1\n    my ($ra_arg_list,             # in  file name, directory name and/or\n                                  #     git commit hash to examine\n        $rh_git_metadata) = @_;   # out repo info\n    # Capture git information where possible--origin, branch, commit hash.\n    my $prt_args = join(\",\", @{$ra_arg_list});\n    print \"-> get_git_metadata($prt_args)\\n\" if $opt_v > 2;\n    foreach my $arg (@{$ra_arg_list}) {\n        next if is_file($arg);\n        my $origin = `git -c \\\"safe.directory=*\\\" remote get-url origin 2>&1`;\n        next if $origin =~ /^fatal:/;\n        chomp($rh_git_metadata->{$arg}{\"origin\"} = $origin);\n        chomp($rh_git_metadata->{$arg}{\"branch\"} = `git -c \\\"safe.directory=*\\\" symbolic-ref --short HEAD`);\n        if (is_dir($arg)) {\n            chomp($rh_git_metadata->{$arg}{\"commit\"}   = `git -c \\\"safe.directory=*\\\" rev-parse HEAD`);\n        } else {\n            chomp($rh_git_metadata->{$arg}{\"commit\"}   = `git -c \\\"safe.directory=*\\\" rev-parse $arg`);\n        }\n    }\n    print \"<- get_git_metadata()\\n\" if $opt_v > 2;\n} # 1}}}\nsub replace_git_hash_with_tarfile {          # {{{1\n    my ($ra_arg_list,             # in  file name, directory name and/or\n                                  #     git commit hash to examine\n        $ra_git_similarity) = @_; # out only if --opt-git-diff-simindex\n    # replace git hashes in $ra_arg_list with tar files\n    # Diff mode and count mode behave differently:\n    #   Diff:\n    #       file  git_hash\n    #          Extract file from the git repo and only compare to it.\n    #       git_hash1  git_hash2\n    #          Get listings of all files in git_hash1 and git_hash2.\n    #            git ls-tree --name-only -r *git_hash1*\n    #            git ls-tree --name-only -r *git_hash2*\n    #          Next, get listings of files that changed with git_hash1\n    #          and git_hash2.\n    #            git diff-tree -r --no-commit-id --name-only *git_hash1* *git_hash2*\n    #          Finally, make two tar files of git repos1 and 2 where the file\n    #          listing is the union of changes.\n    #            git archive -o tarfile1 *git_hash1* \\\n    #               <union of files that changed and exist in this commit>\n    #            git archive -o tarfile2 *git_hash2* \\\n    #               <union of files that changed and exist in this commit>\n    #          To avoid \"Argument list too long\" error, repeat the git\n    #          archive step with chunks of 30,000 files at a time then\n    #          merge the tar files as the final step.\n    #   Regular count:\n    #       Simply make a tar file of all files in the git repo.\n\n    my $prt_args = join(\",\", @{$ra_arg_list});\n    print \"-> replace_git_hash_with_tarfile($prt_args)\\n\" if $opt_v > 2;\n#print \"ra_arg_list 1: @{$ra_arg_list}\\n\";\n\n    my $hash_regex = qr/^([a-f\\d]{5,40}|master|HEAD)(~\\d+)?$/;\n    my %replacement_arg_list = ();\n\n    # early exit if none of the inputs look like git hashes\n    my %git_hash = ();\n    my $i = 0;\n    foreach my $file_or_dir (@{$ra_arg_list}) {\n        ++$i;\n        if (can_read($file_or_dir)) { # readable file or dir; not a git hash\n            $replacement_arg_list{$i} = $file_or_dir;\n            next;\n        } elsif ($opt_force_git or $file_or_dir =~ m/$hash_regex/) {\n            $git_hash{$file_or_dir} = $i;\n        } # else the input can't be understood; ignore for now\n    }\n    return unless %git_hash;\n\n#   my $have_tar_git = external_utility_exists($ON_WINDOWS ? \"unzip\" : \"tar --version\") &&\n    my $have_tar_git = external_utility_exists(\"tar --version\") &&\n                       external_utility_exists(\"git --version\");\n    if (!$have_tar_git) {\n        warn \"One or more inputs looks like a git hash but \" .\n             \"either git or tar is unavailable.\\n\";\n        return;\n    }\n\n    my %repo_listing = ();  # $repo_listing{hash}{files} = 1;\n    foreach my $hash (sort keys %git_hash) {\n        my $git_list_cmd = \"git -c \\\"safe.directory=*\\\" ls-tree --name-only -r \";\n        if ($hash =~ m/(.*?):(.*?)$/) {\n            # requesting specific file(s) from this hash; grep for them\n            # Note:  this capability not fully implemented yet\n            $git_list_cmd .= \"$1|grep '$2'\";\n        } else {\n            $git_list_cmd .= $hash;\n        }\n        print \"$git_list_cmd\\n\" if $opt_v;\n        foreach my $file (`$git_list_cmd`) {\n            $file =~ s/\\s+$//;\n            $repo_listing{$hash}{$file} = 1;\n        }\n    }\n\n    # logic for each of the modes\n    if ($opt_diff) {\n#print \"A DIFF\\n\";\n        # set the default git diff algorithm\n        $opt_git_diff_rel = 1 unless $opt_git_diff_all or\n                                     $opt_git_diff_simindex;\n        # is it git to git, or git to file/dir ?\n        my ($Left, $Right) = @{$ra_arg_list};\n\n#use Data::Dumper;\n#print \"diff_listing= \"; print Dumper(\\%diff_listing);\n#print \"git_hash= \"; print Dumper(\\%git_hash);\n        if ($git_hash{$Left} and $git_hash{$Right}) {\n#print \"A DIFF git-to-git\\n\";\n            # git to git\n            # first make a union of all files that have changed in both commits\n            my %files_union = ();\n\n            my @left_files  = ();\n            my @right_files = ();\n            if ($opt_git_diff_rel) {\n                # Strategy 1:  Union files are what git considers have changed\n                #              between the two commits.\n                my $git_list_cmd = \"git -c \\\"safe.directory=*\\\" diff-tree -r --no-commit-id --name-only $Left $Right\";\n                # print \"$git_list_cmd\\n\" if $opt_v;\n                foreach my $file (`$git_list_cmd`) {\n                    chomp($file);\n                    $files_union{$file} = 1;\n                }\n            } elsif ($opt_git_diff_all) {\n                # Strategy 2:  Union files all files in both repos.\n                foreach my $file (keys %{$repo_listing{$Left }},\n                                  keys %{$repo_listing{$Right}}) {\n                   $files_union{$file} = 1;\n                }\n            } elsif ($opt_git_diff_simindex) {\n                # Strategy 3:  Use git's own similarity index to figure\n                #              out which files to compare.\n                git_similarity_index($Left              , # in\n                                     $Right             , # in\n                                    \\@left_files        , # out\n                                    \\@right_files       , # out\n                                     $ra_git_similarity); # out\n\n            }\n\n            if ($opt_exclude_list_file) {\n                my @reject_list = read_list_file($opt_exclude_list_file);\n                my %entries_to_drop = ();\n                foreach my $f_or_d (@reject_list) {\n                    if (-d $f_or_d) {\n                        # directory match\n                        $entries_to_drop{$f_or_d} = 1;\n                        foreach my $file (keys %files_union) {\n                            $entries_to_drop{$file} = 1 if $file =~ m{$f_or_d/};\n                        }\n                    } else {\n                        # exact match\n                        $entries_to_drop{$f_or_d} = 1;\n                    }\n                }\n                foreach my $file (keys %entries_to_drop) {\n                    delete $files_union{$file};\n                }\n            }\n\n            if ($opt_list_file) {\n                my @include_list = read_list_file($opt_list_file);\n                my %entries_to_add  = ();\n                foreach my $f_or_d (@include_list) {\n                    if (-d $f_or_d) {\n                        # directory match\n                        $entries_to_add{$f_or_d} = 1;\n                        foreach my $file (keys %files_union) {\n                            $entries_to_add{$file} = 1 if $file =~ m{$f_or_d/};\n                        }\n                    } else {\n                        # exact match\n                        $entries_to_add{$f_or_d} = 1;\n                    }\n                }\n                %files_union = %entries_to_add; # and exclude all others\n            }\n\n            # then make truncated tar files of those union files which\n            # actually exist in each repo\n            foreach my $file (sort keys %files_union) {\n                push @left_files , $file if $repo_listing{$Left }{$file};\n                push @right_files, $file if $repo_listing{$Right}{$file};\n            }\n            # backslash whitespace, weird chars within file names (#257, #284)\n\n#           my @Lfiles= map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\$\\?])/\\\\$1/g; $_}   @left_files;\n#           my @Lfiles= @left_files;\n            if(scalar(@left_files) > 0) {\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left , \\@left_files);\n            } else {\n                # In the right side commit ONLY file(s) was added, so no file(s) will exist in the left side commit.\n                # Create empty TAR to detect added lines of code.\n                $replacement_arg_list{$git_hash{$Left}} = empty_tar();\n            }\n#           $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left , \\@Lfiles);\n#           my @Rfiles= map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\$\\?])/\\\\$1/g; $_}   @right_files ;\n#           my @Rfiles= @right_files ;\n#use Data::Dumper;\n#print Dumper('left' , \\@left_files);\n#print Dumper('right', \\@right_files);\n#die;\n\n            if(scalar(@right_files) > 0) {\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \\@right_files);\n            } else {\n                 # In the left side commit ONLY file(s) was deleted, so file(s) will not exist in right side commit.\n                 # Create empty TAR to detect removed lines of code.\n                 $replacement_arg_list{$git_hash{$Right}} = empty_tar();\n            }\n#           $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \\@Rfiles);\n#write_file(\"/tmp/Lfiles.txt\", {}, sort @Lfiles);\n#write_file(\"/tmp/Rfiles.txt\", {}, sort @Rfiles);\n#write_file(\"/tmp/files_union.txt\", {}, sort keys %files_union);\n\n        } else {\n#print \"A DIFF git-to-file or file-to-git Left=$Left Right=$Right\\n\";\n            # git to file/dir or file/dir to git\n            if      ($git_hash{$Left}  and $repo_listing{$Left}{$Right} ) {\n#print \"A DIFF 1\\n\";\n                # $Left is a git hash and $Right is a file\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left, $Right);\n            } elsif ($git_hash{$Right} and $repo_listing{$Right}{$Left}) {\n#print \"A DIFF 2\\n\";\n                # $Left is a file and $Right is a git hash\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, $Left);\n            } elsif ($git_hash{$Left}) {\n#print \"A DIFF 3\\n\";\n                # assume Right is a directory; tar the entire git archive at this hash\n                $replacement_arg_list{$git_hash{$Left}}  = git_archive($Left, \"\");\n            } else {\n#print \"A DIFF 4\\n\";\n                # assume Left  is a directory; tar the entire git archive at this hash\n                $replacement_arg_list{$git_hash{$Right}} = git_archive($Right, \"\");\n            }\n        }\n    } else {\n#print \"B COUNT\\n\";\n        foreach my $hash (sort keys %git_hash) {\n            $replacement_arg_list{$git_hash{$hash}} = git_archive($hash);\n        }\n    }\n# print \"git_hash= \"; print Dumper(\\%git_hash);\n#print \"repo_listing= \"; print Dumper(\\%repo_listing);\n\n    # replace the input arg list with the new one\n    @{$ra_arg_list} = ();\n    foreach my $index (sort {$a <=> $b} keys %replacement_arg_list) {\n        push @{$ra_arg_list}, $replacement_arg_list{$index};\n    }\n\n#print \"ra_arg_list 2: @{$ra_arg_list}\\n\";\n    print \"<- replace_git_hash_with_tarfile()\\n\" if $opt_v > 2;\n} # 1}}}\nsub git_similarity_index {                   # {{{\n    my ($git_hash_Left    ,       # in\n        $git_hash_Right   ,       # in\n        $ra_left_files    ,       # out\n        $ra_right_files   ,       # out\n        $ra_git_similarity) = @_; # out\n    die \"this option is not yet implemented\";\n    print \"-> git_similarity_index($git_hash_Left, $git_hash_Right)\\n\" if $opt_v > 2;\n    my $cmd = \"git -c \\\"safe.directory=*\\\" diff -M --name-status $git_hash_Left $git_hash_Right\";\n    print  $cmd, \"\\n\" if $opt_v;\n    open(GSIM, \"$cmd |\") or die \"Unable to run $cmd  $!\";\n    while (<GSIM>) {\n        print \"git similarity> $_\";\n    }\n    close(GSIM);\n    print \"<- git_similarity_index\\n\" if $opt_v > 2;\n} # 1}}}\nsub empty_tar {                              # {{{1\n    my ($Tarfh, $Tarfile);\n    if ($opt_sdir) {\n      File::Path::mkpath($opt_sdir) unless is_dir($opt_sdir);\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, DIR => $opt_sdir, SUFFIX => $ON_WINDOWS ? '.zip' : '.tar');  # delete on exit\n    } else {\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, SUFFIX => $ON_WINDOWS ? '.zip' : '.tar');  # delete on exit\n    }\n    my $cmd = $ON_WINDOWS ? \"type nul > $Tarfile\" : \"tar -cf $Tarfile -T /dev/null\";\n    print  $cmd, \"\\n\" if $opt_v;\n    system $cmd;\n    if (!can_read($Tarfile)) {\n        # not readable\n        die \"Failed to create empty tarfile.\";\n    }\n\n    return $Tarfile;\n} # 1}}}\nsub git_archive {                            # {{{1\n    # Invoke 'git archive' as a system command to create a tar file\n    # using the given argument(s).\n    my ($A1, $A2) = @_;\n    print \"-> git_archive($A1)\\n\" if $opt_v > 2;\n\n    my $args = undef;\n    my @File_Set = ( );\n    my $n_sets   = 1;\n    if (ref $A2 eq 'ARRAY') {\n        # Avoid \"Argument list too long\" for the git archive command\n        # by splitting the inputs into sets of 10,000 files (issue 273).\n        my $FILES_PER_ARCHIVE = 1_000;\n           $FILES_PER_ARCHIVE =   100 if $ON_WINDOWS; # github.com/AlDanial/cloc/issues/404\n\n        my $n_files  = scalar(@{$A2});\n        $n_sets = $n_files/$FILES_PER_ARCHIVE;\n        $n_sets = 1 + int($n_sets) if $n_sets > int($n_sets);\n        $n_sets = 1 if !$n_sets;\n        foreach my $i (0..$n_sets-1) {\n            @{$File_Set[$i]} = ( );\n            my $start = $i*$FILES_PER_ARCHIVE;\n            my $end   = smaller(($i+1)*$FILES_PER_ARCHIVE, $n_files) - 1;\n            # Wrap each file name in single quotes to protect spaces\n            # and other odd characters.  File names that themselves have\n            # single quotes are instead wrapped in double quotes.  File\n            # names with both single and double quotes... jeez.\n            foreach my $fname (@{$A2}[$start .. $end]) {\n                if      ($fname =~ /^\".*?\\\\\".*?\"$/) {\n                    # git pre-handles filenames with double quotes by backslashing\n                    # each double quote then surrounding entire name in double\n                    # quotes; undo this otherwise archive command crashes\n                    $fname =~ s/\\\\\"/\"/g;\n                    $fname =~ s/^\"(.*)\"$/$1/;\n                } elsif ($fname =~ /'/ or $ON_WINDOWS) {\n                    push @{$File_Set[$i]}, \"\\\"$fname\\\"\";\n                } else {\n                    push @{$File_Set[$i]}, \"'$fname'\";\n                }\n            }\n            unshift @{$File_Set[$i]}, \"$A1 \";  # prepend git hash to beginning of list\n\n##xx#        # don't include \\$ in the regex because git handles these correctly\n#            # to each word in @{$A2}[$start .. $end]: first backslash each\n#            # single quote, then wrap all entries in single quotes (#320)\n#            push @File_Set,\n#                 \"$A1 \" . join(\" \", map {$_ =~ s/'/\\'/g; $_ =~ s/^(.*)$/'$1'/g; $_}\n##                \"$A1 \" . join(\" \", map {$_ =~ s/([\\s\\(\\)\\[\\]{}';\\^\\?])/\\\\$1/g; $_}\n#                              @{$A2}[$start .. $end]);\n        }\n    } else {\n        if (defined $A2) {\n            push @{$File_Set[0]}, \"$A1 $A2\";\n        } else {\n            push @{$File_Set[0]}, \"$A1\";\n        }\n    }\n\n    my $files_this_commit = join(\" \", @{$File_Set[0]});\n    print \"   git_archive(file_set[0]=$files_this_commit)\\n\" if $opt_v > 2;\n    my ($Tarfh, $Tarfile);\n    my $archive_ext = $ON_WINDOWS ? '.zip'         : '.tar';\n    my $format      = $ON_WINDOWS ? '--format=zip' : \"\";\n    if ($opt_sdir) {\n      File::Path::mkpath($opt_sdir) unless is_dir($opt_sdir);\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, DIR => $opt_sdir, SUFFIX => $archive_ext);  # delete on exit\n    } else {\n      ($Tarfh, $Tarfile) = tempfile(UNLINK => 1, SUFFIX => $archive_ext);  # delete on exit\n    }\n    my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o $Tarfile $files_this_commit\";\n    print  $cmd, \"\\n\" if $opt_v;\n    system $cmd;\n    if (!can_read($Tarfile) or !get_size($Tarfile)) {\n        # not readable, or zero sized\n        die \"Failed to create tarfile of files from git.\";\n    }\n    if ($n_sets > 1) {\n        if ($ON_WINDOWS) {\n            my @tar_files = ( $Tarfile );\n            my $start_dir = cwd;\n            foreach my $i (1..$n_sets-1) {\n                my $fname = sprintf \"%s_extra_%08d\", $Tarfile, $i;\n                my $files_this_commit = join(\" \", @{$File_Set[$i]});\n                my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o $fname $files_this_commit\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                push @tar_files, $fname;\n            }\n            # Windows tar can't combine tar files so expand\n            # them all to one directory then re-tar\n            my $extract_dir = tempdir( CLEANUP => 0 );  # 1 = delete on exit\n            chdir \"$extract_dir\";\n            foreach my $T (@tar_files) {\n                next unless is_file($T) and get_size($T);\n                my $cmd = \"tar -x -f \\\"$T\\\"\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                unlink \"$T\";\n            }\n            chdir \"..\";\n            $Tarfile .= \".final.tar\";\n            my $cmd = \"tar -c -f \\\"${Tarfile}\\\" \\\"$extract_dir\\\"\";\n            print  $cmd, \"\\n\" if $opt_v;\n            system $cmd;\n            chdir \"$start_dir\";\n        } else {\n            foreach my $i (1..$n_sets-1) {\n                my $files_this_commit = join(\" \", @{$File_Set[$i]});\n                my $cmd = \"git -c \\\"safe.directory=*\\\" archive $format -o ${Tarfile}_extra $files_this_commit\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n                # and merge into the first one\n                $cmd = \"tar -A -f ${Tarfile} ${Tarfile}_extra\";\n                print  $cmd, \"\\n\" if $opt_v;\n                system $cmd;\n            }\n            unlink \"${Tarfile}_extra\";\n        }\n    }\n    print \"<- git_archive() made $Tarfile\\n\" if $opt_v > 2;\n    return $Tarfile\n} # 1}}}\nsub smaller {                                # {{{1\n    my( $a, $b ) = @_;\n    return $a < $b ? $a : $b;\n} # 1}}}\nsub lower_on_Windows {                       # {{{1\n    # If on Unix(-like), do nothing, just return the input.\n    # If on Windows, return a lowercase version of the file\n    # and also update %upper_lower_map with this new entry.\n    # Needed in make_file_list() because the full file list\n    # isn't known until the end of that routine--where\n    # %upper_lower_map is ordinarily populated.\n    my ($path,) = @_;\n    return $path unless $ON_WINDOWS;\n    my $lower = lc $path;\n    $upper_lower_map{$lower} = $path;\n    return $lower;\n}\n# }}}\nsub make_file_list {                         # {{{1\n    my ($ra_arg_list,  # in   file and/or directory names to examine\n        $iteration  ,  # in   0 if only called once, 1 or 2 if twice for diff\n        $rh_Err     ,  # in   hash of error codes\n        $raa_errors ,  # out  errors encountered\n        $rh_ignored ,  # out  files not recognized as computer languages\n        ) = @_;\n    print \"-> make_file_list(@{$ra_arg_list})\\n\" if $opt_v > 2;\n\n    my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n    my ($fh, $filename);\n    if ($opt_categorized) {\n        if ($iteration) {\n            # am being called twice for diff of Left and Right\n            my $ext = $iteration == 1 ? \"L\" : \"R\";\n            $filename = $opt_categorized . \"-$ext\";\n        } else {\n            $filename = $opt_categorized;\n        }\n        $fh = open_file('+>', $filename, 1);  # open for read/write\n        die \"Unable to write to $filename:  $!\\n\" unless defined $fh;\n    } elsif ($opt_sdir) {\n        # write to the user-defined scratch directory\n        ++$TEMP_OFF;\n        my $scr_dir = \"$opt_sdir/$TEMP_OFF\";\n        File::Path::mkpath($scr_dir) unless is_dir($scr_dir);\n        $filename = $scr_dir . '/cloc_file_list.txt';\n        $fh = open_file('+>', $filename, 1);  # open for read/write\n        die \"Unable to write to $filename:  $!\\n\" unless defined $fh;\n    } else {\n        # let File::Temp create a suitable temporary file\n        ($fh, $filename) = tempfile(UNLINK => 1);  # delete file on exit\n        print \"Using temp file list [$filename]\\n\" if $opt_v;\n    }\n\n    my @dir_list = ();\n    foreach my $file_or_dir (@{$ra_arg_list}) {\n        my $size_in_bytes = 0;\n        my $F = lower_on_Windows($file_or_dir);\n        my $ul_F = $ON_WINDOWS ? $upper_lower_map{$F} : $F;\n        if (!can_read($file_or_dir)) {\n            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];\n            next;\n        }\n        if (is_file($file_or_dir)) {\n            if (!get_size($file_or_dir)) {   # 0 sized file, named pipe, socket\n                $rh_ignored->{$F} = 'zero sized file';\n                next;\n            } elsif (is_binary($file_or_dir) and !$opt_read_binary_files) {\n                # avoid binary files unless user insists on reading them\n                if ($opt_unicode) {\n                    # only ignore if not a Unicode file w/trivial\n                    # ASCII transliteration\n                    if (!unicode_file($file_or_dir)) {\n                        $rh_ignored->{$ul_F} = 'binary file';\n                        next;\n                    }\n                } else {\n                    $rh_ignored->{$ul_F} = 'binary file';\n                    next;\n                }\n            }\n            push @file_list, \"$file_or_dir\";\n        } elsif (is_dir($file_or_dir)) {\n            push @dir_list, $file_or_dir;\n        } elsif (-p $file_or_dir) {\n            # a pipe via process substitution, eg cloc <(cat cloc)\n            my @lines = <>;\n            $tmp_file_to_delete = \"temp_process_substitution_$$\";\n            write_file($tmp_file_to_delete, {}, @lines);\n            push @dir_list, $tmp_file_to_delete;\n        } else {\n            push @{$raa_errors}, [$rh_Err->{'Neither file nor directory'} , $F];\n            $rh_ignored->{$F} = 'not file, not directory';\n        }\n    }\n\n    # apply exclusion rules to file names passed in on the command line\n    my @new_file_list = ();\n    foreach my $File (@file_list) {\n        my ($volume, $directories, $filename) = File::Spec->splitpath( $File );\n        my $ignore_this_file = 0;\n        foreach my $Sub_Dir ( File::Spec->splitdir($directories) ) {\n            my $SD = lower_on_Windows($Sub_Dir);\n            if ($Exclude_Dir{$Sub_Dir}) {\n                $Ignored{$SD} = \"($File) --exclude-dir=$Sub_Dir\";\n                $ignore_this_file = 1;\n                last;\n            }\n        }\n        push @new_file_list, $File unless $ignore_this_file;\n    }\n    @file_list = @new_file_list;\n    foreach my $dir (@dir_list) {\n        my $D = lower_on_Windows($dir);\n#print \"make_file_list dir=$dir  Exclude_Dir{$dir}=$Exclude_Dir{$dir}\\n\";\n        # populates global variable @file_list\n        if ($Exclude_Dir{$dir}) {\n            $Ignored{$D} = \"--exclude-dir=$Exclude_Dir{$dir}\";\n            next;\n        }\n        if ($opt_no_recurse) {\n            my @candidate_file_list = ();\n            if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n                my $d = Win32::LongPath->new();\n                $d->opendirL($dir);\n                foreach my $entry ($d->readdirL()) {\n                    my $F = \"$dir/$entry\";\n                    push @candidate_file_list, $F if is_file($F);\n                }\n                $d->closedirL();\n            } else {\n                opendir(DIR, $dir);\n                push @candidate_file_list, grep(is_file(\"$dir/$_\"), readdir(DIR));\n                closedir(DIR);\n            }\n            my $start_dir = cwd();\n            foreach my $F (@candidate_file_list) {\n                # pretend to be File::Find's wanted() routine, namely subroutine files(),\n                # to apply all file filter rules\n                $File::Find::dir  = $dir;\n                $File::Find::name = basename $F;\n                $_ = basename $F;\n                chdir $dir;\n                files();  # side effect:  populates @file_list\n            }\n            chdir $start_dir;\n            # ... then prepend the directory name to each file\n            @file_list = map { \"$dir/$_\" } @file_list;\n        } else {\n            find({wanted     => \\&files            ,\n                  preprocess => \\&find_preprocessor,\n                  follow     =>  $opt_follow_links }, $dir);\n        }\n    }\n    if ($opt_follow_links) {\n        # giving { 'follow' => 1 } to find() makes it skip the\n        # call to find_preprocessor() so have to call this manually\n        @file_list = manual_find_preprocessor(@file_list);\n    }\n\n    # there's a possibility of file duplication if user provided a list\n    # file or --vcs command that returns directory names; squash these\n    my %unique_file_list = map { $_ => 1 } @file_list;\n    @file_list = sort keys %unique_file_list;\n\n    $nFiles_Found = scalar @file_list;\n    printf \"%8d text file%s.\\n\", plural_form($nFiles_Found) unless $opt_quiet;\n    write_file($opt_found, {}, sort @file_list) if $opt_found;\n\n    my $nFiles_Categorized = 0;\n\n    foreach my $file (@file_list) {\n        my $F = lower_on_Windows($file);\n        if ($ON_WINDOWS) {\n            (my $lc = lc $file) =~ s{\\\\}{/}g;\n            $upper_lower_map{$lc} = $file;\n            $file = $lc;\n        }\n        printf \"classifying $file\\n\" if $opt_v > 2;\n\n        my $basename = basename $file;\n        if ($Not_Code_Filename{$basename}) {\n            $rh_ignored->{$F} = \"listed in \" . '$' .\n                \"Not_Code_Filename{$basename}\";\n            next;\n        } elsif ($basename =~ m{~$}) {\n            $rh_ignored->{$F} = \"temporary editor file\";\n            next;\n        }\n\n        my $size_in_bytes;\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            my $stats = statL($file);\n            $size_in_bytes = $stats->{size} if defined $stats;\n        } else {\n            $size_in_bytes = (stat $file)[7];\n        }\n        my $language      = \"\";\n        if ($All_One_Language) {\n            # user over-rode auto-language detection by using\n            # --force-lang with just a language name (no extension)\n            $language      = $All_One_Language;\n        } else {\n            $language      = classify_file($file      ,\n                                           $rh_Err    ,\n                                           $raa_errors,\n                                           $rh_ignored);\n        }\n        my $skip = 0;\n        if (!defined $size_in_bytes) {\n            $rh_ignored->{$F} = \"no longer readable\";\n            $skip = 1;\n        } elsif (!defined $language) {\n            $rh_ignored->{$F} = \"unable to associate with a language\";\n            $skip = 1;\n        } elsif ($language eq \"(unknown)\") {\n            # entry should already be in %{$rh_ignored}\n            $skip = 1;\n        }\n        next if $skip;\n        $Language_by_Filename{$F} = $language; # global\n        printf $fh \"%d%s%s%s%s\\n\", $size_in_bytes, $separator,\n                                   $language, $separator, $file;\n        ++$nFiles_Categorized;\n        #printf \"classified %d files\\n\", $nFiles_Categorized\n        #    unless (!$opt_progress_rate or\n        #            ($nFiles_Categorized % $opt_progress_rate));\n    }\n    printf \"classified %d files\\r\", $nFiles_Categorized\n        if !$opt_quiet and $nFiles_Categorized > 1;\n    print \"<- make_file_list()\\n\" if $opt_v > 2;\n\n    return $fh;   # handle to the file containing the list of files to process\n}  # 1}}}\nsub invoke_generator {                       # {{{1\n    my ($generator, $ra_user_inputs) = @_;\n    # If user provided file/directory inputs, only return\n    # generated files that are in user's request.\n    # Populates global variable %Ignored.\n    print \"-> invoke_generator($generator, @{$ra_user_inputs})\\n\" if $opt_v > 2;\n    my $start_dir = cwd();\n    my @dir_list  = ();\n    my @file_list = ();\n\n    if (!@{$ra_user_inputs}) {\n        # input must be a generator command, ie \"find -type f -name '*.c'\"\n        # issued from the cwd\n        push @dir_list, \".\";\n    }\n    foreach my $file_dir (@{$ra_user_inputs}) {\n        if (is_dir($file_dir)) {\n            push @dir_list, $file_dir;\n        } elsif (is_file($file_dir)) {\n            push @file_list, $file_dir;\n        }\n    }\n\n    my @files = ();\n    foreach my $work_dir (@dir_list) {\n        if ($work_dir ne $start_dir) {\n            chdir $work_dir or die \"Failed to chdir to $work_dir: $!\";\n        }\n        open(FH, \"$generator |\") or die \"Failed to pipe $generator: $!\";\n        while(<FH>) {\n            chomp;\n            my $F = \"$work_dir/$_\";\n            print \"VCS input:  $F\\n\" if $opt_v >= 2;\n            if (!@file_list) {\n                # no files given on the command line; accept all\n                push @files, $F;\n            } else {\n                # is this file desired?\n                my $want_this_one = 0;\n                foreach my $file (@file_list) {\n                    $file =~ s{\\\\}{/}g if $ON_WINDOWS;\n                    if (/^$file/) {\n                        $want_this_one = 1;\n                        last;\n                    }\n                }\n                push @files, $F if $want_this_one;\n            }\n        }\n        close(FH);\n        if ($work_dir ne $start_dir) {\n            chdir $start_dir or die \"Failed to chdir to $start_dir: $!\";\n        }\n    }\n\n    # apply match/not-match file/dir filters to the list so far\n    my @post_filter = ();\n    foreach my $F (@files) {\n        if ($opt_match_f) {\n            push @post_filter, $F if basename($F) =~ m{$opt_match_f};\n            next;\n        }\n        if ($opt_match_d) {\n            push @post_filter, $F if $F =~ m{$opt_match_d};\n            next;\n        }\n        if (@opt_not_match_d) {\n            my $rule;\n            if ($opt_fullpath and any_match($F, 0, \\$rule, @opt_not_match_d)) {\n                $Ignored{$F} = \"--not-match-d=$rule\";\n                next;\n            } elsif (!$opt_fullpath and any_match(basename($F), 0, \\$rule, @opt_not_match_d)) {\n                $Ignored{$F} = \"--not-match-d (basename) =$rule\";\n                next;\n            }\n        }\n        if (@opt_not_match_f) {\n            my $rule;\n            if ($opt_fullpath and any_match($F, 0, \\$rule, @opt_not_match_f)) {\n                $Ignored{$F} = \"--not-match-f=$rule\";\n                next;\n            } elsif (!$opt_fullpath and any_match(basename($F), 0, \\$rule, @opt_not_match_f)) {\n                $Ignored{$F} = \"--not-match-f (basename) =$rule\";\n                next;\n            }\n        }\n        my $nBytes = get_size($F);\n        if (!$nBytes) {\n            $Ignored{$F} = 'zero sized file';\n            printf \"files(%s)  zero size\\n\", $F if $opt_v > 5;\n        }\n        next unless $nBytes;\n        if ($nBytes > $opt_max_file_size*1024**2) {\n            $Ignored{$F} = \"file size of \" .\n                $nBytes/1024**2 . \" MB exceeds max file size of \" .\n                \"$opt_max_file_size MB\";\n            printf \"file(%s)  exceeds $opt_max_file_size MB\\n\",\n                $F if $opt_v > 5;\n            next;\n        }\n        my $is_bin = is_binary($F);\n        printf \"files(%s)  size=%d  -B=%d\\n\",\n            $F, $nBytes, $is_bin if $opt_v > 5;\n        $is_bin = 0 if $opt_unicode and unicode_file($_);\n        $is_bin = 0 if $opt_read_binary_files;\n        next if $is_bin;\n        push @post_filter, $F;\n    }\n    print \"<- invoke_generator\\n\" if $opt_v > 2;\n    return @post_filter;\n} # 1}}}\nsub any_match {                              # {{{1\n    my ($string, $entire, $rs_matched_pattern, @patterns) = @_;\n    print \"-> any_match($string, $entire)\\n\" if $opt_v > 2;\n    foreach my $pattern (@patterns) {\n        if ($entire) {\n            if ($string =~ m{^${pattern}$}) {\n                ${$rs_matched_pattern} = $pattern;\n                print \"<- any_match(1)\\n\" if $opt_v > 2;\n                return 1;\n            }\n        } else {\n            if ($string =~ m{$pattern}) {\n                ${$rs_matched_pattern} = $pattern;\n                print \"<- any_match(1)\\n\" if $opt_v > 2;\n                return 1;\n            }\n        }\n    }\n    print \"<- any_match(0)\\n\" if $opt_v > 2;\n    return 0;\n}\n# }}}\nsub remove_duplicate_files {                 # {{{1\n    my ($fh                   , # in\n        $rh_Language          , # out\n        $rh_unique_source_file, # out\n        $rh_Err               , # in\n        $raa_errors           , # out  errors encountered\n        $rh_ignored           , # out\n        ) = @_;\n\n    # Check for duplicate files by comparing file sizes.\n    # Where files are equally sized, compare their MD5 checksums.\n    print \"-> remove_duplicate_files\\n\" if $opt_v > 2;\n\n    my $separator = defined $opt_csv_delimiter ? $opt_csv_delimiter : \",\";\n    my $n = 0;\n    my %files_by_size = (); # files_by_size{ # bytes } = [ list of files ]\n    seek($fh, 0, 0); # rewind to beginning of the temp file\n    while (<$fh>) {\n        ++$n;\n        my ($size_in_bytes, $language, $file) = split(/\\Q$separator\\E/, $_, 3);\n        if (!defined($size_in_bytes) or\n            !defined($language)      or\n            !defined($file)) {\n            print \"-> remove_duplicate_files skipping error line [$_]\\n\"\n                if $opt_v;\n            next;\n        }\n        chomp($file);\n        $file =~ s{\\\\}{/}g if $ON_WINDOWS;\n        $rh_Language->{$file} = $language;\n        push @{$files_by_size{$size_in_bytes}}, $file;\n        if ($opt_skip_uniqueness) {\n            $rh_unique_source_file->{$file} = 1;\n        }\n    }\n    return if $opt_skip_uniqueness;\n    if ($opt_progress_rate and ($n > $opt_progress_rate)) {\n        printf \"Duplicate file check %d files (%d known unique)\\r\",\n            $n, scalar keys %files_by_size;\n    }\n    $n = 0;\n    foreach my $bytes (sort {$a <=> $b} keys %files_by_size) {\n        ++$n;\n        printf \"Unique: %8d files                                          \\r\",\n            $n unless (!$opt_progress_rate or ($n % $opt_progress_rate));\n        if (scalar @{$files_by_size{$bytes}} == 1) {\n            # only one file is this big; must be unique\n            $rh_unique_source_file->{$files_by_size{$bytes}[0]} = 1;\n            next;\n        } else {\n#print \"equally sized files: \",join(\", \", @{$files_by_size{$bytes}}), \"\\n\";\n            # Files in the list @{$files_by_size{$bytes} all are\n            # $bytes long.  Sort the list by file basename.\n\n          # # sorting on basename causes repeatability problems\n          # # if the basename is not unique (eg \"includeA/x.h\"\n          # # and \"includeB/x.h\".  Instead, sort on full path.\n          # # Ref bug #114.\n          # my @sorted_bn = ();\n          # my %BN = map { basename($_) => $_ } @{$files_by_size{$bytes}};\n          # foreach my $F (sort keys %BN) {\n          #     push @sorted_bn, $BN{$F};\n          # }\n\n            my @sorted_bn = sort @{$files_by_size{$bytes}};\n\n            foreach my $F (different_files(\\@sorted_bn  ,\n                                            $rh_Err     ,\n                                            $raa_errors ,\n                                            $rh_ignored ) ) {\n                $rh_unique_source_file->{$F} = 1;\n            }\n        }\n    }\n    print \"<- remove_duplicate_files\\n\" if $opt_v > 2;\n} # 1}}}\nsub manual_find_preprocessor {               # {{{1\n    # When running with --follow-links, find_preprocessor() is not\n    # called by find().  Have to do it manually.  Inputs here\n    # are only files, which differs from find_preprocessor() which\n    # gets directories too.\n    # Reads global variable %Exclude_Dir.\n    # Populates global variable %Ignored.\n    # Reject files/directories in cwd which are in the exclude list.\n    print \"-> manual_find_preprocessor(\", cwd(), \")\\n\" if $opt_v > 2;\n    my @ok = ();\n\n    foreach my $File (@_) {  # pure file or directory name, no separators\n        my $Dir = dirname($File);\n        my $got_exclude_dir = 0;\n        foreach my $d (File::Spec->splitdir( $Dir )) {\n            # tests/inputs/issues/407/level2/level/Test/level2 ->\n            # $d iterates over tests, inputs, issues, 407,\n            #                  level2, level, Test, level2\n            # check every item against %Exclude_Dir\n            if ($Exclude_Dir{$d}) {\n                $got_exclude_dir = $d;\n                last;\n            }\n        }\n        if ($got_exclude_dir) {\n            $Ignored{$File} = \"--exclude-dir=$Exclude_Dir{$got_exclude_dir}\";\n#print \"ignoring $File\\n\";\n        } else {\n            if (@opt_not_match_d) {\n                my $rule;\n                if ($opt_fullpath) {\n                    if (any_match($Dir, 1, \\$rule, @opt_not_match_d)) {\n                        $Ignored{$File} = \"--not-match-d=$rule\";\n#print \"matched fullpath\\n\"\n                    } else {\n                        push @ok, $File;\n                    }\n                } elsif (any_match(basename($Dir), 0, \\$rule, @opt_not_match_d)) {\n                    $Ignored{$File} = \"--not-match-d=$rule\";\n#print \"matched partial\\n\"\n                } else {\n                    push @ok, $File;\n                }\n            } else {\n                push @ok, $File;\n            }\n        }\n    }\n\n    print \"<- manual_find_preprocessor(@ok)\\n\" if $opt_v > 2;\n    return @ok;\n} # 1}}}\nsub find_preprocessor {                      # {{{1\n    # invoked by File::Find's find() each time it enters a new directory\n    # Reads global variable %Exclude_Dir.\n    # Populates global variable %Ignored.\n    # Reject files/directories in cwd which are in the exclude list.\n    print \"-> find_preprocessor(\", cwd(), \")\\n\" if $opt_v > 2;\n    my @ok = ();\n\n    foreach my $F_or_D (@_) {  # pure file or directory name, no separators\n        next if $F_or_D =~ /^\\.{1,2}$/;  # skip .  and  ..\n        if ($Exclude_Dir{$F_or_D}) {\n            $Ignored{$File::Find::name} = \"--exclude-dir=$Exclude_Dir{$F_or_D}\";\n        } else {\n#printf \"  F_or_D=%-20s File::Find::name=%s\\n\", $F_or_D, $File::Find::name;\n            if (@opt_not_match_d) {\n                my $rule;\n                if ($opt_fullpath) {\n                    if (any_match($File::Find::name, 0, \\$rule, @opt_not_match_d)) {\n                        $Ignored{$File::Find::name} = \"--not-match-d=$rule\";\n                    } else {\n                        push @ok, $F_or_D;\n                    }\n                } elsif (!is_dir($F_or_D) and\n                         any_match($File::Find::name, 0, \\$rule,\n                                   @opt_not_match_d)) {\n                    $Ignored{$File::Find::name} = \"--not-match-d (basename) =$rule\";\n                } else {\n                    push @ok, $F_or_D;\n                }\n            } else {\n                push @ok, $F_or_D;\n            }\n        }\n    }\n\n    print \"<- find_preprocessor(@ok)\\n\" if $opt_v > 2;\n    return @ok;\n} # 1}}}\nsub files {                                  # {{{1\n    # invoked by File::Find's find()   Populates global variable @file_list.\n    # See also find_preprocessor() which prunes undesired directories.\n\n#   my $Dir = fastcwd();         # fully qualified path -- problematic\n    my $Dir = $File::Find::dir;  # path anchored to cloc's cwd\n    my $rule;\n    if ($opt_fullpath) {\n        # look at as much of the path as is known\n        if ($opt_match_f    ) {\n            return unless $File::Find::name =~ m{$opt_match_f};\n        }\n        if (@opt_not_match_f) {\n            return if any_match($File::Find::name, 0, \\$rule, @opt_not_match_f);\n        }\n    } else {\n        # only look at the basename\n        if ($opt_match_f    ) { return unless m{$opt_match_f}; }\n        if (@opt_not_match_f) { return if     any_match($_, 0, \\$rule, @opt_not_match_f)}\n    }\n    if ($opt_match_d) {\n        return unless \"$Dir/\" =~ m{$opt_match_d} or $Dir =~ m{$opt_match_d};\n    }\n\n    my $nBytes = get_size($_);\n    if (!$nBytes and is_file($File::Find::name)) {\n        $Ignored{$File::Find::name} = 'zero sized file';\n        printf \"files(%s)  zero size\\n\", $File::Find::name if $opt_v > 5;\n    }\n    return unless $nBytes  ; # attempting other tests w/pipe or socket will hang\n    if ($nBytes > $opt_max_file_size*1024**2) {\n        $Ignored{$File::Find::name} = \"file size of \" .\n            $nBytes/1024**2 . \" MB exceeds max file size of \" .\n            \"$opt_max_file_size MB\";\n        printf \"file(%s)  exceeds $opt_max_file_size MB\\n\",\n            $File::Find::name if $opt_v > 5;\n        return;\n    }\n    my $is_dir = is_dir($_);\n    my $is_bin = is_binary($_);\n    printf \"files(%s)  size=%d is_dir=%d  -B=%d\\n\",\n        $File::Find::name, $nBytes, $is_dir, $is_bin if $opt_v > 5;\n    $is_bin = 0 if $opt_unicode and unicode_file($_);\n    $is_bin = 0 if $opt_read_binary_files;\n    if ($is_bin and !$is_dir) {\n        $Ignored{$File::Find::name} = \"binary file\";\n        printf \"files(%s)  binary file\\n\", $File::Find::name if $opt_v > 5;\n    }\n    return if $is_dir or $is_bin;\n    ++$nFiles_Found;\n    printf \"%8d files\\r\", $nFiles_Found\n        unless (!$opt_progress_rate or ($nFiles_Found % $opt_progress_rate));\n    push @file_list, $File::Find::name;\n} # 1}}}\nsub archive_files {                          # {{{1\n    # invoked by File::Find's find()  Populates global variable @binary_archive\n    foreach my $ext (keys %Known_Binary_Archives) {\n        push @binary_archive, $File::Find::name\n            if $File::Find::name =~ m{$ext$};\n    }\n} # 1}}}\nsub open_file {                              # {{{1\n    # portable method to open a file. On Windows this uses Win32::LongPath to\n    # allow reading/writing files past the 255 char path length limit. When on\n    # other operating systems, $use_new_file can be used to specify opening a\n    # file with `new IO::File` instead of `open`. Note: `openL` doesn't support\n    # the C-like fopen modes (\"w\", \"r+\", etc.), it only supports Perl mode\n    # strings (\">\", \"+<\", etc.). So be sure to only use Perl mode strings to\n    # ensure compatibility. Additionally, openL doesn't handle pipe modes; if\n    # you need to open a pipe/STDIN/STDOUT, use the native `open` function.\n    my ($mode,         # Perl file mode; can not be C-style file mode\n        $filename,     # filename to open\n        $use_new_file, # whether to use `new IO::File` or `open` when not using Win32::LongPath\n        ) = @_;\n    my $fh = undef;\n    if (defined $opt_encoding) {\n        open($fh,\"<:encoding($opt_encoding)\", $filename) or\n            die \"Failed open('<:encoding($opt_encoding)', $filename): $!\";\n    } else {\n        if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n            openL(\\$fh, $mode, $filename);\n        } elsif ($use_new_file) {\n            return new IO::File $filename, $mode;\n        }\n        open($fh, $mode, $filename);\n    }\n    return $fh;\n} # 1}}}\nsub unlink_file {                            # {{{1\n    # portable method to unlink a file. On Windows this uses Win32::LongPath to\n    # allow unlinking files past the 255 char path length limit. Otherwise, the\n    # native `unlink` will be used.\n    my $filename = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return unlinkL($filename);\n    }\n    return unlink $filename;\n} # 1}}}\nsub is_binary {                              # {{{1\n    # portable method to test if item is a binary file. For Windows,\n    # Win32::LongPath doesn't provide a testL option for -B, but -B\n    # accepts a filehandle which does work with files opened with openL.\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        my $IN = open_file('<', $item, 0);\n        if (defined $IN) {\n            my $res = -B $IN;\n            close($IN);\n            return $res;\n        }\n        return;\n    }\n    return (-B $item);\n} # 1}}}\nsub can_read {                               # {{{1\n    # portable method to test if item can be read\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('r', $item);\n    }\n    return (-r $item);\n} # 1}}}\nsub get_size {                               # {{{1\n    # portable method to get size in bytes of a file\n    my $filename = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('s', $filename);\n    }\n    return (-s $filename);\n} # 1}}}\nsub is_file {                                # {{{1\n    # portable method to test if item is a file\n    # (-f doesn't work in ActiveState Perl on Windows)\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('f', $item);\n    }\n    return (-f $item);\n\n#     Was:\n####if ($ON_WINDOWS) {\n####    my $mode = (stat $item)[2];\n####       $mode = 0 unless $mode;\n####    if ($mode & 0100000) { return 1; }\n####    else                 { return 0; }\n####} else {\n####    return (-f $item);  # works on Unix, Linux, CygWin, z/OS\n####}\n} # 1}}}\nsub is_dir {                                 # {{{1\n    my $item = shift @_;\n    if ($ON_WINDOWS and $HAVE_Win32_Long_Path) {\n        return testL('d', $item);\n    }\n    return (-d $item); # should work everywhere now (July 2017)\n\n#     Was:\n##### portable method to test if item is a directory\n##### (-d doesn't work in older versions of ActiveState Perl on Windows)\n\n####if ($ON_WINDOWS) {\n####    my $mode = (stat $item)[2];\n####       $mode = 0 unless $mode;\n####    if ($mode & 0040000) { return 1; }\n####    else                 { return 0; }\n####} else {\n####    return (-d $item);  # works on Unix, Linux, CygWin, z/OS\n####}\n} # 1}}}\nsub is_excluded {                            # {{{1\n    my ($file       , # in\n        $excluded   , # in   hash of excluded directories\n       ) = @_;\n    my($filename, $filepath, $suffix) = fileparse($file);\n    foreach my $path (sort keys %{$excluded}) {\n        return 1 if ($filepath =~ m{^\\Q$path\\E/}i);\n    }\n} # 1}}}\nsub classify_file {                          # {{{1\n    my ($full_file   , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rh_ignored  , # out\n       ) = @_;\n\n    print \"-> classify_file($full_file)\\n\" if $opt_v > 2;\n    my $language = \"(unknown)\";\n\n    if (basename($full_file) eq \"-\" && defined $opt_stdin_name) {\n       $full_file = $opt_stdin_name;\n    }\n\n    my $look_at_first_line = 0;\n    my $file = basename $full_file;\n    if ($opt_autoconf and $file =~ /\\.in$/) {\n       $file =~ s/\\.in$//;\n    }\n    return $language if $Not_Code_Filename{$file}; # (unknown)\n    return $language if $file =~ m{~$}; # a temp edit file (unknown)\n    if (defined $Language_by_File_Type{$file}) {\n        if      ($Language_by_File_Type{$file} eq \"Ant/XML\") {\n            return Ant_or_XML(  $full_file, $rh_Err, $raa_errors);\n        } elsif ($Language_by_File_Type{$file} eq \"Maven/XML\") {\n            return Maven_or_XML($full_file, $rh_Err, $raa_errors);\n        } else {\n            return $Language_by_File_Type{$file};\n        }\n    }\n\n    if ($file =~ /\\.([^\\.]+)$/) { # has an extension\n      print \"$full_file extension=[$1]\\n\" if $opt_v > 2;\n      my $extension = $1;\n         # Windows file names are case insensitive so map\n         # all extensions to lowercase there.\n         $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n      my @extension_list = ( $extension );\n      if ($file =~ /\\.([^\\.]+\\.[^\\.]+)$/) { # has a double extension\n          my $extension = $1;\n          $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n          unshift @extension_list, $extension;  # examine double ext first\n      }\n      if ($file =~ /\\.([^\\.]+\\.[^\\.]+\\.[^\\.]+)$/) { # has a triple extension\n          my $extension = $1;\n          $extension = lc $extension if $ON_WINDOWS or $opt_ignore_case_ext;\n          unshift @extension_list, $extension;  # examine triple ext first\n      }\n      foreach my $extension (@extension_list) {\n        if ($Not_Code_Extension{$extension} and\n           !$Forced_Extension{$extension}) {\n           # If .1 (for example) is an extension that would ordinarily be\n           # ignored but the user has insisted this be counted with the\n           # --force-lang option, then go ahead and count it.\n            $rh_ignored->{$full_file} =\n                'listed in $Not_Code_Extension{' . $extension . '}';\n            return $language;\n        }\n        # handle extension collisions\n        if (defined $Language_by_Extension{$extension}) {\n            if ($Language_by_Extension{$extension} eq\n                'MATLAB/Mathematica/Objective-C/MUMPS/Mercury') {\n                my $lang_M_or_O = \"\";\n                matlab_or_objective_C($full_file ,\n                                      $rh_Err    ,\n                                      $raa_errors,\n                                     \\$lang_M_or_O);\n                if ($lang_M_or_O) {\n                    return $lang_M_or_O;\n                } else { # an error happened in matlab_or_objective_C()\n                    $rh_ignored->{$full_file} =\n                        'failure in matlab_or_objective_C($full_file)';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'PHP/Pascal/Fortran/Pawn/BitBake') {\n                my $lang_F_or_P_or_P_or_B = \"\";\n                php_pascal_fortran_pawn_bitbake($full_file ,\n                                        $rh_Err    ,\n                                        $raa_errors,\n                                       \\$lang_F_or_P_or_P_or_B);\n                if ($lang_F_or_P_or_P_or_B) {\n                    return $lang_F_or_P_or_P_or_B;\n                } else { # an error happened in php_pascal_fortran_pawn_bitbake()\n                    $rh_ignored->{$full_file} =\n                        'failure in php_pascal_fortran_pawn_bitbake($full_file)';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Pascal/Puppet') {\n                my $lang_Pasc_or_Pup = \"\";\n                pascal_or_puppet(     $full_file ,\n                                      $rh_Err    ,\n                                      $raa_errors,\n                                     \\$lang_Pasc_or_Pup);\n                if ($lang_Pasc_or_Pup) {\n                    return $lang_Pasc_or_Pup;\n                } else { # an error happened in pascal_or_puppet()\n                    $rh_ignored->{$full_file} =\n                        'failure in pascal_or_puppet()';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Lisp/OpenCL') {\n                return Lisp_or_OpenCL($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Lisp/Julia') {\n                return Lisp_or_Julia( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Perl/Prolog') {\n                return Perl_or_Prolog($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Raku/Prolog') {\n                return Raku_or_Prolog($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq\n                     'IDL/Qt Project/Prolog/ProGuard') {\n                return IDL_or_QtProject($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'D/dtrace') {\n                # is it D or an init.d shell script?\n                my $a_script = really_is_D($full_file, $rh_Err, $raa_errors);\n                if ($a_script) {\n                    # could be dtrace, sh, bash or anything one would\n                    # write an init.d script in\n                    if (defined $Language_by_Script{$a_script}) {\n                        return $Language_by_Script{$a_script};\n                    } else {\n                        $rh_ignored->{$full_file} =\n                            \"Unrecognized script language, '$a_script'\";\n                    }\n                } else {\n                    return 'D';\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Fortran 77/Forth') {\n                return Forth_or_Fortran($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'F#/Forth') {\n                return Forth_or_Fsharp( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Verilog-SystemVerilog/Coq') {\n                return Verilog_or_Coq( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Smarty') {\n                if ($extension ne \"tpl\") {\n                    # unambiguous -- if ends with .smarty, is Smarty\n                    return $Language_by_Extension{$extension};\n                }\n                # Smarty extension .tpl is generic; make sure the\n                # file at least roughly resembles PHP.  Alternatively,\n                # if the user forces the issue, do the count.\n                my $force_smarty = 0;\n                foreach (@opt_force_lang) {\n                    if (lc($_) eq \"smarty,tpl\") {\n                        $force_smarty = 1;\n                        last;\n                    }\n                }\n                if (really_is_smarty($full_file) or $force_smarty) {\n                    return 'Smarty';\n                } else {\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'TypeScript/Qt Linguist') {\n                return TypeScript_or_QtLinguist( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'XML-Qt-GTK/Glade') {\n                return Qt_or_Glade( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'C#/Smalltalk') {\n                my $L = Csharp_or_Smalltalk( $full_file, $rh_Err, $raa_errors);\n                if ($L eq 'C#') {\n                    my $lines = first_line($full_file, 2, $rh_Err, $raa_errors);\n                    $lines =~ s/\\n//mg;\n                    if ($lines =~ m[//\\s+<auto-generated>]) {\n                        $L = \"C# Generated\";\n                        if ($opt_no_autogen) {\n                            $rh_ignored->{$full_file} =\n                                '--no-autogen ignores this auto-generated C# file';\n                            $L = \"(unknown)\"; # forces it to be ignored\n                        }\n                    }\n                }\n                return $L;\n            } elsif ($Language_by_Extension{$extension} eq 'Scheme/SaltStack') {\n                return Scheme_or_SaltStack( $full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Visual Basic/TeX/Apex Class') {\n                my $lang_VB_T_A = \"\";\n                Visual_Basic_or_TeX_or_Apex($full_file ,\n                                            $rh_Err    ,\n                                            $raa_errors,\n                                           \\$lang_VB_T_A);\n                if ($lang_VB_T_A) {\n                    return $lang_VB_T_A;\n                } else { # an error happened in Visual_Basic_or_TeX_or_Apex\n                    $rh_ignored->{$full_file} =\n                        'failure in Visual_Basic_or_TeX_or_Apex()';\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Pascal/Pawn') {\n                my $lang_p_or_p = \"\";\n                return Pascal_or_Pawn($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'SKILL/.NET IL') {\n                return SKILL_or_DotNetIL($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Clojure/Cangjie') {\n                return Clojure_or_Cangjie($full_file, $rh_Err, $raa_errors);\n            } elsif ($Language_by_Extension{$extension} eq 'Brainfuck') {\n                if (really_is_bf($full_file)) {\n                    return $Language_by_Extension{$extension};\n                } else {\n                    return $language; # (unknown)\n                }\n            } elsif ($Language_by_Extension{$extension} eq 'Unknown/BitBake') {\n                my $lang_t_or_b = \"\";\n                return really_is_BitBake($full_file, $rh_Err, $raa_errors);\n            } else {\n                return $Language_by_Extension{$extension};\n            }\n        } else { # has an unmapped file extension\n            $look_at_first_line = 1;\n        }\n      }\n      # if all else fails look at the prefix instead of extension\n      ( my $stem = $file ) =~ s/^(.*?)\\.\\S+$/$1/;\n      if ($stem and defined($Language_by_Prefix{$stem})) {\n          return $Language_by_Prefix{$stem}\n      }\n    } elsif (defined $Language_by_File_Type{lc $file}) {\n        return $Language_by_File_Type{lc $file};\n    } elsif ($opt_lang_no_ext and\n             defined $Filters_by_Language{$opt_lang_no_ext}) {\n        return $opt_lang_no_ext;\n    } else {  # no file extension\n        $look_at_first_line = 1;\n    }\n\n    if ($look_at_first_line) {\n        # maybe it is a shell/Perl/Python/Ruby/etc script that\n        # starts with pound bang:\n        #   #!/usr/bin/perl\n        #   #!/usr/bin/env perl\n        my ($script_language, $L) = peek_at_first_line($full_file ,\n                                                       $rh_Err    ,\n                                                       $raa_errors);\n        if (!$script_language) {\n            $rh_ignored->{$full_file} = \"language unknown (#2)\";\n            # returns (unknown)\n        }\n        if (defined $Language_by_Script{$script_language}) {\n            if (defined $Filters_by_Language{\n                            $Language_by_Script{$script_language}}) {\n                $language = $Language_by_Script{$script_language};\n            } else {\n                $rh_ignored->{$full_file} =\n                    \"undefined:  Filters_by_Language{\" .\n                    $Language_by_Script{$script_language} .\n                    \"} for scripting language $script_language\";\n                # returns (unknown)\n            }\n        } else {\n            # #456:  XML files can have a variety of domain-specific file\n            #        extensions.  If the extension is unrecognized, examine\n            #        the first line of the file to see if it is XML\n            if ($L =~ /<\\?xml\\s/) {\n                $language = \"XML\";\n                delete $rh_ignored->{$full_file};\n            } else {\n                $rh_ignored->{$full_file} = \"language unknown (#3)\";\n            }\n            # returns (unknown)\n        }\n    }\n    print \"<- classify_file($full_file)=$language\\n\" if $opt_v > 2;\n    return $language;\n} # 1}}}\nsub first_line {                             # {{{1\n    # return the first $n_lines of text in the file as one string\n    my ($file        , # in\n        $n_lines     , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n    my $line = \"\";\n    print \"-> first_line($file, $n_lines)\\n\" if $opt_v > 2;\n    if (!can_read($file)) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $line;\n    }\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        print \"<- first_line($file, $n_lines)\\n\" if $opt_v > 2;\n        return $line;\n    }\n    # issue 644: Unicode files can have non-zero $n_lines\n    # but empty <$IN> contents\n    for (my $i = 0; $i < $n_lines; $i++) {\n        my $L = <$IN>;\n        last unless defined $L;\n        chomp($line .= $L);\n    }\n    $IN->close;\n    print \"<- first_line($file, $n_lines, '$line')\\n\" if $opt_v > 2;\n    return $line;\n} # 1}}}\nsub peek_at_first_line {                     # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> peek_at_first_line($file)\\n\" if $opt_v > 2;\n\n    my $script_language = \"\";\n    my $first_line = first_line($file, 1, $rh_Err, $raa_errors);\n\n    if (defined $first_line) {\n#print \"peek_at_first_line of [$file] first_line=[$first_line]\\n\";\n        if ($first_line =~ /^#\\!\\s*(\\S.*?)$/) {\n#print \"peek_at_first_line 1=[$1]\\n\";\n            my @pound_bang = split(' ', $1);\n#print \"peek_at_first_line basename 0=[\", basename($pound_bang[0]), \"]\\n\";\n            if (basename($pound_bang[0]) eq \"env\" and\n                scalar @pound_bang > 1) {\n                $script_language = $pound_bang[1];\n#print \"peek_at_first_line pound_bang A $pound_bang[1]\\n\";\n            } else {\n                $script_language = basename $pound_bang[0];\n#print \"peek_at_first_line pound_bang B $script_language\\n\";\n            }\n        }\n    }\n    print \"<- peek_at_first_line($file)\\n\" if $opt_v > 2;\n    return ($script_language, $first_line);\n} # 1}}}\nsub different_files {                        # {{{1\n    # See which of the given files are unique by computing each file's MD5\n    # sum.  Return the subset of files which are unique.\n    my ($ra_files    , # in\n        $rh_Err      , # in\n        $raa_errors  , # out\n        $rh_ignored  , # out\n       ) = @_;\n\n    print \"-> different_files(@{$ra_files})\\n\" if $opt_v > 2;\n    my %file_hash = ();  # file_hash{md5 hash} = [ file1, file2, ... ]\n    foreach my $F (@{$ra_files}) {\n        next if is_dir($F);  # needed for Windows\n        my $IN = open_file('<', $F, 1);\n        if (!defined $IN) {\n            push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $F];\n            $rh_ignored->{$F} = 'cannot read';\n        } else {\n            if ($HAVE_Digest_MD5) {\n                binmode $IN;\n                my $MD5 = Digest::MD5->new->addfile($IN)->hexdigest;\n#print \"$F, $MD5\\n\";\n                push @{$file_hash{$MD5}}, $F;\n            } else {\n                # all files treated unique\n                push @{$file_hash{$F}}, $F;\n            }\n            $IN->close;\n        }\n    }\n\n    # Loop over file sets having identical MD5 sums.  Within\n    # each set, pick the file that most resembles known source\n    # code.\n    my @unique = ();\n    for my $md5 (sort keys %file_hash) {\n        my $i_best = 0;\n        for (my $i = 1; $i < scalar(@{$file_hash{$md5}}); $i++) {\n            my $F = $file_hash{$md5}[$i];\n            my (@nul_a, %nul_h);\n            my $language = classify_file($F, $rh_Err,\n                                        # don't save these errors; pointless\n                                        \\@nul_a, \\%nul_h);\n            $i_best = $i if $language ne \"(unknown)\";\n        }\n        # keep the best one found and identify the rest as ignored\n        for (my $i = 0; $i < scalar(@{$file_hash{$md5}}); $i++) {\n            if ($i == $i_best) {\n                push @unique, $file_hash{$md5}[$i_best];\n            } else {\n                $rh_ignored->{$file_hash{$md5}[$i]} = \"duplicate of \" .\n                    $file_hash{$md5}[$i_best];\n            }\n        }\n\n    }\n    print \"<- different_files(@unique)\\n\" if $opt_v > 2;\n    return @unique;\n} # 1}}}\nsub call_counter {                           # {{{1\n    my ($file                    , # in\n        $language                , # in\n        $rha_ignore_regex        , # in\n        $ra_Errors               , # out\n       ) = @_;\n\n    # Logic:  pass the file through the following filters:\n    #         1. remove leading lines (if --skip-leading)\n    #         2. remove blank lines\n    #         3. remove comments using each filter defined for this language\n    #            (example:  SQL has two, remove_starts_with(--) and\n    #             remove_c_comments() )\n    #         4. if ignore regex filters are defined, remove lines that\n    #            match any of them\n    #         5. compute comment lines as\n    #               total lines - blank lines - lines left over after all\n    #                   comment filters have been applied\n\n    print \"-> call_counter($file, $language)\\n\" if $opt_v > 2;\n#print \"call_counter:  \", Dumper(@routines), \"\\n\";\n\n    my @lines = ();\n    my $ascii = \"\";\n    if (is_binary($file) and $opt_unicode) {\n        # was binary so must be unicode\n\n        $/ = undef;\n        my $IN = open_file('<', $file, 1);\n        my $bin_text = <$IN>;\n        $IN->close;\n        $/ = \"\\n\";\n\n        $ascii = unicode_to_ascii( $bin_text );\n        @lines = split(\"\\n\", $ascii );\n        foreach (@lines) { $_ = \"$_\\n\"; }\n\n    } else {\n        # regular text file\n        @lines = read_file($file);\n        $ascii = join('', @lines);\n    }\n\n    # implement --perl-ignore-data here\n\n    if ($opt_skip_leading) {\n        my $strip = 1;\n        my ($N, @exts) = split(/,/, $opt_skip_leading);\n        if (@exts) {\n            # only apply if this file's extension is listed\n            my $this_file_ext = file_extension($file);\n            $strip = grep(/^${this_file_ext}$/, @exts);\n        }\n        @lines = remove_first_n($N, \\@lines) if $strip;\n    }\n\n    my @original_lines = @lines;\n    my $total_lines    = scalar @lines;\n\n    print_lines($file, \"Original file:\", \\@lines) if $opt_print_filter_stages;\n    @lines = rm_blanks(\\@lines, $language, \\%EOL_Continuation_re); # remove blank lines\n    my $blank_lines = $total_lines - scalar @lines;\n    print \"   call_counter: total_lines=$total_lines  blank_lines=\",\n        $blank_lines, \"\\n\" if $opt_v > 2;\n    print_lines($file, \"Blank lines removed:\", \\@lines)\n        if $opt_print_filter_stages;\n\n    @lines = rm_comments(\\@lines, $language, $file,\n                               \\%EOL_Continuation_re, $ra_Errors);\n\n    my $n_code_removed = 0;\n    @lines = apply_ignores(\\@lines, $language, $file, $rha_ignore_regex,\n                           \\$n_code_removed);\n    $total_lines -= $n_code_removed;\n\n    my $comment_lines = $total_lines - $blank_lines - scalar @lines;\n    if ($opt_strip_comments) {\n        my $stripped_file = \"\";\n        if ($opt_original_dir) {\n            $stripped_file =          $file . \".$opt_strip_comments\";\n        } else {\n            $stripped_file = basename $file . \".$opt_strip_comments\";\n        }\n        write_file($stripped_file, {}, @lines);\n    }\n    if ($opt_strip_code) {\n        my $stripped_file = \"\";\n        if ($opt_original_dir) {\n            $stripped_file =          $file . \".$opt_strip_code\";\n        } else {\n            $stripped_file = basename $file . \".$opt_strip_code\";\n        }\n        write_file($stripped_file, {}, rm_code(\\@original_lines, \\@lines));\n    }\n    if ($opt_html and !$opt_diff) {\n        chomp(@original_lines);  # includes blank lines, comments\n        chomp(@lines);           # no blank lines, no comments\n\n        my (@diff_L, @diff_R, %count);\n\n        # remove blank lines to get better quality diffs; count\n        # blank lines separately\n        my @original_lines_minus_white = ();\n        # however must keep track of how many blank lines were removed and\n        # where they were removed so that the HTML display can include it\n        my %blank_line  = ();\n        my $insert_line = 0;\n        foreach (@original_lines) {\n            if (/^\\s*$/) {\n               ++$count{blank}{same};\n               ++$blank_line{ $insert_line };\n            } else {\n                ++$insert_line;\n                push @original_lines_minus_white, $_;\n            }\n        }\n\n        array_diff( $file                       ,   # in\n                   \\@original_lines_minus_white ,   # in\n                   \\@lines                      ,   # in\n                   \"comment\"                    ,   # in\n                   \\@diff_L, \\@diff_R,          ,   # out\n                    $ra_Errors);                    # in/out\n        write_comments_to_html($file, \\@diff_L, \\@diff_R, \\%blank_line);\n#print Dumper(\"count\", \\%count);\n    }\n\n    print \"<- call_counter($total_lines, $blank_lines, $comment_lines)\\n\"\n        if $opt_v > 2;\n    return ($total_lines, $blank_lines, $comment_lines);\n} # 1}}}\nsub windows_glob {                           # {{{1\n    # Windows doesn't expand wildcards.  Use code from Sean M. Burke's\n    # Win32::Autoglob module to do this.\n    return map {;\n        ( defined($_) and m/[\\*\\?]/ ) ? sort(glob($_)) : $_\n          } @_;\n} # 1}}}\nsub write_file {                             # {{{1\n    my ($file       , # in\n        $rh_options , # in\n        @lines      , # in\n       ) = @_;\n    # If $file is a conventional scalar, it is the name of the file to write to.\n    # if $file is a reference to a scalar, rather than writing @lines to a file,\n    # write @lines to this scalar as a single string.\n\n    my $local_formatting = 0;\n    foreach my $opt (sort keys %{$rh_options}) {\n#       print \"write_file option $opt = $rh_options->{$opt}\\n\";\n        $local_formatting = 1;\n    }\n    my $write_to_file = ref($file) eq \"\" ? 1 : 0;\n\n#print \"write_file 1 [$file]\\n\";\n    # Do ~ expansion (by Tim LaBerge, fixes bug 2787984)\n    if ($write_to_file) {\n        my $preglob_filename = $file;\n    #print \"write_file 2 [$preglob_filename]\\n\";\n        if ($ON_WINDOWS) {\n            $file = (windows_glob($file))[0];\n        } else {\n            $file = File::Glob::bsd_glob($file);\n        }\n    #print \"write_file 3 [$file]\\n\";\n        $file = $preglob_filename unless $file;\n    #print \"write_file 4 [$file]\\n\";\n    }\n\n    if ($write_to_file) {\n        print \"-> write_file($file)\\n\" if $opt_v > 2;\n    } else {\n        print \"-> write_file() -- writing to string variable\\n\" if $opt_v > 2;\n    }\n\n    my @prt_lines = ();\n\n    my $n_col = undef;\n    if ($local_formatting) {\n        $n_col = scalar @{$rh_options->{'columns'}};\n        if ($opt_xml) {\n            push @prt_lines, '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' . \"\\n\";\n            push @prt_lines, \"<all_$rh_options->{'file_type'}>\\n\";\n        } elsif ($opt_yaml) {\n            push @prt_lines, \"---\\n\";\n        } elsif ($opt_md) {\n            push @prt_lines, join(\"|\", @{$rh_options->{'columns'}})  . \"\\n\";\n            push @prt_lines, join(\"|\", map( \":------\", 1 .. $n_col)) . \"\\n\";\n        }\n    }\n\n    chomp(@lines);\n\n    if ($local_formatting) {\n        my @json_lines = ();\n        foreach my $L (@lines) {\n            my @entries;\n            if ($rh_options->{'separator'}) {\n                @entries = split($rh_options->{'separator'}, $L, $n_col);\n            } else {\n                @entries = ( $L );\n            }\n            if ($opt_xml) {\n                push @prt_lines, \"  <$rh_options->{'file_type'} \";\n                for (my $i = 0; $i < $n_col; $i++) {\n                    push @prt_lines, sprintf(\"%s=\\\"%s\\\" \", $rh_options->{'columns'}[$i], $entries[$i]);\n                }\n                push @prt_lines, \"/>\\n\";\n            } elsif ($opt_yaml or $opt_json) {\n                my @pairs = ();\n                for (my $i = 0; $i < $n_col; $i++) {\n                    push @pairs,\n                        sprintf \"\\\"%s\\\":\\\"%s\\\"\", $rh_options->{'columns'}[$i], $entries[$i];\n                }\n                if ($opt_json) {\n                    # JSON can't literal '\\x' in filenames, #575\n                    $pairs[0] =~ s/\\\\x//g;\n                    push @json_lines, join(\", \", @pairs );\n                } else {\n                    push @prt_lines, \"- {\", join(\", \", @pairs) . \"}\\n\";\n                }\n            } elsif ($opt_csv) {\n                push @prt_lines, join(\",\", @entries) . \"\\n\";\n            } elsif ($opt_md) {\n                push @prt_lines, join(\"|\", @entries) . \"\\n\";\n            }\n        }\n        if ($opt_json) {\n            push @prt_lines, \"[{\" . join(\"},\\n {\", @json_lines) . \"}]\\n\";\n        }\n        if (!$opt_json and !$opt_yaml and !$opt_xml and !$opt_csv) {\n            push @prt_lines, join(\"\\n\", @lines) . \"\\n\";\n        }\n    } else {\n        push @prt_lines, join(\"\\n\", @lines) . \"\\n\";\n    }\n\n    if ($local_formatting and $opt_xml) {\n        push @prt_lines, \"</all_$rh_options->{'file_type'}>\\n\";\n    }\n\n    # Create the destination directory if it doesn't already exist.\n    my $abs_file_path = File::Spec->rel2abs( $file );\n    my ($volume, $directories, $filename) = File::Spec->splitpath( $abs_file_path );\n    mkpath($volume . $directories, 1, 0777);\n\n    my $OUT = undef;\n    unlink_file($file);\n    # If $file is a reference to a scalar, write to that scalar.  This works\n    # cleanly on Unix, but on Windows a zero-length file is created.  The\n    # filename starts with \"SCALAR\" followed by a memory address in hex.\n    # This temporary file will need to be cleaned up before the program ends.\n    if ($ON_WINDOWS and (ref($file) eq \"SCALAR\" or $file =~ /^SCALAR/)) {\n        $tmp_file_to_delete = \"$file\"; # string version of the file name\n    }\n    if ($opt_file_encoding) {\n        $OUT = open_file(\">:encoding($opt_file_encoding)\", $file, 0);\n    } else {\n        $OUT = open_file('>', $file, 1);\n    }\n    if (!defined $OUT) {\n        warn \"Unable to write to $file\\n\";\n        print \"<- write_file\\n\" if $opt_v > 2;\n        return;\n    }\n    print $OUT @prt_lines;\n    $OUT->close;\n\n    if (can_read($file)) {\n        print \"Wrote $file\" unless $opt_quiet;\n        print \", $CLOC_XSL\" if $opt_xsl and $opt_xsl eq $CLOC_XSL;\n        print \"\\n\" unless $opt_quiet;\n    }\n\n    print \"<- write_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub file_pairs_from_file {                   # {{{1\n    my ($file             , # in\n        $ra_added         , # out\n        $ra_removed       , # out\n        $ra_compare_list  , # out\n       ) = @_;\n    #\n    # Example valid input format for $file\n    # 1)\n    #   A/d1/hello.f90 | B/d1/hello.f90\n    #   A/hello.C | B/hello.C\n    #   A/d2/hi.py | B/d2/hi.py\n    #\n    # 2)\n    # Files added: 1\n    #   + B/extra_file.pl ; Perl\n    #\n    # Files removed: 1\n    #   - A/d2/hello.java ; Java\n    #\n    # File pairs compared: 3\n    #   != A/d1/hello.f90 | B/d1/hello.f90 ; Fortran 90\n    #   != A/hello.C | B/hello.C ; C++\n    #   == A/d2/hi.py | B/d2/hi.py ; Python\n\n    print \"-> file_pairs_from_file($file)\\n\" if $opt_v and $opt_v > 2;\n    @{$ra_compare_list} = ();\n    my @lines = read_file($file);\n    my $mode = \"compare\";\n    foreach my $L (@lines) {\n        next if $L =~ /^\\s*$/ or $L =~ /^\\s*#/;\n        chomp($L);\n        if      ($L =~ /^Files\\s+(added|removed):/) {\n            $mode = $1;\n        } elsif ($L =~ /^File\\s+pairs\\s+compared:/) {\n            $mode = \"compare\";\n        } elsif ($mode eq \"added\" or $mode eq \"removed\") {\n            $L =~ m/^\\s*[+-]\\s+(.*?)\\s+;/;\n            my $F = $1;\n            if (!defined $1) {\n                warn \"file_pairs_from_file($file) parse failure\\n\",\n                     \"in $mode mode for '$L', ignoring\\n\";\n                next;\n            }\n            if ($mode eq \"added\") {\n                push @{$ra_added}  , $F;\n            } else {\n                push @{$ra_removed}, $F;\n            }\n        } else {\n            $L =~ m/^\\s*([!=]=\\s*)?(.*?)\\s*\\|\\s*(.*?)\\s*(;.*?)?$/;\n            if (!defined $2 or !defined $3) {\n                warn \"file_pairs_from_file($file) parse failure\\n\",\n                     \"in compare mode for '$L', ignoring\\n\";\n                next;\n            }\n            push @{$ra_compare_list}, ( [$2, $3] );\n        }\n    }\n    print \"<- file_pairs_from_file\\n\" if $opt_v and $opt_v > 2;\n}\nsub read_file  {                             # {{{1\n    my ($file, ) = @_;\n    print \"-> read_file($file)\\n\" if $opt_v and $opt_v > 2;\n    my %BoM = (\n        \"fe ff\"           => 2 ,\n        \"ff fe\"           => 2 ,\n        \"ef bb bf\"        => 3 ,\n        \"f7 64 4c\"        => 3 ,\n        \"0e fe ff\"        => 3 ,\n        \"fb ee 28\"        => 3 ,\n        \"00 00 fe ff\"     => 4 ,\n        \"ff fe 00 00\"     => 4 ,\n        \"2b 2f 76 38\"     => 4 ,\n        \"2b 2f 76 39\"     => 4 ,\n        \"2b 2f 76 2b\"     => 4 ,\n        \"2b 2f 76 2f\"     => 4 ,\n        \"dd 73 66 73\"     => 4 ,\n        \"84 31 95 33\"     => 4 ,\n        \"2b 2f 76 38 2d\"  => 5 ,\n        );\n\n    my @lines = ();\n    my $IN = open_file('<', $file, 1);\n    if (defined $IN) {\n        @lines = <$IN>;\n        $IN->close;\n        if ($lines[$#lines]) {  # test necessary for zero content files\n                                # (superfluous?)\n            # Some files don't end with a new line.  Force this:\n            $lines[$#lines] .= \"\\n\" unless $lines[$#lines] =~ m/\\n$/;\n        }\n    } else {\n        warn \"Unable to read $file\\n\";\n    }\n\n    # Are first few characters of the file Unicode Byte Order\n    # Marks (http://en.wikipedia.org/wiki/Byte_Order_Mark)?\n    # If yes, remove them.\n    if (@lines) {\n        my @chrs   = split('', $lines[0]);\n        my $n_chrs = scalar @chrs;\n        my ($n2, $n3, $n4, $n5) = ('', '', '', '');\n        $n2 = sprintf(\"%x %x\", map  ord, @chrs[0,1]) if $n_chrs >= 2;\n        $n3 = sprintf(\"%s %x\", $n2, ord  $chrs[2])   if $n_chrs >= 3;\n        $n4 = sprintf(\"%s %x\", $n3, ord  $chrs[3])   if $n_chrs >= 4;\n        $n5 = sprintf(\"%s %x\", $n4, ord  $chrs[4])   if $n_chrs >= 5;\n        if      (defined $BoM{$n2}) { $lines[0] = substr $lines[0], 2;\n        } elsif (defined $BoM{$n3}) { $lines[0] = substr $lines[0], 3;\n        } elsif (defined $BoM{$n4}) { $lines[0] = substr $lines[0], 4;\n        } elsif (defined $BoM{$n5}) { $lines[0] = substr $lines[0], 5;\n        }\n    }\n\n    # Trim DOS line endings.  This allows Windows files\n    # to be diff'ed with Unix files without line endings\n    # causing every line to differ.\n    foreach (@lines) { s/\\cM$// }\n\n    print \"<- read_file\\n\" if $opt_v and $opt_v > 2;\n    return @lines;\n} # 1}}}\nsub rm_blanks {                              # {{{1\n    my ($ra_in    ,\n        $language ,\n        $rh_EOL_continuation_re) = @_;\n    print \"-> rm_blanks(language=$language)\\n\" if $opt_v > 2;\n#print \"rm_blanks: language = [$language]\\n\";\n    my @out = ();\n    if ($language eq \"COBOL\") {\n        @out = remove_cobol_blanks($ra_in);\n    } else {\n        # removes blank lines\n        if (defined $rh_EOL_continuation_re->{$language}) {\n            @out = remove_matches_2re($ra_in, blank_regex($language),\n                                      $rh_EOL_continuation_re->{$language});\n        } else {\n            @out = remove_matches($ra_in, blank_regex($language));\n        }\n    }\n\n    print \"<- rm_blanks(language=$language, n_remain= \",\n        scalar(@out), \"\\n\" if $opt_v > 2;\n    return @out;\n} # 1}}}\nsub blank_regex {                            # {{{1\n    my ($language) = @_;\n\n    print \"-> blank_regex(language=$language)\\n\" if $opt_v > 2;\n\n    my $blank_regex = '^\\s*$';\n    if ($language eq \"X++\") {\n        $blank_regex = '^\\s*#?\\s*$';\n    }\n\n    print \"<- blank_regex(language=$language) = \\\"\", $blank_regex, \"\\\"\\n\" if $opt_v > 2;\n    return $blank_regex;\n} # 1}}}\nsub rm_comments {                            # {{{1\n    my ($ra_lines , # in, must be free of blank lines\n        $language , # in\n        $file     , # in (some language counters, eg Haskell, need\n                    #     access to the original file)\n        $rh_EOL_continuation_re , # in\n        $raa_Errors , # out\n       ) = @_;\n    print \"-> rm_comments(file=$file)\\n\" if $opt_v > 2;\n    my @routines       = @{$Filters_by_Language{$language}};\n    my @lines          = @{$ra_lines};\n    my @original_lines = @{$ra_lines};\n\n    if (!scalar @original_lines) {\n        return @lines;\n    }\n\n    foreach my $call_string (@routines) {\n        my $subroutine = $call_string->[0];\n        next if $subroutine eq \"rm_comments_in_strings\" and !$opt_strip_str_comments;\n        if (! defined &{$subroutine}) {\n            warn \"rm_comments undefined subroutine $subroutine for $file\\n\";\n            next;\n        }\n        print \"rm_comments file=$file sub=$subroutine\\n\" if $opt_v > 1;\n        my @args  = @{$call_string};\n        shift @args; # drop the subroutine name\n        if (@args and $args[0] eq '>filename<') {\n            shift   @args;\n            unshift @args, $file;\n        }\n\n        # Unusual inputs, namely /* within strings without\n        # a corresponding */ can cause huge delays so put a timer on this.\n        my $max_duration_sec = scalar(@lines)/1000.0; # est lines per second\n           $max_duration_sec = 1.0 if $max_duration_sec < 1;\n        # add a scale factor for super long lines\n        my $max_line_len = 0;\n        foreach my $line (@lines) {\n            my $len = length($line);\n            $max_line_len = $len if $len > $max_line_len;\n        }\n        if ($max_line_len > 1000) {\n            $max_duration_sec *= $max_line_len / 2000;\n        }\n        if (defined $opt_timeout) {\n            $max_duration_sec = $opt_timeout if $opt_timeout > 0;\n        }\n#my $T_start = Time::HiRes::time();\n        eval {\n            local $SIG{ALRM} = sub { die \"alarm\\n\" };\n            alarm $max_duration_sec;\n            no strict 'refs';\n            @lines = &{$subroutine}(\\@lines, @args);   # apply filter...\n            alarm 0;\n        };\n        #$@ = \"alarm\\n\"; # to trigger the timeout case in tests\n        if ($@) {\n            # timed out\n            die unless $@ eq \"alarm\\n\";\n            push @{$raa_Errors},\n                [ $Error_Codes{'Line count, exceeded timeout'}, $file ];\n            @lines = ();\n            if ($opt_v) {\n                warn \"rm_comments($subroutine): exceeded timeout for $file--ignoring\\n\";\n            }\n            next;\n        }\n#print \"end time = \",Time::HiRes::time() - $T_start;\n\n        print \"   rm_comments after $subroutine line count=\",\n            scalar(@lines), \"\\n\" if $opt_v > 2;\n\n#print \"lines after=\\n\";\n#print Dumper(\\@lines);\n\n        print_lines($file, \"After $subroutine(@args)\", \\@lines)\n            if $opt_print_filter_stages;\n        # then remove blank lines which are created by comment removal\n        if (defined $rh_EOL_continuation_re->{$language}) {\n            @lines = remove_matches_2re(\\@lines, '^\\s*$',\n                                        $rh_EOL_continuation_re->{$language});\n        } else {\n            @lines = remove_matches(\\@lines, '^\\s*$');\n        }\n\n        print_lines($file, \"post $subroutine(@args) blank cleanup:\", \\@lines)\n            if $opt_print_filter_stages;\n    }\n\n    foreach (@lines) { chomp }   # make sure no spurious newlines were added\n\n    # Exception for scripting languages:  treat the first #! line as code.\n    # Will need to add it back in if it was removed earlier.\n    chomp( $original_lines[0] );\n    if (defined $Script_Language{$language} and\n        $original_lines[0] =~ /^#!/ and\n        (!scalar(@lines) or ($lines[0] ne $original_lines[0]))) {\n        unshift @lines, $original_lines[0];  # add the first line back\n    }\n\n    print \"<- rm_comments\\n\" if $opt_v > 2;\n    return @lines;\n} # 1}}}\nsub rm_code {                                # {{{1\n    # Return lines containing only comments.\n    my ($ra_lines_w_comments , # in\n        $ra_lines_no_comments, # in\n       )  = @_;\n\n    my @w_comments_no_blanks  = grep { ! /^\\s*$/ } @{$ra_lines_w_comments} ;\n    my @no_comments_no_blanks = grep { ! /^\\s*$/ } @{$ra_lines_no_comments};\n    chomp( @w_comments_no_blanks  );\n    chomp( @no_comments_no_blanks );\n\n    my @sdiffs = sdiff( \\@w_comments_no_blanks, \\@no_comments_no_blanks, );\n    my @comments = ();\n    foreach my $entry (@sdiffs) {\n        my ($out_1, $out_2) = ('', '');\n        next if $entry->[0] eq 'u';\n        if ($entry->[0] eq '-') {\n            $out_1 = $entry->[1];\n        }\n        next if $out_1 =~ /^\\s*$/;\n        push @comments, $out_1;\n    }\n    return @comments;\n} # 1}}}\nsub remove_first_n {                         # {{{1\n    my ($n, $ra_lines, ) = @_;\n    print \"-> remove_first_n\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    if (scalar @{$ra_lines} > $n) {\n        for (my $i = $n; $i < scalar @{$ra_lines}; $i++) {\n            push @save_lines, $ra_lines->[$i];\n        }\n    }\n\n    print \"<- remove_first_n\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_f77_comments {                    # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> remove_f77_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        next if m{^[*cC]};\n        next if m{^\\s*!};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_f77_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_f90_comments {                    # {{{1\n    # derived from SLOCCount\n    my ($ra_lines, ) = @_;\n    print \"-> remove_f90_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        # a comment is              m/^\\s*!/\n        # an empty line is          m/^\\s*$/\n        # a HPF statement is        m/^\\s*!hpf\\$/i\n        # an Open MP statement is   m/^\\s*!omp\\$/i\n        if (! m/^(\\s*!|\\s*$)/ || m/^\\s*!(hpf|omp)\\$/i) {\n            push @save_lines, $_;\n        }\n    }\n\n    print \"<- remove_f90_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub reduce_to_rmd_code_blocks {              #{{{1\n    my ($ra_lines) = @_; #in\n    print \"-> reduce_to_rmd_code_blocks()\\n\" if $opt_v > 2;\n\n    my $in_code_block = 0;\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        if ( m/^```\\{\\s*[[:alpha:]]/ ) {\n            $in_code_block = 1;\n            next;\n        }\n        if ( m/^```\\s*$/ ) {\n            $in_code_block = 0;\n        }\n        next if (!$in_code_block);\n        push @save_lines, $_;\n    }\n\n    print \"<- reduce_to_rmd_code_blocks()\\n\" if $opt_v> 2;\n    return @save_lines;\n} # 1}}}\nsub remove_matches {                         # {{{1\n    my ($ra_lines, # in\n        $pattern , # in   Perl regular expression (case insensitive)\n       ) = @_;\n    print \"-> remove_matches(pattern=$pattern)\\n\" if $opt_v > 2;\n    print \"in:  [\", join(\"]\\nin:  [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n#chomp;\n#print \"remove_matches [$pattern] [$_]\\n\";\n        next if m{$pattern}i;\n#       s{$pattern}{}i;\n#       next unless /\\S/; # at least one non space\n        push @save_lines, $_;\n    }\n\n    print \"out: [\", join(\"]\\nout: [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_matches\\n\" if $opt_v > 2;\n#print \"remove_matches returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_matches_2re {                     # {{{1\n    my ($ra_lines, # in\n        $pattern1, # in Perl regex 1 (case insensitive) to match\n        $pattern2, # in Perl regex 2 (case insensitive) to not match prev line\n       ) = @_;\n    print \"-> remove_matches_2re(pattern=$pattern1,$pattern2)\\n\" if $opt_v > 2;\n    print \"[\", join(\"]\\nin:  [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {\n#       chomp($ra_lines->[$i]);\n#print \"remove_matches_2re [$pattern1] [$pattern2] [$ra_lines->[$i]]\\n\";\n        if ($i) {\n#print \"remove_matches_2re prev=[$ra_lines->[$i-1]] this=[$ra_lines->[$i]]\\n\";\n            next if ($ra_lines->[$i]   =~ m{$pattern1}i) and\n                    ($ra_lines->[$i-1] !~ m{$pattern2}i);\n        } else {\n            # on first line\n            next if $ra_lines->[$i]   =~  m{$pattern1}i;\n        }\n        push @save_lines, $ra_lines->[$i];\n    }\n\n    print \"[\", join(\"]\\nout: [\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_matches_2re\\n\" if $opt_v > 2;\n#print \"remove_matches_2re returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_inline {                          # {{{1\n    my ($ra_lines, # in\n        $pattern , # in   Perl regular expression (case insensitive)\n       ) = @_;\n    print \"-> remove_inline(pattern=$pattern)\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    unless ($opt_inline) {\n        return @{$ra_lines};\n    }\n    my $nLines_affected = 0;\n    foreach (@{$ra_lines}) {\n#chomp; print \"remove_inline [$pattern] [$_]\\n\";\n        if (m{$pattern}i) {\n            ++$nLines_affected;\n            s{$pattern}{}i;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_inline\\n\" if $opt_v > 2;\n#print \"remove_inline returning\\n   \", join(\"\\n   \", @save_lines), \"\\n\";\n    return @save_lines;\n} # 1}}}\nsub remove_above {                           # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    print \"-> remove_above(marker=$marker)\\n\" if $opt_v > 2;\n\n    # Make two passes through the code:\n    # 1. check if the marker exists\n    # 2. remove anything above the marker if it exists,\n    #    do nothing if the marker does not exist\n\n    # Pass 1\n    my $found_marker = 0;\n    for (my $line_number  = 1;\n            $line_number <= scalar @{$ra_lines};\n            $line_number++) {\n        if ($ra_lines->[$line_number-1] =~ m{$marker}) {\n            $found_marker = $line_number;\n            last;\n        }\n    }\n\n    # Pass 2 only if needed\n    my @save_lines = ();\n    if ($found_marker) {\n        my $n = 1;\n        foreach (@{$ra_lines}) {\n            push @save_lines, $_\n                if $n >= $found_marker;\n            ++$n;\n        }\n    } else { # marker wasn't found; save all lines\n        foreach (@{$ra_lines}) {\n            push @save_lines, $_;\n        }\n    }\n\n    print \"<- remove_above\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_below {                           # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    print \"-> remove_below(marker=$marker)\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n        last if m{$marker};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_below\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_below_above {                     # {{{1\n    my ($ra_lines, $marker_below, $marker_above, ) = @_;\n    # delete lines delimited by start and end line markers such\n    # as Perl POD documentation\n    print \"-> remove_below_above(markerB=$marker_below, A=$marker_above)\\n\"\n        if $opt_v > 2;\n\n    my @save_lines = ();\n    my $between    = 0;\n    foreach (@{$ra_lines}) {\n        if (!$between and m{$marker_below}) {\n            $between    = 1;\n            next;\n        }\n        if ($between and m{$marker_above}) {\n            $between    = 0;\n            next;\n        }\n        next if $between;\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_below_above\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between {                         # {{{1\n    my ($ra_lines, $marker, ) = @_;\n    # $marker must contain one of the balanced pairs understood\n    # by Regexp::Common::balanced, namely\n    # '{}'  '()'  '[]'  or  '<>'\n\n    print \"-> remove_between(marker=$marker)\\n\" if $opt_v > 2;\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    my %acceptable = ('{}'=>1,  '()'=>1,  '[]'=>1,  '<>'=>1, );\n    die \"remove_between:  invalid delimiter '$marker'\\n\",\n        \"the delimiter must be one of these four pairs:\\n\",\n        \"{}  ()  []  <>\\n\" unless\n        $acceptable{$marker};\n\n    Install_Regexp_Common() unless $HAVE_Rexexp_Common;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    no strict 'vars';\n    # otherwise get:\n    #  Global symbol \"%RE\" requires explicit package name at cloc line xx.\n    if ($all_lines =~ m/$RE{balanced}{-parens => $marker}/) {\n        no warnings;\n        $all_lines =~ s/$1//g;\n    }\n\n    print \"[\", join(\"]\\n[\", split(/\\n/, $all_lines)), \"]\\n\" if $opt_v > 4;\n    print \"<- remove_between\\n\" if $opt_v > 2;\n    return split(\"\\n\", $all_lines);\n} # 1}}}\nsub rm_comments_in_strings {                 # {{{1\n    my ($ra_lines, $string_marker, $start_comment, $end_comment, $multiline_mode) = @_;\n    $multiline_mode = 0 if not defined $multiline_mode;\n    # Replace comments within strings with 'xx'.\n\n    print \"-> rm_comments_in_strings(string_marker=$string_marker, \" .\n          \"start_comment=$start_comment, end_comment=$end_comment)\\n\"\n        if $opt_v > 2;\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n\n    my @save_lines = ();\n    my $in_ml_string = 0;\n    foreach my $line (@{$ra_lines}) {\n       #print \"line=[$line]\\n\";\n        my $new_line = \"\";\n\n        if ($line !~ /${string_marker}/) {\n            # short circuit; no strings on this line\n            if ( $in_ml_string ) {\n                $line =~ s/\\Q${start_comment}\\E/xx/g;\n                $line =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            }\n            push @save_lines, $line;\n            next;\n        }\n\n        # replace backslashed string markers with 'Q'\n        $line =~ s/\\\\${string_marker}/Q/g;\n\n        if ( $in_ml_string and $line =~ /^(.*?)(${string_marker})(.*)$/ ) {\n            # A multiline string ends on this line. Process the part\n            # until the end of the multiline string first.\n            my ($lastpart_ml_string, $firstpart_marker, $rest_of_line )  = ($1, $2, $3);\n            $lastpart_ml_string =~ s/\\Q${start_comment}\\E/xx/g;\n            $lastpart_ml_string =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            $new_line = $lastpart_ml_string . $firstpart_marker;\n            $line = $rest_of_line;\n            $in_ml_string = 0;\n        }\n\n        my @tokens = split(/(${string_marker}.*?${string_marker})/, $line);\n        foreach my $t (@tokens) {\n           #printf \"  t0 = [$t]\\n\";\n            if ($t =~ /${string_marker}.*${string_marker}$/) {\n                # enclosed in quotes; process this token\n                $t =~ s/\\Q${start_comment}\\E/xx/g;\n                $t =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n            }\n            elsif ( $multiline_mode and $t =~ /(${string_marker})/ ) {\n                # Unclosed quote present in line. If multiline_mode is enabled,\n                # consider it the start of a multiline string.\n                my $firstpart_marker = $1;\n                my @sub_token = split(/${string_marker}/, $t );\n\n                if ( scalar @sub_token == 1 ) {\n                    # The line ends with a string marker that starts\n                    # a multiline string.\n                    $t = $sub_token[0] . $firstpart_marker;\n                    $in_ml_string = 1;\n                }\n                elsif ( scalar @sub_token == 2 ) {\n                    # The line has some more content after the string\n                    # marker that starts a multiline string\n                    $t = $sub_token[0] . $firstpart_marker;\n                    $sub_token[1] =~ s/\\Q${start_comment}\\E/xx/g;\n                    $sub_token[1] =~ s/\\Q${end_comment}\\E/xx/g if $end_comment;\n                    $t .= $sub_token[1];\n                    $in_ml_string = 1;\n                } else {\n                    print \"Warning: rm_comments_in_string length \\@sub_token > 2\\n\";\n                }\n\n            }\n            #printf \"  t1 = [$t]\\n\";\n            $new_line .= $t;\n        }\n        push @save_lines, $new_line;\n    }\n\n    print \"[\", join(\"]\\n[\", @save_lines), \"]\\n\" if $opt_v > 4;\n    print \"<- rm_comments_in_strings\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between_general {                 # {{{1\n    my ($ra_lines, $start_marker, $end_marker, ) = @_;\n    # Start and end markers may be any length strings.\n\n    print \"-> remove_between_general(start=$start_marker, end=$end_marker)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/\\Q$start_marker\\E.*?\\Q$end_marker\\E//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\Q$end_marker\\E/) {\n                s/^.*?\\Q$end_marker\\E//;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)\\Q$start_marker\\E/; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)\\Q$start_marker\\E.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_between_general\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_between_regex   {                 # {{{1\n    my ($ra_lines, $start_RE, $end_RE, ) = @_;\n    # Start and end regex's may be any length strings.\n\n    print \"-> remove_between_regex(start=$start_RE, end=$end_RE)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${start_RE}.*?${end_RE}//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/$end_RE/) {\n                s/^.*?${end_RE}//;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)${start_RE}/; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)${start_RE}.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_between_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub replace_regex  {                         # {{{1\n    my ($ra_lines, $regex, $replace, ) = @_;\n\n    print \"-> replace_regex(regex=$regex, replace=$replace)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${regex}/${replace}/g;\n        next if /^\\s*$/;\n        push @save_lines, $_;\n    }\n\n    print \"<- replace_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub replace_between_regex  {                 # {{{1\n    my ($ra_lines, $start_RE, $end_RE, $replace_RE, $multiline_mode ) = @_;\n    # If multiline_mode is enabled, $replace_RE should not refer\n    # to any captured groups in $start_RE.\n    $multiline_mode = 1 if not defined $multiline_mode;\n    # Start and end regex's may be any length strings.\n\n    print \"-> replace_between_regex(start=$start_RE, end=$end_RE, replace=$replace_RE)\\n\"\n        if $opt_v > 2;\n\n    my $all_lines = join(\"\", @{$ra_lines});\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/${start_RE}.*?${end_RE}/${replace_RE}/eeg;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/$end_RE/) {\n                s/^.*?${end_RE}/${replace_RE}/ee;\n                $in_comment = 0;\n            }\n            next if $in_comment;\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if $multiline_mode and /^(.*?)${start_RE}/ ; # $1 may be blank or code\n        next if defined $1 and $1 =~ /^\\s*$/; # leading blank; all comment\n        if ($in_comment) {\n            # part code, part comment; strip the comment and keep the code\n            s/^(.*?)${start_RE}.*$/$1/;\n        }\n        push @save_lines, $_;\n    }\n\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- replace_between_regex\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_cobol_blanks {                    # {{{1\n    # subroutines derived from SLOCCount\n    my ($ra_lines, ) = @_;\n\n    my $free_format = 0;  # Support \"free format\" source code.\n    my @save_lines  = ();\n\n    foreach (@{$ra_lines}) {\n        next if m/^\\s*$/;\n        my $line = expand($_);  # convert tabs to equivalent spaces\n        $free_format = 1 if $line =~ m/^......\\$.*SET.*SOURCEFORMAT.*FREE/i;\n        if ($free_format) {\n            push @save_lines, $_;\n        } else {\n            # Greg Toth:\n            #  (1) Treat lines with any alphanum in cols 1-6 and\n            #      blanks in cols 7 through 71 as blank line, and\n            #  (2) Treat lines with any alphanum in cols 1-6 and\n            #      slash (/) in col 7 as blank line (this is a\n            #      page eject directive).\n            push @save_lines, $_ unless m/^\\d{6}\\s*$/             or\n                                        ($line =~ m/^.{6}\\s{66}/) or\n                                        ($line =~ m/^......\\//);\n        }\n    }\n    return @save_lines;\n} # 1}}}\nsub remove_cobol_comments {                  # {{{1\n    # subroutines derived from SLOCCount\n    my ($ra_lines, ) = @_;\n\n    my $free_format = 0;  # Support \"free format\" source code.\n    my @save_lines  = ();\n\n    foreach (@{$ra_lines}) {\n        if (m/^......\\$.*SET.*SOURCEFORMAT.*FREE/i) {$free_format = 1;}\n        if ($free_format) {\n            push @save_lines, $_ unless m{^\\s*\\*};\n        } else {\n            push @save_lines, $_ unless m{^......\\*} or m{^\\*};\n        }\n    }\n    return @save_lines;\n} # 1}}}\nsub remove_jcl_comments {                    # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_jcl_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n        next if /^\\s*$/;\n        next if m{^//\\*};\n        last if m{^\\s*//\\s*$};\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_jcl_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_jsp_comments {                    # {{{1\n    #  JSP comment is   <%--  body of comment   --%>\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_jsp_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/<\\%\\-\\-.*?\\-\\-\\%>//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\-\\-\\%>/) {\n                s/^.*?\\-\\-\\%>//;\n                $in_comment = 0;\n            }\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)<\\%\\-\\-/;\n        next if defined $1 and $1 =~ /^\\s*$/;\n        next if ($in_comment);\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_jsp_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_html_comments {                   # {{{1\n    #  HTML comment is   <!--  body of comment   -->\n    #  Need to use my own routine until the HTML comment regex in\n    #  the Regexp::Common module can handle  <!--  --  -->\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_html_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        s/<!\\-\\-.*?\\-\\->//g;  # strip one-line comments\n        next if /^\\s*$/;\n        if ($in_comment) {\n            if (/\\-\\->/) {\n                s/^.*?\\-\\->//;\n                $in_comment = 0;\n            }\n        }\n        next if /^\\s*$/;\n        $in_comment = 1 if /^(.*?)<!\\-\\-/;\n        if (defined $1 and $1 !~ /^\\s*$/) {\n            # has both code and comment\n            push @save_lines, \"$1\\n\";\n            next;\n        }\n        next if ($in_comment);\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_html_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_bf_comments {                     # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_bf_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        s/[^<>+-.,\\[\\]]+//g;\n        next if /^\\s*$/;\n        push @save_lines, $_;\n    }\n\n    print \"<- remove_bf_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub really_is_bf {                           # {{{1\n    my ($file, ) = @_;\n\n    print \"-> really_is_bf\\n\" if $opt_v > 2;\n    my $n_bf_indicators  = 0;\n    my @lines = read_file($file);\n    foreach my $L (@lines) {\n        my $ind = 0;\n        if ($L =~ /([+-]{4,}  |          # at least four +'s or -'s in a row\n                   [\\[\\]]{4,} |          # at least four [ or ] in a row\n                   [<>][+-]   |          # >- or >+ or <+ or <-\n                   <{3,}      |          # at least three < in a row\n                   ^\\s*[\\[\\]]\\s*$)/x) {  # [ or ] on line by itself\n            ++$n_bf_indicators;\n            $ind = 1;\n        }\n        # if ($ind) { print \"YES: $L\"; } else { print \"NO : $L\"; }\n    }\n    my $ratio = scalar(@lines) > 0 ? $n_bf_indicators / scalar(@lines) : 0;\n    my $decision = ($ratio > 0.5) || ($n_bf_indicators > 5);\n    printf \"<- really_is_bf(Y/N=%d %s, R=%.3f, N=%d)\\n\",\n            $decision, $file, $ratio, $n_bf_indicators if $opt_v > 2;\n    return $decision;\n} # 1}}}\nsub remove_indented_block {                  # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    /\n    # or\n    #    -#\n    # followed by indented text on subsequent lines.\n    # http://haml.info/docs/yardoc/file.REFERENCE.html#comments\n    my ($ra_lines, $regex, ) = @_;\n\n    print \"-> remove_indented_block\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    foreach (@{$ra_lines}) {\n\n        next if /^\\s*$/;\n        my $line = expand($_);  # convert tabs to equivalent spaces\n        if ($in_comment) {\n            $line =~ /^(\\s*)/;\n            # print \"indent=\", length $1, \"\\n\";\n            if (length $1 < $in_comment) {\n                # indent level is less than comment level\n                # are back in code\n                $in_comment = 0;\n            } else {\n                # still in comments, don't use this line\n                next;\n            }\n        } elsif ($line =~ m{$regex}) {\n            if ($1) {\n                $in_comment = length($1) + 1; # number of leading spaces + 1\n            } else {\n                $in_comment = 1;\n            }\n            # print \"in_comment=$in_comment\\n\";\n            next;\n        }\n        push @save_lines, $line;\n    }\n\n    print \"<- remove_indented_block\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_haml_block {                      # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    /\n    # or\n    #    -#\n    # followed by indented text on subsequent lines.\n    # http://haml.info/docs/yardoc/file.REFERENCE.html#comments\n    my ($ra_lines, ) = @_;\n\n    return remove_indented_block($ra_lines, '^(\\s*)(/|-#)\\s*$');\n\n} # 1}}}\nsub remove_pug_block {                       # {{{1\n    # Haml block comments are defined by a silent comment marker like\n    #    //\n    # followed by indented text on subsequent lines.\n    # http://jade-lang.com/reference/comments/\n    my ($ra_lines, ) = @_;\n    return remove_indented_block($ra_lines, '^(\\s*)(//)\\s*$');\n} # 1}}}\nsub remove_OCaml_comments {                  # {{{1\n    my ($ra_lines, ) = @_;\n\n    print \"-> remove_OCaml_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;   # counter to depth of nested comments\n    foreach my $L (@{$ra_lines}) {\n        next if $L =~ /^\\s*$/;\n        # make an array of tokens where a token is a start comment\n        # marker, end comment marker, string, or anything else\n        my $clean_line = \"\"; # ie, free of comments\n        my @tokens = split(/(\\(\\*|\\*\\)|\".*?\")/, $L);\n        foreach my $t (@tokens) {\n            next unless $t;\n            if      ($t eq \"(*\") {\n                ++$in_comment;\n            } elsif ($t eq \"*)\") {\n                --$in_comment;\n            } elsif (!$in_comment) {\n                $clean_line .= $t;\n            }\n        }\n        push @save_lines, $clean_line if $clean_line;\n    }\n    print \"<- remove_OCaml_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_TLAPlus_generated_code {          # {{{1\n    my ($ra_lines, ) = @_;\n    # If --no-autogen, remove code created by the PlusCal translator.\n    return @{$ra_lines} if !$opt_no_autogen;\n    return remove_between_regex($ra_lines, '^\\\\\\\\\\\\* BEGIN TRANSLATION\\b', '^\\\\\\\\\\\\* END TRANSLATION\\b');\n} # 1}}}\nsub remove_TLAPlus_comments {                # {{{1\n    my ($ra_lines, ) = @_;\n    # TLA+ block comments are like OCaml comments (remove_OCaml_comments).\n    # However, TLA+ comments may contain PlusCal code, and we must consider the\n    # PlusCal code as code, not comments.\n\n    print \"-> remove_TLAPlus_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;        # counter to depth of nested (* *) comments\n    my $in_pluscal_head = 0;   # whether we saw the start of PlusCal code\n    my $in_pluscal_block = 0;  # counter to depth of nested { } blocks\n    my $saved_in_comment = 0;  # $in_comment before we entered PlusCal code\n    foreach my $L (@{$ra_lines}) {\n        next if $L =~ /^\\s*$/;\n        # make an array of interesting tokens we need to act upon\n        my $clean_line = \"\"; # ie, free of comments\n        my @tokens = split(/(\\(\\*|\\*\\)|\".*?\"|[{}]|--fair\\b|--algorithm|PlusCal options)/, $L);\n        foreach my $t (@tokens) {\n            next unless $t;\n            if      ($t eq \"(*\") {\n                ++$in_comment;\n            } elsif ($t eq \"*)\") {\n                --$in_comment;\n            } elsif ($t eq \"{\" && $in_pluscal_head) {\n                # start block matching when we see '{' in '--algorithm NAME {'\n                $in_pluscal_head = 0;\n                $in_pluscal_block = 1;\n                $saved_in_comment = $in_comment;\n                $in_comment = 0;\n                $clean_line .= $t;\n            } elsif ($t eq \"{\" && $in_pluscal_block && !$in_comment) {\n                ++$in_pluscal_block;\n                $clean_line .= $t;\n            } elsif ($t eq \"}\" && $in_pluscal_block && !$in_comment) {\n                --$in_pluscal_block;\n                if ($in_pluscal_block == 0) {\n                    $in_comment = $saved_in_comment;\n                }\n                $clean_line .= $t;\n            } elsif ($t eq \"--fair\" || $t eq \"--algorithm\") {\n                $in_pluscal_head = 1;\n                $clean_line .= $t;\n            } elsif (!$in_comment || $in_pluscal_head || $in_pluscal_block || $t eq \"PlusCal options\") {\n                $clean_line .= $t;\n            }\n        }\n        push @save_lines, $clean_line if $clean_line;\n    }\n    print \"<- remove_TLAPlus_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub remove_slim_block {                      # {{{1\n    # slim comments start with /\n    # followed by indented text on subsequent lines.\n    # http://www.rubydoc.info/gems/slim/frames\n    my ($ra_lines, ) = @_;\n    return remove_indented_block($ra_lines, '^(\\s*)(/[^!])');\n} # 1}}}\nsub add_newlines {                           # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> add_newlines \\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    foreach (@{$ra_lines}) {\n\n        push @save_lines, \"$_\\n\";\n    }\n\n    print \"<- add_newlines \\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub docstring_to_C {                         # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Python docstrings to C comments.\n\n    if ($opt_docstring_as_code) {\n        return @{$ra_lines};\n    }\n\n    print \"-> docstring_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        while (/((\"\"\")|('''))/) {\n            if (!$in_docstring) {\n                s{[uU]?((\"\"\")|('''))}{/*};\n                $in_docstring = 1;\n            } else {\n                s{((\"\"\")|('''))}{*/};\n                $in_docstring = 0;\n            }\n        }\n    }\n\n    print \"<- docstring_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub docstring_rm_comments {                  # {{{1\n    my ($ra_lines, ) = @_;\n    # Remove embedded C/C++ style comments in docstrings.\n\n    print \"-> docstring_rm_comments()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        if (/((\"\"\")|('''))(.*?)\\1/) {\n            # single line docstring\n            my ($i_start, $i_end) = ($-[0]+3, $+[0]-3);\n            # replace /*, */, // with xx\n            substr($_, $i_start, $i_end-$i_start) =~ s{(/\\*|\\*/|//)}{xx}g;\n            next;\n        } elsif (m{/\\*.*?((\"\"\")|(''')).*?\\*/}) {\n            # docstring start or end within /* */ comments\n            my $i_start = $-[0]+2;\n            substr($_, $i_start, 3) = \"xxx\";\n        } elsif (m{//.*?((\"\"\")|('''))}) {\n            # docstring start or end after //\n            my $i_start = $-[0]+2;\n            substr($_, $i_start, 3) = \"xxx\";\n        } elsif (/^(.*?)((\"\"\")|('''))/ and  $in_docstring) {\n            $in_docstring = 0;\n            my $i_end = length $1;\n            if ($i_end) {\n                substr($_, 0, $i_end) =~ s{(/\\*|\\*/|//)}{xx}g;\n            }\n        } elsif (/((\"\"\")|('''))(.*?)$/ and !$in_docstring) {\n            $in_docstring = 1;\n            my $i_start = $-[0]+3;\n            substr($_, $i_start) =~ s{(/\\*|\\*/|//)}{xx}g;\n        } elsif ($in_docstring) {\n            s{(/\\*|\\*/|//)}{xx}g;\n        }\n    }\n\n    print \"[\", join(\"]\\n[\", @{$ra_lines}), \"]\\n\" if $opt_v > 4;\n    print \"<- docstring_rm_comments\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub jupyter_nb {                             # {{{1\n    my ($ra_lines, ) = @_;\n    # Translate .ipynb file content into an equivalent set of code\n    # lines as expected by cloc.\n\n    print \"-> jupyter_nb()\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_code   = 0;\n    my $in_source = 0;\n    foreach (@{$ra_lines}) {\n        if (!$in_code and !$in_source and /^\\s*\"cell_type\":\\s*\"code\",\\s*$/) {\n            $in_code = 1;\n        } elsif ($in_code and !$in_source and /^\\s*\"source\":\\s*\\[\\s*$/) {\n            $in_source = 1;\n        } elsif ($in_code and $in_source) {\n            if (/^\\s*\"\\s*\\\\n\",\\s*$/) {    #  \"\\n\",  -> empty line\n                next;\n            } elsif (/^\\s*\"\\s*#/) {       #  comment within the code block\n                next;\n            } elsif (/^\\s*\\]\\s*$/) {\n                $in_code   = 0;\n                $in_source = 0;\n            } else {\n                push @save_lines, $_;\n            }\n        }\n    }\n\n    print \"<- jupyter_nb\\n\" if $opt_v > 2;\n\n    return @save_lines;\n} # 1}}}\nsub elixir_doc_to_C {                        # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Elixir docs to C comments.\n\n    print \"-> elixir_doc_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        if (!$in_docstring && /(\\@(module)?doc\\s+(~[sScC])?['\"]{3})/) {\n            s{$1}{/*};\n            $in_docstring = 1;\n        } elsif ($in_docstring && /(['\"]{3})/) {\n            s{$1}{*/};\n            $in_docstring = 0;\n        }\n    }\n\n    print \"<- elixir_doc_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub Forth_paren_to_C  {                      # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Forth comment parentheses to C comments.\n\n    print \"-> Forth_paren_to_C()\\n\" if $opt_v > 2;\n\n    my $in_comment = 0;\n    my $max_paren_pair_per_line = 255;\n    foreach (@{$ra_lines}) {\n#print \"Forth_paren_to_C: [$_]\\n\";\n        my $n_iter = 0;\n        while (/\\s\\(\\s/ or ($in_comment and /\\)/)) {\n#print \"TOP n_iter=$n_iter in_comment=$in_comment\\n\";\n            if (/\\s\\(\\s.*?\\)/) {\n                # in-line parenthesis comment; handle here\n                s/\\s+\\(\\s+.*?\\)//g;\n#print \"B\\n\";\n            } elsif (!$in_comment and /\\s\\(\\s/) {\n                s{\\s+\\(\\s+}{/*};\n#print \"C\\n\";\n                $in_comment = 1;\n            } elsif ($in_comment and /\\)/) {\n                s{\\)}{*/};\n#print \"D\\n\";\n                $in_comment = 0;\n            } else {\n                # gets here if it can't find a matching\n                # close parenthesis; in this case the\n                # results will likely be incorrect\n                ++$n_iter;\n#print \"E\\n\";\n                last if $n_iter > $max_paren_pair_per_line;\n            }\n        }\n    }\n\n    print \"<- Forth_paren_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub powershell_to_C {                        # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts PowerShell block comment markers to C comments.\n\n    print \"-> powershell_to_C()\\n\" if $opt_v > 2;\n\n    my $in_docstring = 0;\n    foreach (@{$ra_lines}) {\n        s{<#}{/*}g;\n        s{#>}{*/}g;\n    }\n\n    print \"<- powershell_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub smarty_to_C {                            # {{{1\n    my ($ra_lines, ) = @_;\n    # Converts Smarty comments to C comments.\n\n    print \"-> smarty_to_C()\\n\" if $opt_v > 2;\n\n    foreach (@{$ra_lines}) {\n        s[{\\*][/*]g;\n        s[\\*}][*/]g;\n    }\n\n    print \"<- smarty_to_C\\n\" if $opt_v > 2;\n    return @{$ra_lines};\n} # 1}}}\nsub determine_lit_type {                     # {{{1\n  my ($file) = @_;\n\n  my $FILE = open_file('<', $file, 0);\n  while (<$FILE>) {\n    if (m/^\\\\begin\\{code\\}/) { close $FILE; return 2; }\n    if (m/^>\\s/) { close $FILE; return 1; }\n  }\n\n  return 0;\n} # 1}}}\nsub remove_haskell_comments {                # {{{1\n    # SLOCCount's haskell_count script with modifications to handle\n    # Elm empty and nested block comments.\n    # Strips out {- .. -} and -- comments and counts the rest.\n    # Pragmas, {-#...}, are counted as SLOC.\n    # BUG: Doesn't handle strings with embedded block comment markers gracefully.\n    #      In practice, that shouldn't be a problem.\n    my ($ra_lines, $file, ) = @_;\n\n    print \"-> remove_haskell_comments\\n\" if $opt_v > 2;\n\n    my @save_lines = ();\n    my $in_comment = 0;\n    my $incomment  = 0;\n    my $inlitblock = 0;\n    my $literate   = 0;\n    my $is_elm     = 0;\n\n    $is_elm   = 1 if $file =~ /\\.elm$/;\n    $literate = 1 if $file =~ /\\.lhs$/;\n    if ($literate) { $literate = determine_lit_type($file) }\n\n    foreach (@{$ra_lines}) {\n        chomp;\n        if ($literate == 1) {\n            if (!s/^>//) { s/.*//; }\n        } elsif ($literate == 2) {\n            if ($inlitblock) {\n                if (m/^\\\\end\\{code\\}/) { s/.*//; $inlitblock = 0; }\n            } elsif (!$inlitblock) {\n                if (m/^\\\\begin\\{code\\}/) { s/.*//; $inlitblock = 1; }\n                else { s/.*//; }\n            }\n        }\n\n        # keep pragmas\n        if (/^\\s*{-#/) {\n            push @save_lines, $_;\n            next;\n        }\n\n        # Elm allows nested comments so track nesting depth\n        # with $incomment.\n\n        my $n_open  = () = $_ =~ /{-/g;\n        my $n_close = () = $_ =~ /-}/g;\n        s/{-.*?-}//g;\n\n        if ($incomment) {\n            if (m/\\-\\}/) {\n                s/^.*?\\-\\}//;\n                if ($is_elm) {\n                    $incomment += $n_open - $n_close;\n                } else {\n                    $incomment = 0;\n                }\n            } else {\n                s/.*//;\n            }\n        } else {\n            s/--.*//;\n            if (m/{-/ && (!m/{-#/)) {\n                s/{-.*//;\n                if ($is_elm) {\n                    $incomment += $n_open - $n_close;\n                } else {\n                    $incomment = 1;\n                }\n            }\n        }\n        if (m/\\S/) { push @save_lines, $_; }\n    }\n#   if ($incomment) {print \"ERROR: ended in comment in $ARGV\\n\";}\n\n    print \"<- remove_haskell_comments\\n\" if $opt_v > 2;\n    return @save_lines;\n} # 1}}}\nsub print_lines {                            # {{{1\n    my ($file     , # in\n        $title    , # in\n        $ra_lines , # in\n       ) = @_;\n    printf \"->%-30s %s\\n\", $file, $title;\n    for (my $i = 0; $i < scalar @{$ra_lines}; $i++) {\n        printf \"%5d | %s\", $i+1, $ra_lines->[$i];\n        print \"\\n\" unless $ra_lines->[$i] =~ m{\\n$}\n    }\n} # 1}}}\nsub set_constants {                          # {{{1\n    my ($rh_Language_by_Extension , # out\n        $rh_Language_by_Script    , # out\n        $rh_Language_by_File_Type      , # out\n        $rh_Language_by_Prefix    , # out\n        $rhaa_Filters_by_Language , # out\n        $rh_Not_Code_Extension    , # out\n        $rh_Not_Code_Filename     , # out\n        $rh_Scale_Factor          , # out\n        $rh_Known_Binary_Archives , # out\n        $rh_EOL_continuation_re   , # out\n       ) = @_;\n# 1}}}\n%{$rh_Language_by_Extension} = (             # {{{1\n            'abap'        => 'ABAP'                  ,\n            'ac'          => 'm4'                    ,\n            'ada'         => 'Ada'                   ,\n            'adb'         => 'Ada'                   ,\n            'ads'         => 'Ada'                   ,\n            'adso'        => 'ADSO/IDSM'             ,\n            'ahkl'        => 'AutoHotkey'            ,\n            'ahk'         => 'AutoHotkey'            ,\n            'agda'        => 'Agda'                  ,\n            'lagda'       => 'Agda'                  ,\n            'aj'          => 'AspectJ'               ,\n            'am'          => 'make'                  ,\n            'ample'       => 'AMPLE'                 ,\n            'apl'         => 'APL'                   ,\n            'apla'        => 'APL'                   ,\n            'aplf'        => 'APL'                   ,\n            'aplo'        => 'APL'                   ,\n            'apln'        => 'APL'                   ,\n            'aplc'        => 'APL'                   ,\n            'apli'        => 'APL'                   ,\n            'applescript' => 'AppleScript'           ,\n            'dyalog'      => 'APL'                   ,\n            'dyapp'       => 'APL'                   ,\n            'mipage'      => 'APL'                   ,\n            'art'         => 'Arturo'                ,\n            'as'          => 'ActionScript'          ,\n            'adoc'        => 'AsciiDoc'              ,\n            'asciidoc'    => 'AsciiDoc'              ,\n            'dofile'      => 'AMPLE'                 ,\n            'startup'     => 'AMPLE'                 ,\n            'aria'        => 'Aria'                  ,\n            'axd'         => 'ASP'                   ,\n            'ashx'        => 'ASP'                   ,\n            'asa'         => 'ASP'                   ,\n            'asax'        => 'ASP.NET'               ,\n            'ascx'        => 'ASP.NET'               ,\n            'asd'         => 'Lisp'                  , # system definition file\n            'asmx'        => 'ASP.NET'               ,\n            'asp'         => 'ASP'                   ,\n            'aspx'        => 'ASP.NET'               ,\n            'master'      => 'ASP.NET'               ,\n            'sitemap'     => 'ASP.NET'               ,\n            'nasm'        => 'Assembly'              ,\n            'a51'         => 'Assembly'              ,\n            'asm'         => 'Assembly'              ,\n            'astro'       => 'Astro'                 ,\n            'asy'         => 'Asymptote'             ,\n            'cshtml'      => 'Razor'                 ,\n            'razor'       => 'Razor'                 , # Client-side Blazor\n            'nawk'        => 'awk'                   ,\n            'mawk'        => 'awk'                   ,\n            'gawk'        => 'awk'                   ,\n            'auk'         => 'awk'                   ,\n            'awk'         => 'awk'                   ,\n            'axaml'       => 'AXAML'                 ,\n            'bash'        => 'Bourne Again Shell'    ,\n            'bazel'       => 'Starlark'              ,\n            'BUILD'       => 'Bazel'                 ,\n            'dxl'         => 'DOORS Extension Language',\n            'bat'         => 'DOS Batch'             ,\n            'BAT'         => 'DOS Batch'             ,\n            'cmd'         => 'DOS Batch'             ,\n            'CMD'         => 'DOS Batch'             ,\n            'btm'         => 'DOS Batch'             ,\n            'BTM'         => 'DOS Batch'             ,\n            'blade'       => 'Blade'                 ,\n            'blade.php'   => 'Blade'                 ,\n            'b'           => 'Brainfuck'             ,\n            'bel'         => 'Beluga'                ,\n            'bf'          => 'Brainfuck'             ,\n            'bicep'       => 'Bicep'                 ,\n            'bicepparam'  => 'Bicep'                 ,\n            'blp'         => 'Blueprint'             ,\n            'bpmn'        => 'Activiti Business Process',\n            'brs'         => 'BrightScript'          ,\n            'btp'         => 'BizTalk Pipeline'      ,\n            'build.xml'   => 'Ant'                   ,\n            'bzl'         => 'Starlark'              ,\n            'odx'         => 'BizTalk Orchestration' ,\n            'carbon'      => 'Carbon'                ,\n            'cpy'         => 'COBOL'                 ,\n            'cobol'       => 'COBOL'                 ,\n            'ccp'         => 'COBOL'                 ,\n            'cbl'         => 'COBOL'                 ,\n            'CBL'         => 'COBOL'                 ,\n            'idc'         => 'C'                     ,\n            'cats'        => 'C'                     ,\n            'c'           => 'C'                     ,\n            'c++'         => 'C++'                   ,\n            'C'           => 'C++'                   ,\n            'cc'          => 'C++'                   ,\n            'ccm'         => 'C++'                   ,\n            'c++m'        => 'C++'                   ,\n            'cppm'        => 'C++'                   ,\n            'cxxm'        => 'C++'                   ,\n            'h++'         => 'C++'                   ,\n            'inl'         => 'C++'                   ,\n            'ipp'         => 'C++'                   ,\n            'ixx'         => 'C++'                   ,\n            'tcc'         => 'C++'                   ,\n            'tpp'         => 'C++'                   ,\n            'cxx'         => 'C++'                   ,\n            'cpp'         => 'C++'                   ,\n            'CPP'         => 'C++'                   ,\n            'cdc'         => 'Cadence'               ,\n            'ccs'         => 'CCS'                   ,\n            'civet'       => 'Civet'                 ,\n            'cvt'         => 'Civet'                 ,\n            'cvtx'        => 'Civet'                 ,\n            'cfc'         => 'ColdFusion CFScript'   ,\n            'cfml'        => 'ColdFusion'            ,\n            'cfm'         => 'ColdFusion'            ,\n            'chpl'        => 'Chapel'                ,\n            'cl'          => 'Lisp/OpenCL'           ,\n            'riemann.config'=> 'Clojure'               ,\n            'hic'         => 'Clojure'               ,\n            'cljx'        => 'Clojure'               ,\n            'cljscm'      => 'Clojure'               ,\n            'cljs.hl'     => 'Clojure'               ,\n            'cl2'         => 'Clojure'               ,\n            'boot'        => 'Clojure'               ,\n            'cj'          => 'Clojure/Cangjie'       ,\n            'clj'         => 'Clojure'               ,\n            'cljs'        => 'ClojureScript'         ,\n            'cljc'        => 'ClojureC'              ,\n            'cls'         => 'Visual Basic/TeX/Apex Class' ,\n            'cmake.in'    => 'CMake'                 ,\n            'CMakeLists.txt' => 'CMake'              ,\n            'cmake'       => 'CMake'                 ,\n            'cob'         => 'COBOL'                 ,\n            'COB'         => 'COBOL'                 ,\n            'cocoa5'      => 'CoCoA 5'               ,\n            'code-workspace' => 'VSCode Workspace'   ,\n            'ql'          => 'CodeQL'                ,\n            'qll'         => 'CodeQL'                ,\n            'c5'          => 'CoCoA 5'               ,\n            'cpkg5'       => 'CoCoA 5'               ,\n            'cocoa5server'=> 'CoCoA 5'               ,\n            'iced'        => 'CoffeeScript'          ,\n            'cjsx'        => 'CoffeeScript'          ,\n            'cakefile'    => 'CoffeeScript'          ,\n            '_coffee'     => 'CoffeeScript'          ,\n            'coffee'      => 'CoffeeScript'          ,\n            'component'   => 'Visualforce Component' ,\n            'cg3'         => 'Constraint Grammar'    ,\n            'rlx'         => 'Constraint Grammar'    ,\n            'Containerfile'  => 'Containerfile'      ,\n            'cr'          => 'Crystal'               ,\n            'cs'          => 'C#/Smalltalk'          ,\n            'designer.cs' => 'C# Designer'           ,\n            'cake'        => 'Cake Build Script'     ,\n            'csh'         => 'C Shell'               ,\n            'cson'        => 'CSON'                  ,\n            'css'         => \"CSS\"                   ,\n            'csv'         => \"CSV\"                   ,\n            'cu'          => 'CUDA'                  ,\n            'cuh'         => 'CUDA'                  , # CUDA header file\n            'c3'          => 'C3'                    ,\n            'c3i'         => 'C3'                    ,\n            'c3t'         => 'C3'                    ,\n            'd'           => 'D/dtrace'              ,\n# in addition, .d can map to init.d files typically written as\n# bash or sh scripts\n            'dfy'         => 'Dafny'                 ,\n            'da'          => 'DAL'                   ,\n            'daml'        => 'DAML'                  ,\n            'dart'        => 'Dart'                  ,\n            'dsc'         => 'DenizenScript'         ,\n            'derw'        => 'Derw'                  ,\n            'def'         => 'Windows Module Definition',\n            'dhall'       => 'dhall'                 ,\n            'dt'          => 'DIET'                  ,\n            'patch'       => 'diff'                  ,\n            'diff'        => 'diff'                  ,\n            'dmap'        => 'NASTRAN DMAP'          ,\n            'sthlp'       => 'Stata'                 ,\n            'matah'       => 'Stata'                 ,\n            'mata'        => 'Stata'                 ,\n            'ihlp'        => 'Stata'                 ,\n            'doh'         => 'Stata'                 ,\n            'ado'         => 'Stata'                 ,\n            'do'          => 'Stata'                 ,\n            'DO'          => 'Stata'                 ,\n            'Dockerfile'  => 'Dockerfile'            ,\n            'dockerfile'  => 'Dockerfile'            ,\n            'pascal'      => 'Pascal'                ,\n            'lpr'         => 'Pascal'                ,\n            'dfm'         => 'Delphi Form'           ,\n            'dpr'         => 'Pascal'                ,\n            'dita'        => 'DITA'                  ,\n            'drl'         => 'Drools'                ,\n            'dtd'         => 'DTD'                   ,\n            'ec'          => 'C'                     ,\n            'ecpp'        => 'ECPP'                  ,\n            'eex'         => 'EEx'                   ,\n            'el'          => 'Lisp'                  ,\n            'elm'         => 'Elm'                   ,\n            'exs'         => 'Elixir Script'         ,\n            'ex'          => 'Elixir'                ,\n            'ecr'         => 'Embedded Crystal'      ,\n            'ejs'         => 'EJS'                   ,\n            'erb'         => 'ERB'                   ,\n            'ERB'         => 'ERB'                   ,\n            'ets'         => 'ArkTs'                 , # OpenHarmonyOS app language\n            'yrl'         => 'Erlang'                ,\n            'xrl'         => 'Erlang'                ,\n            'rebar.lock'  => 'Erlang'                ,\n            'rebar.config.lock'=> 'Erlang'           ,\n            'rebar.config'=> 'Erlang'                ,\n            'emakefile'   => 'Erlang'                ,\n            'app.src'     => 'Erlang'                ,\n            'erl'         => 'Erlang'                ,\n            'exp'         => 'Expect'                ,\n            '4th'         => 'Forth'                 ,\n            'fish'        => 'Fish Shell'            ,\n            'fsl'         => 'Finite State Language' ,\n            'jssm'        => 'Finite State Language' ,\n            'fnl'         => 'Fennel'                ,\n            'forth'       => 'Forth'                 ,\n            'fr'          => 'Forth'                 ,\n            'frt'         => 'Forth'                 ,\n            'fth'         => 'Forth'                 ,\n            'f83'         => 'Forth'                 ,\n            'fb'          => 'Forth'                 ,\n            'fpm'         => 'Forth'                 ,\n            'e4'          => 'Forth'                 ,\n            'rx'          => 'Forth'                 ,\n            'ft'          => 'Forth'                 ,\n            'f77'         => 'Fortran 77'            ,\n            'F77'         => 'Fortran 77'            ,\n            'f90'         => 'Fortran 90'            ,\n            'F90'         => 'Fortran 90'            ,\n            'f95'         => 'Fortran 95'            ,\n            'F95'         => 'Fortran 95'            ,\n            'f'           => 'Fortran 77/Forth'      ,\n            'F'           => 'Fortran 77'            ,\n            'for'         => 'Fortran 77/Forth'      ,\n            'FOR'         => 'Fortran 77'            ,\n            'ftl'         => 'Freemarker Template'   ,\n            'ftn'         => 'Fortran 77'            ,\n            'FTN'         => 'Fortran 77'            ,\n            'f03'         => 'Fortran 2003'          ,\n            'F03'         => 'Fortran 2003'          ,\n            'fmt'         => 'Oracle Forms'          ,\n            'focexec'     => 'Focus'                 ,\n            'fs'          => 'F#/Forth'              ,\n            'fsi'         => 'F#'                    ,\n            'fsx'         => 'F# Script'             ,\n            'fut'         => 'Futhark'               ,\n            'fxml'        => 'FXML'                  ,\n            'gnumakefile' => 'make'                  ,\n            'Gnumakefile' => 'make'                  ,\n            'gd'          => 'GDScript'              ,\n            'gdshader'    => 'Godot Shaders'         ,\n            'vshader'     => 'GLSL'                  ,\n            'vsh'         => 'GLSL'                  ,\n            'vrx'         => 'GLSL'                  ,\n            'gshader'     => 'GLSL'                  ,\n            'glslv'       => 'GLSL'                  ,\n            'geo'         => 'GLSL'                  ,\n            'fshader'     => 'GLSL'                  ,\n            'fsh'         => 'GLSL'                  ,\n            'frg'         => 'GLSL'                  ,\n            'fp'          => 'GLSL'                  ,\n            'fbs'         => 'Flatbuffers'           ,\n            'gjs'         => 'Glimmer JavaScript'    ,\n            'gts'         => 'Glimmer TypeScript'    ,\n            'glsl'        => 'GLSL'                  ,\n            'graphqls'    => 'GraphQL'               ,\n            'gql'         => 'GraphQL'               ,\n            'graphql'     => 'GraphQL'               ,\n            'vert'        => 'GLSL'                  ,\n            'tesc'        => 'GLSL'                  ,\n            'tese'        => 'GLSL'                  ,\n            'geom'        => 'GLSL'                  ,\n            'feature'     => 'Cucumber'              ,\n            'frag'        => 'GLSL'                  ,\n            'comp'        => 'GLSL'                  ,\n            'g'           => 'ANTLR Grammar'         ,\n            'g4'          => 'ANTLR Grammar'         ,\n            'gleam'       => 'Gleam'                 ,\n            'go'          => 'Go'                    ,\n            'ʕ◔ϖ◔ʔ'       => 'Go'                    ,\n            'gsp'         => 'Grails'                ,\n            'jenkinsfile' => 'Groovy'                ,\n            'gvy'         => 'Groovy'                ,\n            'gtpl'        => 'Groovy'                ,\n            'grt'         => 'Groovy'                ,\n            'groovy'      => 'Groovy'                ,\n            'gant'        => 'Groovy'                ,\n            'gradle'      => 'Gradle'                ,\n            'gradle.kts'  => 'Gradle'                ,\n            'h'           => 'C/C++ Header'          ,\n            'H'           => 'C/C++ Header'          ,\n            'hh'          => 'C/C++ Header'          ,\n            'hpp'         => 'C/C++ Header'          ,\n            'hxx'         => 'C/C++ Header'          ,\n            'hb'          => 'Harbour'               ,\n            'hrl'         => 'Erlang'                ,\n            'tfvars'      => 'HCL'                   ,\n            'hcl'         => 'HCL'                   ,\n            'tf'          => 'HCL'                   ,\n            'nomad'       => 'HCL'                   ,\n            'hlsli'       => 'HLSL'                  ,\n            'fxh'         => 'HLSL'                  ,\n            'hlsl'        => 'HLSL'                  ,\n            'shader'      => 'HLSL'                  ,\n            'cg'          => 'HLSL'                  ,\n            'cginc'       => 'HLSL'                  ,\n            'haml.deface' => 'Haml'                  ,\n            'haml'        => 'Haml'                  ,\n            'handlebars'  => 'Handlebars'            ,\n            'hbs'         => 'Handlebars'            ,\n            'hbm.xml'     => 'Hibernate'             ,\n            'ha'          => 'Hare'                  ,\n            'hxsl'        => 'Haxe'                  ,\n            'hx'          => 'Haxe'                  ,\n            'HC'          => 'HolyC'                 ,\n            'hoon'        => 'Hoon'                  ,\n            'xht'         => 'HTML'                  ,\n            'html.hl'     => 'HTML'                  ,\n            'htm'         => 'HTML'                  ,\n            'html'        => 'HTML'                  ,\n            'heex'        => 'HTML EEx'              ,\n            'hsc'         => 'Haskell'               ,\n            'hs'          => 'Haskell'               ,\n            'lhs'         => 'Haskell'               ,\n            'hs-boot'     => 'Haskell Boot'          ,\n            'lhs-boot'    => 'Haskell Boot'          ,\n            'i3'          => 'Modula3'               ,\n            'ice'         => 'Slice'                 ,\n            'icl'         => 'Clean'                 ,\n            'dcl'         => 'Clean'                 ,\n            'dlm'         => 'IDL'                   ,\n            'idl'         => 'IDL'                   ,\n            'idr'         => 'Idris'                 ,\n            'lidr'        => 'Literate Idris'        ,\n            'imba'        => 'Imba'                  ,\n            'prefs'       => 'INI'                   ,\n            'lektorproject'=> 'INI'                  ,\n            'buildozer.spec'=> 'INI'                 ,\n            'ini'         => 'INI'                   ,\n            'editorconfig'=> 'INI'                   ,\n            'ism'         => 'InstallShield'         ,\n            'ipl'         => 'IPL'                   ,\n            'pro'         => 'IDL/Qt Project/Prolog/ProGuard' ,\n            'ig'          => 'Modula3'               ,\n            'il'          => 'SKILL/.NET IL'         ,\n            'ils'         => 'SKILL++'               ,\n            'inc'         => 'PHP/Pascal/Fortran/Pawn/BitBake' ,\n            'ino'         => 'Arduino Sketch'        ,\n            'ipf'         => 'Igor Pro'              ,\n           #'pde'         => 'Arduino Sketch'        , # pre 1.0\n            'pde'         => 'Processing'            , # pre 1.0\n            'itk'         => 'Tcl/Tk'                ,\n            'java'        => 'Java'                  ,\n            'jcl'         => 'JCL'                   , # IBM Job Control Lang.\n            'jl'          => 'Lisp/Julia'            ,\n            'jai'         => 'Jai'                   ,\n            'janet'       => 'Janet'                 ,\n            'xsjslib'     => 'JavaScript'            ,\n            'xsjs'        => 'JavaScript'            ,\n            'ssjs'        => 'JavaScript'            ,\n            'sjs'         => 'JavaScript'            ,\n            'pac'         => 'JavaScript'            ,\n            'njs'         => 'JavaScript'            ,\n            'mjs'         => 'JavaScript'            ,\n            'cjs'         => 'JavaScript'            ,\n            'jss'         => 'JavaScript'            ,\n            'jsm'         => 'JavaScript'            ,\n            'jsfl'        => 'JavaScript'            ,\n            'jscad'       => 'JavaScript'            ,\n            'jsb'         => 'JavaScript'            ,\n            'jakefile'    => 'JavaScript'            ,\n            'jake'        => 'JavaScript'            ,\n            'bones'       => 'JavaScript'            ,\n            '_js'         => 'JavaScript'            ,\n            'js'          => 'JavaScript'            ,\n            'es6'         => 'JavaScript'            ,\n            'jrxml'       => 'Jasper Report XML/Template' ,\n            'jsf'         => 'JavaServer Faces'      ,\n            'jsx'         => 'JSX'                   ,\n            'xhtml'       => 'XHTML'                 ,\n            'j2'          => 'Jinja Template'        ,\n            'jinja'       => 'Jinja Template'        ,\n            'jinja2'      => 'Jinja Template'        ,\n            'yyp'         => 'JSON'                  ,\n            'webmanifest' => 'JSON'                  ,\n            'webapp'      => 'JSON'                  ,\n            'topojson'    => 'JSON'                  ,\n            'tfstate.backup'=> 'JSON'                  ,\n            'tfstate'     => 'JSON'                  ,\n            'mcmod.info'  => 'JSON'                  ,\n            'mcmeta'      => 'JSON'                  ,\n            'json-tmlanguage'=> 'JSON'                  ,\n            'jsonl'       => 'JSON'                  ,\n            'har'         => 'JSON'                  ,\n            'gltf'        => 'JSON'                  ,\n            'geojson'     => 'JSON'                  ,\n            'composer.lock'=> 'JSON'                  ,\n            'avsc'        => 'JSON'                  ,\n            'watchmanconfig'=> 'JSON'                  ,\n            'tern-project'=> 'JSON'                  ,\n            'tern-config' => 'JSON'                  ,\n            'htmlhintrc'  => 'JSON'                  ,\n            'arcconfig'   => 'JSON'                  ,\n            'json'        => 'JSON'                  ,\n            'json5'       => 'JSON5'                 ,\n            'jsonnet'     => 'Jsonnet'               ,\n            'jsp'         => 'JSP'                   , # Java server pages\n            'jspf'        => 'JSP'                   , # Java server pages\n            'tld'         => 'JSP Tag Library Definition',\n            'junos'       => 'Juniper Junos'         ,\n            'just'        => 'Justfile'              ,\n            'vm'          => 'Velocity Template Language' ,\n            'kv'          => 'kvlang'                ,\n            'ksc'         => 'Kermit'                ,\n            'ksh'         => 'Korn Shell'            ,\n            'ktm'         => 'Kotlin'                ,\n            'kt'          => 'Kotlin'                ,\n            'kts'         => 'Kotlin'                ,\n            'hlean'       => 'Lean'                  ,\n            'lean'        => 'Lean'                  ,\n            'lex'         => 'lex'                   ,\n            'l'           => 'lex'                   ,\n            'ld'          => 'Linker Script'         ,\n            'lb.xml'      => 'Liquibase'             ,\n            'lem'         => 'Lem'                   ,\n            'less'        => 'LESS'                  ,\n            'lfe'         => 'LFE'                   ,\n            'liquid'      => 'liquid'                ,\n            'lsp'         => 'Lisp'                  ,\n            'lisp'        => 'Lisp'                  ,\n            'll'          => 'LLVM IR'               ,\n            'lgt'         => 'Logtalk'               ,\n            'logtalk'     => 'Logtalk'               ,\n            'lp'          => 'AnsProlog'             ,  # Answer Set Programming / clingo\n            'wlua'        => 'Lua'                   ,\n            'rbxs'        => 'Lua'                   ,\n            'pd_lua'      => 'Lua'                   ,\n            'p8'          => 'Lua'                   ,\n            'nse'         => 'Lua'                   ,\n            'lua'         => 'Lua'                   ,\n            'luau'        => 'Luau'                  ,\n            'm3'          => 'Modula3'               ,\n            'm4'          => 'm4'                    ,\n            'makefile'    => 'make'                  ,\n            'Makefile'    => 'make'                  ,\n            'mao'         => 'Mako'                  ,\n            'mako'        => 'Mako'                  ,\n            'workbook'    => 'Markdown'              ,\n            'ronn'        => 'Markdown'              ,\n            'mkdown'      => 'Markdown'              ,\n            'mkdn'        => 'Markdown'              ,\n            'mkd'         => 'Markdown'              ,\n            'mdx'         => 'Markdown'              ,\n            'mdwn'        => 'Markdown'              ,\n            'mdown'       => 'Markdown'              ,\n            'markdown'    => 'Markdown'              ,\n            'contents.lr' => 'Markdown'              ,\n            'md'          => 'Markdown'              ,\n            'org'         => 'Org Mode'              ,\n            'mc'          => 'Windows Message File'  ,\n            'met'         => 'Teamcenter met'        ,\n            'mg'          => 'Modula3'               ,\n            'mojom'       => 'Mojom'                 ,\n            'mojo'        => 'Mojo'                  ,\n            '🔥'          => 'Mojo'                  ,\n            'mbt'         => 'MoonBit'               ,\n            'mbti'        => 'MoonBit'               ,\n            'mbtx'        => 'MoonBit'               ,\n            'mbty'        => 'MoonBit'               ,\n            'meson.build' => 'Meson'                 ,\n            'metal'       => 'Metal'                 ,\n            'mk'          => 'make'                  ,\n#           'mli'         => 'ML'                    , # ML not implemented\n#           'ml'          => 'ML'                    ,\n            'ml4'         => 'OCaml'                 ,\n            'eliomi'      => 'OCaml'                 ,\n            'eliom'       => 'OCaml'                 ,\n            'ml'          => 'OCaml'                 ,\n            'mli'         => 'OCaml'                 ,\n            'mly'         => 'OCaml'                 ,\n            'mll'         => 'OCaml'                 ,\n            'm'           => 'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' ,\n            'mm'          => 'Objective-C++'         ,\n            'msg'         => 'Gencat NLS'            ,\n            'magik'       => 'Magik'                 ,\n            'nbp'         => 'Mathematica'           ,\n            'mathematica' => 'Mathematica'           ,\n            'ma'          => 'Mathematica'           ,\n            'cdf'         => 'Mathematica'           ,\n            'mt'          => 'Mathematica'           ,\n            'wl'          => 'Mathematica'           ,\n            'wlt'         => 'Mathematica'           ,\n            'mo'          => 'Modelica'              ,\n            'mustache'    => 'Mustache'              ,\n            'wdproj'      => 'MSBuild script'        ,\n            'csproj'      => 'MSBuild script'        ,\n            'vcproj'      => 'MSBuild script'        ,\n            'wixproj'     => 'MSBuild script'        ,\n            'btproj'      => 'MSBuild script'        ,\n            'msbuild'     => 'MSBuild script'        ,\n            'sln'         => 'Visual Studio Solution',\n            'mps'         => 'MUMPS'                 ,\n            'mth'         => 'Teamcenter mth'        ,\n            'n'           => 'Nemerle'               ,\n            'nlogo'       => 'NetLogo'               ,\n            'nls'         => 'NetLogo'               ,\n            'nf'          => 'Nextflow'              ,\n            'ncl'         => 'Nickel'                ,\n            'nims'        => 'Nim'                   ,\n            'nimrod'      => 'Nim'                   ,\n            'nimble'      => 'Nim'                   ,\n            'nim.cfg'     => 'Nim'                   ,\n            'nim'         => 'Nim'                   ,\n            'nix'         => 'Nix'                   ,\n            'nu'          => 'Nushell'               ,\n            'nuon'        => 'Nushell Object Notation',\n            'nut'         => 'Squirrel'              ,\n            'njk'         => 'Nunjucks'              ,\n            'odin'        => 'Odin'                  ,\n            'oscript'     => 'LiveLink OScript'      ,\n            'bod'         => 'Oracle PL/SQL'         ,\n            'bdy'         => 'Oracle PL/SQL'         ,\n            'spc'         => 'Oracle PL/SQL'         ,\n            'fnc'         => 'Oracle PL/SQL'         ,\n            'prc'         => 'Oracle PL/SQL'         ,\n            'trg'         => 'Oracle PL/SQL'         ,\n            'p'           => 'Pascal/Pawn'           ,\n            'pad'         => 'Ada'                   , # Oracle Ada preprocessor\n            'page'        => 'Visualforce Page'      ,\n            'pas'         => 'Pascal'                ,\n            'pcc'         => 'C++'                   , # Oracle C++ preprocessor\n            'rexfile'     => 'Perl'                  ,\n            'psgi'        => 'Perl'                  ,\n            'ph'          => 'Perl'                  ,\n            'makefile.pl' => 'Perl'                  ,\n            'cpanfile'    => 'Perl'                  ,\n            'al'          => 'Perl'                  ,\n            'ack'         => 'Perl'                  ,\n            'perl'        => 'Perl'                  ,\n            'pfo'         => 'Fortran 77'            ,\n            'pgc'         => 'C'                     , # Postgres embedded C/C++\n            'phpt'        => 'PHP'                   ,\n            'phps'        => 'PHP'                   ,\n            'phakefile'   => 'PHP'                   ,\n            'ctp'         => 'PHP'                   ,\n            'aw'          => 'PHP'                   ,\n            'php_cs.dist' => 'PHP'                   ,\n            'php_cs'      => 'PHP'                   ,\n            'php3'        => 'PHP'                   ,\n            'php4'        => 'PHP'                   ,\n            'php5'        => 'PHP'                   ,\n            'php'         => 'PHP'                   ,\n            'phtml'       => 'PHP'                   ,\n            'pig'         => 'Pig Latin'             ,\n            'plh'         => 'Perl'                  ,\n            'pl'          => 'Perl/Prolog'           ,\n            'PL'          => 'Perl/Prolog'           ,\n            'p6'          => 'Raku/Prolog'           ,\n            'P6'          => 'Raku/Prolog'           ,\n            'plx'         => 'Perl'                  ,\n            'pm'          => 'Perl'                  ,\n            'pm6'         => 'Raku'                  ,\n            'raku'        => 'Raku'                  ,\n            'rakumod'     => 'Raku'                  ,\n            'pom.xml'     => 'Maven'                 ,\n            'pom'         => 'Maven'                 ,\n            'scad'        => 'OpenSCAD'              ,\n            'yap'         => 'Prolog'                ,\n            'prolog'      => 'Prolog'                ,\n            'P'           => 'Prolog'                ,\n            'pp'          => 'Pascal/Puppet'         ,\n            'viw'         => 'SQL'                   ,\n            'udf'         => 'SQL'                   ,\n            'tab'         => 'SQL'                   ,\n            'mysql'       => 'SQL'                   ,\n            'cql'         => 'SQL'                   ,\n            'psql'        => 'SQL'                   ,\n            'xpy'         => 'Python'                ,\n            'wsgi'        => 'Python'                ,\n            'wscript'     => 'Python'                ,\n            'workspace'   => 'Python'                ,\n            'tac'         => 'Python'                ,\n            'snakefile'   => 'Python'                ,\n            'sconstruct'  => 'Python'                ,\n            'sconscript'  => 'Python'                ,\n            'pyt'         => 'Python'                ,\n            'pyp'         => 'Python'                ,\n            'pyi'         => 'Python'                ,\n            'pyde'        => 'Python'                ,\n            'py3'         => 'Python'                ,\n            'lmi'         => 'Python'                ,\n            'gypi'        => 'Python'                ,\n            'gyp'         => 'Python'                ,\n            'build.bazel' => 'Python'                ,\n            'buck'        => 'Python'                ,\n            'gclient'     => 'Python'                ,\n            'py'          => 'Python'                ,\n            'pyw'         => 'Python'                ,\n            'ipynb'       => 'Jupyter Notebook'      ,\n            'pyj'         => 'RapydScript'           ,\n            'pxi'         => 'Cython'                ,\n            'pxd'         => 'Cython'                ,\n            'pyx'         => 'Cython'                ,\n            'qbs'         => 'QML'                   ,\n            'qml'         => 'QML'                   ,\n            'watchr'      => 'Ruby'                  ,\n            'vagrantfile' => 'Ruby'                  ,\n            'thorfile'    => 'Ruby'                  ,\n            'thor'        => 'Ruby'                  ,\n            'snapfile'    => 'Ruby'                  ,\n            'ru'          => 'Ruby'                  ,\n            'rbx'         => 'Ruby'                  ,\n            'rbw'         => 'Ruby'                  ,\n            'rbuild'      => 'Ruby'                  ,\n            'rabl'        => 'Ruby'                  ,\n            'puppetfile'  => 'Ruby'                  ,\n            'podfile'     => 'Ruby'                  ,\n            'mspec'       => 'Ruby'                  ,\n            'mavenfile'   => 'Ruby'                  ,\n            'jbuilder'    => 'Ruby'                  ,\n            'jarfile'     => 'Ruby'                  ,\n            'guardfile'   => 'Ruby'                  ,\n            'god'         => 'Ruby'                  ,\n            'gemspec'     => 'Ruby'                  ,\n            'gemfile.lock'=> 'Ruby'                  ,\n            'gemfile'     => 'Ruby'                  ,\n            'fastfile'    => 'Ruby'                  ,\n            'eye'         => 'Ruby'                  ,\n            'deliverfile' => 'Ruby'                  ,\n            'dangerfile'  => 'Ruby'                  ,\n            'capfile'     => 'Ruby'                  ,\n            'buildfile'   => 'Ruby'                  ,\n            'builder'     => 'Ruby'                  ,\n            'brewfile'    => 'Ruby'                  ,\n            'berksfile'   => 'Ruby'                  ,\n            'appraisals'  => 'Ruby'                  ,\n            'pryrc'       => 'Ruby'                  ,\n            'irbrc'       => 'Ruby'                  ,\n            'rb'          => 'Ruby'                  ,\n            'podspec'     => 'Ruby'                  ,\n            'rake'        => 'Ruby'                  ,\n         #  'resx'        => 'ASP.NET'               ,\n            'rex'         => 'Oracle Reports'        ,\n            'pprx'        => 'Rexx'                  ,\n            'rexx'        => 'Rexx'                  ,\n            'rhtml'       => 'Ruby HTML'             ,\n            'circom'      => 'Circom'                ,\n            'cairo'       => 'Cairo'                 ,\n            'clar'        => 'Clarity'                ,\n            'rs.in'       => 'Rust'                  ,\n            'rs'          => 'Rust'                  ,\n            'rst.txt'     => 'reStructuredText'      ,\n            'rest.txt'    => 'reStructuredText'      ,\n            'rest'        => 'reStructuredText'      ,\n            'rst'         => 'reStructuredText'      ,\n            's'           => 'Assembly'              ,\n            'S'           => 'Assembly'              ,\n            'SCA'         => 'Visual Fox Pro'        ,\n            'sca'         => 'Visual Fox Pro'        ,\n            'sbt'         => 'Scala'                 ,\n            'kojo'        => 'Scala'                 ,\n            'scala'       => 'Scala'                 ,\n            'sbl'         => 'Softbridge Basic'      ,\n            'SBL'         => 'Softbridge Basic'      ,\n            'sed'         => 'sed'                   ,\n            'sp'          => 'SparForte'             ,\n            'sol'         => 'Solidity'              ,\n            'p4'          => 'P4'                    ,\n            'ses'         => 'Patran Command Language'   ,\n            'pcl'         => 'Patran Command Language'   ,\n            'pwn'         => 'Pawn'                  ,\n            'pawn'        => 'Pawn'                  ,\n            'pek'         => 'Pek'                   ,\n            'peg'         => 'PEG'                   ,\n            'pegjs'       => 'peg.js'                ,\n            'peggy'       => 'peggy'                 ,\n            'pest'        => 'Pest'                  ,\n            'pkl'         => 'Pkl'                   ,\n            'prisma'      => 'Prisma Schema'         ,\n            'tspeg'       => 'tspeg'                 ,\n            'jspeg'       => 'tspeg'                 ,\n            'pl1'         => 'PL/I'                  ,\n            'plm'         => 'PL/M'                  ,\n            'lit'         => 'PL/M'                  ,\n            'iuml'        => 'PlantUML'              ,\n            'pu'          => 'PlantUML'              ,\n            'puml'        => 'PlantUML'              ,\n            'plantuml'    => 'PlantUML'              ,\n            'wsd'         => 'PlantUML'              ,\n            'properties'  => 'Properties'            ,\n            'po'          => 'PO File'               ,\n            'pony'        => 'Pony'                  ,\n            'pbt'         => 'PowerBuilder'          ,\n            'sra'         => 'PowerBuilder'          ,\n            'srf'         => 'PowerBuilder'          ,\n            'srm'         => 'PowerBuilder'          ,\n            'srs'         => 'PowerBuilder'          ,\n            'sru'         => 'PowerBuilder'          ,\n            'srw'         => 'PowerBuilder'          ,\n            'jade'        => 'Pug'                   ,\n            'pug'         => 'Pug'                   ,\n            'purs'        => 'PureScript'            ,\n            'prefab'      => 'Unity-Prefab'          ,\n            'proto'       => 'Protocol Buffers'      ,\n            'mat'         => 'Unity-Prefab'          ,\n            'ps1'         => 'PowerShell'            ,\n            'psd1'        => 'PowerShell'            ,\n            'psm1'        => 'PowerShell'            ,\n            'prql'        => 'PRQL'                  ,\n            'rsx'         => 'R'                     ,\n            'rd'          => 'R'                     ,\n            'expr-dist'   => 'R'                     ,\n            'rprofile'    => 'R'                     ,\n            'R'           => 'R'                     ,\n            'r'           => 'R'                     ,\n            'raml'        => 'RAML'                  ,\n            'ring'        => 'Ring'                  ,\n            'rh'          => 'Ring'                  ,\n            'rform'       => 'Ring'                  ,\n            'rktd'        => 'Racket'                ,\n            'rkt'         => 'Racket'                ,\n            'rktl'        => 'Racket'                ,\n            'Rmd'         => 'Rmd'                   ,\n            'rhai'        => 'Rhai'                  ,\n            're'          => 'ReasonML'              ,\n            'rei'         => 'ReasonML'              ,\n            'res'         => 'ReScript'              ,\n            'resi'        => 'ReScript'              ,\n            'scrbl'       => 'Racket'                ,\n            'sps'         => 'Scheme'                ,\n            'sc'          => 'Scheme'                ,\n            'ss'          => 'Scheme'                ,\n            'scm'         => 'Scheme'                ,\n            'sch'         => 'Scheme'                ,\n            'sls'         => 'Scheme/SaltStack'      ,\n            'sld'         => 'Scheme'                ,\n            'robot'       => 'RobotFramework'        ,\n            'rc'          => 'Windows Resource File' ,\n            'rc2'         => 'Windows Resource File' ,\n            'sas'         => 'SAS'                   ,\n            'sass'        => 'Sass'                  ,\n            'scss'        => 'SCSS'                  ,\n            'sh'          => 'Bourne Shell'          ,\n            'smarty'      => 'Smarty'                ,\n            'sml'         => 'Standard ML'           ,\n            'sig'         => 'Standard ML'           ,\n            'fun'         => 'Standard ML'           ,\n            'slim'        => 'Slim'                  ,\n            'e'           => 'Specman e'             ,\n            'sql'         => 'SQL'                   ,\n            'SQL'         => 'SQL'                   ,\n            'sproc.sql'   => 'SQL Stored Procedure'  ,\n            'spoc.sql'    => 'SQL Stored Procedure'  ,\n            'spc.sql'     => 'SQL Stored Procedure'  ,\n            'udf.sql'     => 'SQL Stored Procedure'  ,\n            'data.sql'    => 'SQL Data'              ,\n            'sss'         => 'SugarSS'               ,\n            'slint'       => 'Slint'                 ,\n            'st'          => 'Smalltalk'             ,\n            'rules'       => 'Snakemake'             ,\n            'smk'         => 'Snakemake'             ,\n            'styl'        => 'Stylus'                ,\n            'surql'       => 'SurrealQL'             ,\n            'i'           => 'SWIG'                  ,\n            'svelte'      => 'Svelte'                ,\n            'sv'          => 'Verilog-SystemVerilog' ,\n            'svh'         => 'Verilog-SystemVerilog' ,\n            'svg'         => 'SVG'                   ,\n            'SVG'         => 'SVG'                   ,\n            'v'           => 'Verilog-SystemVerilog/Coq' ,\n            'td'          => 'TableGen'              ,\n            'tcl'         => 'Tcl/Tk'                ,\n            'tcsh'        => 'C Shell'               ,\n            'tk'          => 'Tcl/Tk'                ,\n            'teal'        => 'TEAL'                  ,\n            'templ'       => 'Templ'                 ,\n            'mkvi'        => 'TeX'                   ,\n            'mkiv'        => 'TeX'                   ,\n            'mkii'        => 'TeX'                   ,\n            'ltx'         => 'TeX'                   ,\n            'lbx'         => 'TeX'                   ,\n            'ins'         => 'TeX'                   ,\n            'cbx'         => 'TeX'                   ,\n            'bib'         => 'TeX'                   ,\n            'bbx'         => 'TeX'                   ,\n            'aux'         => 'TeX'                   ,\n            'tex'         => 'TeX'                   , # TeX, LaTex, MikTex, ..\n            'toml'        => 'TOML'                  ,\n            'sty'         => 'TeX'                   ,\n#           'cls'         => 'TeX'                   ,\n            'dtx'         => 'TeX'                   ,\n            'bst'         => 'TeX'                   ,\n            'txt'         => 'Text'                  ,\n            'text'        => 'Text'                  ,\n            'tres'        => 'Godot Resource'        ,\n            'tscn'        => 'Godot Scene'           ,\n            'thrift'      => 'Thrift'                ,\n            'tla'         => 'TLA+'                  ,\n            'tpl'         => 'Smarty'                ,\n            'trigger'     => 'Apex Trigger'          ,\n            'ttcn'        => 'TTCN'                  ,\n            'ttcn2'       => 'TTCN'                  ,\n            'ttcn3'       => 'TTCN'                  ,\n            'ttcnpp'      => 'TTCN'                  ,\n            'sdl'         => 'TNSDL'                 ,\n            'ssc'         => 'TNSDL'                 ,\n            'sdt'         => 'TNSDL'                 ,\n            'spd'         => 'TNSDL'                 ,\n            'sst'         => 'TNSDL'                 ,\n            'rou'         => 'TNSDL'                 ,\n            'cin'         => 'TNSDL'                 ,\n            'cii'         => 'TNSDL'                 ,\n            'interface'   => 'TNSDL'                 ,\n            'in1'         => 'TNSDL'                 ,\n            'in2'         => 'TNSDL'                 ,\n            'in3'         => 'TNSDL'                 ,\n            'in4'         => 'TNSDL'                 ,\n            'inf'         => 'TNSDL'                 ,\n            'tpd'         => 'TITAN Project File Information',\n            'ts'          => 'TypeScript/Qt Linguist',\n            'cts'         => 'TypeScript'            ,\n            'mts'         => 'TypeScript'            ,\n            'tsx'         => 'TypeScript'            ,\n            'tss'         => 'Titanium Style Sheet'  ,\n            'twig'        => 'Twig'                  ,\n            'typ'         => 'Typst'                 ,\n            'um'          => 'Umka'                  ,\n            'uss'         => 'USS'                   ,\n            'uxml'        => 'UXML'                  ,\n            'ui'          => 'XML-Qt-GTK/Glade'      ,\n            'glade'       => 'Glade'                 ,\n            'vala'        => 'Vala'                  ,\n            'vapi'        => 'Vala Header'           ,\n            'vhw'         => 'VHDL'                  ,\n            'vht'         => 'VHDL'                  ,\n            'vhs'         => 'VHDL'                  ,\n            'vho'         => 'VHDL'                  ,\n            'vhi'         => 'VHDL'                  ,\n            'vhf'         => 'VHDL'                  ,\n            'vhd'         => 'VHDL'                  ,\n            'VHD'         => 'VHDL'                  ,\n            'vhdl'        => 'VHDL'                  ,\n            'VHDL'        => 'VHDL'                  ,\n            'bas'         => 'Visual Basic'          ,\n            'BAS'         => 'Visual Basic'          ,\n            'ctl'         => 'Visual Basic'          ,\n            'dsr'         => 'Visual Basic'          ,\n            'Dsr'         => 'Visual Basic'          ,\n            'frm'         => 'Visual Basic'          ,\n            'frx'         => 'Visual Basic'          ,\n            'FRX'         => 'Visual Basic'          ,\n            'vba'         => 'VBA'                   ,\n            'VBA'         => 'VBA'                   ,\n            'vbhtml'      => 'Visual Basic .NET'     ,\n            'VBHTML'      => 'Visual Basic .NET'     ,\n            'vbproj'      => 'Visual Basic .NET'     ,\n            'vbp'         => 'Visual Basic'          , # .vbp - autogenerated\n            'vbs'         => 'VBScript'              ,\n            'VBS'         => 'VBScript'              ,\n            'vb'          => 'Visual Basic .NET'     ,\n            'VB'          => 'Visual Basic .NET'     ,\n            'vbw'         => 'Visual Basic'          , # .vbw - autogenerated\n            'vue'         => 'Vuejs Component'       ,\n            'vy'          => 'Vyper'                 ,\n            'webinfo'     => 'ASP.NET'               ,\n            'wsdl'        => 'Web Services Description',\n            'x'           => 'Logos'                 ,\n            'xm'          => 'Logos'                 ,\n            'xpo'         => 'X++'                   , # Microsoft Dynamics AX 4.0 export format\n            'xmi'         => 'XMI'                   ,\n            'XMI'         => 'XMI'                   ,\n            'zcml'        => 'XML'                   ,\n            'xul'         => 'XML'                   ,\n            'xspec'       => 'XML'                   ,\n            'xproj'       => 'XML'                   ,\n            'xml.dist'    => 'XML'                   ,\n            'xliff'       => 'XML'                   ,\n            'xlf'         => 'XML'                   ,\n            'xib'         => 'XML'                   ,\n            'xacro'       => 'XML'                   ,\n            'x3d'         => 'XML'                   ,\n            'wsf'         => 'XML'                   ,\n            'web.release.config'=> 'XML'             ,\n            'web.debug.config'=> 'XML'               ,\n            'web.config'  => 'XML'                   ,\n            'wxml'        => 'WXML'                  ,\n            'wxss'        => 'WXSS'                  ,\n            'vxml'        => 'XML'                   ,\n            'vstemplate'  => 'XML'                   ,\n            'vssettings'  => 'XML'                   ,\n            'vsixmanifest'=> 'XML'                   ,\n            'vcxproj'     => 'XML'                   ,\n            'ux'          => 'XML'                   ,\n            'urdf'        => 'XML'                   ,\n            'tmtheme'     => 'XML'                   ,\n            'tmsnippet'   => 'XML'                   ,\n            'tmpreferences'=> 'XML'                  ,\n            'tmlanguage'  => 'XML'                   ,\n            'tml'         => 'XML'                   ,\n            'tmcommand'   => 'XML'                   ,\n            'targets'     => 'XML'                   ,\n            'sublime-snippet'=> 'XML'                   ,\n            'sttheme'     => 'XML'                   ,\n            'storyboard'  => 'XML'                   ,\n            'srdf'        => 'XML'                   ,\n            'shproj'      => 'XML'                   ,\n            'sfproj'      => 'XML'                   ,\n            'settings.stylecop'=> 'XML'                   ,\n            'scxml'       => 'XML'                   ,\n            'rss'         => 'XML'                   ,\n            'resx'        => 'XML'                   ,\n            'rdf'         => 'XML'                   ,\n            'pt'          => 'XML'                   ,\n            'psc1'        => 'XML'                   ,\n            'ps1xml'      => 'XML'                   ,\n            'props'       => 'XML'                   ,\n            'proj'        => 'XML'                   ,\n            'plist'       => 'XML'                   ,\n            'pkgproj'     => 'XML'                   ,\n            'packages.config'=> 'XML'                   ,\n            'osm'         => 'XML'                   ,\n            'odd'         => 'XML'                   ,\n            'nuspec'      => 'XML'                   ,\n            'nuget.config'=> 'XML'                   ,\n            'nproj'       => 'XML'                   ,\n            'ndproj'      => 'XML'                   ,\n            'natvis'      => 'XML'                   ,\n            'mjml'        => 'XML'                   ,\n            'mdpolicy'    => 'XML'                   ,\n            'launch'      => 'XML'                   ,\n            'kml'         => 'XML'                   ,\n            'jsproj'      => 'XML'                   ,\n            'jelly'       => 'XML'                   ,\n            'ivy'         => 'XML'                   ,\n            'iml'         => 'XML'                   ,\n            'grxml'       => 'XML'                   ,\n            'gmx'         => 'XML'                   ,\n            'fsproj'      => 'XML'                   ,\n            'filters'     => 'XML'                   ,\n            'dotsettings' => 'XML'                   ,\n            'dll.config'  => 'XML'                   ,\n            'ditaval'     => 'XML'                   ,\n            'ditamap'     => 'XML'                   ,\n            'depproj'     => 'XML'                   ,\n            'ct'          => 'XML'                   ,\n            'csl'         => 'XML'                   ,\n            'csdef'       => 'XML'                   ,\n            'cscfg'       => 'XML'                   ,\n            'cproject'    => 'XML'                   ,\n            'clixml'      => 'XML'                   ,\n            'ccxml'       => 'XML'                   ,\n            'ccproj'      => 'XML'                   ,\n            'builds'      => 'XML'                   ,\n            'axml'        => 'XML'                   ,\n            'app.config'  => 'XML'                   ,\n            'ant'         => 'XML'                   ,\n            'admx'        => 'XML'                   ,\n            'adml'        => 'XML'                   ,\n            'project'     => 'XML'                   ,\n            'classpath'   => 'XML'                   ,\n            'xml'         => 'XML'                   ,\n            'XML'         => 'XML'                   ,\n            'mxml'        => 'MXML'                  ,\n            'xml.builder' => 'builder'               ,\n            'build'       => 'NAnt script'           ,\n            'vim'         => 'vim script'            ,\n            'swift'       => 'Swift'                 ,\n            'xaml'        => 'XAML'                  ,\n            'wast'        => 'WebAssembly'           ,\n            'wat'         => 'WebAssembly'           ,\n            'wgsl'        => 'WGSL'                  ,\n            'wxs'         => 'WiX source'            ,\n            'wxi'         => 'WiX include'           ,\n            'wxl'         => 'WiX string localization' ,\n            'prw'         => 'xBase'                 ,\n            'prg'         => 'xBase'                 ,\n            'ch'          => 'xBase Header'          ,\n            'xqy'         => 'XQuery'                ,\n            'xqm'         => 'XQuery'                ,\n            'xql'         => 'XQuery'                ,\n            'xq'          => 'XQuery'                ,\n            'xquery'      => 'XQuery'                ,\n            'xsd'         => 'XSD'                   ,\n            'XSD'         => 'XSD'                   ,\n            'xslt'        => 'XSLT'                  ,\n            'XSLT'        => 'XSLT'                  ,\n            'xsl'         => 'XSLT'                  ,\n            'XSL'         => 'XSLT'                  ,\n            'xtend'       => 'Xtend'                 ,\n            'yacc'        => 'yacc'                  ,\n            'y'           => 'yacc'                  ,\n            'yml.mysql'   => 'YAML'                  ,\n            'yaml-tmlanguage'=> 'YAML'                  ,\n            'syntax'      => 'YAML'                  ,\n            'sublime-syntax'=> 'YAML'                  ,\n            'rviz'        => 'YAML'                  ,\n            'reek'        => 'YAML'                  ,\n            'mir'         => 'YAML'                  ,\n            'glide.lock'  => 'YAML'                  ,\n            'gemrc'       => 'YAML'                  ,\n            'clang-tidy'  => 'YAML'                  ,\n            'clang-format'=> 'YAML'                  ,\n            'yaml'        => 'YAML'                  ,\n            'yml'         => 'YAML'                  ,\n            'yang'        => 'Yang'                  ,\n            'yarn'        => 'Yarn'                  ,\n            'zig'         => 'Zig'                   ,\n            'zsh'         => 'zsh'                   ,\n            'rego'        => 'Rego'                  ,\n            'bb'          => 'BitBake'               ,\n            'bbappend'    => 'BitBake'               ,\n            'bbclass'     => 'BitBake'               ,\n            'conf'        => 'Unknown/BitBake'       ,\n            );\n# 1}}}\n%{$rh_Language_by_Script}    = (             # {{{1\n            'awk'       => 'awk'                   ,\n            'bash'      => 'Bourne Again Shell'    ,\n            'bc'        => 'bc'                    ,# calculator\n            'crystal'   => 'Crystal'               ,\n            'csh'       => 'C Shell'               ,\n            'dmd'       => 'D'                     ,\n            'dtrace'    => 'dtrace'                ,\n            'escript'   => 'Erlang'                ,\n            'groovy'    => 'Groovy'                ,\n            'idl'       => 'IDL'                   ,\n            'kermit'    => 'Kermit'                ,\n            'ksh'       => 'Korn Shell'            ,\n            'lua'       => 'Lua'                   ,\n            'luau'      => 'Luau'                  ,\n            'make'      => 'make'                  ,\n            'octave'    => 'Octave'                ,\n            'perl5'     => 'Perl'                  ,\n            'perl'      => 'Perl'                  ,\n            'miniperl'  => 'Perl'                  ,\n            'nextflow'  => 'Nextflow'              ,\n            'php'       => 'PHP'                   ,\n            'php5'      => 'PHP'                   ,\n            'python'    => 'Python'                ,\n            'python2.6' => 'Python'                ,\n            'python2.7' => 'Python'                ,\n            'python3'   => 'Python'                ,\n            'python3.3' => 'Python'                ,\n            'python3.4' => 'Python'                ,\n            'python3.5' => 'Python'                ,\n            'python3.6' => 'Python'                ,\n            'python3.7' => 'Python'                ,\n            'python3.8' => 'Python'                ,\n            'python3.9' => 'Python'                ,\n            'python3.10'=> 'Python'                ,\n            'python3.11'=> 'Python'                ,\n            'python3.12'=> 'Python'                ,\n            'python3.13'=> 'Python'                ,\n            'python3.14'=> 'Python'                ,\n            'perl6'     => 'Raku'                  ,\n            'raku'      => 'Raku'                  ,\n            'rakudo'    => 'Raku'                  ,\n            'rexx'      => 'Rexx'                  ,\n            'regina'    => 'Rexx'                  ,\n            'ruby'      => 'Ruby'                  ,\n            'sed'       => 'sed'                   ,\n            'sh'        => 'Bourne Shell'          ,\n            'swipl'     => 'Prolog'                ,\n            'tcl'       => 'Tcl/Tk'                ,\n            'tclsh'     => 'Tcl/Tk'                ,\n            'tcsh'      => 'C Shell'               ,\n            'wish'      => 'Tcl/Tk'                ,\n            'zsh'       => 'zsh'                   ,\n            );\n# 1}}}\n%{$rh_Language_by_File_Type}      = (        # {{{1\n            'build.xml'         => 'Ant/XML'            ,\n            'BUILD'             => 'Bazel'              ,\n            'WORKSPACE'         => 'Bazel'              ,\n            'cmakelists.txt'    => 'CMake'              ,\n            'CMakeLists.txt'    => 'CMake'              ,\n            'Jamfile'           => 'Jam'                ,\n            'jamfile'           => 'Jam'                ,\n            'Jamrules'          => 'Jam'                ,\n            'justfile'          => 'Justfile'           ,\n            'Justfile'          => 'Justfile'           ,\n            'Makefile'          => 'make'               ,\n            'makefile'          => 'make'               ,\n            'meson.build'       => 'Meson'              ,\n            'Gnumakefile'       => 'make'               ,\n            'gnumakefile'       => 'make'               ,\n            'pom.xml'           => 'Maven/XML'          ,\n            'Rakefile'          => 'Ruby'               ,\n            'rakefile'          => 'Ruby'               ,\n            'Snakefile'         => 'Snakemake'          ,\n            'Dockerfile'        => 'Dockerfile'         ,\n            'Dockerfile.m4'     => 'Dockerfile'         ,\n            'Dockerfile.cmake'  => 'Dockerfile'         ,\n            'dockerfile'        => 'Dockerfile'         ,\n            'dockerfile.m4'     => 'Dockerfile'         ,\n            'dockerfile.cmake'  => 'Dockerfile'         ,\n            'Containerfile'     => 'Containerfile'      ,\n            'Jenkinsfile'       => 'Groovy'             ,\n            'jenkinsfile'       => 'Groovy'             ,\n            );\n# 1}}}\n%{$rh_Language_by_Prefix}     = (            # {{{1\n            'Dockerfile'        => 'Dockerfile'         ,\n            'Containerfile'     => 'Containerfile'         ,\n            );\n# 1}}}\n%{$rhaa_Filters_by_Language} = (            # {{{1\n    '(unknown)'          => [ ],\n    'ABAP'               => [   [ 'remove_matches'      , '^\\*'    ], ],\n    'ActionScript'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Activiti Business Process' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Apex Class'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'AppleScript'         => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_comments_in_strings', '\"', '(*', '*)' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'ASP'                => [   [ 'remove_matches'      , '^\\s*\\47'], ],  # \\47 = '\n    'ASP.NET'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_between_general', '<%--', '--%>' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                            ],\n    'Ada'                => [   [ 'remove_matches'      , '^\\s*--' ], ],\n    'ADSO/IDSM'          => [   [ 'remove_matches'      , '^\\s*\\*[\\+\\!]' ], ],\n    'Agda'               => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'AMPLE'              => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'APL'                => [\n                                [ 'remove_matches'      , '^\\s*⍝' ],\n                            ],\n    'AnsProlog'          => [\n                                [ 'remove_between_general', '%*', '*%' ],\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Ant/XML'            => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'ANTLR Grammar'      => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Ant'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Apex Trigger'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Aria'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Arduino Sketch'     => [ # Arduino IDE inserts problematic 0xA0 characters; strip them\n                                [ 'replace_regex' , '\\xa0', \" \" ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ArkTs'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Arturo'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'AsciiDoc'           => [\n                                [ 'remove_between_general', '////', '////' ],\n                                [ 'remove_matches'      , '^\\s*\\/\\/'  ],\n                            ],\n    'AspectJ'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Assembly'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*\\@' ],\n                                [ 'remove_matches'      , '^\\s*\\|' ],\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                                [ 'remove_inline'       , '\\@.*$'  ],\n                                [ 'remove_inline'       , '\\|.*$'  ],\n                                [ 'remove_inline'       , '!.*$'   ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                                [ 'remove_matches'      , '^\\*'    ],  # z/OS Assembly\n                            ],\n    'Astro'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Asymptote'          => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'AutoHotkey'         => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'awk'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'AXAML'              => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Bazel'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'bc'                 => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Beluga'             => [\n                                [ 'remove_between_general', '%{', '%}' ],\n                                [ 'remove_matches'      , '^\\s*%'      ],\n                            ],\n    'Bicep'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'BizTalk Pipeline' =>   [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'BizTalk Orchestration' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Blade'              => [\n                                [ 'remove_between_general', '{{--', '--}}' ],\n                                [ 'remove_html_comments',                  ],\n                            ],\n    'Blueprint'          => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Bourne Again Shell' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Bourne Shell'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Brainfuck'          => [ # puerile name for a language\n#                               [ 'call_regexp_common'  , 'Brainfuck' ],  # inaccurate\n                                [ 'remove_bf_comments',               ],\n                            ],\n    'BrightScript'       => [\n                                [ 'remove_matches'      , '^\\s*rem', ],\n                                [ 'remove_matches'      , '^\\s*\\'',  ],\n                            ],\n    'builder'            => [\n                                [ 'remove_matches'      , '^\\s*xml_markup.comment!'  ],\n                            ],\n    'C'                  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C++'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C/C++ Header'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cadence'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cangjie'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Carbon'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Chapel'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clean'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clojure'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_matches'      , '^\\s*#_'  ],\n                            ],\n    'ClojureScript'      => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'ClojureC'           => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'Clojure/Cangjie'    => [ [ 'die' ,  ], ], # never called\n    'CMake'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Crystal'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Constraint Grammar' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'CUDA'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cython'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'C#/Smalltalk' => [ [ 'die' ,  ], ], # never called\n    'C#'                 => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C# Designer'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'C# Generated'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cake Build Script'  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'CCS'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Civet'              => [\n                                [ 'call_parse_civet'               ],\n                            ],\n    'CSS'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'CSV'                => [  # comma separated value files have no comments;\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ], # included simply to allow diff's\n    'COBOL'              => [   [ 'remove_cobol_comments',         ], ],\n    'CoCoA 5'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'CodeQL'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'CoffeeScript'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'ColdFusion'         => [   [ 'remove_html_comments',          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'ColdFusion CFScript'=> [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Containerfile'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Coq'                => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Crystal Reports'    => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'CSON'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Cucumber'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                            ],\n    'C3'                 => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_between_general', '<*', '*>' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'D/dtrace'           => [ [ 'die' ,          ], ], # never called\n    'D'                  => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/+', '+/' ],\n                                [ 'remove_between_general', '/+', '+/' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'DAL'                => [\n                                [ 'remove_between_general', '[', ']', ],\n                            ],\n    'DAML'               => [\n                                [ 'remove_haskell_comments', '>filename<' ],\n                            ],\n    'Dart'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'DenizenScript'      => [ # same as YAML\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Derw'               => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_between_general', '{-', '-}' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Dafny'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'dhall'              => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Delphi Form'        => [ # same as Pascal\n                                [ 'remove_between_regex', '\\{[^$]', '}' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'DIET'               => [  # same as Pug\n                                [ 'remove_pug_block'    ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    # diff is kind of weird: anything but a space in the first column\n    # will count as code, with the exception of #, ---, +++.  Spaces\n    # in the first column denote context lines which aren't part of the\n    # difference.\n    'diff'               => [\n                                [ 'remove_matches'      , '^#' ],\n                                [ 'remove_matches'      , '^\\-\\-\\-' ],\n                                [ 'remove_matches'      , '^\\+\\+\\+' ],\n                                [ 'remove_matches'      , '^\\s' ],\n                            ],\n    'DITA'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'DOORS Extension Language' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Drools'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'dtrace'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'ECPP'               => [\n                                [ 'remove_between_general',\n                                  '<%doc>', '</%doc>',             ],\n                                [ 'remove_between_general',\n                                  '<#'    , '#>'     ,             ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'EEx'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'EJS'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Elm'                => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Embedded Crystal'   => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'ERB'                => [\n                                [ 'remove_between_general', '<%#', '%>' ],\n                            ],\n    'Gencat NLS'         => [   [ 'remove_matches'       , '^\\$ .*$' ], ],\n    'NASTRAN DMAP'       => [\n                                [ 'remove_matches'      , '^\\s*\\$' ],\n                                [ 'remove_inline'       , '\\$.*$'  ],\n                            ],\n    'Dockerfile'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'DOS Batch'          => [\n                                [ 'remove_matches'      , '^\\s*rem' ],\n                                [ 'remove_matches'      , '^\\s*::'  ],\n                            ],\n    'DTD'                => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Elixir'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'elixir_doc_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Elixir Script'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'elixir_doc_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Erlang'             => [\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Expect'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Fennel'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Finite State Language' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Fish Shell'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Focus'              => [   [ 'remove_matches'      , '^\\s*\\-\\*'  ], ],\n    'Forth'              => [\n                                [ 'remove_matches'      , '^\\s*\\\\\\\\.*$'  ],\n                                [ 'Forth_paren_to_C'                 ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                                [ 'remove_inline'       , '\\\\\\\\.*$'  ],\n                            ],\n    'Fortran 77'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 77/Forth'   => [ [ 'die' ,          ], ], # never called\n    'F#/Forth'           => [ [ 'die' ,          ], ], # never called\n    'Fortran 90'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_f90_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 95'         => [\n                                [ 'remove_f77_comments' ,          ],\n                                [ 'remove_f90_comments' ,          ],\n                                [ 'remove_inline'       , '\\!.*$'  ],\n                            ],\n    'Fortran 2003'       => [\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                            ],\n    'Freemarker Template' => [\n                                [ 'remove_between_general', '<#--', '-->' ],\n                            ],\n    'Futhark'            => [\n                                [ 'remove_matches'      , '^\\s*--'  ],\n                            ],\n    'FXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'F#'                 => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'F# Script'          => [\n                                [ 'call_regexp_common'  , 'Pascal' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Flatbuffers'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Godot Scene'        => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Godot Resource'     => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Godot Shaders'      => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'GDScript'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Glade'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Gleam'              => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Glimmer JavaScript' => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Glimmer TypeScript' => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'GLSL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Go'                 => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '[\"`]', '*/*', '' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Gradle'             => [ # same as Groovy\n                                [ 'remove_inline'       , '//.*$'  ],\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Grails'             => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'GraphQL'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Groovy'             => [\n                                [ 'remove_inline'       , '//.*$'  ],\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Haml'               => [\n                                [ 'remove_haml_block'   ,          ],\n                                [ 'remove_html_comments',          ],\n                                [ 'remove_matches'      , '^\\s*/\\s*\\S+' ],\n                                [ 'remove_matches'      , '^\\s*-#\\s*\\S+' ],\n                            ],\n    'Handlebars'         => [\n                                [ 'remove_between_general', '{{!--', '--}}' ],\n                                [ 'remove_between_general', '{{!', '}}' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Harbour'            => [\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Hare'               => [\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '//.*$' ],\n                            ],\n    'Haxe'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HCL'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HLSL'               => [\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'HTML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'HTML EEx'           => [\n                                [ 'remove_matches'       , '^\\s*<% #' ],\n                                [ 'remove_between_general', '<%!--', '--%>' ],\n                            ],\n    'Hibernate'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'HolyC'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Hoon'               => [\n                                [ 'remove_matches'      , '^\\s*:[:><]' ],\n                                [ 'remove_inline'       , ':[:><].*$'  ],\n                            ],\n    'INI'                => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'XHTML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Haskell'            => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'Haskell Boot'       => [   [ 'remove_haskell_comments', '>filename<' ], ],\n    'IDL'                => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'IDL/Qt Project/Prolog/ProGuard' => [ [ 'die' ,          ], ], # never called\n    'Idris'              => [\n                                [ 'remove_haskell_comments', '>filename<' ],\n                                [ 'remove_matches'      , '^\\s*\\|{3}' ],\n                            ],\n    'Igor Pro'           => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'Literate Idris'     => [\n                                [ 'remove_matches'      , '^[^>]'  ],\n                            ],\n    'Imba'               => [\n                                [ 'remove_matches'      , '^\\s*#\\s'],\n                                [ 'remove_inline'       , '#\\s.*$' ],\n                                [ 'remove_between_regex', '###', '###' ],\n                            ],\n    'InstallShield'      => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'IPL'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jai'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jam'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Janet'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'JSP'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'JSP Tag Library Definition' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Jasper Report XML/Template' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'JavaServer Faces'   => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Java'               => [\n                                [ 'docstring_rm_comments', ],\n                                [ 'replace_regex', '\\\\\\\\$', ' '],\n                                # Java seems to have more path globs in strings\n                                # than other languages.  The variations makes\n                                # it tricky to craft a universal fix.\n                                # \\1 is a backreference to the first group, meaning\n                                # either single or double quote\n                                [ 'replace_between_regex', '([\"\\'])(.*?/\\*)(.*?)\\1',\n                                  '(.*?)' , '\"xx\"'],\n                                [ 'replace_between_regex', '([\"\\'])(.*?\\*/)(.*?)\\1',\n                                  '(.*?)' , '\"xx\"'],\n                               ## separate /* inside quoted strings with two\n                               ## concatenated strings split between / and *\n                               ##    -> defeated by \"xx/**/*_xx\" issue 365\n                               #[ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                               #  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"'],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'JavaScript'         => [\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jinja Template'     => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'JSX'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'JCL'                => [   [ 'remove_jcl_comments' ,          ], ],\n    'JSON'               => [   # ECMA-404, the JSON standard definition\n                                # makes no provision for JSON comments\n                                # so just use a placeholder filter\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'JSON5'              => [   # same as JavaScript\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Jsonnet'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Julia'              => [\n                                [ 'remove_between_general', '#=', '=#' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Juniper Junos'      => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Justfile'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'kvlang'             => [\n                                [\"remove_matches\", '^\\s*#[^:]'],\n                            ],\n    'Kotlin'             => [\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Lean'               => [\n                                [ 'remove_between_general', '/-', '-/' ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Lem'                => [\n                                [ 'remove_OCaml_comments',         ],\n                            ],\n    'LESS'               => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'lex'                => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'LFE'                => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_between_general', '#|', '|#' ],\n                            ],\n    'Linker Script'      => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/'],\n                                [ 'call_regexp_common',     'C'            ],\n                            ],\n    'Liquibase'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'liquid'             => [\n                                [ 'remove_between_general', '{% comment %}',\n                                                            '{% endcomment %}' ],\n                                [ 'remove_html_comments',          ],\n                            ],\n    'Lisp'               => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_between_general', '#|', '|#' ],\n                            ],\n    'Lisp/OpenCL'        => [ [ 'die' ,          ], ], # never called\n    'Lisp/Julia'         => [ [ 'die' ,          ], ], # never called\n    'LiveLink OScript'   => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'LLVM IR'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Logos'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Logtalk'            => [  # same filters as Prolog\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Lua'                => [\n                                [ 'remove_between_general', '--[=====[', ']=====]' ],\n                                [ 'remove_between_general', '--[====[', ']====]' ],\n                                [ 'remove_between_general', '--[===[', ']===]' ],\n                                [ 'remove_between_general', '--[==[', ']==]' ],\n                                [ 'remove_between_general', '--[=[', ']=]' ],\n                                [ 'remove_between_general', '--[[', ']]' ],\n                                [ 'remove_matches'      , '^\\s*\\-\\-' ],\n                            ],\n    'Luau'               => [\n                                [ 'remove_between_general', '--[=====[', ']=====]' ],\n                                [ 'remove_between_general', '--[====[', ']====]' ],\n                                [ 'remove_between_general', '--[===[', ']===]' ],\n                                [ 'remove_between_general', '--[==[', ']==]' ],\n                                [ 'remove_between_general', '--[=[', ']=]' ],\n                                [ 'remove_between_general', '--[[', ']]' ],\n                                [ 'remove_matches'      , '^\\s*\\-\\-' ],\n                            ],\n    'make'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Meson'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'MATLAB'             => [\n                                [ 'remove_between_general', '%{', '%}' ],\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Magik'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Mathematica'        => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Maven/XML'          => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Maven'              => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Mercury'            => [\n                                [ 'remove_inline'       , '%.*$'   ],\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                            ],\n    'Metal'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Modelica'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Modula3'            => [   [ 'call_regexp_common'  , 'Pascal' ], ],\n        # Modula 3 comments are (* ... *) so applying the Pascal filter\n        # which also treats { ... } as a comment is not really correct.\n    'Mojom'              => [   [ 'call_regexp_common' , 'C++' ], ],\n    'Mojo'               => [\n                                [ 'remove_matches'      , '/\\*'    ],\n                                [ 'remove_matches'      , '\\*/'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'MoonBit'            => [   [ 'remove_matches'      , '^\\s*//' ], ],\n    'Nemerle'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nextflow'             => [\n                                # copy of Groovy\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'rm_comments_in_strings', '\"\"\"', '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', '\"\"\"', '//', '', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '/*', '*/', 1],\n                                [ 'rm_comments_in_strings', \"'''\", '//', '', 1],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nunjucks'           => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'Nushell'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Nushell Object Notation' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Objective-C'        => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Objective-C++'      => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'OCaml'              => [\n                                [ 'rm_comments_in_strings', '\"', '(*', '*)', 1 ],\n                                [ 'remove_OCaml_comments',         ],\n                            ],\n    'OpenCL'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PHP/Pascal/Fortran/Pawn/BitBake' => [ [ 'die' ,          ], ], # never called\n    'Mako'               => [\n                                [ 'remove_matches'       , '##.*$'  ],\n                            ],\n    'Markdown'           => [\n                                [ 'remove_between_general', '<!--', '-->' ],\n                                [ 'remove_between_regex',\n                                  '\\[(comment|\\/\\/)?\\]\\s*:?\\s*(<\\s*>|#)?\\s*\\(.*?', '.*?\\)' ],\n                                # http://stackoverflow.com/questions/4823468/comments-in-markdown\n                            ],\n    'Org Mode'           => [\n                                # https://orgmode.org/guide/Comment-Lines.html\n                                [ 'remove_matches'      , '^\\s*#\\s.*'   ],\n                                [ 'remove_between_general', '#+BEGIN_COMMENT', '#+END_COMMENT' ],\n                                [ 'remove_between_general', '#+begin_comment', '#+end_comment' ],\n                                [ 'remove_between_regex',\n                                  '^\\*+\\s+COMMENT\\b.*',\n                                  '^\\*+\\s+(?!COMMENT\\b)'\n                                ],\n                            ],\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' => [ [ 'die' ,          ], ], # never called\n    'MUMPS'              => [   [ 'remove_matches'      , '^\\s*;'  ], ],\n    'Mustache'           => [\n                                [ 'remove_between_general', '{{!', '}}' ],\n                            ],\n    '.NET IL'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Nickel'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Nim'                => [\n                                [ 'remove_between_general', '#[', ']#' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n#                               [ 'docstring_to_C'                 ],\n#                               [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'NetLogo'            => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Nix'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Octave'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Odin'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'OpenSCAD'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Oracle Forms'       => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Oracle Reports'     => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Oracle PL/SQL'      => [\n                              # [ 'call_regexp_common'  , 'PL/SQL' ], # bad results\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Pascal'             => [\n                                [ 'remove_between_regex', '\\{[^$]', '}' ],\n                                [ 'remove_between_general', '(*', '*)' ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Pascal/Puppet'            => [ [ 'die' ,          ], ], # never called\n    'Puppet'             => [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'P4'                 => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Patran Command Language'=> [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'remove_matches'      , '^\\s*\\$#' ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                            ],\n    'Pawn'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Perl'               => [   [ 'remove_below'        , '^__(END|DATA)__'],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above' , '^=(?:pod|over|head\\d+)', '^=cut' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'PEG'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'peg.js'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'peggy'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Pek'                => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Pest'               => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'Perl/Prolog'        => [ [ 'die' ,          ], ], # never called\n    'Pig Latin'          => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                                [ 'call_regexp_common'  , 'C'       ],\n                            ],\n    'Pkl'                => [\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PL/I'               => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'PL/M'               => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'PlantUML'           => [\n                                [ 'remove_between_general', \"/'\", \"'/\" ],\n                                [ 'remove_matches'      , \"^\\\\s*'\" ],\n                            ],\n    'Prisma Schema'      => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Processing'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ProGuard'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'PO File'            => [\n                                [ 'remove_matches'      , '^\\s*#[^,]' ],  # '#,' is not a comment\n                            ],\n    'Pony'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PowerBuilder'       => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PowerShell'         => [\n                                [ 'powershell_to_C'                ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Prolog'             => [\n                                [ 'remove_matches'      , '^\\s*\\%' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '(//|\\%).*$' ],\n                            ],\n    'Properties'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*!'  ],\n                            ],\n    'Protocol Buffers'   => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'PRQL'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                            ],\n    'Pug'                => [\n                                [ 'remove_pug_block'    ,          ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'PureScript'         => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_between_general', '{-', '-}' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Python'             => [\n                                [ 'remove_matches'      , '/\\*'    ],\n                                [ 'remove_matches'      , '\\*/'    ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Jupyter Notebook'   => [   # these are JSON files; have no comments\n                                # would have to parse JSON for\n                                #      \"cell_type\": \"code\"\n                                # to count code lines\n                                [ 'jupyter_nb'                     ],\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'PHP'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'QML'                => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'XML (Qt/GTK)'       => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Qt Linguist'        => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Qt Project'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'R'                  => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ring'               => [\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Rmd'                => [\n                                [ 'reduce_to_rmd_code_blocks'      ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Racket'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'Raku'               => [   [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above'  , '^=head1', '^=cut'  ],\n                                [ 'remove_below_above'  , '^=begin', '^=end'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Raku/Prolog'        => [ [ 'die' ,          ], ], # never called\n    'RAML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'RapydScript'        => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Razor'              => [\n                                [ 'remove_between_general', '@*', '*@' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_between_general', '<!--', '-->' ],\n                            ],\n    'reStructuredText'   => [\n                                [ 'remove_between_regex', '^\\.\\.', '^[^ \\n\\t\\r\\f\\.]' ]\n                            ],\n    'Rexx'               => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'ReasonML'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Rhai'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'ReScript'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'RobotFramework'     => [\n                                [ 'remove_matches'      , '^\\s*#'   ],\n                                [ 'remove_matches'      , '^\\s*Comment' ],\n                                [ 'remove_matches'      , '^\\s*\\*{3}\\s+(Variables|Test\\s+Cases|Settings|Keywords)\\s+\\*{3}' ] ,\n                                [ 'remove_matches'      , '^\\s*\\[(Documentation|Tags)\\]' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ruby'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_below_above'  , '^=begin', '^=end' ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Ruby HTML'          => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Circom'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Cairo'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Clarity'            => [\n                                [ 'remove_matches'      , '^\\s*;;' ],\n                                [ 'remove_inline'       , ';;.*$'  ],\n                            ],\n    'Rust'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SaltStack'          => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'SAS'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_between_general', '*', ';' ],\n                            ],\n    'Sass'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Scala'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Scheme/SaltStack' => [ [ 'die' ,          ], ], # never called\n    'Scheme'             => [\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , ';.*$'   ],\n                            ],\n    'SCSS'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'sed'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Slice'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Slim'               => [\n                                [ 'remove_slim_block'   ,          ],\n                            ],\n    'Slint'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SKILL/.NET IL'      => [   [ 'die' ,          ], ], # never called\n    'SKILL'              => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'SKILL++'            => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                            ],\n    'Smalltalk'          => [\n                                [ 'call_regexp_common'  , 'Smalltalk'      ],\n                            ],\n    'Smarty'             => [\n                                [ 'smarty_to_C'                    ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Snakemake'          => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Solidity'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SparForte'          => [\n                                [ 'remove_matches'      , '^\\s*#!' ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                            ],\n    'Specman e'          => [\n                                [ 'pre_post_fix'        , \"'>\", \"<'\"],\n                                [ 'remove_between_general', \"^'>\", \"^<'\" ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++',   ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_last_line'        , ],  # undo pre_post_fix addition\n                                                              # of trailing line of just <'\n                            ],\n    'Squirrel'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Starlark'           => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'SQL'                => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SQL Stored Procedure'=> [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SQL Data'           => [\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'SurrealQL'          => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'rm_comments_in_strings', '\"', '--', '' ],\n                                [ 'rm_comments_in_strings', '\"', '#', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'Standard ML'        => [\n                                [ 'remove_between_general', '(*', '*)' ],\n                            ],\n    'Stata'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Stylus'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SugarSS'            => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Svelte'             => [\n                                [ 'rm_comments_in_strings', \"`\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', \"'\", '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SVG'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Swift'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'SWIG'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n\n    'm4'                 => [   [ 'remove_matches'      , '^dnl\\s'  ], ],\n    'C Shell'            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Kermit'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_matches'      , '^\\s*;'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Korn Shell'         => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TableGen'           => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Tcl/Tk'             => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TEAL'               => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                            ],\n    'Teamcenter met'     => [   [ 'call_regexp_common'  , 'C'      ], ],\n    'Teamcenter mth'     => [   [ 'remove_matches'      , '^\\s*#'  ], ],\n    'Templ'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '[\"`]', '*/*', '' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                            ],\n    'TeX'                => [\n                                [ 'remove_matches'      , '^\\s*%'  ],\n                                [ 'remove_inline'       , '%.*$'   ],\n                            ],\n    'Text'               => [\n                                [ 'remove_matches'      , '^\\s*$'  ],\n                            ],\n    'TLA+'               => [\n                                [ 'remove_TLAPlus_generated_code'                 ],\n                                [ 'remove_matches'               , '^\\\\s*\\\\\\\\\\\\*' ],\n                                [ 'remove_TLAPlus_comments'                       ],\n                            ],\n    'Thrift'             => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Titanium Style Sheet'  => [\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_inline'       , '//.*$'  ],\n                                [ 'remove_between_regex', '/[^/]', '[^/]/' ],\n                            ],\n    'TNSDL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                            ],\n    'TOML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'TTCN'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'      ],\n                            ],\n    'TITAN Project File Information'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'tspeg'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Twig'               => [\n                                [ 'remove_between_general', '{#', '#}' ],\n                            ],\n    'TypeScript'         => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Typst'              => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Umka'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Unity-Prefab'       => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'USS'                => [   # same as CSS\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'UXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visual Fox Pro'     =>  [\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_inline'       , '\\*.*$'  ],\n                                [ 'remove_matches'      , '^\\s*&&' ],\n                                [ 'remove_inline'       , '&&.*$'  ],\n                            ],\n    'Softbridge Basic'   => [   [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'], ],  # \\47 = '\n    # http://www.altium.com/files/learningguides/TR0114%20VHDL%20Language%20Reference.pdf\n    'Vala'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vala Header'        => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Velocity Template Language' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_jsp_comments' ,          ],\n                                [ 'remove_matches'      , '^\\s*##' ],\n                                [ 'remove_between_general', '#**', '*#' ],\n                                [ 'add_newlines'        ,          ],\n                            ],\n    'Verilog-SystemVerilog/Coq' => [ ['die'] ], # never called\n    'Verilog-SystemVerilog' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'VHDL'               => [\n                                [ 'remove_matches'      , '^\\s*--' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_inline'       , '--.*$'  ],\n                            ],\n    'vim script'         => [\n                                [ 'remove_matches'      , '^\\s*\"'  ],\n                                [ 'remove_inline'       , '\".*$'   ],\n                            ],\n    'VBScript' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visual Basic .NET' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'VBA' => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visual Basic'       => [\n                                [ 'remove_above'        , '^\\s*Attribute\\s+VB_Name\\s+=' ],\n                                [ 'remove_matches'      , '^\\s*Attribute\\s+'],\n                                [ 'remove_matches'      , '^\\s*\\47'],     # \\47 = '\n                            ],\n    'Visualforce Component' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visualforce Page'   => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'Visual Studio Module' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Visual Studio Solution' => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'VSCode Workspace'    => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vuejs Component'     => [\n                                [ 'remove_html_comments',          ],\n#                               [ 'call_regexp_common'  , 'HTML'   ], # problematic, ref #876\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Vyper'              => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'docstring_to_C'                 ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'Teamcenter def'     => [   [ 'remove_matches'      , '^\\s*#'  ], ],\n    'Windows Module Definition' => [\n                                [ 'remove_matches'      , '^\\s*;' ],\n                                [ 'remove_inline'       , ';.*$'  ],\n                            ],\n    'yacc'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'YAML'               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    'XAML'               => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'xBase Header'       => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'xBase'              => [\n#                               [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'remove_matches'      , '^\\s*\\&\\&' ],\n                                [ 'remove_matches'      , '^\\s*\\*' ],\n                                [ 'remove_matches'      , '^\\s*NOTE' ],\n                                [ 'remove_matches'      , '^\\s*note' ],\n                                [ 'remove_matches'      , '^\\s*Note' ],\n                                [ 'remove_inline'       , '\\&\\&.*$' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'MXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                                [ 'remove_matches'      , '^\\s*//' ],\n                                [ 'add_newlines'        ,          ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'Web Services Description' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WebAssembly'           => [\n                                [ 'remove_matches'      , '^\\s*;;' ],\n                            ],\n    'WGSL'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Windows Message File'  => [\n                                [ 'remove_matches'      , '^\\s*;\\s*//' ],\n                                [ 'call_regexp_common'  , 'C'          ],\n                                [ 'remove_matches'      , '^\\s*;\\s*$'  ],\n#                               next line only hypothetical\n#                               [ 'remove_matches_2re'  , '^\\s*;\\s*/\\*',\n#                                                         '^\\s*;\\s*\\*/', ],\n                            ],\n    'Windows Resource File' => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'WiX source'         => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WiX include'        => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WiX string localization' => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WXML'               => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'WXSS'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C'      ],\n                            ],\n    'X++'                => [\n                                [ 'remove_matches', '\\s*#\\s*//' ],\n                                [ 'remove_between_regex', '#\\s*/\\*', '\\*/' ],\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'XMI'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'XML'                => [\n                                [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ],\n                            ],\n    'XQuery'             => [\n                                [ 'remove_between_general', '(:', ':)' ],\n                            ],\n    'XSD'                => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'XSLT'               => [   [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Xtend'              => [   # copy of Java, plus triple << inline\n                                # separate /* inside quoted strings with two\n                                # concatenated strings split between / and *\n                                [ 'replace_between_regex', '([\"\\'])(.*?/)(\\*.*?)\\1',\n                                  '(.*?)' , '\"$1$2$1 + $1$3$1$4\"', 0],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                                [ 'remove_matches'      , '^\\s*\\x{c2ab}{3}'  ], # doesn't work\n                                # \\xCA2B is unicode << character\n                            ],\n    'NAnt script'       => [    [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'MSBuild script'    => [    [ 'remove_html_comments',          ],\n                                [ 'call_regexp_common'  , 'HTML'   ], ],\n    'Yang'               => [\n                                [ 'rm_comments_in_strings', '\"', '/*', '*/' ],\n                                [ 'rm_comments_in_strings', '\"', '//', '' ],\n                                [ 'call_regexp_common'  , 'C++'    ],\n                            ],\n    'Yarn'               => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                            ],\n    'Zig'                => [\n                                [ 'remove_matches'      , '^\\s*//'  ],\n                                [ 'remove_inline'       , '//.*$'   ],\n                            ],\n    'zsh'                => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    \"Rego\"               => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    \"BitBake\"            => [\n                                [ 'remove_matches'      , '^\\s*#'  ],\n                                [ 'remove_inline'       , '#.*$'   ],\n                            ],\n    );\n# 1}}}\n%{$rh_EOL_continuation_re} = (               # {{{1\n    'ActionScript'       =>     '\\\\\\\\$'         ,\n    'AspectJ'            =>     '\\\\\\\\$'         ,\n    'Assembly'           =>     '\\\\\\\\$'         ,\n    'ASP'                =>     '\\\\\\\\$'         ,\n    'ASP.NET'            =>     '\\\\\\\\$'         ,\n    'Ada'                =>     '\\\\\\\\$'         ,\n    'awk'                =>     '\\\\\\\\$'         ,\n    'bc'                 =>     '\\\\\\\\$'         ,\n    'C'                  =>     '\\\\\\\\$'         ,\n    'C++'                =>     '\\\\\\\\$'         ,\n    'C/C++ Header'       =>     '\\\\\\\\$'         ,\n    'CMake'              =>     '\\\\\\\\$'         ,\n    'Cython'             =>     '\\\\\\\\$'         ,\n    'C#'                 =>     '\\\\\\\\$'         ,\n    'C# Designer'        =>     '\\\\\\\\$'         ,\n    'Cake Build Script'  =>     '\\\\\\\\$'         ,\n    'D'                  =>     '\\\\\\\\$'         ,\n    'Dart'               =>     '\\\\\\\\$'         ,\n    'Expect'             =>     '\\\\\\\\$'         ,\n    'Futhark'            =>     '\\\\\\\\$'         ,\n    'Gencat NLS'         =>     '\\\\\\\\$'         ,\n    'Go'                 =>     '\\\\\\\\$'         ,\n    'IDL'                =>     '\\$\\\\$'         ,\n    'Igor Pro'           =>     '\\\\$'           ,\n#   'Java'               =>     '\\\\\\\\$'         ,\n    'JavaScript'         =>     '\\\\\\\\$'         ,\n    'JSON5'              =>     '\\\\\\\\$'         ,\n    'JSX'                =>     '\\\\\\\\$'         ,\n    'LESS'               =>     '\\\\\\\\$'         ,\n    'Lua'                =>     '\\\\\\\\$'         ,\n    'Luau'               =>     '\\\\\\\\$'         ,\n    'make'               =>     '\\\\\\\\$'         ,\n    'MATLAB'             =>     '\\.\\.\\.\\s*$'    ,\n    'Meson'              =>     '\\\\\\\\$'         ,\n    'Metal'              =>     '\\\\\\\\$'         ,\n    'MXML'               =>     '\\\\\\\\$'         ,\n    'Objective-C'        =>     '\\\\\\\\$'         ,\n    'Objective-C++'      =>     '\\\\\\\\$'         ,\n    'OCaml'              =>     '\\\\\\\\$'         ,\n    'Octave'             =>     '\\.\\.\\.\\s*$'    ,\n    'Qt Project'         =>     '\\\\\\\\$'         ,\n    'Patran Command Language'=> '\\\\\\\\$'         ,\n    'PowerBuilder'       =>     '\\\\\\\\$'         ,\n    'PowerShell'         =>     '\\\\\\\\$'         ,\n    'Python'             =>     '\\\\\\\\$'         ,\n    'R'                  =>     '\\\\\\\\$'         ,\n    'Rmd'                =>     '\\\\\\\\$'         ,\n    'Ruby'               =>     '\\\\\\\\$'         ,\n    'sed'                =>     '\\\\\\\\$'         ,\n    'Swift'              =>     '\\\\\\\\$'         ,\n    'Bourne Again Shell' =>     '\\\\\\\\$'         ,\n    'Bourne Shell'       =>     '\\\\\\\\$'         ,\n    'C Shell'            =>     '\\\\\\\\$'         ,\n    'kvlang'             =>     '\\\\\\\\$'         ,\n    'Kermit'             =>     '\\\\\\\\$'         ,\n    'Korn Shell'         =>     '\\\\\\\\$'         ,\n    'Slint'              =>     '\\\\\\\\$'         ,\n    'Snakemake'          =>     '\\\\\\\\$'         ,\n    'Starlark'           =>     '\\\\\\\\$'         ,\n    'Solidity'           =>     '\\\\\\\\$'         ,\n    'Stata'              =>     '///$'          ,\n    'Stylus'             =>     '\\\\\\\\$'         ,\n    'Tcl/Tk'             =>     '\\\\\\\\$'         ,\n    'TTCN'               =>     '\\\\\\\\$'         ,\n    'TypeScript'         =>     '\\\\\\\\$'         ,\n    'lex'                =>     '\\\\\\\\$'         ,\n    'Vala'               =>     '\\\\\\\\$'         ,\n    'Vala Header'        =>     '\\\\\\\\$'         ,\n    'Vyper'              =>     '\\\\\\\\$'         ,\n    'X++'                =>     '\\\\\\\\$'         ,\n    'zsh'                =>     '\\\\\\\\$'         ,\n    );\n# 1}}}\n%{$rh_Not_Code_Extension}    = (             # {{{1\n   '1'             => 1,  # Man pages (documentation):\n   '2'             => 1,\n   '3'             => 1,\n   '4'             => 1,\n   '5'             => 1,\n   '6'             => 1,\n   '7'             => 1,\n   '8'             => 1,\n   '9'             => 1,\n   'a'             => 1,  # Static object code.\n   'ad'            => 1,  # X application default resource file.\n   'afm'           => 1,  # font metrics\n   'arc'           => 1,  # arc(1) archive\n   'arj'           => 1,  # arj(1) archive\n   'au'            => 1,  # Audio sound filearj(1) archive\n   'bak'           => 1,  # Backup files - we only want to count the \"real\" files.\n   'bdf'           => 1,\n   'bmp'           => 1,\n   'bz2'           => 1,  # bzip2(1) compressed file\n   'csv'           => 1,\n   'desktop'       => 1,\n   'dic'           => 1,\n   'doc'           => 1,\n   'elc'           => 1,\n   'eps'           => 1,\n   'fig'           => 1,\n   'gif'           => 1,\n   'gz'            => 1,\n   'h5'            => 1,  # hierarchical data format\n   'hdf'           => 1,  # hierarchical data format\n   'in'            => 1,  # Debatable.\n   'jpg'           => 1,\n   'kdelnk'        => 1,\n   'man'           => 1,\n   'mf'            => 1,\n   'mp3'           => 1,\n   'n'             => 1,\n   'o'             => 1,  # Object code is generated from source code.\n   'o.cmd'         => 1,  # not DOS Batch; Linux kernel compilation optimization file\n   'o.d'           => 1,  # cmake object dependency file\n   'pbm'           => 1,\n   'pdf'           => 1,\n   'pfb'           => 1,\n   'png'           => 1,\n   'ppt'           => 1,\n   'pptx'          => 1,\n   'ps'            => 1,  # Postscript is _USUALLY_ generated automatically.\n   'sgm'           => 1,\n   'sgml'          => 1,\n   'so'            => 1,  # Dynamically-loaded object code.\n   'Tag'           => 1,\n   'tfm'           => 1,\n   'tgz'           => 1,  # gzipped tarball\n   'tiff'          => 1,\n   'tsv'           => 1,  # tab separated values\n   'vf'            => 1,\n   'wav'           => 1,\n   'xbm'           => 1,\n   'xls'           => 1,\n   'xlsx'          => 1,\n   'xpm'           => 1,\n   'Y'             => 1,  # file compressed with \"Yabba\"\n   'Z'             => 1,  # file compressed with \"compress\"\n   'zip'           => 1,  # zip archive\n   'gitattributes' => 1,\n   'gitignore'     => 1,\n   'gitmodules'    => 1,\n); # 1}}}\n%{$rh_Not_Code_Filename}     = (             # {{{1\n   'AUTHORS'     => 1,\n   'BUGS'        => 1,\n   'BUGS'        => 1,\n   'Changelog'   => 1,\n   'ChangeLog'   => 1,\n   'ChangeLog'   => 1,\n   'Changes'     => 1,\n   'CHANGES'     => 1,\n   'COPYING'     => 1,\n   'COPYING'     => 1,\n   'DESCRIPTION' => 1, # R packages metafile\n   '.cvsignore'  => 1,\n   'Entries'     => 1,\n   'FAQ'         => 1,\n   'INSTALL'     => 1,\n   'MAINTAINERS' => 1,\n   'MD5SUMS'     => 1,\n   'NAMESPACE'   => 1, # R packages metafile\n   'NEWS'        => 1,\n   'readme'      => 1,\n   'Readme'      => 1,\n   'README'      => 1,\n   'README.tk'   => 1, # used in kdemultimedia, it's confusing.\n   'Repository'  => 1,\n   'Root'        => 1, # CVS\n   'TODO'        => 1,\n);\n# 1}}}\n%{$rh_Scale_Factor}          = (             # {{{1\n    '(unknown)'                    =>   0.00,\n    '1st generation default'       =>   0.25,\n    '2nd generation default'       =>   0.75,\n    '3rd generation default'       =>   1.00,\n    '4th generation default'       =>   4.00,\n    '5th generation default'       =>  16.00,\n    'ABAP'                         =>   5.00,\n    'ActionScript'                 =>   1.36,\n    'Activiti Business Process'    =>   2.00,\n    'Ada'                          =>   0.52,\n    'ADSO/IDSM'                    =>   3.00,\n    'Agda'                         =>   2.11,\n    'AMPLE'                        =>   2.00,\n    'AnsProlog'                    =>   1.25,\n    'Ant/XML'                      =>   1.90,\n    'Ant'                          =>   1.90,\n    'ANTLR Grammar'                =>   2.00,\n    'SQL'                          =>   6.15,\n    'SQL Stored Procedure'         =>   6.15,\n    'SQL Data'                     =>   1.00,\n    'Apex Class'                   =>   1.50,\n    'APL'                          =>   2.50,\n    'Aria'                         =>   3.50,\n    'ArkTs'                        =>   2.50,\n    'Arturo'                       =>   4.00,\n    'AsciiDoc'                     =>   1.50,\n    'AspectJ'                      =>   1.36,\n    'asa'                          =>   1.29,\n    'ASP'                          =>   1.29,\n    'ASP.NET'                      =>   1.29,\n    'Apex Trigger'                 =>   1.4 ,\n    'AppleScript'                  =>   4.0 ,\n    'Arduino Sketch'               =>   1.00,\n    'Assembly'                     =>   0.25,\n    'Astro'                        =>   3.0,\n    'Asymptote'                    =>   2.50,\n    'autocoder'                    =>   0.25,\n    'AutoHotkey'                   =>   1.29,\n    'awk'                          =>   3.81,\n    'AXAML'                        =>   2.00,\n    'basic'                        =>   0.75,\n    'Bazel'                        =>   1.00,\n    'bc'                           =>   1.50,\n    'Bicep'                        =>   3.00,\n    'Beluga'                       =>   5.00,\n    'Blade'                        =>   2.00,\n    'bliss'                        =>   0.75,\n    'Blueprint'                    =>   2.50,\n    'bmsgen'                       =>   2.22,\n    'bteq'                         =>   6.15,\n    'Brainfuck'                    =>   0.10,\n    'BrightScript'                 =>   2.00,\n    'builder'                      =>   2.00,\n    'C'                            =>   0.77,\n    'C#'                           =>   1.36,\n    'C# Designer'                  =>   1.36,\n    'C# Generated'                 =>   1.36,\n    'Cake Build Script'            =>   1.36,\n    'C++'                          =>   1.51,\n    'Cadence'                      =>   3.00,\n    'Cangjie'                      =>   3.00,\n    'Carbon'                       =>   1.51,\n    'CCS'                          =>   5.33,\n    'Civet'                        =>   3.00,\n    'ColdFusion'                   =>   4.00,\n    'ColdFusion CFScript'          =>   4.00,\n    'Chapel'                       =>   2.96,\n    'Clean'                        =>   2.50,\n    'Clojure'                      =>   1.25,\n    'ClojureScript'                =>   1.25,\n    'ClojureC'                     =>   1.25,\n    'CMake'                        =>   1.00,\n    'COBOL'                        =>   1.04,\n    'CoCoA 5'                      =>   1.04,\n    'CodeQL'                       =>   2.50,\n    'CoffeeScript'                 =>   2.00,\n    'Constraint Grammar'           =>   4.00,\n    'Containerfile'                =>   2.00,\n    'Coq'                          =>   5.00,\n    'Crystal'                      =>   2.50,\n    'Crystal Reports'              =>   4.00,\n    'csl'                          =>   1.63,\n    'CSON'                         =>   2.50,\n    'csp'                          =>   1.51,\n    'cssl'                         =>   1.74,\n    'CSS'                          =>   1.0,\n    'CSV'                          =>   0.1,\n    'Cucumber'                     =>   3.00,\n    'CUDA'                         =>   1.00,\n    'C3'                           =>   1.61,\n    'D'                            =>   1.70,\n    'Dafny'                        =>   3.00,\n    'DAL'                          =>   1.50,\n    'DAML'                         =>   2.11,\n    'Dart'                         =>   2.00,\n    'DenizenScript'                =>   1.00,\n    'Delphi Form'                  =>   2.00,\n    'DIET'                         =>   2.00,\n    'diff'                         =>   1.00,\n    'Derw'                         =>   3.00,\n    'dhall'                        =>   2.11,\n    'DITA'                         =>   1.90,\n    'dtrace'                       =>   2.00,\n    'NASTRAN DMAP'                 =>   2.35,\n    'DOORS Extension Language'     =>   1.50,\n    'Dockerfile'                   =>   2.00,\n    'DOS Batch'                    =>   0.63,\n    'Drools'                       =>   2.00,\n    'ECPP'                         =>   1.90,\n    'eda/sql'                      =>   6.67,\n    'edscheme 3.4'                 =>   1.51,\n    'EEx'                          =>   2.00,\n    'EJS'                          =>   2.50,\n    'Elixir Script'                =>   2.11,\n    'Elixir'                       =>   2.11,\n    'Elm'                          =>   2.50,\n    'Embedded Crystal'             =>   2.00,\n    'ERB'                          =>   2.00,\n    'Erlang'                       =>   2.11,\n    'Fennel'                       =>   2.50,\n    'Finite State Language'        =>   2.00,\n    'Focus'                        =>   1.90,\n    'Forth'                        =>   1.25,\n    'Fortran 66'                   =>   0.63,\n    'Fortran 77'                   =>   0.75,\n    'Fortran 90'                   =>   1.00,\n    'Fortran 95'                   =>   1.13,\n    'Fortran II'                   =>   0.63,\n    'Fortran 2003'                 =>   2.50,\n    'foundation'                   =>   2.76,\n    'Freemarker Template'          =>   1.48,\n    'Futhark'                      =>   3.00, # Guessed from value of ML\n    'F#'                           =>   2.50,\n    'F# Script'                    =>   2.50,\n    'Flatbuffers'                  =>   2.50,\n    'Glade'                        =>   2.00,\n    'Gleam'                        =>   2.50,\n    'GLSL'                         =>   2.00,\n    'Glimmer JavaScript'           =>   3.50,\n    'Glimmer TypeScript'           =>   3.50,\n    'gml'                          =>   1.74,\n    'gpss'                         =>   1.74,\n    'guest'                        =>   2.86,\n    'guru'                         =>   1.63,\n    'GDScript'                     =>   2.50,\n    'Godot Scene'                  =>   2.50,\n    'Godot Resource'               =>   2.50,\n    'Godot Shaders'                =>   2.50,\n    'Go'                           =>   2.50,\n    'Gradle'                       =>   4.00,\n    'Grails'                       =>   1.48,\n    'GraphQL'                      =>   4.00,\n    'Groovy'                       =>   4.10,\n    'gw basic'                     =>   0.82,\n    'HCL'                          =>   2.50,\n    'high c'                       =>   0.63,\n    'hlevel'                       =>   1.38,\n    'hp basic'                     =>   0.63,\n    'Haml'                         =>   2.50,\n    'Handlebars'                   =>   2.50,\n    'Harbour'                      =>   2.00,\n    'Hare'                         =>   2.50,\n    'Haskell'                      =>   2.11,\n    'Haskell Boot'                 =>   2.11,\n    'Haxe'                         =>   2.00,\n    'Hibernate'                    =>   2.00,\n    'HolyC'                        =>   2.50,\n    'Hoon'                         =>   2.00,\n    'HTML'                         =>   1.90,\n    'HTML EEx'                     =>   3.00,\n    'XHTML'                        =>   1.90,\n    'XMI'                          =>   1.90,\n    'XML'                          =>   1.90,\n    'FXML'                         =>   1.90,\n    'MXML'                         =>   1.90,\n    'XSLT'                         =>   1.90,\n    'DTD'                          =>   1.90,\n    'XSD'                          =>   1.90,\n    'NAnt script'                  =>   1.90,\n    'MSBuild script'               =>   1.90,\n    'Visual Studio Module'         =>   1.00,\n    'Visual Studio Solution'       =>   1.00,\n    'HLSL'                         =>   2.00,\n    'Idris'                        =>   2.00,\n    'Literate Idris'               =>   2.00,\n    'Igor Pro'                     =>   4.00,\n    'Imba'                         =>   3.00,\n    'INI'                          =>   1.00,\n    'InstallShield'                =>   1.90,\n    'IPL'                          =>   2.00,\n    'Jai'                          =>   1.13,\n    'Jam'                          =>   2.00,\n    'Janet'                        =>   3.00,\n    'Jasper Report XML/Template'   =>   2.00,\n    'Java'                         =>   1.36,\n    'JavaScript'                   =>   1.48,\n    'JavaServer Faces'             =>   1.5 ,\n    'Jinja Template'               =>   1.5 ,\n    'JSON'                         =>   2.50,\n    'JSON5'                        =>   2.50,\n    'Jsonnet'                      =>   2.50,\n    'JSP'                          =>   1.48,\n    'JSP Tag Library Definition'   =>   2.00,\n    'JSX'                          =>   1.48,\n    'Velocity Template Language'   =>   1.00,\n    'JCL'                          =>   1.67,\n    'Juniper Junos'                =>   2.00,\n    'Justfile'                     =>   2.50,\n    'kvlang'                       =>   2.00,\n    'Kermit'                       =>   2.00,\n    'Korn Shell'                   =>   3.81,\n    'Kotlin'                       =>   2.00,\n    'Lean'                         =>   3.00,\n    'LESS'                         =>   1.50,\n    'Lem'                          =>   3.00,\n    'LFE'                          =>   1.25,\n    'Linker Script'                =>   1.00,\n    'Liquibase'                    =>   2.00,\n    'liquid'                       =>   3.00,\n    'Lisp'                         =>   1.25,\n    'LiveLink OScript'             =>   3.5 ,\n    'LLVM IR'                      =>   0.90,\n    'Logos'                        =>   2.00,\n    'Logtalk'                      =>   2.00,\n    'm4'                           =>   1.00,\n    'make'                         =>   2.50,\n    'Mako'                         =>   1.50,\n    'Markdown'                     =>   1.00,\n    'mathcad'                      =>  16.00,\n    'Maven'                        =>   1.90,\n    'Meson'                        =>   1.00,\n    'Metal'                        =>   1.51,\n    'Modelica'                     =>   2.00,\n    'MUMPS'                        =>   4.21,\n    'Mustache'                     =>   1.75,\n    'MoonBit'                      =>   2.50,\n    'Nastran'                      =>   1.13,\n    'Nemerle'                      =>   2.50,\n    '.NET IL'                      =>   3.00,\n    'NetLogo'                      =>   4.00,\n    'Nextflow'                     =>   4.10,\n    'Nickel'                       =>   2.00,\n    'Nim'                          =>   2.00,\n    'Nix'                          =>   2.70,\n    'Nunjucks'                     =>   1.5 ,\n    'Nushell'                      =>   3.81,\n    'Nushell Object Notation'      =>   2.50,\n    'Objective-C'                  =>   2.96,\n    'Objective-C++'                =>   2.96,\n    'OCaml'                        =>   3.00,\n    'Odin'                         =>   2.00,\n    'OpenSCAD'                     =>   1.00,\n    'Oracle Reports'               =>   2.76,\n    'Oracle Forms'                 =>   2.67,\n    'Oracle Developer/2000'        =>   3.48,\n    'Other'                        =>   1.00,\n    'Org Mode'                     =>   1.00,\n    'P4'                           =>   1.5 ,\n    'Pawn'                         =>   2.00,\n    'Pascal'                       =>   0.88,\n    'Patran Command Language'      =>   2.50,\n    'Perl'                         =>   4.00,\n    'PEG'                          =>   3.00,\n    'peg.js'                       =>   3.00,\n    'peggy'                        =>   3.00,\n    'Pek'                          =>   2.50,\n    'Pest'                         =>   2.00,\n    'tspeg'                        =>   3.00,\n    'Pig Latin'                    =>   1.00,\n    'Pkl'                          =>   3.00,\n    'PL/I'                         =>   1.38,\n    'PL/M'                         =>   1.13,\n    'PlantUML'                     =>   2.00,\n    'Oracle PL/SQL'                =>   2.58,\n    'PO File'                      =>   1.50,\n    'Pony'                         =>   3.00,\n    'PowerBuilder'                 =>   3.33,\n    'PowerShell'                   =>   3.00,\n    'Prisma Schema'                =>   2.50,\n    'Processing'                   =>   2.50,\n    'ProGuard'                     =>   2.50,\n    'Prolog'                       =>   1.25,\n    'Properties'                   =>   1.36,\n    'Protocol Buffers'             =>   2.00,\n    'PRQL'                         =>   3.00,\n    'Pug'                          =>   2.00,\n    'Puppet'                       =>   2.00,\n    'PureScript'                   =>   2.00,\n    'QML'                          =>   1.25,\n    'XML (Qt/GTK)'                 =>   2.00,\n    'Qt Linguist'                  =>   1.00,\n    'Qt Project'                   =>   1.00,\n    'R'                            =>   3.00,\n    'Rmd'                          =>   3.00,\n    'Racket'                       =>   1.50,\n    'Raku'                         =>   4.00,\n    'rally'                        =>   2.00,\n    'ramis ii'                     =>   2.00,\n    'RAML'                         =>   0.90,\n    'ReasonML'                     =>   2.50,\n    'ReScript'                     =>   2.50,\n    'reStructuredText'             =>   1.50,\n    'Razor'                        =>   2.00,\n    'Rexx'                         =>   1.19,\n    'Rhai'                         =>   3.00,\n    'Ring'                         =>   4.20,\n    'RobotFramework'               =>   2.50,\n    'Circom'                       =>   1.00,\n    'Cairo'                        =>   1.00,\n    'Clarity'                      =>   1.47,\n    'Rust'                         =>   1.00,\n    'sas'                          =>   1.95,\n    'Scala'                        =>   4.10,\n    'Scheme'                       =>   1.51,\n    'Slim'                         =>   3.00,\n    'Solidity'                     =>   1.48,\n    'Bourne Shell'                 =>   3.81,\n    'Bourne Again Shell'           =>   3.81,\n    'ksh'                          =>   3.81,\n    'zsh'                          =>   3.81,\n    'Fish Shell'                   =>   3.81,\n    'C Shell'                      =>   3.81,\n    'SaltStack'                    =>   2.00,\n    'SAS'                          =>   1.5 ,\n    'Sass'                         =>   1.5 ,\n    'SCSS'                         =>   1.5 ,\n    'SKILL'                        =>   2.00,\n    'SKILL++'                      =>   2.00,\n    'Slice'                        =>   1.50,\n    'Slint'                        =>   1.00,\n    'Smalltalk'                    =>   4.00,\n    'Smarty'                       =>   3.50,\n    'Softbridge Basic'             =>   2.76,\n    'SparForte'                    =>   3.80,\n    'sps'                          =>   0.25,\n    'spss'                         =>   2.50,\n    'Specman e'                    =>   2.00,\n    'SQL'                          =>   2.29,\n    'Squirrel'                     =>   2.50,\n    'Standard ML'                  =>   3.00,\n    'Stata'                        =>   3.00,\n    'Stylus'                       =>   1.48,\n    'SugarSS'                      =>   2.50,\n    'SurrealQL'                    =>   2.50,\n    'Svelte'                       =>   2.00,\n    'SVG'                          =>   1.00,\n    'Swift'                        =>   2.50,\n    'SWIG'                         =>   2.50,\n    'TableGen'                     =>   2.00,\n    'Tcl/Tk'                       =>   4.00,\n    'TEAL'                         =>   0.50,\n    'Teamcenter def'               =>   1.00,\n    'Teamcenter met'               =>   1.00,\n    'Teamcenter mth'               =>   1.00,\n    'Templ'                        =>   2.50,\n    'TeX'                          =>   1.50,\n    'Text'                         =>   0.50,\n    'Thrift'                       =>   2.50,\n    'TLA+'                         =>   1.00,\n    'Titanium Style Sheet'         =>   2.00,\n    'TOML'                         =>   2.76,\n    'Twig'                         =>   2.00,\n    'TNSDL'                        =>   2.00,\n    'TTCN'                         =>   2.00,\n    'TITAN Project File Information' =>   1.90,\n    'TypeScript'                   =>   2.00,\n    'Typst'                        =>   3.00,\n    'Umka'                         =>   2.00,\n    'Unity-Prefab'                 =>   2.50,\n    'USS'                          =>   1.0,\n    'UXML'                         =>   1.90,\n    'Vala'                         =>   1.50,\n    'Vala Header'                  =>   1.40,\n    'Verilog-SystemVerilog'        =>   1.51,\n    'VHDL'                         =>   4.21,\n    'vim script'                   =>   3.00,\n    'Visual Basic'                 =>   2.76,\n    'VBA'                          =>   2.76,\n    'Visual Basic .NET'            =>   2.76,\n    'VBScript'                     =>   2.76,\n    'Visual Fox Pro'               =>   4.00, # Visual Fox Pro is not available in the language gearing ratios listed at Mayes Consulting web site\n    'Visualforce Component'        =>   1.9 ,\n    'Visualforce Page'             =>   1.9 ,\n    'VSCode Workspace'             =>   2.50,\n    'Vuejs Component'              =>   2.00,\n    'Vyper'                        =>   4.20,\n    'Web Services Description'     =>   1.00,\n    'WebAssembly'                  =>   0.45,\n    'WGSL'                         =>   2.50,\n    'Windows Message File'         =>   1.00,\n    'Windows Resource File'        =>   1.00,\n    'Windows Module Definition'    =>   1.00,\n    'WiX source'                   =>   1.90,\n    'WiX include'                  =>   1.90,\n    'WiX string localization'      =>   1.90,\n    'WXML'                         =>   1.90,\n    'WXSS'                         =>   1.00,\n    'xBase'                        =>   2.00,\n    'xBase Header'                 =>   2.00,\n    'xlisp'                        =>   1.25,\n    'X++'                          =>   1.51, # This is a guess. Copied from C++, because the overhead for C++ headers might be equivalent to the overhead of structuring elements in XPO files\n    'XAML'                         =>   1.90,\n    'XQuery'                       =>   2.50,\n    'yacc'                         =>   1.51,\n    'yacc++'                       =>   1.51,\n    'YAML'                         =>   0.90,\n    'Yarn'                         => 2.00,\n    'Expect'                       => 2.00,\n    'Gencat NLS'                   => 1.50,\n    'C/C++ Header'                 => 1.00,\n    'inc'                          => 1.00,\n    'lex'                          => 1.00,\n    'Julia'                        => 4.00,\n    'MATLAB'                       => 4.00,\n    'Magik'                        => 2.50,\n    'Mathematica'                  => 5.00,\n    'Mercury'                      => 3.00,\n    'Maven/XML'                    => 2.5,\n    'IDL'                          => 3.80,\n    'Octave'                       => 4.00,\n    'ML'                           => 3.00,\n    'Modula3'                      => 2.00,\n    'Mojom'                        => 2.00,\n    'Mojo'                         => 4.20,\n    'PHP'                          => 3.50,\n    'Jupyter Notebook'             => 4.20,\n    'Python'                       => 4.20,\n    'Snakemake'                    => 4.20,\n    'RapydScript'                  => 4.20,\n    'Starlark'                     => 4.20,\n    'BizTalk Pipeline'             => 1.00,\n    'BizTalk Orchestration'        => 1.00,\n    'Cython'                       => 3.80,\n    'Ruby'                         => 4.20,\n    'Ruby HTML'                    => 4.00,\n    'sed'                          => 4.00,\n    'Lua'                          => 4.00,\n    'Luau'                         => 4.50,\n    'OpenCL'                       => 1.50,\n    'Xtend'                        => 2.00,\n    'Yang'                         => 3.00,\n    'Zig'                          => 2.50,\n    \"Rego\"                         => 1.00,\n    \"BitBake\"                      => 1.00,\n    # aggregates; value is meaningless\n    'C#/Smalltalk'                    => 1.00,\n    'D/dtrace'                        => 1.00,\n    'F#/Forth'                        => 1.00,\n    'Fortran 77/Forth'                => 1.00,\n    'Lisp/Julia'                      => 1.00,\n    'Lisp/OpenCL'                     => 1.00,\n    'PHP/Pascal/Fortran/Pawn/Bitbake' => 1.00,\n    'Pascal/Puppet'                   => 1.00,\n    'Perl/Prolog'                     => 1.00,\n    'Raku/Prolog'                     => 1.00,\n    'Verilog-SystemVerilog/Coq'    => 1.00,\n    'MATLAB/Mathematica/Objective-C/MUMPS/Mercury' => 1.00,\n    'IDL/Qt Project/Prolog/ProGuard'     => 1.00,\n    'SKILL/.NET IL'                => 1.00,\n    'Clojure/Cangjie'              => 1.00,\n    'Unknown/BitBake'              => 1.00,\n);\n# 1}}}\n%{$rh_Known_Binary_Archives} = (             # {{{1\n            '.tar'     => 1 ,\n            '.tar.Z'   => 1 ,\n            '.tar.gz'  => 1 ,\n            '.tar.bz2' => 1 ,\n            '.zip'     => 1 ,\n            '.Zip'     => 1 ,\n            '.ZIP'     => 1 ,\n            '.ear'     => 1 ,  # Java\n            '.war'     => 1 ,  # contained within .ear\n            '.xz'      => 1 ,\n            '.whl'     => 1 ,  # Python wheel files (zip)\n            );\n# 1}}}\n} # end sub set_constants()\nsub check_scale_existence {                  # {{{1\n    # do a few sanity checks\n    my ($rhaa_Filters_by_Language,\n        $rh_Language_by_Extension,\n        $rh_Scale_Factor) = @_;\n\n    my $OK = 1;\n    foreach my $language (sort keys %{$rhaa_Filters_by_Language}) {\n        next if defined $Extension_Collision{$language};\n        if (!defined $rh_Scale_Factor->{$language}) {\n            $OK = 0;\n            warn \"Missing scale factor for $language\\n\";\n        }\n    }\n\n    my %seen_it = ();\n    foreach my $ext (sort keys %{$rh_Language_by_Extension}) {\n        my $language = $rh_Language_by_Extension->{$ext};\n        next if defined $Extension_Collision{$language};\n        next if $seen_it{$language};\n        if (!$rhaa_Filters_by_Language->{$language}) {\n            $OK = 0;\n            warn \"Missing language filter for $language\\n\";\n        }\n        $seen_it{$language} = 1;\n    }\n    die unless $OK;\n} # 1}}}\nsub pre_post_fix {                           # {{{1\n    # Return the input lines prefixed and postfixed\n    # by the given strings.\n    my ($ra_lines, $prefix, $postfix ) = @_;\n    print \"-> pre_post_fix with $prefix, $postfix\\n\" if $opt_v > 2;\n\n    my $all_lines = $prefix . join(\"\"  , @{$ra_lines}) . $postfix;\n\n    print \"<- pre_post_fix\\n\" if $opt_v > 2;\n    return split(\"\\n\", $all_lines);\n} # 1}}}\nsub rm_last_line {                           # {{{1\n    # Return all but the last line.\n    my ($ra_lines, ) = @_;\n    print \"-> rm_last_line\\n\" if $opt_v > 2;\n    print \"<- rm_last_line\\n\" if $opt_v > 2;\n    my $n = scalar(@{$ra_lines}) - 2;\n    return @{$ra_lines}[0..$n];\n} # 1}}}\nsub call_parse_civet {                       # {{{1\n    my ($ra_lines, ) = @_;\n    print \"-> call_parse_civet\\n\" if $opt_v > 2;\n    my $coffeeComment = 0;\n    foreach my $L (@{$ra_lines}) {\n        if ($L =~ /^\\s*civet\\s+coffee(Comment|Compat)/) {\n            $coffeeComment = 1;\n            last;\n        }\n    }\n    my (@step_1, @step_2, @step_3, @step_4);\n    if ($coffeeComment) {\n        @step_1 = remove_between_general($ra_lines, '###', '###');\n        @step_4 = remove_matches(        \\@step_1, '^\\s*#');\n    } else {\n        @step_1 = call_regexp_common($ra_lines, 'C');\n        @step_2 = remove_matches(        \\@step_1, '^///');\n        @step_3 = remove_matches(        \\@step_2, '^\\s*//[^/]');\n        @step_4 = remove_between_general(\\@step_3, '###', '###');\n    }\n    print \"<- call_parse_civet\\n\" if $opt_v > 2;\n    return @step_4;\n} # 1}}}\nsub call_regexp_common {                     # {{{1\n    my ($ra_lines, $language ) = @_;\n    print \"-> call_regexp_common for $language\\n\" if $opt_v > 2;\n\n    Install_Regexp_Common() unless $HAVE_Rexexp_Common;\n\n    my $all_lines = undef;\n    if ($language eq \"C++\") { # Regexp::Common's C++ comment regex is multi-line\n#       $all_lines = join(\"\\n\", @{$ra_lines});\n        $all_lines = \"\";\n        foreach (@{$ra_lines}) {\n            if (m/\\\\$/) {  # line ends with a continuation marker\n                $all_lines .= $_;\n            } else {\n                $all_lines .= \"$_\\n\";\n            }\n        }\n    } else {\n        $all_lines = join(\"\"  , @{$ra_lines});\n    }\n\n    {\n    my @ra_lines = split(\"\\n\", $all_lines);\n    print \"in:  [\", join(\"]\\nin:  [\", @ra_lines), \"]\\n\" if $opt_v > 4;\n    }\n\n    no strict 'vars';\n    # otherwise get:\n    #  Global symbol \"%RE\" requires explicit package name at cloc line xx.\n    if ($all_lines =~ $RE{comment}{$language}) {\n        # Suppress \"Use of uninitialized value in regexp compilation\" that\n        # pops up when $1 is undefined--happens if there's a bug in the $RE\n        # This Pascal comment will trigger it:\n        #         (* This is { another } test. **)\n        # Curiously, testing for \"defined $1\" breaks the substitution.\n        no warnings;\n        # Remove comments.\n        $all_lines =~ s/$1//g;\n    }\n    # a bogus use of %RE to avoid:\n    # Name \"main::RE\" used only once: possible typo at cloc line xx.\n    print scalar keys %RE if $opt_v < -20;\n    my @out = split(\"\\n\", $all_lines);\n    print \"out: [\", join(\"]\\nout: [\", @out), \"]\\n\" if $opt_v > 4;\n    print \"<- call_regexp_common\\n\" if $opt_v > 2;\n    return @out;\n} # 1}}}\nsub plural_form {                            # {{{1\n    # For getting the right plural form on some English nouns.\n    my $n = shift @_;\n    if ($n == 1) { return ( 1, \"\" ); }\n    else         { return ($n, \"s\"); }\n} # 1}}}\nsub matlab_or_objective_C {                  # {{{1\n    # Decide if code is MATLAB, Mathematica, Objective-C, MUMPS, or Mercury\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n    print \"-> matlab_or_objective_C\\n\" if $opt_v > 2;\n    # matlab markers:\n    #   first line starts with \"function\"\n    #   some lines start with \"%\"\n    #   high marks for lines that start with [\n    #\n    # Objective-C markers:\n    #   must have at least two brace characters, { }\n    #   has /* ... */ style comments\n    #   some lines start with @\n    #   some lines start with #include\n    #\n    # MUMPS:\n    #   has ; comment markers\n    #   do not match:  \\w+\\s*=\\s*\\w\n    #   lines begin with   \\s*\\.?\\w+\\s+\\w\n    #   high marks for lines that start with \\s*K\\s+ or \\s*Kill\\s+\n    #\n    # Mercury:\n    #   any line that begins with :- immediately triggers this\n    #\n    # Mathematica:\n    #   (* .. *)\n    #   BeginPackage\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG              = 0;\n\n    my $matlab_points      = 0;\n    my $mathematica_points = 0;\n    my $objective_C_points = 0;\n    my $mumps_points       = 0;\n    my $mercury_points     = 0;\n    my $has_braces         = 0;\n    while (<$IN>) {\n        ++$has_braces if $_ =~ m/[{}]/;\n#print \"LINE $. has_braces=$has_braces\\n\";\n        ++$mumps_points if $. == 1 and m{^[A-Z]};\n        if      (m{^\\s*/\\*} or m {^\\s*//}) {   #   /* or //\n            $objective_C_points += 5;\n            $matlab_points      -= 5;\nprintf \".m:  /*|//  obj C=% 2d  matlab=% 2d  mathematica=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^:-\\s+}) {      # gotta be mercury\n            $mercury_points = 1000;\n            last;\n        } elsif (m{\\w+\\s*=\\s*\\[}) {      # matrix assignment, very matlab\n            $matlab_points += 5;\n        }\n        if (m{\\w+\\[}) {      # function call by []\n            $mathematica_points += 2;\nprintf \".m:  \\\\w=[   obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*\\w+\\s*=\\s*}) {    # definitely not MUMPS\n            --$mumps_points;\nprintf \".m:  \\\\w=    obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*\\.?(\\w)\\s+(\\w)} and $1 !~ /\\d/ and $2 !~ /\\d/) {\n            ++$mumps_points;\nprintf \".m:  \\\\w \\\\w  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*;}) {\n            ++$mumps_points;\nprintf \".m:  ;      obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        }\n        if (m{^\\s*#(include|import)}) {\n            # Objective-C without a doubt\n            $objective_C_points = 1000;\n            $matlab_points      = 0;\nprintf \".m: #include obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n            $has_braces         = 2;\n            last;\n        } elsif (m{^\\s*@(interface|implementation|protocol|public|protected|private|end)\\s}o) {\n            # Objective-C without a doubt\n            $objective_C_points = 1000;\n            $matlab_points      = 0;\nprintf \".m: keyword obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n            last;\n        } elsif (m{^\\s*BeginPackage}) {\n            $mathematica_points += 2;\n        } elsif (m{^\\s*\\[}) {             #   line starts with [  -- very matlab\n            $matlab_points += 5;\nprintf \".m:  [      obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\sK(ill)?\\s+}) {\n            $mumps_points  += 5;\nprintf \".m:  Kill   obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*function}) {\n            --$objective_C_points;\n            ++$matlab_points;\nprintf \".m:  funct  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        } elsif (m{^\\s*%}) {              #   %\n            # matlab commented line\n            --$objective_C_points;\n            ++$matlab_points;\nprintf \".m:  pcent  obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n        }\n    }\n    $IN->close;\nprintf \"END LOOP    obj C=% 2d  matlab=% 2d  mumps=% 2d  mercury= % 2d\\n\", $objective_C_points, $matlab_points, $mathematica_points, $mumps_points, $mercury_points if $DEBUG;\n\n    # next heuristic is unreliable for small files\n#   $objective_C_points = -9.9e20 unless $has_braces >= 2;\n\n    my %points = ( 'MATLAB'      => $matlab_points     ,\n                   'Mathematica' => $mathematica_points     ,\n                   'MUMPS'       => $mumps_points      ,\n                   'Objective-C' => $objective_C_points,\n                   'Mercury'     => $mercury_points    , );\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n\n    print \"<- matlab_or_objective_C($file: matlab=$matlab_points, mathematica=$mathematica_points, C=$objective_C_points, mumps=$mumps_points, mercury=$mercury_points) => ${$rs_language}\\n\"\n        if $opt_v > 2;\n\n} # 1}}}\nsub php_pascal_fortran_pawn_bitbake {                # {{{1\n    # Decide if code is Fortran, PHP, Pascal, Pawn\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n    print \"-> php_pascal_or_fortran\\n\" if $opt_v > 2;\n    # fortran markers:\n    #   'implicit none' or 'implicit real' or 'implicit integer'\n    #   'program' or 'subroutine' or 'function' or 'module'\n    #   'end program' or 'end subroutine' or 'end function' or 'end module'\n    #   'write(', 'enddo'\n    #\n    # PHP:\n    #   must have at least two brace characters, { }\n    #   has /* ... */ style comments\n    #   some lines start with @\n    #   some lines start with #include\n    #\n    # Pascal:\n    #   lines ending with ;\n    #   writeln\n    #\n    # Pawn:\n    #   lines ending with ;\n    #   has /* ... */ style comments\n    #   writeln\n    #\n    # BitBake:\n    #   some lines start with variables: SRC_URI, SRC_REV, SUMMARY, LICENSE, DEPENDS, RDEPENDS, LIC_FILES_CHKSUM\n    #   some lines start with tasks: do_compile, do_install, do_configure, python\n    #   some lines start with include, require, inherit statements\n    #   contains .=, =., ?=, ??= operators\n    #   contains :... = assignments\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG           = 0;\n\n    my $fortran_90      = 0;\n    my $fortran_points  = 0;\n    my $php_points      = 0;\n    my $pascal_points   = 0;\n    my $pawn_points     = 0;\n    my $bitbake_points  = 0;\n    while (<$IN>) {\n        if (/^\\s*<\\?php/i) {\n            $php_points += 100;\n            last;\n        } elsif (/^\\s*end\\./i ) {\n            $pascal_points += 100;\n            last;\n        } elsif (/^\\s*implicit\\s+(none|real|integer|complex|double)/i) {\n            $fortran_points += 100;\n            # don't end here; try to get 77 or 90 flavor\n        } elsif (/^\\s*end;/i ) {\n            ++$pascal_points;\n            last;\n        } elsif (/^\\s*program\\b/i) {\n            ++$fortran_points;\n            ++$pascal_points;\n        # 'function' is common to all three languages so ignore it\n        } elsif (/^\\s*(subroutine|module|stop)\\b/i or\n                 /^\\s*write\\s*\\(/i                 or\n                 /^\\s*end\\s+(program|subroutine)/i or\n                 /^\\s*end\\s*(if|do)\\b/i) {\n            ++$fortran_points;\n        } elsif (/^\\s*(writeln|begin|procedure|interface|implementation|const)\\b/i) {\n            ++$pascal_points;\n        } elsif (/^\\s*(<|\\?>)/) {\n            ++$php_points;\n        } elsif (/;\\s*$/) {\n            ++$pascal_points;\n            ++$php_points;\n        } elsif (/^\\@/ or /^\\s*(Float:|bool:)/) {\n            $pawn_points += 1e+20;\n            last;\n        }\n        if (/^\\s*(integer|real|complex|double|character|logical|public|private).*?::/i or\n            /^\\s*(allocatable|dimension)/i or\n            /^\\s*(end\\s+)?(interface|type|function|module)\\b/i) {\n            ++$fortran_90;\n        }\n        if (/^\\s*(SRC_URI|SRC_REV|SUMMARY|LICENSE|DEPENDS|RDEPENDS|LIC_FILES_CHKSUM)\\s*=/i or\n            /^\\s*(do_compile|do_install|do_configure|python)\\b/i or\n            /^\\s*(inherit|include|require)\\b/i) {\n            ++$bitbake_points;\n        }\n        if (/\\.=/i or /=\\./i or /\\?=/i or /\\?\\?=/i) {\n            ++$bitbake_points;\n        }\n        if (/^[A-Z0-9_:-]+:[A-Za-z0-9_-]+\\s*=/) {\n            ++$bitbake_points;\n        }\n    }\n    $IN->close;\n\n    my %points = ( 'Fortran'      => $fortran_points     ,\n                   'PHP'          => $php_points         ,\n                   'Pascal'       => $pascal_points      ,\n                   'Pawn'         => $pawn_points        ,\n                   'BitBake'      => $bitbake_points     , );\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n    if (${$rs_language} eq 'Fortran') {\n        if ($fortran_90) {\n            ${$rs_language} = 'Fortran 90';\n        } else {\n            ${$rs_language} = 'Fortran 77';\n        }\n    }\n\n    print \"<- php_pascal_fortran_pawn_bitbake($file: fortran=$fortran_points, php=$php_points, \",\n          \"pascal=$pascal_points, pawn=$pawn_points, bitbake=$bitbake_points) => ${$rs_language}\\n\"\n        if $opt_v > 2;\n\n} # 1}}}\nsub Lisp_or_OpenCL {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Lisp_or_OpenCL\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $lisp_points   = 0;\n    my $opcl_points = 0;\n    while (<$IN>) {\n        ++$lisp_points if  /^\\s*;/;\n        ++$lisp_points if  /\\((def|eval|require|export|let|loop|dec|format)/;\n        ++$opcl_points if  /^\\s*(int|float|const|{)/;\n    }\n    $IN->close;\n    # print \"lisp_points=$lisp_points   opcl_points=$opcl_points\\n\";\n    if ($lisp_points > $opcl_points) {\n        $lang = \"Lisp\";\n    } else {\n        $lang = \"OpenCL\";\n    }\n\n    print \"<- Lisp_or_OpenCL\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Lisp_or_Julia {                          # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Lisp_or_Julia\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $lisp_points   = 0;\n    my $julia_points = 0;\n    while (<$IN>) {\n        ++$lisp_points if  /^\\s*;/;\n        ++$lisp_points if  /\\((def|eval|require|export|let|loop|dec|format)/;\n        ++$julia_points if  /^\\s*(function|end|println|for|while)/;\n    }\n    $IN->close;\n    # print \"lisp_points=$lisp_points   julia_points=$julia_points\\n\";\n    if ($lisp_points > $julia_points) {\n        $lang = \"Lisp\";\n    } else {\n        $lang = \"Julia\";\n    }\n\n    print \"<- Lisp_or_Julia\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Perl_or_Prolog {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Perl_or_Prolog\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $perl_points = 0;\n    my $prolog_points = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if ($. == 1 and /^#!.*?\\bperl/) {\n            $perl_points = 100;\n            last;\n        }\n        ++$perl_points   if  /^=(head|over|item|cut)/;\n        ++$perl_points   if  /;\\s*$/;\n        ++$perl_points   if  /(\\{|\\})/;\n        ++$perl_points   if  /^\\s*sub\\s+/;\n        ++$perl_points   if  /\\s*<<'/;  # start HERE block\n        ++$perl_points   if  /\\$(\\w+\\->|[_!])/;\n        ++$prolog_points if !/\\s*#/ and /\\.\\s*$/;\n        ++$prolog_points if  /:-/;\n    }\n    $IN->close;\n    # print \"perl_points=$perl_points   prolog_points=$prolog_points\\n\";\n    if ($perl_points > $prolog_points) {\n        $lang = \"Perl\";\n    } else {\n        $lang = \"Prolog\";\n    }\n\n    printf \"<- Perl_or_Prolog(%s, Perl=%d Prolog=%d)\\n\",\n        $file, $perl_points, $prolog_points if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Raku_or_Prolog {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Raku_or_Prolog\\n\" if $opt_v > 2;\n    my $lang = Perl_or_Prolog($file, $rh_Err, $raa_errors);\n    $lang = \"Raku\" if $lang eq \"Perl\";\n\n    print \"<- Raku_or_Prolog\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub IDL_or_QtProject {                       # {{{1\n    # IDL, QtProject, Prolog, or ProGuard\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> IDL_or_QtProject($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $idl_points      = 0;\n    my $qtproj_points   = 0;\n    my $prolog_points   = 0;\n    my $proguard_points = 0;\n    while (<$IN>) {\n        ++$idl_points      if /^\\s*;/;\n        ++$idl_points      if /plot\\(/i;\n        ++$qtproj_points   if /^\\s*(qt|configs|sources|template|target|targetpath|subdirs)\\b/i;\n        ++$qtproj_points   if /qthavemodule/i;\n        ++$prolog_points   if /\\.\\s*$/;\n        ++$prolog_points   if /:-/;\n        ++$proguard_points if /^\\s*#/;\n        ++$proguard_points if /^-keep/;\n        ++$proguard_points if /^-(dont)?obfuscate/;\n    }\n    $IN->close;\n    # print \"idl_points=$idl_points   qtproj_points=$qtproj_points\\n\";\n\n    my %points = ( 'IDL'        => $idl_points       ,\n                   'Qt Project' => $qtproj_points    ,\n                   'Prolog'     => $prolog_points    ,\n                   'ProGuard'   => $proguard_points  ,\n                 );\n\n    $lang = (sort { $points{$b} <=> $points{$a} or $a cmp $b} keys %points)[0];\n\n    print \"<- IDL_or_QtProject(idl_points=$idl_points, \",\n          \"qtproj_points=$qtproj_points, prolog_points=$prolog_points, \",\n          \"proguard_points=$proguard_points)\\n\"\n           if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Ant_or_XML {                             # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Ant_or_XML($file)\\n\" if $opt_v > 2;\n\n    my $lang = \"XML\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Ant_points   = 0;\n    my $XML_points   = 1;\n    while (<$IN>) {\n        if (/^\\s*<project\\s+/) {\n            ++$Ant_points  ;\n            --$XML_points  ;\n        }\n        if (/xmlns:artifact=\"antlib:org.apache.maven.artifact.ant\"/) {\n            ++$Ant_points  ;\n            --$XML_points  ;\n        }\n    }\n    $IN->close;\n\n    if ($XML_points >= $Ant_points) {\n        # tie or better goes to XML\n        $lang = \"XML\";\n    } else {\n        $lang = \"Ant\";\n    }\n\n    print \"<- Ant_or_XML($lang)\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Maven_or_XML {                           # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Maven_or_XML($file)\\n\" if $opt_v > 2;\n\n    my $lang = \"XML\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Mvn_points   = 0;\n    my $XML_points   = 1;\n    while (<$IN>) {\n        if (/^\\s*<project\\s+/) {\n            ++$Mvn_points  ;\n            --$XML_points  ;\n        }\n        if (m{xmlns=\"http://maven.apache.org/POM/}) {\n            ++$Mvn_points  ;\n            --$XML_points  ;\n        }\n    }\n    $IN->close;\n\n    if ($XML_points >= $Mvn_points) {\n        # tie or better goes to XML\n        $lang = \"XML\";\n    } else {\n        $lang = \"Maven\";\n    }\n\n    print \"<- Maven_or_XML($lang)\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub pascal_or_puppet {                       # {{{1\n    # Decide if code is Pascal or Puppet manifest\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n\n    print \"-> pascal_or_puppet\\n\" if $opt_v > 2;\n\n    ${$rs_language} = \"\";\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return;\n    }\n\n    my $DEBUG              = 0;\n    my $pascal_points      = 0;\n    my $puppet_points      = 0;\n\n    while (<$IN>) {\n\n        if ( /^\\s*\\#\\s+/ ) {\n                $puppet_points += .001;\n                next;\n        }\n\n        ++$pascal_points if /\\bprogram\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bunit\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bmodule\\s+[A-Za-z]/i;\n        ++$pascal_points if /\\bprocedure\\b/i;\n        ++$pascal_points if /\\bfunction\\b/i;\n        ++$pascal_points if /^\\s*interface\\s+/i;\n        ++$pascal_points if /^\\s*implementation\\s+/i;\n        ++$pascal_points if /^\\s*uses\\s+/i;\n        ++$pascal_points if /(?<!\\:\\:)\\bbegin\\b(?!\\:\\:)/i;\n        ++$pascal_points if /(?<!\\:\\:)\\bend\\b(?!\\:\\:)/i;\n        ++$pascal_points if /\\:\\=/;\n        ++$pascal_points if /\\<\\>/;\n        ++$pascal_points if /^\\s*\\{\\$(I|INCLUDE)\\s+.*\\}/i;\n        ++$pascal_points if /writeln/;\n\n        ++$puppet_points if /^\\s*class\\s+/ and not /class\\s+operator\\s+/;\n        ++$puppet_points if /^\\s*function\\s+[a-z][a-z0-9]+::[a-z][a-z0-9]+\\s*/;\n        ++$puppet_points if /^\\s*type\\s+[A-Z]\\w+::[A-Z]\\w+\\s+/;\n        ++$puppet_points if /^\\s*case\\s+/;\n        ++$puppet_points if /^\\s*package\\s+/;\n        ++$puppet_points if /^\\s*file\\s+/;\n        ++$puppet_points if /^\\s*include\\s\\w+/;\n        ++$puppet_points if /^\\s*service\\s+/;\n        ++$puppet_points if /\\s\\$\\w+\\s*\\=\\s*\\S/;\n        ++$puppet_points if /\\S\\s*\\=\\>\\s*\\S/;\n\n        # No need to process rest of file if language seems obvious.\n        last\n                if (abs ($pascal_points - $puppet_points ) > 20 );\n    }\n    $IN->close;\n\n    print \"<- pascal_or_puppet(pascal=$pascal_points, puppet=$puppet_points)\\n\"\n        if $opt_v > 2;\n\n    if ($pascal_points > $puppet_points) {\n        ${$rs_language} = \"Pascal\";\n    } else {\n        ${$rs_language} = \"Puppet\";\n    }\n\n} # 1}}}\nsub Forth_or_Fortran {                       # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Forth_or_Fortran\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $forth_points = 0;\n    my $fortran_points = 0;\n    while (<$IN>) {\n        ++$forth_points if  /^:\\s/;\n        ++$fortran_points if  /^([c*][^a-z]|\\s{6,}(subroutine|program|end|implicit)\\s|\\s*!)/i;\n    }\n    $IN->close;\n    if ($forth_points > $fortran_points) {\n        $lang = \"Forth\";\n    } else {\n        $lang = \"Fortran 77\";\n    }\n\n    print \"<- Forth_or_Fortran\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Forth_or_Fsharp {                        # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Forth_or_Fsharp\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $forth_points = 0;\n    my $fsharp_points = 0;\n    while (<$IN>) {\n        ++$forth_points if  /^:\\s/;\n        ++$fsharp_points if  /^\\s*(#light|import|let|module|namespace|open|type)/;\n    }\n    $IN->close;\n    if ($forth_points > $fsharp_points) {\n        $lang = \"Forth\";\n    } else {\n        $lang = \"F#\";\n    }\n\n    print \"<- Forth_or_Fsharp\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Verilog_or_Coq {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Verilog_or_Coq\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $coq_points     = 0;\n    my $verilog_points = 0;\n    while (<$IN>) {\n        ++$verilog_points if  /^\\s*(module|begin|input|output|always)/;\n        ++$coq_points if /\\b(Inductive|Fixpoint|Definition|\n                             Theorem|Lemma|Proof|Qed|forall|\n                             Section|Check|Notation|Variable|\n                             Goal|Fail|Require|Scheme|Module|Ltac|\n                             Set|Unset|Parameter|Coercion|Axiom|\n                             Locate|Type|Record|Existing|Class)\\b/x;\n    }\n    $IN->close;\n    if ($coq_points > $verilog_points) {\n        $lang = \"Coq\";\n    } else {\n        $lang = \"Verilog-SystemVerilog\";\n    }\n\n    print \"<- Verilog_or_Coq\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub TypeScript_or_QtLinguist {               # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> TypeScript_or_QtLinguist\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $tscript_points  = 0;\n    my $linguist_points = 0;\n    while (<$IN>) {\n        ++$linguist_points if m{\\b</?(message|source|translation)>};\n        ++$tscript_points  if /^\\s*(var|const|let|class|document)\\b/;\n        ++$tscript_points  if /[;}]\\s*$/;\n        ++$tscript_points  if m{^\\s*//};\n    }\n    $IN->close;\n    if ($tscript_points >= $linguist_points) {\n        $lang = \"TypeScript\";\n    } else {\n        $lang = \"Qt Linguist\";\n    }\n    print \"<- TypeScript_or_QtLinguist\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Qt_or_Glade {                            # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Qt_or_Glade\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $qt_points    =  1;\n    my $glade_points = -1;\n    while (<$IN>) {\n        if (/generated\\s+with\\s+glade/i) {\n            $glade_points =  1;\n            $qt_points    = -1;\n            last;\n        }\n    }\n    $IN->close;\n    if ($glade_points > $qt_points) {\n        $lang = \"Glade\";\n    } else {\n        $lang = \"XML (Qt/GTK)\";\n    }\n    print \"<- Qt_or_Glade\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Csharp_or_Smalltalk {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Csharp_or_Smalltalk($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $cs_points        = 0;\n    my $smalltalk_points = 0;\n    while (<$IN>) {\n        s{//.*?$}{};        # strip inline C# comments for better clarity\n        next if /^\\s*$/;\n        if (/[;}{]\\s*$/) {\n            ++$cs_points       ;\n        } elsif (/^(using|namespace)\\s/) {\n            $cs_points += 20;\n        } elsif (/^\\s*(public|private|new)\\s/) {\n            $cs_points += 20;\n        } elsif (/^\\s*\\[assembly:/) {\n            ++$cs_points       ;\n        }\n        if (/(\\!|\\]\\.)\\s*$/) {\n            ++$smalltalk_points;\n            --$cs_points       ;\n        }\n    }\n    $IN->close;\n    if ($smalltalk_points > $cs_points) {\n        $lang = \"Smalltalk\";\n    } else {\n        $lang = \"C#\";\n    }\n    print \"<- Csharp_or_Smalltalk($file)=$lang\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Visual_Basic_or_TeX_or_Apex {            # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n        $rs_language , # out\n       ) = @_;\n\n    print \"-> Visual_Basic_or_TeX_or_Apex($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $VB_points        = 0;\n    my $tex_points       = 0;\n    my $apex_points      = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n#print \"$_\";\n        if (/\\s*%/ or /\\s*\\\\/) {\n            ++$tex_points   ;\n        } else {\n            if (/^\\s*(public|private)\\s/i) {\n                ++$VB_points    ;\n                ++$apex_points  ;\n#print \"+VB1 +A1\";\n            } elsif (/^\\s*(end|attribute|version)\\s/i) {\n                ++$VB_points    ;\n#print \"+VB2\";\n            }\n            if (/[{}]/ or /;\\s*$/) {\n                ++$apex_points  ;\n#print \"+A2\";\n            }\n#print \"\\n\";\n        }\n    }\n    $IN->close;\n\n    my %points = ( 'Visual Basic'   => $VB_points   ,\n                   'TeX'            => $tex_points  ,\n                   'Apex Class'     => $apex_points ,);\n\n    ${$rs_language} = (sort { $points{$b} <=> $points{$a} or $a cmp $b } keys %points)[0];\n\n    print \"<- Visual_Basic_or_TeX_or_Apex($file: VB=$VB_points, TeX=$tex_points, Apex=$apex_points\\n\" if $opt_v > 2;\n    return $lang;\n} # 1}}}\nsub Scheme_or_SaltStack {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Scheme_or_SaltStack($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $Sch_points = 0;\n    my $SS_points  = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/{\\%.*%}/) {\n            $SS_points += 5;\n        } elsif (/map\\.jinja\\b/) {\n            $SS_points += 5;\n        } elsif (/\\((define|lambda|let|cond|do)\\s/) {\n            $Sch_points += 1;\n        } else {\n        }\n    }\n    $IN->close;\n\n    print \"<- Scheme_or_SaltStack($file: Scheme=$Sch_points, SaltStack=$SS_points\\n\" if $opt_v > 2;\n    if ($Sch_points > $SS_points) {\n        return \"Scheme\";\n    } else {\n        return \"SaltStack\";\n    }\n} # 1}}}\nsub Pascal_or_Pawn {                         # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Pascal_or_Pawn($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $scal = 0;\n    my $wn   = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(program|begin|end|[Ww]riteln|procedure)\\s/) {\n            $scal += 1e+20;\n            last;\n        } elsif (/^\\@/ or m{/\\*} or m{\\*/} or /^\\s*(Float:|bool:)/) {\n            $wn += 1e+20;\n            last;\n        } elsif (/^\\s*(static|printf?|switch)\\s/) {\n            $wn += 1;\n        } elsif (/;\\s*$/) {\n            $scal += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- Pascal_or_Pawn($file: Pascal=$scal, Pawn=$wn\\n\" if $opt_v > 2;\n    if ($scal > $wn) {\n        return \"Pascal\";\n    } else {\n        return \"Pawn\";\n    }\n} # 1}}}\nsub SKILL_or_DotNetIL {                      # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> SKILL_or_DotNetIL($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $skill   = 0;\n    my $dnet_il = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*;/) {\n            $skill += 50;\n        } elsif (/^\\.(class|assembly|method|custom|entrypoint)/) {\n            $dnet_il += 50;\n            last;\n        } elsif (/{\\s*$/ or /^\\s*}/) {\n            $dnet_il += 5;\n        } elsif (/^\\s*(procedure|let|foreach)\\b/) {\n            $skill += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- SKILL_or_DotNetIL($file: SKILL=$skill, .NET IL=$dnet_il\\n\" if $opt_v > 2;\n    if ($skill > $dnet_il) {\n        return \"SKILL\";\n    } else {\n        return \".NET IL\";\n    }\n} # 1}}}\nsub Clojure_or_Cangjie {                     # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> Clojure_or_Cangjie($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $clojure   = 0;\n    my $cangjie = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(;|\\(|\\[)/) {\n            $clojure += 50;\n        } elsif (/^(import|func|main)/) {\n            $cangjie += 50;\n        } elsif (/{\\s*$/ or /^\\s*}$/) {\n            $cangjie += 5;\n        } elsif (/^\\s*(procedure|let|foreach)\\b/) {\n            $clojure += 1;\n        }\n    }\n    $IN->close;\n\n    print \"<- Clojure_or_Cangjie($file: clojure=$clojure, .NET IL=$cangjie\\n\" if $opt_v > 2;\n    if ($clojure > $cangjie) {\n        return \"Clojure\";\n    } else {\n        return \"Cangjie\";\n    }\n} # 1}}}\nsub really_is_BitBake {                    # {{{1\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n\n    print \"-> really_is_BitBake($file)\\n\" if $opt_v > 2;\n\n    my $lang = undef;\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        push @{$raa_errors}, [$rh_Err->{'Unable to read'} , $file];\n        return $lang;\n    }\n    my $text   = 3; # Text is assumed if no BitBake markers are found\n    my $bitbake = 0;\n    while (<$IN>) {\n        next if /^\\s*$/;\n        if (/^\\s*(SRC_URI|SRC_REV|SUMMARY|LICENSE|DEPENDS|RDEPENDS|LIC_FILES_CHKSUM)\\s*=/i or\n            /^\\s*(BBFILE|LAYER).*\\s*=/i or\n            /^\\s*(do_compile|do_install|do_configure|python)\\b/i or\n            /^\\s*(inherit|include|require)\\b/i) {\n            ++$bitbake;\n        }\n        if (/\\.=/i or /=\\./i or /\\?=/i or /\\?\\?=/i) {\n            ++$bitbake;\n        }\n        if (/^[A-Z0-9_:-]+:[A-Za-z0-9_-]+\\s*=/) {\n            ++$bitbake;\n        }\n    }\n    $IN->close;\n\n    print \"<- really_is_BitBake($file: Text=$text, BitBake=$bitbake\\n\" if $opt_v > 2;\n    if ($text > $bitbake) {\n        return undef;\n    } else {\n        return \"BitBake\";\n    }\n} # 1}}}\nsub html_colored_text {                      # {{{1\n    # http://www.pagetutor.com/pagetutor/makapage/pics/net216-2.gif\n    my ($color, $text) = @_;\n#?#die \"html_colored_text($text)\";\n    if      ($color =~ /^red$/i)   {\n        $color = \"#ff0000\";\n    } elsif ($color =~ /^green$/i) {\n        $color = \"#00ff00\";\n    } elsif ($color =~ /^blue$/i)  {\n        $color = \"#0000ff\";\n    } elsif ($color =~ /^grey$/i)  {\n        $color = \"#cccccc\";\n    }\n#   return \"\" unless $text;\n    return '<font color=\"' . $color . '\">' . html_metachars($text) . \"</font>\";\n} # 1}}}\nsub xml_metachars {                          # {{{1\n    # http://en.wikipedia.org/wiki/Character_encodings_in_HTML#XML_character_references\n    my ($string, ) = shift @_;\n\n    my  @in_chars    = split(//, $string);\n    my  @out_chars   = ();\n    foreach my $c (@in_chars) {\n        if      ($c eq '&') { push @out_chars, '&amp;'\n        } elsif ($c eq '<') { push @out_chars, '&lt;'\n        } elsif ($c eq '>') { push @out_chars, '&gt;'\n        } elsif ($c eq '\"') { push @out_chars, '&quot;'\n        } elsif ($c eq \"'\") { push @out_chars, '&apos;'\n        } else {\n            push @out_chars, $c;\n        }\n    }\n    return join \"\", @out_chars;\n} # 1}}}\nsub html_metachars {                         # {{{1\n    # Replace HTML metacharacters with their printable forms.\n    # Future:  use HTML-Encoder-0.00_04/lib/HTML/Encoder.pm\n    # from Fabiano Reese Righetti's HTML::Encoder module if\n    # this subroutine proves to be too simplistic.\n    my ($string, ) = shift @_;\n\n    my  @in_chars    = split(//, $string);\n    my  @out_chars   = ();\n    foreach my $c (@in_chars) {\n        if      ($c eq '<') {\n            push @out_chars, '&lt;'\n        } elsif ($c eq '>') {\n            push @out_chars, '&gt;'\n        } elsif ($c eq '&') {\n            push @out_chars, '&amp;'\n        } else {\n            push @out_chars, $c;\n        }\n    }\n    return join \"\", @out_chars;\n} # 1}}}\nsub test_alg_diff {                          # {{{1\n    my ($file_1 ,\n        $file_2 )\n       = @_;\n    my $fh_1 = open_file('<', $file_1, 1);\n    die \"Unable to read $file_1:  $!\\n\" unless defined $fh_1;\n    chomp(my @lines_1 = <$fh_1>);\n    $fh_1->close;\n\n    my $fh_2 = open_file('<', $file_2, 1);\n    die \"Unable to read $file_2:  $!\\n\" unless defined $fh_2;\n    chomp(my @lines_2 = <$fh_2>);\n    $fh_2->close;\n\n    my $n_no_change = 0;\n    my $n_modified  = 0;\n    my $n_added     = 0;\n    my $n_deleted   = 0;\n    my @min_sdiff   = ();\nmy $NN = chr(27) . \"[0m\";  # normal\nmy $BB = chr(27) . \"[1m\";  # bold\n\n    my @sdiffs = sdiff( \\@lines_1, \\@lines_2 );\n    foreach my $entry (@sdiffs) {\n        my ($out_1, $out_2) = ('', '');\n        if ($entry->[0] eq 'u') {\n            ++$n_no_change;\n          # $out_1 = $entry->[1];\n          # $out_2 = $entry->[2];\n            next;\n        }\n#       push @min_sdiff, $entry;\n        if      ($entry->[0] eq 'c') {\n            ++$n_modified;\n            ($out_1, $out_2) = diff_two_strings($entry->[1], $entry->[2]);\n            $out_1 =~ s/\\cA(\\w)/${BB}$1${NN}/g;\n            $out_2 =~ s/\\cA(\\w)/${BB}$1${NN}/g;\n          # $out_1 =~ s/\\cA//g;\n          # $out_2 =~ s/\\cA//g;\n        } elsif ($entry->[0] eq '+') {\n            ++$n_added;\n            $out_1 = $entry->[1];\n            $out_2 = $entry->[2];\n        } elsif ($entry->[0] eq '-') {\n            ++$n_deleted;\n            $out_1 = $entry->[1];\n            $out_2 = $entry->[2];\n        } elsif ($entry->[0] eq 'u') {\n        } else { die \"unknown entry->[0]=[$entry->[0]]\\n\"; }\n        printf \"%-80s | %s\\n\", $out_1, $out_2;\n    }\n\n#   foreach my $entry (@min_sdiff) {\n#       printf \"DIFF:  %s  %s  %s\\n\", @{$entry};\n#   }\n} # 1}}}\nsub write_comments_to_html {                 # {{{1\n    my ($filename      , # in\n        $rah_diff_L    , # in  see routine array_diff() for explanation\n        $rah_diff_R    , # in  see routine array_diff() for explanation\n        $rh_blank      , # in  location and counts of blank lines\n       ) = @_;\n\n    print \"-> write_comments_to_html($filename)\\n\" if $opt_v > 2;\n    my $file = $filename . \".html\";\n\n    my $approx_line_count = scalar @{$rah_diff_L};\n       $approx_line_count = 1 unless $approx_line_count;\n    my $n_digits = 1 + int(log($approx_line_count)/2.30258509299405); # log_10\n\n    my $html_out = html_header($filename);\n\n    my $comment_line_number = 0;\n    for (my $i = 0; $i < scalar @{$rah_diff_R}; $i++) {\n        if (defined $rh_blank->{$i}) {\n            foreach (1..$rh_blank->{$i}) {\n                $html_out .= \"<!-- blank -->\\n\";\n            }\n        }\n        my $line_num = \"\";\n        my $pre      = \"\";\n        my $post     = '</span> &nbsp;';\nwarn \"undef rah_diff_R[$i]{type} \" unless defined $rah_diff_R->[$i]{type};\n        if ($rah_diff_R->[$i]{type} eq 'nonexist') {\n            ++$comment_line_number;\n            $line_num = sprintf \"\\&nbsp; <span class=\\\"clinenum\\\"> %0${n_digits}d %s\",\n                            $comment_line_number, $post;\n            $pre = '<span class=\"comment\">';\n            $html_out .= $line_num;\n            $html_out .= $pre .\n                         html_metachars($rah_diff_L->[$i]{char}) .\n                         $post . \"\\n\";\n            next;\n        }\n        if      ($rah_diff_R->[$i]{type} eq 'code' and\n                 $rah_diff_R->[$i]{desc} eq 'same') {\n            # entire line remains as-is\n            $line_num = sprintf \"\\&nbsp; <span class=\\\"linenum\\\"> %0${n_digits}d %s\",\n                            $rah_diff_R->[$i]{lnum}, $post;\n            $pre    = '<span class=\"normal\">';\n            $html_out .= $line_num;\n            $html_out .= $pre .\n                         html_metachars($rah_diff_R->[$i]{char}) . $post;\n#XX     } elsif ($rah_diff_R->[$i]{type} eq 'code') { # code+comments\n#XX\n#XX         $line_num = '<span class=\"linenum\">' .\n#XX                      $rah_diff_R->[$i]{lnum} . $post;\n#XX         $html_out .= $line_num;\n#XX\n#XX         my @strings = @{$rah_diff_R->[$i]{char}{strings}};\n#XX         my @type    = @{$rah_diff_R->[$i]{char}{type}};\n#XX         for (my $i = 0; $i < scalar @strings; $i++) {\n#XX             if ($type[$i] eq 'u') {\n#XX                 $pre = '<span class=\"normal\">';\n#XX             } else {\n#XX                 $pre = '<span class=\"comment\">';\n#XX             }\n#XX             $html_out .= $pre .  html_metachars($strings[$i]) . $post;\n#XX         }\n# print Dumper(@strings, @type); die;\n\n        } elsif ($rah_diff_R->[$i]{type} eq 'comment') {\n            $line_num = '<span class=\"clinenum\">' . $comment_line_number . $post;\n            # entire line is a comment\n            $pre    = '<span class=\"comment\">';\n            $html_out .= $pre .\n                         html_metachars($rah_diff_R->[$i]{char}) . $post;\n        }\n#printf \"%-30s %s %-30s\\n\", $line_1, $separator, $line_2;\n        $html_out .= \"\\n\";\n    }\n\n    $html_out .= html_end();\n\n    my $out_file = \"$filename.html\";\n    write_file($out_file, {}, ( $html_out ) );\n\n    print \"<- write_comments_to_html\\n\" if $opt_v > 2;\n} # 1}}}\nsub array_diff {                             # {{{1\n    my ($file          , # in  only used for error reporting\n        $ra_lines_L    , # in  array of lines in Left  file (no blank lines)\n        $ra_lines_R    , # in  array of lines in Right file (no blank lines)\n        $mode          , # in  \"comment\" | \"revision\"\n        $rah_diff_L    , # out\n        $rah_diff_R    , # out\n        $raa_Errors    , # in/out\n       ) = @_;\n\n    # This routine operates in two ways:\n    # A. Computes diffs of the same file with and without comments.\n    #    This is used to classify lines as code, comments, or blank.\n    # B. Computes diffs of two revisions of a file.  This method\n    #    requires a prior run of method A using the older version\n    #    of the file because it needs lines to be classified.\n\n    # $rah_diff structure:\n    # An array with n entries where n equals the number of lines in\n    # an sdiff of the two files.  Each entry in the array describes\n    # the contents of the corresponding line in file Left and file Right:\n    #  diff[]{type} = blank | code | code+comment | comment | nonexist\n    #        {lnum} = line number within the original file (1-based)\n    #        {desc} = same | added | removed | modified\n    #        {char} = the input line unless {desc} = 'modified' in\n    #                 which case\n    #        {char}{strings} = [ substrings ]\n    #        {char}{type}    = [ disposition (added, removed, etc)]\n    #\n\n    @{$rah_diff_L} = ();\n    @{$rah_diff_R} = ();\n\n    print \"-> array_diff()\\n\" if $opt_v > 2;\n    my $COMMENT_MODE = 0;\n       $COMMENT_MODE = 1 if $mode eq \"comment\";\n\n#print \"array_diff(mode=$mode)\\n\";\n#print Dumper(\"block left:\" , $ra_lines_L);\n#print Dumper(\"block right:\", $ra_lines_R);\n\n    my @sdiffs = ();\n    eval {\n        local $SIG{ALRM} = sub { die \"alarm\\n\" };\n        alarm $opt_diff_timeout;\n        @sdiffs = sdiff($ra_lines_L, $ra_lines_R);\n        alarm 0;\n    };\n    if ($@) {\n        # timed out\n        die unless $@ eq \"alarm\\n\"; # propagate unexpected errors\n        push @{$raa_Errors},\n             [ $Error_Codes{'Diff error, exceeded timeout'}, $file ];\n        if ($opt_v) {\n          warn \"array_diff: diff timeout failure for $file--ignoring\\n\";\n        }\n        return;\n    }\n\n    my $n_L        = 0;\n    my $n_R        = 0;\n    my $n_sdiff    = 0;  # index to $rah_diff_L, $rah_diff_R\n    foreach my $triple (@sdiffs) {\n        my $flag   = $triple->[0];\n        my $line_L = $triple->[1];\n        my $line_R = $triple->[2];\n        $rah_diff_L->[$n_sdiff]{char} = $line_L;\n        $rah_diff_R->[$n_sdiff]{char} = $line_R;\n        if      ($flag eq 'u') {  # u = unchanged\n            ++$n_L;\n            ++$n_R;\n            if ($COMMENT_MODE) {\n                # line exists in both with & without comments, must be code\n                $rah_diff_L->[$n_sdiff]{type} = \"code\";\n                $rah_diff_R->[$n_sdiff]{type} = \"code\";\n            }\n            $rah_diff_L->[$n_sdiff]{desc} = \"same\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"same\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n        } elsif ($flag eq 'c') {  # c = changed\n# warn \"per line sdiff() commented out\\n\"; if (0) {\n            ++$n_L;\n            ++$n_R;\n\n            if ($COMMENT_MODE) {\n                # line has text both with & without comments;\n                # count as code\n                $rah_diff_L->[$n_sdiff]{type} = \"code\";\n                $rah_diff_R->[$n_sdiff]{type} = \"code\";\n            }\n\n            my @chars_L = split '', $line_L;\n            my @chars_R = split '', $line_R;\n\n            $rah_diff_L->[$n_sdiff]{desc} = \"modified\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"modified\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n\n        } elsif ($flag eq '+') {  # + = added\n            ++$n_R;\n            if ($COMMENT_MODE) {\n                # should never get here, but may due to sdiff() bug,\n                # ref https://rt.cpan.org/Public/Bug/Display.html?id=131629\n                # Rather than failing, ignore and continue.  A possible\n                # consequence is counts may be inconsistent.\n#####           @{$rah_diff_L} = ();\n#####           @{$rah_diff_R} = ();\n#####           push @{$raa_Errors},\n#####                [ $Error_Codes{'Diff error (quoted comments?)'}, $file ];\n                if ($opt_v) {\n                  warn \"array_diff: diff failure (diff says the\\n\";\n                  warn \"comment-free file has added lines).\\n\";\n                  warn \"$n_sdiff  $line_L\\n\";\n                }\n            }\n####        $rah_diff_L->[$n_sdiff]{type} = \"nonexist\";\n            $rah_diff_L->[$n_sdiff]{type} = \"comment\";\n            $rah_diff_L->[$n_sdiff]{desc} = \"removed\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"added\";\n            $rah_diff_R->[$n_sdiff]{lnum} = $n_R;\n        } elsif ($flag eq '-') {  # - = removed\n            ++$n_L;\n            if ($COMMENT_MODE) {\n                # line must be comment because blanks already gone\n                $rah_diff_L->[$n_sdiff]{type} = \"comment\";\n            }\n            $rah_diff_R->[$n_sdiff]{type} = \"nonexist\";\n            $rah_diff_R->[$n_sdiff]{desc} = \"removed\";\n            $rah_diff_L->[$n_sdiff]{desc} = \"added\";\n            $rah_diff_L->[$n_sdiff]{lnum} = $n_L;\n        }\n#printf \"%-30s %s %-30s\\n\", $line_L, $separator, $line_R;\n        ++$n_sdiff;\n    }\n#use Data::Dumper::Simple;\n#print Dumper($rah_diff_L, $rah_diff_R);\n#print Dumper($rah_diff_L);\n\n    print \"<- array_diff\\n\" if $opt_v > 2;\n} # 1}}}\nsub remove_leading_dir {                     # {{{1\n    my @filenames = @_;\n    #\n    #  Input should be a list of file names\n    #  with the same leading directory such as\n    #\n    #      dir1/dir2/a.txt\n    #      dir1/dir2/b.txt\n    #      dir1/dir2/dir3/c.txt\n    #\n    #  Output is the same list minus the common\n    #  directory path:\n    #\n    #      a.txt\n    #      b.txt\n    #      dir3/c.txt\n    #\n    print \"-> remove_leading_dir()\\n\" if $opt_v > 2;\n    my @D = (); # a matrix:   [ [ dir1, dir2 ],         # dir1/dir2/a.txt\n                #               [ dir1, dir2 ],         # dir1/dir2/b.txt\n                #               [ dir1, dir2 , dir3] ]  # dir1/dir2/dir3/c.txt\n    if ($ON_WINDOWS) {\n        foreach my $F (@filenames) {\n            $F =~ s{\\\\}{/}g;\n            $F = ucfirst($F) if $F =~ /^\\w:/;  # uppercase drive letter\n        }\n    }\n    if (scalar @filenames == 1) {\n        # special case:  with only one filename\n        # cannot determine a baseline, just remove first directory level\n        $filenames[0] =~ s{^.*?/}{};\n        # print \"-> $filenames[0]\\n\";\n        return $filenames[0];\n    }\n    foreach my $F (@filenames) {\n        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);\n        my @x = File::Spec->splitdir( $Dir );\n        pop @x unless $x[$#x]; # last entry usually null, remove it\n        if ($ON_WINDOWS) {\n            if (defined($Vol) and $Vol) {\n                # put the drive letter, eg, C:, at the front\n                unshift @x, uc $Vol;\n            }\n        }\n#print \"F=$F, Dir=$Dir  x=[\", join(\"][\", @x), \"]\\n\";\n        push @D, [ @x ];\n    }\n\n    # now loop over columns until either they are all\n    # eliminated or a unique column is found\n\n    my @common   = ();  # to contain the common leading directories\n    my $mismatch = 0;\n    while (!$mismatch) {\n        for (my $row = 1; $row < scalar @D; $row++) {\n#print \"comparing $D[$row][0] to $D[0][0]\\n\";\n\n            if (!defined $D[$row][0] or !defined $D[0][0] or\n                ($D[$row][0] ne $D[0][0])) {\n                $mismatch = 1;\n                last;\n            }\n        }\n#print \"mismatch=$mismatch\\n\";\n        if (!$mismatch) {\n            push @common, $D[0][0];\n            # all terms in the leading match; unshift the batch\n            foreach my $ra (@D) {\n                shift @{$ra};\n            }\n        }\n    }\n\n    push @common, \" \";  # so that $leading will end with \"/ \"\n    my $leading = File::Spec->catdir( @common );\n       $leading =~ s{ $}{};  # now take back the bogus appended space\n#print \"remove_leading_dir leading=[$leading]\\n\"; die;\n    if ($ON_WINDOWS) {\n       $leading =~ s{\\\\}{/}g;\n    }\n    foreach my $F (@filenames) {\n        $F =~ s{^$leading}{};\n    }\n\n    print \"<- remove_leading_dir()\\n\" if $opt_v > 2;\n    return @filenames;\n\n} # 1}}}\nsub strip_leading_dir {                      # {{{1\n    my ($leading, @filenames) = @_;\n    #  removes the string $leading from each entry in @filenames\n    print \"-> strip_leading_dir()\\n\" if $opt_v > 2;\n\n#print \"remove_leading_dir leading=[$leading]\\n\"; die;\n    if ($ON_WINDOWS) {\n       $leading =~ s{\\\\}{/}g;\n        foreach my $F (@filenames) {\n            $F =~ s{\\\\}{/}g;\n        }\n    }\n    foreach my $F (@filenames) {\n#print \"strip_leading_dir F before $F\\n\";\n        if ($ON_WINDOWS) {\n            $F =~ s{^$leading}{}i;\n        } else {\n            $F =~ s{^$leading}{};\n        }\n#print \"strip_leading_dir F after  $F\\n\";\n    }\n\n    print \"<- strip_leading_dir()\\n\" if $opt_v > 2;\n    return @filenames;\n\n} # 1}}}\nsub find_deepest_file {                      # {{{1\n    my @filenames = @_;\n    #\n    #  Input should be a list of file names\n    #  with the same leading directory such as\n    #\n    #      dir1/dir2/a.txt\n    #      dir1/dir2/b.txt\n    #      dir1/dir2/dir3/c.txt\n    #\n    #  Output is the file with the most parent directories:\n    #\n    #      dir1/dir2/dir3/c.txt\n\n    print \"-> find_deepest_file()\\n\" if $opt_v > 2;\n\n    my $deepest    = undef;\n    my $max_subdir = -1;\n    foreach my $F (sort @filenames) {\n        my ($Vol, $Dir, $File) = File::Spec->splitpath($F);\n        my @x = File::Spec->splitdir( $Dir );\n        pop @x unless $x[$#x]; # last entry usually null, remove it\n        if (scalar @x > $max_subdir) {\n            $deepest    = $F;\n            $max_subdir = scalar @x;\n        }\n    }\n\n    print \"<- find_deepest_file()\\n\" if $opt_v > 2;\n    return $deepest;\n\n} # 1}}}\nsub find_uncommon_parent_dir {               # {{{1\n    my ($file_L, $file_R) = @_;\n    #\n    # example:\n    #\n    #   file_L = \"perl-5.16.1/cpan/CPANPLUS/lib/CPANPLUS/Internals/Source/SQLite/Tie.pm\"\n    #   file_R = \"/tmp/8VxQG0OLbp/perl-5.16.3/cpan/CPANPLUS/lib/CPANPLUS/Internals/Source/SQLite/Tie.pm\"\n    #\n    # then return\n    #\n    #   \"perl-5.16.1\",\n    #   \"/tmp/8VxQG0OLbp/perl-5.16.3\",\n\n    my ($Vol_L, $Dir_L, $File_L) = File::Spec->splitpath($file_L);\n    my @x_L = File::Spec->splitdir( $Dir_L );\n    my ($Vol_R, $Dir_R, $File_R) = File::Spec->splitpath($file_R);\n    my @x_R = File::Spec->splitdir( $Dir_R );\n\n    my @common  = ();\n\n    # work backwards\n    while ($x_L[$#x_L] eq $x_R[$#x_R]) {\n        push @common, $x_L[$#x_L];\n        pop  @x_L;\n        pop  @x_R;\n    }\n    my $success = scalar @common;\n\n    my $dirs_L = File::Spec->catdir( @x_L );\n    my $dirs_R = File::Spec->catdir( @x_R );\n    my $lead_L = File::Spec->catpath( $Vol_L, $dirs_L, \"\" );\n    my $lead_R = File::Spec->catpath( $Vol_R, $dirs_R, \"\" );\n\n    return $lead_L, $lead_R, $success;\n\n} # 1}}}\nsub get_leading_dirs {                       # {{{1\n    my ($rh_file_list_L, $rh_file_list_R) = @_;\n    # find uniquely named files in both sets to help determine the\n    # leading directory positions\n    my %unique_filename = ();\n    my %basename_L = ();\n    my %basename_R = ();\n    foreach my $f (keys %{$rh_file_list_L}) {\n        my $bn = basename($f);\n        $basename_L{ $bn }{'count'}   += 1;\n        $basename_L{ $bn }{'fullpath'} = $f;\n    }\n    foreach my $f (keys %{$rh_file_list_R}) {\n        my $bn = basename($f);\n        $basename_R{ $bn }{'count'}   += 1;\n        $basename_R{ $bn }{'fullpath'} = $f;\n    }\n    foreach my $f (keys %basename_L) {\n        next unless $basename_L{$f}{'count'} == 1;\n        next unless defined $basename_R{$f} and $basename_R{$f}{'count'} == 1;\n        $unique_filename{$f}{'L'} = $basename_L{ $f }{'fullpath'};\n        $unique_filename{$f}{'R'} = $basename_R{ $f }{'fullpath'};\n    }\n    return undef, undef, 0 unless %unique_filename;\n\n    my ($L_drop, $R_drop) = (undef, undef);\n    foreach my $f (keys %unique_filename) {\n        my $fL = $unique_filename{ $f }{'L'};\n        my $fR = $unique_filename{ $f }{'R'};\n\n        my @DL = File::Spec->splitdir($fL);\n        my @DR = File::Spec->splitdir($fR);\n        # find the most number of common directories between L and R\n        if (!defined $L_drop) {\n            $L_drop = dirname $fL;\n        }\n        if (!defined $R_drop) {\n            $R_drop = dirname $fR;\n        }\n        my $n_path_elements_L = scalar @DL;\n        my $n_path_elements_R = scalar @DR;\n        my $n_path_elem = $n_path_elements_L < $n_path_elements_R ?\n                          $n_path_elements_L : $n_path_elements_R;\n        my ($n_L_drop_this_pair, $n_R_drop_this_pair) = (0, 0);\n        for (my $i = 0; $i < $n_path_elem; $i++) {\n            last if $DL[ $#DL - $i] ne $DR[ $#DR - $i];\n            ++$n_L_drop_this_pair;\n            ++$n_R_drop_this_pair;\n        }\n        my $L_common = File::Spec->catdir( @DL[0..($#DL-$n_L_drop_this_pair)] );\n        my $R_common = File::Spec->catdir( @DR[0..($#DR-$n_R_drop_this_pair)] );\n        $L_drop = $L_common if length $L_common < length $L_drop;\n        $R_drop = $R_common if length $R_common < length $R_drop;\n\n        $L_drop = $L_drop . \"/\" if $L_drop;\n        $R_drop = $R_drop . \"/\" if $R_drop;\n    }\n    # at this point path separator on Windows is already /\n\n    while ($L_drop =~ m{//}) {\n        $L_drop =~ s{//}{/}g;\n    }\n    while ($R_drop =~ m{//}) {\n        $R_drop =~ s{//}{/}g;\n    }\n\n    return $L_drop, $R_drop, 1;\n} # 1}}}\nsub align_by_pairs {                         # {{{1\n    my ($rh_file_list_L        , # in\n        $rh_file_list_R        , # in\n        $ra_added              , # out\n        $ra_removed            , # out\n        $ra_compare_list       , # out\n        ) = @_;\n    print \"-> align_by_pairs()\\n\" if $opt_v > 2;\n    @{$ra_compare_list} = ();\n\n    my @files_L = sort keys %{$rh_file_list_L};\n    my @files_R = sort keys %{$rh_file_list_R};\n    return () unless @files_L or  @files_R;  # at least one must have stuff\n    if ($ON_WINDOWS) {\n        foreach (@files_L) { $_ =~ s{\\\\}{/}g; }\n        foreach (@files_R) { $_ =~ s{\\\\}{/}g; }\n        if ($opt_ignore_case_ext) {\n            foreach (@files_L) { $_ = lc $_; }\n            foreach (@files_R) { $_ = lc $_; }\n        }\n    }\n\n    if      ( @files_L and !@files_R) {\n        # left side has stuff, right side is empty; everything deleted\n        @{$ra_added   }     = ();\n        @{$ra_removed }     = @files_L;\n        @{$ra_compare_list} = ();\n        return;\n    } elsif (!@files_L and  @files_R) {\n        # left side is empty, right side has stuff; everything added\n        @{$ra_added   }     = @files_R;\n        @{$ra_removed }     = ();\n        @{$ra_compare_list} = ();\n        return;\n    } elsif (scalar(@files_L) == 1 and scalar(@files_R) == 1) {\n        # Special case of comparing one file against another.  In\n        # this case force the pair to be aligned with each other,\n        # otherwise the file naming logic will think one file\n        # was added and the other deleted.\n        @{$ra_added   }     = ();\n        @{$ra_removed }     = ();\n        @{$ra_compare_list} = ( [$files_L[0], $files_R[0]] );\n        return;\n    }\n#use Data::Dumper::Simple;\n#print Dumper(\"align_by_pairs\", %{$rh_file_list_L}, %{$rh_file_list_R},);\n#die;\n\n    # The harder case:  compare groups of files.  This only works\n    # if the groups are in different directories so the first step\n    # is to strip the leading directory names from file lists to\n    # make it possible to align by file names.\n    my @files_L_minus_dir = undef;\n    my @files_R_minus_dir = undef;\n\n    my $deepest_file_L    = find_deepest_file(@files_L);\n    my $deepest_file_R    = find_deepest_file(@files_R);\n#print \"deepest L = [$deepest_file_L]\\n\";\n#print \"deepest R = [$deepest_file_R]\\n\";\n    my ($leading_dir_L, $leading_dir_R, $success) =\n                get_leading_dirs($rh_file_list_L, $rh_file_list_R);\n#print \"leading_dir_L=[$leading_dir_L]\\n\";\n#print \"leading_dir_R=[$leading_dir_R]\\n\";\n#print \"success      =[$success]\\n\";\n    if ($success) {\n        @files_L_minus_dir = strip_leading_dir($leading_dir_L, @files_L);\n        @files_R_minus_dir = strip_leading_dir($leading_dir_R, @files_R);\n    } else {\n        # otherwise fall back to old strategy\n        @files_L_minus_dir = remove_leading_dir(@files_L);\n        @files_R_minus_dir = remove_leading_dir(@files_R);\n    }\n\n    # Keys of the stripped_X arrays are canonical file names;\n    # should overlap mostly.  Keys in stripped_L but not in\n    # stripped_R are files that have been deleted.  Keys in\n    # stripped_R but not in stripped_L have been added.\n    my %stripped_L = ();\n       @stripped_L{ @files_L_minus_dir } = @files_L;\n    my %stripped_R = ();\n       @stripped_R{ @files_R_minus_dir } = @files_R;\n\n    my %common = ();\n    foreach my $f (keys %stripped_L) {\n        $common{$f}  = 1 if     defined $stripped_R{$f};\n    }\n\n    my %deleted = ();\n    foreach my $f (keys %stripped_L) {\n        $deleted{$stripped_L{$f}} = $f unless defined $stripped_R{$f};\n    }\n\n    my %added = ();\n    foreach my $f (keys %stripped_R) {\n        $added{$stripped_R{$f}}   = $f unless defined $stripped_L{$f};\n    }\n\n#use Data::Dumper::Simple;\n#print Dumper(\"align_by_pairs\", %stripped_L, %stripped_R);\n#print Dumper(\"align_by_pairs\", %common, %added, %deleted);\n\n    foreach my $f (sort keys %common) {\n        push @{$ra_compare_list}, [ $stripped_L{$f},\n                                    $stripped_R{$f} ];\n    }\n    @{$ra_added   } = keys %added  ;\n    @{$ra_removed } = keys %deleted;\n\n    print \"<- align_by_pairs()\\n\" if $opt_v > 2;\n    return;\n#print Dumper(\"align_by_pairs\", @files_L_minus_dir, @files_R_minus_dir);\n#die;\n} # 1}}}\nsub align_from_git {                         # {{{1\n    # have git identify the files that changed, as well as how\n    my ($L_tag_in              , # in\n        $R_tag_in              , # in\n        $ra_added              , # out\n        $ra_removed            , # out\n        $ra_compare_list       , # out\n        $rh_renamed            , # out\n        ) = @_;\n    print \"-> align_from_git()\\n\" if $opt_v > 2;\n\n    my $L_tag = $L_tag_in;\n    my $R_tag = $R_tag_in;\n    if ($ON_WINDOWS) {\n        $L_tag =~ s{\\\\}{/}g;\n        $R_tag =~ s{\\\\}{/}g;\n    }\n    # On the command line, L_tag and R_tag are commit hashes or tags.  Here they are\n    # replaced with temp directories like /tmp/vGxIL7AWRw and /tmp/BS400yIQEl\n    my $cmd = \"git -c \\\"safe.directory=*\\\" --no-pager diff --name-status --diff-filter=ADRM $L_tag $R_tag\";\n    # Note:  the above command has a problematic side-effect in a git-bash\n    #        terminal on Windows in that the output file path uses the\n    #        native Windows location instead of the Unix-like path.  Here's\n    #        an example:\n    # $ git -c \"safe.directory=*\" --no-pager diff --name-status --diff-filter=ADRM /tmp/pyXXfAJosD /tmp/GftmAmyjOH\n    # M       C:/Users/al/AppData/Local/Temp/pyXXfAJosD/file.js\n    #        In other words, /tmp was replaced by C:/Users/al/AppData/Local/Temp\n    #        This has to be undone otherwise the file pairing will be broken.\n\n\n    # A = added, D = deleted, M = modified, R = renamed; entries tab separated\n    # Example:\n    # M   README.md\n    # R089    package.json    dist/pack age.json-AND\n    # M   package-lock.json\n    # A   src/apps/compare-tags-branches-commits-llm-explanation/README.md\n    # A   src/internals/cloc-git/cloc-diff-rel.ts\n    # D   src/internals/cloc-git/cloc-git-diff-rel-between-commits.ts\n\n    print $cmd, \"\\n\" if $opt_v > 1;\n    open(GSIM, \"$cmd |\") or die \"Unable to run $cmd  $!\";\n    while (<GSIM>) {\n        chomp;\n        my @words = split(/\\t/);\n        if ($ON_MINGW64) {\n            # \"C:/Users/al/AppData/Local/Temp\" => \"/tmp\"\n            $words[1] =~ s{^[A-Z]:/.*?/AppData/Local/Temp}{/tmp};\n        }\n        #print \"align_from_git: words=[@words]\\n\";\n        if (scalar(@words) == 2) {\n            if ($words[0] =~ /^M/) {\n                ( my $right = $words[1] ) =~ s[^${L_tag}/][${R_tag}/];\n                push @{$ra_compare_list}, [ $words[1], $right ];\n            } elsif ($words[0] =~ /^A/) {\n                push @{$ra_added}  , $words[1];\n            } elsif ($words[0] =~ /^D/) {\n                push @{$ra_removed}, $words[1];\n            } else {\n                die \"cloc.align_from_git() parse failure with [$_]\\n\";\n            }\n        } elsif (scalar(@words) == 3) {\n            if ($words[0] =~ /^R/) { # rename\n                ( my $clean_L = $words[1] ) =~ s[^${L_tag}/][];\n                ( my $clean_R = $words[2] ) =~ s[^${R_tag}/][];\n                $rh_renamed->{ $clean_L } = $clean_R;\n                push @{$ra_compare_list}, [ $words[1], $words[2] ];\n            } elsif ($words[0] =~ /^A/) {\n                push @{$ra_added}  , $words[1];\n            } elsif ($words[0] =~ /^D/) {\n                push @{$ra_removed}, $words[1];\n            } else {\n                die \"cloc.align_from_git() parse failure with [$_]\\n\";\n            }\n        } else {\n            die \"Unexpected output from git diff --name-status\\n\";\n        }\n    }\n    close(GSIM);\n\n    print \"<- align_from_git()\\n\" if $opt_v > 2;\n    return;\n} # 1}}}\nsub html_header {                            # {{{1\n    my ($title , ) = @_;\n\n    print \"-> html_header\\n\" if $opt_v > 2;\n    return\n'<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<meta name=\"GENERATOR\" content=\"cloc http://github.com/AlDanial/cloc\">\n' .\n\"\n<!-- Created by $script v$VERSION -->\n<title>$title</title>\n\" .\n'\n<style TYPE=\"text/css\">\n<!--\n    body {\n        color: black;\n        background-color: white;\n        font-family: monospace\n    }\n\n    .whitespace {\n        background-color: gray;\n    }\n\n    .comment {\n        color: gray;\n        font-style: italic;\n    }\n\n    .clinenum {\n        color: red;\n    }\n\n    .linenum {\n        color: green;\n    }\n -->\n</style>\n</head>\n<body>\n<pre><tt>\n';\n    print \"<- html_header\\n\" if $opt_v > 2;\n} # 1}}}\nsub html_end {                               # {{{1\nreturn\n'</tt></pre>\n</body>\n</html>\n';\n} # 1}}}\nsub die_unknown_lang {                       # {{{1\n    my ($lang, $option_name) = @_;\n    die \"Unknown language '$lang' used with $option_name option.  \" .\n        \"The command\\n  $script --show-lang\\n\" .\n        \"will print all recognized languages.  Language names are \" .\n        \"case sensitive.\\n\" ;\n} # 1}}}\nsub unicode_file {                           # {{{1\n    my $file = shift @_;\n\n    print \"-> unicode_file($file)\\n\" if $opt_v > 2;\n    return 0 if (get_size($file) > 2_000_000);\n    # don't bother trying to test binary files bigger than 2 MB\n\n    my $IN = open_file('<', $file, 1);\n    if (!defined $IN) {\n        warn \"Unable to read $file; ignoring.\\n\";\n        return 0;\n    }\n    my @lines = <$IN>;\n    $IN->close;\n\n    if (unicode_to_ascii( join('', @lines) )) {\n        print \"<- unicode_file()\\n\" if $opt_v > 2;\n        return 1;\n    } else {\n        print \"<- unicode_file()\\n\" if $opt_v > 2;\n        return 0;\n    }\n\n} # 1}}}\nsub unicode_to_ascii {                       # {{{1\n    my $string = shift @_;\n\n    # A trivial attempt to convert UTF-16 little or big endian\n    # files into ASCII.  These files exhibit the following byte\n    # sequence:\n    #   byte   1:  255\n    #   byte   2:  254\n    #   byte   3:  ord of ASCII character\n    #   byte   4:    0\n    #   byte 3+i:  ord of ASCII character\n    #   byte 4+i:    0\n    # or\n    #   byte   1:  255\n    #   byte   2:  254\n    #   byte   3:    0\n    #   byte   4:  ord of ASCII character\n    #   byte 3+i:    0\n    #   byte 4+i:  ord of ASCII character\n    #\n    print \"-> unicode_to_ascii()\\n\" if $opt_v > 2;\n\n    my $length  = length $string;\n#print \"length=$length\\n\";\n    return '' if $length <= 3;\n    my @unicode = split(//, $string);\n\n    # check the first 100 characters (= 200 bytes) for big or\n    # little endian UTF-16 encoding\n    my $max_peek     = $length < 200 ? $length : 200;\n    my $max_for_pass = $length < 200 ? 0.9*$max_peek/2 : 90;\n    my @view_1   = ();\n    for (my $i = 2; $i < $max_peek; $i += 2) { push @view_1, $unicode[$i] }\n    my @view_2   = ();\n    for (my $i = 3; $i < $max_peek; $i += 2) { push @view_2, $unicode[$i] }\n\n    my $points_1 = 0;\n    foreach my $C (@view_1) {\n        ++$points_1 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13\n                                                          or ord($C) == 10\n                                                          or ord($C) ==  9;\n    }\n\n    my $points_2 = 0;\n    foreach my $C (@view_2) {\n        ++$points_2 if (32 <= ord($C) and ord($C) <= 127) or ord($C) == 13\n                                                          or ord($C) == 10\n                                                          or ord($C) ==  9;\n    }\n#print \"points 1: $points_1\\n\";\n#print \"points 2: $points_2\\n\";\n#print \"max_peek    : $max_peek\\n\";\n#print \"max_for_pass: $max_for_pass\\n\";\n\n    my $offset = undef;\n    if    ($points_1 > $max_for_pass) { $offset = 2; }\n    elsif ($points_2 > $max_for_pass) { $offset = 3; }\n    else                   {\n        print \"<- unicode_to_ascii() a p1=$points_1 p2=$points_2\\n\" if $opt_v > 2;\n        return '';\n    }  # neither big or little endian UTF-16\n\n    my @ascii              = ();\n    for (my $i = $offset; $i < $length; $i += 2) {\n        # some compound characters are made of HT (9), LF (10), or CR (13)\n        # True HT, LF, CR are followed by 00; only add those.\n        my $L = $unicode[$i];\n        if (ord($L) == 9 or ord($L) == 10 or ord($L) == 13) {\n            my $companion;\n            if ($points_1) {\n                last if $i+1 >= $length;\n                $companion = $unicode[$i+1];\n            } else {\n                $companion = $unicode[$i-1];\n            }\n            if (ord($companion) == 0) {\n                push @ascii, $L;\n            } else {\n                push @ascii, \" \";  # no clue what this letter is\n            }\n        } else {\n            push @ascii, $L;\n        }\n    }\n    print \"<- unicode_to_ascii() b p1=$points_1 p2=$points_2\\n\" if $opt_v > 2;\n    return join(\"\", @ascii);\n} # 1}}}\nsub uncompress_archive_cmd {                 # {{{1\n    my ($archive_file, ) = @_;\n\n    # Wrap $archive_file in single or double quotes in the system\n    # commands below to avoid filename chicanery (including\n    # spaces in the names).\n\n    print \"-> uncompress_archive_cmd($archive_file)\\n\" if $opt_v > 2;\n    my $extract_cmd = \"\";\n    my $missing     = \"\";\n    if ($opt_extract_with) {\n        ( $extract_cmd = $opt_extract_with ) =~ s/>FILE</$archive_file/g;\n    } elsif (basename($archive_file) eq \"-\" and !$ON_WINDOWS) {\n        $extract_cmd = \"cat > -\";\n    } elsif ($archive_file =~ /\\.tar$/ and $ON_WINDOWS) {\n        $extract_cmd = \"tar -xf \\\"$archive_file\\\"\";\n    } elsif (($archive_file =~ /\\.tar\\.(gz|Z)$/ or\n              $archive_file =~ /\\.tgz$/       ) and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"gzip --version\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"gzip -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"gzip\";\n        }\n    } elsif ($archive_file =~ /\\.tar\\.bz2$/ and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"bzip2 --help\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"bzip2 -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"bzip2\";\n        }\n    } elsif ($archive_file =~ /\\.tar\\.xz$/ and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"unxz --version\")) {\n            if (external_utility_exists(\"tar --version\")) {\n                $extract_cmd = \"unxz -dc '$archive_file' | tar xf -\";\n            } else {\n                $missing = \"tar\";\n            }\n        } else {\n            $missing = \"bzip2\";\n        }\n    } elsif ($archive_file =~ /\\.tar$/ and !$ON_WINDOWS)    {\n        $extract_cmd = \"tar xf '$archive_file'\";\n    } elsif ($archive_file =~ /\\.src\\.rpm$/i and !$ON_WINDOWS) {\n        if (external_utility_exists(\"cpio --version\")) {\n            if (external_utility_exists(\"rpm2cpio\")) {\n                $extract_cmd = \"rpm2cpio '$archive_file' | cpio -i\";\n            } else {\n                $missing = \"rpm2cpio\";\n            }\n        } else {\n            $missing = \"cpio\";\n        }\n    } elsif ($archive_file =~ /\\.(whl|zip)$/i and !$ON_WINDOWS)    {\n        if (external_utility_exists(\"unzip\")) {\n            $extract_cmd = \"unzip -qq -d . '$archive_file'\";\n        } else {\n            $missing = \"unzip\";\n        }\n    } elsif ($archive_file =~ /\\.deb$/i and !$ON_WINDOWS)    {\n        # only useful if the .deb contains source code--most\n        # .deb files just have compiled executables\n        if (external_utility_exists(\"dpkg-deb\")) {\n            $extract_cmd = \"dpkg-deb -x '$archive_file' .\";\n        } else {\n            $missing = \"dpkg-deb\";\n        }\n    } elsif ($ON_WINDOWS and $archive_file =~ /\\.(whl|zip)$/i) {\n        # use unzip on Windows (comes with git-for-Windows)\n        if (external_utility_exists(\"unzip\")) {\n             $extract_cmd = \"unzip -qq -d . \\\"$archive_file\\\" \";\n        } else {\n            $missing = \"unzip\";\n        }\n    }\n    print \"<- uncompress_archive_cmd\\n\" if $opt_v > 2;\n    if ($missing) {\n        die \"Unable to expand $archive_file because external\\n\",\n            \"utility '$missing' is not available.\\n\",\n            \"Another possibility is to use the --extract-with option.\\n\";\n    } else {\n        return $extract_cmd;\n    }\n}\n# 1}}}\nsub read_list_file {                         # {{{1\n    my ($file, ) = @_;\n    # reads filenames from a STDIN pipe if $file == \"-\"\n\n    print \"-> read_list_file($file)\\n\" if $opt_v > 2;\n    my @entry = ();\n\n    if ($file eq \"-\") {\n        # read from a STDIN pipe\n        my $IN;\n        open($IN, $file);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            return ();\n        }\n        while (<$IN>) {\n            next if /^\\s*$/ or /^\\s*#/; # skip empty or commented lines\n            s/\\cM$//;  # DOS to Unix\n            chomp;\n            push @entry, $_;\n        }\n        $IN->close;\n    } else {\n        # read from an actual file\n        foreach my $line (read_file($file)) {\n            next if $line =~ /^\\s*$/ or $line =~ /^\\s*#/;\n            $line =~ s/\\cM$//;  # DOS to Unix\n            chomp $line;\n            push @entry, $line;\n        }\n    }\n\n    print \"<- read_list_file\\n\" if $opt_v > 2;\n    return @entry;\n}\n# 1}}}\nsub external_utility_exists {                # {{{1\n    my $exe = shift @_;\n\n    # remove args, if any\n    my $leading_exe = $exe;\n    $leading_exe =~ s/^(\\S+)\\s*.*?$/$1/;\n\n    my $success      = 0;\n    if ($ON_WINDOWS) {\n        $success = 1 unless system $exe . ' > nul';\n    } else {\n        $success = 1 unless system $exe . ' >/dev/null 2>&1';\n        if (!$success) {\n            $success = 1 unless system \"which\" . \" $leading_exe\" . ' >/dev/null 2>&1';\n        }\n    }\n\n    return $success;\n} # 1}}}\nsub write_xsl_file {                         # {{{1\n    print \"-> write_xsl_file\\n\" if $opt_v > 2;\n    my $XSL =             # <style>  </style> {{{2\n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- XSL file by Paul Schwann, January 2009.\n     Fixes for by-file and by-file-by-lang by d_uragan, November 2010.\n     -->\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n  <xsl:output method=\"html\"/>\n  <xsl:template match=\"/\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n      <head>\n        <title>CLOC Results</title>\n      </head>\n      <style type=\"text/css\">\n        table {\n          table-layout: auto;\n          border-collapse: collapse;\n          empty-cells: show;\n        }\n        td, th {\n          padding: 4px;\n        }\n        th {\n          background-color: #CCCCCC;\n        }\n        td {\n          text-align: center;\n        }\n        table, td, tr, th {\n          border: thin solid #999999;\n        }\n      </style>\n      <body>\n        <h3><xsl:value-of select=\"results/header\"/></h3>\n';\n# 2}}}\n\n    if ($opt_by_file) {\n        $XSL .=             # <table> </table>{{{2\n'        <table>\n          <thead>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n              <th>Language</th>\n';\n        $XSL .=\n'             <th>3<sup>rd</sup> Generation Equivalent</th>\n              <th>Scale</th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"results/files/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n              <td><xsl:value-of select=\"@language\"/></td>\n';\n        $XSL .=\n'             <td><xsl:value-of select=\"@factor\"/></td>\n              <td><xsl:value-of select=\"@scaled\"/></td>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </xsl:for-each>\n            <tr>\n              <th>Total</th>\n              <th><xsl:value-of select=\"results/files/total/@blank\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@comment\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@code\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@language\"/></th>\n';\n        $XSL .=\n'             <th><xsl:value-of select=\"results/files/total/@factor\"/></th>\n              <th><xsl:value-of select=\"results/files/total/@scaled\"/></th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </tbody>\n        </table>\n        <br/>\n';\n# 2}}}\n    }\n\n    if (!$opt_by_file or $opt_by_file_by_lang) {\n        $XSL .=             # <table> </table> {{{2\n'       <table>\n          <thead>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n';\n        $XSL .=\n'             <th>Scale</th>\n              <th>3<sup>rd</sup> Generation Equivalent</th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"results/languages/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n';\n        $XSL .=\n'             <td><xsl:value-of select=\"@factor\"/></td>\n              <td><xsl:value-of select=\"@scaled\"/></td>\n' if $opt_3;\n        $XSL .=\n'          </tr>\n          </xsl:for-each>\n            <tr>\n              <th>Total</th>\n              <th><xsl:value-of select=\"results/languages/total/@sum_files\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@blank\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@comment\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@code\"/></th>\n';\n        $XSL .=\n'             <th><xsl:value-of select=\"results/languages/total/@factor\"/></th>\n              <th><xsl:value-of select=\"results/languages/total/@scaled\"/></th>\n' if $opt_3;\n        $XSL .=\n'           </tr>\n          </tbody>\n        </table>\n';\n# 2}}}\n    }\n\n    $XSL.= <<'EO_XSL'; # {{{2\n      </body>\n    </html>\n  </xsl:template>\n</xsl:stylesheet>\n\nEO_XSL\n# 2}}}\n\n    my $XSL_DIFF = <<'EO_DIFF_XSL'; # {{{2\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- XSL file by Blazej Kroll, November 2010 -->\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n  <xsl:output method=\"html\"/>\n  <xsl:template match=\"/\">\n    <html xmlns=\"http://www.w3.org/1999/xhtml\">\n      <head>\n        <title>CLOC Results</title>\n      </head>\n      <style type=\"text/css\">\n        table {\n          table-layout: auto;\n          border-collapse: collapse;\n          empty-cells: show;\n          margin: 1em;\n        }\n        td, th {\n          padding: 4px;\n        }\n        th {\n          background-color: #CCCCCC;\n        }\n        td {\n          text-align: center;\n        }\n        table, td, tr, th {\n          border: thin solid #999999;\n        }\n      </style>\n      <body>\n        <h3><xsl:value-of select=\"results/header\"/></h3>\nEO_DIFF_XSL\n# 2}}}\n\n    if ($opt_by_file) {\n        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Same</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/same/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Modified</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/modified/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Added</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/added/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"4\">Removed</th>\n          </tr>\n            <tr>\n              <th>File</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/removed/file\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\nEO_DIFF_XSL\n# 2}}}\n    }\n\n    if (!$opt_by_file or $opt_by_file_by_lang) {\n        $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Same</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/same/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Modified</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/modified/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Added</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/added/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\n\n        <table>\n          <thead>\n          <tr><th colspan=\"5\">Removed</th>\n          </tr>\n            <tr>\n              <th>Language</th>\n              <th>Files</th>\n              <th>Blank</th>\n              <th>Comment</th>\n              <th>Code</th>\n            </tr>\n          </thead>\n          <tbody>\n          <xsl:for-each select=\"diff_results/removed/language\">\n            <tr>\n              <th><xsl:value-of select=\"@name\"/></th>\n              <td><xsl:value-of select=\"@files_count\"/></td>\n              <td><xsl:value-of select=\"@blank\"/></td>\n              <td><xsl:value-of select=\"@comment\"/></td>\n              <td><xsl:value-of select=\"@code\"/></td>\n            </tr>\n          </xsl:for-each>\n          </tbody>\n        </table>\nEO_DIFF_XSL\n# 2}}}\n\n    }\n\n    $XSL_DIFF.= <<'EO_DIFF_XSL'; # {{{2\n      </body>\n    </html>\n  </xsl:template>\n</xsl:stylesheet>\nEO_DIFF_XSL\n# 2}}}\n    if ($opt_diff) {\n        write_file($CLOC_XSL, {}, ( $XSL_DIFF ) );\n    } else {\n        write_file($CLOC_XSL, {}, ( $XSL ) );\n    }\n    print \"<- write_xsl_file\\n\" if $opt_v > 2;\n} # 1}}}\nsub normalize_file_names {                   # {{{1\n    print \"-> normalize_file_names\\n\" if $opt_v > 2;\n    my (@files, ) = @_;\n\n    # Returns a hash of file names reduced to a canonical form\n    # (fully qualified file names, all path separators changed to /,\n    # Windows file names lowercased).  Hash values are the original\n    # file name.\n\n    my %normalized = ();\n    foreach my $F (@files) {\n        my $F_norm = $F;\n        if ($ON_WINDOWS) {\n            $F_norm = lc $F_norm; # for case insensitive file name comparisons\n            $F_norm =~ s{\\\\}{/}g; # Windows directory separators to Unix\n            $F_norm =~ s{^\\./}{}g;  # remove leading ./\n            if (($F_norm !~ m{^/}) and ($F_norm !~ m{^\\w:/})) {\n                # looks like a relative path; prefix with cwd\n                $F_norm = lc \"$cwd/$F_norm\";\n            }\n        } else {\n            $F_norm =~ s{^\\./}{}g;  # remove leading ./\n            if ($F_norm !~ m{^/}) {\n                # looks like a relative path; prefix with cwd\n                $F_norm = \"$cwd/$F_norm\";\n            }\n        }\n        # Remove trailing / so it does not interfere with further regex code\n        # that does not expect it\n        $F_norm =~ s{/+$}{};\n        $normalized{ $F_norm } = $F;\n    }\n    print \"<- normalize_file_names\\n\" if $opt_v > 2;\n    return %normalized;\n} # 1}}}\nsub combine_diffs {                          # {{{1\n    # subroutine by Andy (awalshe@sf.net)\n    # https://sourceforge.net/tracker/?func=detail&aid=3261017&group_id=174787&atid=870625\n    my ($ra_files) = @_;\n    print \"-> combine_diffs\\n\" if $opt_v > 2;\n\n    my $res   = \"$URL v $VERSION\\n\";\n    my $dl    = '-';\n    my $width = 79;\n    # columns are in this order\n    my @cols  = ('files', 'blank', 'comment', 'code');\n    my %HoH   = ();\n\n    foreach my $file (@{$ra_files}) {\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n\n        my $sec;\n        while (<$IN>) {\n            chomp;\n            s/\\cM$//;\n            next if /^(http|Language|-----)/;\n            if (/^[A-Za-z0-9]+/) {        # section title\n                $sec = $_;\n                chomp($sec);\n                $HoH{$sec} = () if ! exists $HoH{$sec};\n                next;\n            }\n\n            if (/^\\s(same|modified|added|removed)/) {  # calculated totals row\n                my @ar = grep { $_ ne '' } split(/ /, $_);\n                chomp(@ar);\n                my $ttl = shift @ar;\n                my $i = 0;\n                foreach(@ar) {\n                    my $t = \"${ttl}${dl}${cols[$i]}\";\n                    $HoH{$sec}{$t} = 0 if ! exists $HoH{$sec}{$t};\n                    $HoH{$sec}{$t} += $_;\n                    $i++;\n                }\n            }\n        }\n        $IN->close;\n    }\n\n    # rows are in this order\n    my @rows = ('same', 'modified', 'added', 'removed');\n\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n    $res .= sprintf(\"%-19s %14s %14s %14s %14s\\n\", 'Language',\n                    $cols[0], $cols[1], $cols[2], $cols[3]);\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n\n    # no inputs? %HoH will be empty\n    return $res unless %HoH;\n\n    for my $sec ( keys %HoH ) {\n        next if $sec =~ /SUM:/;\n        next unless defined $HoH{$sec};  # eg, the header line\n        $res .= \"$sec\\n\";\n        foreach (@rows) {\n            $res .= sprintf(\" %-18s %14s %14s %14s %14s\\n\",\n                            $_, $HoH{$sec}{\"${_}${dl}${cols[0]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[1]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[2]}\"},\n                                $HoH{$sec}{\"${_}${dl}${cols[3]}\"});\n        }\n    }\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n    my $sec = 'SUM:';\n    $res .= \"$sec\\n\";\n    foreach (@rows) {\n        $res .= sprintf(\" %-18s %14s %14s %14s %14s\\n\",\n                        $_, $HoH{$sec}{\"${_}${dl}${cols[0]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[1]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[2]}\"},\n                            $HoH{$sec}{\"${_}${dl}${cols[3]}\"});\n    }\n    $res .= sprintf(\"%s\\n\", \"-\" x $width);\n\n    print \"<- combine_diffs\\n\" if $opt_v > 2;\n    return $res;\n} # 1}}}\nsub combine_csv_diffs {                      # {{{1\n    my ($delimiter, $ra_files) = @_;\n    print \"-> combine_csv_diffs\\n\" if $opt_v > 2;\n\n    my %sum = ();  # sum{ language } = array of 17 values\n    foreach my $file (@{$ra_files}) {\n        my $IN = open_file('<', $file, 1);\n        if (!defined $IN) {\n            warn \"Unable to read $file; ignoring.\\n\";\n            next;\n        }\n\n        my $sec;\n        while (<$IN>) {\n            next if /^Language${delimiter}\\s==\\sfiles${delimiter}/;\n            chomp;\n            my @words = split(/$delimiter/);\n            my $n_col = scalar(@words);\n            if ($n_col != 18) {\n                warn \"combine_csv_diffs(): Parse failure line $. of $file\\n\";\n                warn \"Expected 18 columns, got $n_col\\n\";\n                die;\n            }\n            my $Lang = $words[0];\n            my @count = map { int($_) } @words[1..16];\n            if (defined $sum{$Lang}) {\n                for (my $i = 0; $i < 16; $i++) {\n                    $sum{$Lang}[$i] += $count[$i];\n                }\n            } else {\n                @{$sum{$Lang}} = @count;\n            }\n        }\n        $IN->close;\n    }\n\n    my @header = (\"Language\", \"== files\", \"!= files\", \"+ files\", \"- files\",\n                  \"== blank\", \"!= blank\", \"+ blank\", \"- blank\", \"== comment\",\n                  \"!= comment\", \"+ comment\", \"- comment\", \"== code\",\n                  \"!= code\", \"+ code\", \"- code\", \"$URL v $VERSION\" );\n\n    my $res = join(\"$delimiter \", @header) . \"$delimiter\\n\";\n    foreach my $Lang (sort keys %sum) {\n        $res .= $Lang . \"$delimiter \";\n        for (my $i = 0; $i < 16; $i++) {\n            $res .= $sum{$Lang}[$i] . \"$delimiter \";\n        }\n        $res .= \"\\n\";\n    }\n\n    print \"<- combine_csv_diffs\\n\" if $opt_v > 2;\n    return $res;\n} # 1}}}\nsub get_time {                               # {{{1\n    if ($HAVE_Time_HiRes) {\n        return Time::HiRes::time();\n    } else {\n        return time();\n    }\n} # 1}}}\nsub really_is_D {                            # {{{1\n    # Ref bug 131, files ending with .d could be init.d scripts\n    # instead of D language source files.\n    my ($file        , # in\n        $rh_Err      , # in   hash of error codes\n        $raa_errors  , # out\n       ) = @_;\n    print \"-> really_is_D($file)\\n\" if $opt_v > 2;\n    my ($possible_script, $L) = peek_at_first_line($file, $rh_Err, $raa_errors);\n\n    print \"<- really_is_D($file)\\n\" if $opt_v > 2;\n    return $possible_script;    # null string if D, otherwise a language\n} # 1}}}\nsub no_autogen_files {                       # {{{1\n    # ref https://github.com/AlDanial/cloc/issues/151\n    my ($print,) = @_;\n    print \"-> no_autogen($print)\\n\" if $opt_v > 2;\n\n    # These sometimes created manually?\n    #               acinclude.m4\n    #               configure.ac\n    #               Makefile.am\n\n    my @files = qw (\n                    aclocal.m4\n                    announce-gen\n                    autogen.sh\n                    bootstrap\n                    compile\n                    config.guess\n                    config.h.in\n                    config.rpath\n                    config.status\n                    config.sub\n                    configure\n                    configure.in\n                    depcomp\n                    gendocs.sh\n                    gitlog-to-changelog\n                    git-version-gen\n                    gnupload\n                    gnu-web-doc-update\n                    install-sh\n                    libtool\n                    libtool.m4\n                    link-warning.h\n                    ltmain.sh\n                    lt~obsolete.m4\n                    ltoptions.m4\n                    ltsugar.m4\n                    ltversion.in\n                    ltversion.m4\n                    Makefile.in\n                    mdate-sh\n                    missing\n                    mkinstalldirs\n                    test-driver\n                    texinfo.tex\n                    update-copyright\n                    useless-if-before-free\n                    vc-list-files\n                    ylwrap\n                   );\n\n    if ($print) {\n        printf \"cloc will ignore these %d files with --no-autogen:\\n\", scalar @files;\n        foreach my $F (@files) {\n            print \"    $F\\n\";\n        }\n        print \"Additionally, Go files with '// Code generated by .* DO NOT EDIT.'\\n\";\n        print \"on the first line are ignored.\\n\";\n    }\n    print \"<- no_autogen()\\n\" if $opt_v > 2;\n    return @files;\n} # 1}}}\nsub load_from_config_file {                  # {{{1\n    # Supports all options except --config itself which would\n    # be pointless.\n    my ($config_file,\n                                                 $rs_by_file             ,\n                                                 $rs_by_file_by_lang     ,\n                                                 $rs_categorized         ,\n                                                 $rs_counted             ,\n                                                 $rs_include_ext         ,\n                                                 $rs_include_lang        ,\n                                                 $rs_include_content     ,\n                                                 $rs_exclude_content     ,\n                                                 $rs_exclude_lang        ,\n                                                 $rs_exclude_dir         ,\n                                                 $rs_exclude_list_file   ,\n                                                 $rs_explain             ,\n                                                 $rs_extract_with        ,\n                                                 $rs_found               ,\n                                                 $rs_count_diff          ,\n                                                 $rs_diff_list_files     ,\n                                                 $rs_diff                ,\n                                                 $rs_diff_alignment      ,\n                                                 $rs_diff_timeout        ,\n                                                 $rs_timeout             ,\n                                                 $rs_html                ,\n                                                 $rs_ignored             ,\n                                                 $rs_unique              ,\n                                                 $rs_quiet               ,\n                                                 $rs_force_lang_def      ,\n                                                 $rs_read_lang_def       ,\n                                                 $rs_show_ext            ,\n                                                 $rs_show_lang           ,\n                                                 $rs_progress_rate       ,\n                                                 $rs_print_filter_stages ,\n                                                 $rs_report_file         ,\n                                                 $ra_script_lang         ,\n                                                 $rs_sdir                ,\n                                                 $rs_skip_uniqueness     ,\n                                                 $rs_strip_code          ,\n                                                 $rs_strip_comments      ,\n                                                 $rs_original_dir        ,\n                                                 $rs_sum_reports         ,\n                                                 $rs_hide_rate           ,\n                                                 $rs_processes           ,\n                                                 $rs_unicode             ,\n                                                 $rs_3                   ,\n                                                 $rs_v                   ,\n                                                 $rs_vcs                 ,\n                                                 $rs_include_submodules  ,\n                                                 $rs_version             ,\n                                                 $rs_write_lang_def      ,\n                                                 $rs_write_lang_def_incl_dup,\n                                                 $rs_xml                 ,\n                                                 $rs_xsl                 ,\n                                                 $ra_force_lang          ,\n                                                 $rs_lang_no_ext         ,\n                                                 $rs_yaml                ,\n                                                 $rs_csv                 ,\n                                                 $rs_csv_delimiter       ,\n                                                 $rs_json                ,\n                                                 $rs_md                  ,\n                                                 $rs_fullpath            ,\n                                                 $rs_match_f             ,\n                                                 $ra_not_match_f         ,\n                                                 $rs_match_d             ,\n                                                 $ra_not_match_d         ,\n                                                 $rs_list_file           ,\n                                                 $rs_help                ,\n                                                 $rs_skip_win_hidden     ,\n                                                 $rs_read_binary_files   ,\n                                                 $rs_sql                 ,\n                                                 $rs_sql_project         ,\n                                                 $rs_sql_append          ,\n                                                 $rs_sql_style           ,\n                                                 $rs_inline              ,\n                                                 $rs_exclude_ext         ,\n                                                 $rs_ignore_whitespace   ,\n                                                 $rs_ignore_case         ,\n                                                 $rs_ignore_case_ext     ,\n                                                 $ra_ignore_regex        ,\n                                                 $rs_follow_links        ,\n                                                 $rs_autoconf            ,\n                                                 $rs_sum_one             ,\n                                                 $rs_by_percent          ,\n                                                 $rs_stdin_name          ,\n                                                 $rs_force_on_windows    ,\n                                                 $rs_force_on_unix       ,\n                                                 $rs_show_os             ,\n                                                 $rs_skip_archive        ,\n                                                 $rs_max_file_size       ,\n                                                 $rs_use_sloccount       ,\n                                                 $rs_no_autogen          ,\n                                                 $rs_force_git           ,\n                                                 $rs_strip_str_comments  ,\n                                                 $rs_file_encoding       ,\n                                                 $rs_docstring_as_code   ,\n                                                 $rs_stat                ,\n                                                 $rs_thousands_delimiter ,\n                                                 $rs_show_errors         ,\n        ) = @_;\n        # look for runtime configuration file in\n        #    $ENV{'HOME'}/.config/cloc/options.txt         -> POSIX\n        #    $ENV{'APPDATA'} . 'cloc'\n\n    print \"-> load_from_config_file($config_file)\\n\" if $opt_v and $opt_v > 2;\n    if (!is_file($config_file)) {\n        print \"<- load_from_config_file() (no such file: $config_file)\\n\" if $opt_v and $opt_v > 2;\n        return;\n    } elsif (!can_read($config_file)) {\n        print \"<- load_from_config_file() (unable to read $config_file)\\n\" if $opt_v and $opt_v > 2;\n        return;\n    }\n    print \"Reading options from $config_file.\\n\" if defined $opt_v;\n\n    my $has_force_lang = @{$ra_force_lang};\n    my $has_script_lang = @{$ra_script_lang};\n    my @lines = read_file($config_file);\n    foreach (@lines) {\n        next if /^\\s*$/ or /^\\s*#/;\n        s/\\s*--//;\n        s/^\\s+//;\n        if      (!defined ${$rs_by_file}             and /^(by_file|by-file)/)                                { ${$rs_by_file}            = 1;\n        } elsif (!defined ${$rs_by_file_by_lang}     and /^(by_file_by_lang|by-file-by-lang)/)                { ${$rs_by_file_by_lang}    = 1;\n        } elsif (!defined ${$rs_categorized}         and /^categorized(=|\\s+)(.*?)$/)                         { ${$rs_categorized}        = $2;\n        } elsif (!defined ${$rs_counted}             and /^counted(=|\\s+)(.*?)$/)                             { ${$rs_counted}            = $2;\n        } elsif (!defined ${$rs_include_ext}         and /^(?:include_ext|include-ext)(=|\\s+)(.*?)$/)         { ${$rs_include_ext}        = $2;\n        } elsif (!defined ${$rs_include_lang}        and /^(?:include_lang|include-lang)(=|\\s+)(.*?)$/)       { ${$rs_include_lang}       = $2;\n        } elsif (!defined ${$rs_include_content}     and /^(?:include_content|include-content)(=|\\s+)(.*?)$/) { ${$rs_include_content}    = $2;\n        } elsif (!defined ${$rs_exclude_content}     and /^(?:exclude_content|exclude-content)(=|\\s+)(.*?)$/) { ${$rs_exclude_content}    = $2;\n        } elsif (!defined ${$rs_exclude_lang}        and /^(?:exclude_lang|exclude-lang)(=|\\s+)(.*?)$/)       { ${$rs_exclude_lang}       = $2;\n        } elsif (!defined ${$rs_exclude_dir}         and /^(?:exclude_dir|exclude-dir)(=|\\s+)(.*?)$/)         { ${$rs_exclude_dir}        = $2;\n        } elsif (!defined ${$rs_explain}             and /^explain(=|\\s+)(.*?)$/)                             { ${$rs_explain}            = $2;\n        } elsif (!defined ${$rs_extract_with}        and /^(?:extract_with|extract-with)(=|\\s+)(.*?)$/)       { ${$rs_extract_with}       = $2;\n        } elsif (!defined ${$rs_found}               and /^found(=|\\s+)(.*?)$/)                               { ${$rs_found}              = $2;\n        } elsif (!defined ${$rs_count_diff}          and /^(count_and_diff|count-and-diff)/)                  { ${$rs_count_diff}         = 1;\n        } elsif (!defined ${$rs_diff_list_files}     and /^(diff_list_files|diff-list-files)/)                { ${$rs_diff_list_files}    = 1;\n        } elsif (!defined ${$rs_diff}                and /^diff/)                                             { ${$rs_diff}               = 1;\n        } elsif (!defined ${$rs_diff_alignment}      and /^(?:diff-alignment|diff_alignment)(=|\\s+)(.*?)$/)   { ${$rs_diff_alignment}     = $2;\n        } elsif (!defined ${$rs_diff_timeout}        and /^(?:diff-timeout|diff_timeout)(=|\\s+)i/)            { ${$rs_diff_timeout}       = $1;\n        } elsif (!defined ${$rs_timeout}             and /^timeout(=|\\s+)i/)                                  { ${$rs_timeout}            = $1;\n        } elsif (!defined ${$rs_html}                and /^html/)                                             { ${$rs_html}               = 1;\n        } elsif (!defined ${$rs_ignored}             and /^ignored(=|\\s+)(.*?)$/)                             { ${$rs_ignored}            = $2;\n        } elsif (!defined ${$rs_unique}              and /^unique(=|\\s+)(.*?)$/)                              { ${$rs_unique}            = $2;\n        } elsif (!defined ${$rs_quiet}               and /^quiet/)                                            { ${$rs_quiet}              = 1;\n        } elsif (!defined ${$rs_force_lang_def}      and /^(?:force_lang_def|force-lang-def)(=|\\s+)(.*?)$/)   { ${$rs_force_lang_def}     = $2;\n        } elsif (!defined ${$rs_read_lang_def}       and /^(?:read_lang_def|read-lang-def)(=|\\s+)(.*?)$/)     { ${$rs_read_lang_def}      = $2;\n        } elsif (!defined ${$rs_progress_rate}       and /^(?:progress_rate|progress-rate)(=|\\s+)(\\d+)/)      { ${$rs_progress_rate}      = $2;\n        } elsif (!defined ${$rs_print_filter_stages} and /^(print_filter_stages|print-filter-stages)/)        { ${$rs_print_filter_stages}= 1;\n        } elsif (!defined ${$rs_report_file}         and /^(?:report_file|report-file)(=|\\s+)(.*?)$/)         { ${$rs_report_file}        = $2;\n        } elsif (!defined ${$rs_report_file}         and /^out(=|\\s+)(.*?)$/)                                 { ${$rs_report_file}        = $2;\n        } elsif (!defined ${$rs_sdir}                and /^sdir(=|\\s+)(.*?)$/)                                { ${$rs_sdir}               = $2;\n        } elsif (!defined ${$rs_skip_uniqueness}     and /^(skip_uniqueness|skip-uniqueness)/)                { ${$rs_skip_uniqueness}    = 1;\n        } elsif (!defined ${$rs_strip_code}          and /^(?:strip_code|strip-code)(=|\\s+)(.*?)$/)           { ${$rs_strip_code}         = $2;\n        } elsif (!defined ${$rs_strip_comments}      and /^(?:strip_comments|strip-comments)(=|\\s+)(.*?)$/)   { ${$rs_strip_comments}     = $2;\n        } elsif (!defined ${$rs_original_dir}        and /^(original_dir|original-dir)/)                      { ${$rs_original_dir}       = 1;\n        } elsif (!defined ${$rs_sum_reports}         and /^(sum_reports|sum-reports)/)                        { ${$rs_sum_reports}        = 1;\n        } elsif (!defined ${$rs_hide_rate}           and /^(hid_rate|hide-rate)/)                             { ${$rs_hide_rate}          = 1;\n        } elsif (!defined ${$rs_processes}           and /^processes(=|\\s+)(\\d+)/)                            { ${$rs_processes}          = $2;\n        } elsif (!defined ${$rs_unicode}             and /^unicode/)                                          { ${$rs_unicode}            = 1;\n        } elsif (!defined ${$rs_3}                   and /^3/)                                                { ${$rs_3}                  = 1;\n        } elsif (!defined ${$rs_vcs}                 and /^vcs(=|\\s+)(\\S+)/)                                  { ${$rs_vcs}                = $2;\n        } elsif (!defined ${$rs_include_submodules}  and /^include-submodules/)                               { ${$rs_include_submodules} = 1;\n        } elsif (!defined ${$rs_version}             and /^version/)                                          { ${$rs_version}            = 1;\n        } elsif (!defined ${$rs_write_lang_def}      and /^(?:write_lang_def|write-lang-def)(=|\\s+)(.*?)$/)   { ${$rs_write_lang_def}     = $2;\n        } elsif (!defined ${$rs_write_lang_def_incl_dup} and /^(?:write_lang_def_incl_dup|write-lang-def-incl-dup)(=|\\s+)(.*?)$/) { ${$rs_write_lang_def_incl_dup} = $2;\n        } elsif (!defined ${$rs_xml}                 and /^xml/)                                              { ${$rs_xml}                = 1;\n        } elsif (!defined ${$rs_xsl}                 and /^xsl(=|\\s+)(.*?)$/)                                 { ${$rs_xsl}                = $2;\n        } elsif (!defined ${$rs_lang_no_ext}         and /^(?:lang_no_ext|lang-no-ext)(=|\\s+)(.*?)$/)         { ${$rs_lang_no_ext}        = $2;\n        } elsif (!defined ${$rs_yaml}                and /^yaml/)                                             { ${$rs_yaml}               = 1;\n        } elsif (!defined ${$rs_csv}                 and /^csv/)                                              { ${$rs_csv}                = 1;\n        } elsif (!defined ${$rs_csv_delimiter}       and /^(?:csv_delimiter|csv-delimiter)(=|\\s+)(.*?)$/)     { ${$rs_csv_delimiter}      = $2;\n        } elsif (!defined ${$rs_json}                and /^json/)                                             { ${$rs_json}               = 1;\n        } elsif (!defined ${$rs_md}                  and /^md/)                                               { ${$rs_md}                 = 1;\n        } elsif (!defined ${$rs_fullpath}            and /^fullpath/)                                         { ${$rs_fullpath}           = 1;\n        } elsif (!defined ${$rs_match_f}             and /^(?:match_f|match-f)(=|\\s+)['\"]?(.*?)['\"]?$/)       { ${$rs_match_f}            = $2;\n        } elsif (!        @{$ra_not_match_f}         and /^(?:not_match_f|not-match-f)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_not_match_f}   , $2;\n        } elsif (!defined ${$rs_match_d}             and /^(?:match_d|match-d)(=|\\s+)['\"]?(.*?)['\"]?$/)       { ${$rs_match_d}            = $2;\n        } elsif (!        @{$ra_not_match_d}         and /^(?:not_match_d|not-match-d)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_not_match_d}   , $2;\n        } elsif (!defined ${$rs_list_file}           and /^(?:list_file|list-file)(=|\\s+)(.*?)$/)             { ${$rs_list_file}          = $2;\n        } elsif (!defined ${$rs_help}                and /^help/)                                             { ${$rs_help}               = 1;\n        } elsif (!defined ${$rs_skip_win_hidden}     and /^(skip_win_hidden|skip-win-hidden)/)                { ${$rs_skip_win_hidden}    = 1;\n        } elsif (!defined ${$rs_read_binary_files}   and /^(read_binary_files|read-binary-files)/)            { ${$rs_read_binary_files}  = 1;\n        } elsif (!defined ${$rs_sql}                 and /^sql(=|\\s+)(.*?)$/)                                 { ${$rs_sql}                = $2;\n        } elsif (!defined ${$rs_sql_project}         and /^(?:sql_project|sql-project)(=|\\s+)(.*?)$/)         { ${$rs_sql_project}        = $2;\n        } elsif (!defined ${$rs_sql_append}          and /^(sql_append|sql-append)/)                          { ${$rs_sql_append}         = 1;\n        } elsif (!defined ${$rs_sql_style}           and /^(?:sql_style|sql-style)(=|\\s+)(.*?)$/)             { ${$rs_sql_style}          = $2;\n        } elsif (!defined ${$rs_inline}              and /^inline/)                                           { ${$rs_inline}             = 1;\n        } elsif (!defined ${$rs_exclude_ext}         and /^(?:exclude_ext|exclude-ext)(=|\\s+)(.*?)$/)         { ${$rs_exclude_ext}        = $2;\n        } elsif (!defined ${$rs_ignore_whitespace}   and /^(ignore_whitespace|ignore-whitespace)/)            { ${$rs_ignore_whitespace}  = 1;\n        } elsif (!defined ${$rs_ignore_case_ext}     and /^(ignore_case_ext|ignore-case-ext)/)                { ${$rs_ignore_case_ext}    = 1;\n        } elsif (!defined ${$rs_ignore_case}         and /^(ignore_case|ignore-case)/)                        { ${$rs_ignore_case}        = 1;\n        } elsif (!        @{$ra_ignore_regex}        and /^(?:ignore_regex|ignore-regex)(=|\\s+)['\"]?(.*?)['\"]?$/) { push @{$ra_ignore_regex}, $2;\n        } elsif (!defined ${$rs_follow_links}        and /^(follow_links|follow-links)/)                      { ${$rs_follow_links}       = 1;\n        } elsif (!defined ${$rs_autoconf}            and /^autoconf/)                                         { ${$rs_autoconf}           = 1;\n        } elsif (!defined ${$rs_sum_one}             and /^(sum_one|sum-one)/)                                { ${$rs_sum_one}            = 1;\n        } elsif (!defined ${$rs_by_percent}          and /^(?:by_percent|by-percent)(=|\\s+)(.*?)$/)           { ${$rs_by_percent}         = $2;\n        } elsif (!defined ${$rs_stdin_name}          and /^(?:stdin_name|stdin-name)(=|\\s+)(.*?)$/)           { ${$rs_stdin_name}         = $2;\n        } elsif (!defined ${$rs_force_on_windows}    and /^windows/)                                          { ${$rs_force_on_windows}   = 1;\n        } elsif (!defined ${$rs_force_on_unix}       and /^unix/)                                             { ${$rs_force_on_unix}      = 1;\n        } elsif (!defined ${$rs_show_os}             and /^(show_os|show-os)/)                                { ${$rs_show_os}            = 1;\n        } elsif (!defined ${$rs_skip_archive}        and /^(?:skip_archive|skip-archive)(=|\\s+)(.*?)$/)       { ${$rs_skip_archive}       = $2;\n        } elsif (!defined ${$rs_max_file_size}       and /^(?:max_file_size|max-file-size)(=|\\s+)(\\d+)/)      { ${$rs_max_file_size}      = $2;\n        } elsif (!defined ${$rs_use_sloccount}       and /^(use_sloccount|use-sloccount)/)                    { ${$rs_use_sloccount}      = 1;\n        } elsif (!defined ${$rs_no_autogen}          and /^(no_autogen|no-autogen)/)                          { ${$rs_no_autogen}         = 1;\n        } elsif (!defined ${$rs_force_git}           and /^git/)                                              { ${$rs_force_git}          = 1;\n        } elsif (!defined ${$rs_exclude_list_file}   and /^(?:exclude_list_file|exclude-list-file)(=|\\s+)(.*?)$/)\n                                                                   { ${$rs_exclude_list_file}  = $2;\n        } elsif (!defined ${$rs_v} and /^(verbose|v)((=|\\s+)(\\d+))?/) {\n            if (!defined $4) { ${$rs_v} =  0; }\n            else             { ${$rs_v} = $4; }\n        } elsif (!$has_script_lang and /^(?:script_lang|script-lang)(=|\\s+)(.*?)$/)         {\n                                                            push @{$ra_script_lang}          , $2;\n        } elsif (!$has_force_lang and /^(?:force_lang|force-lang)(=|\\s+)(.*?)$/)           {\n                                                            push @{$ra_force_lang}           , $2;\n        } elsif (!defined ${$rs_show_ext}          and /^(show_ext|show-ext)((=|\\s+)(.*))?$/)  {\n            if (!defined $4) { ${$rs_show_ext} =  0; }\n            else             { ${$rs_show_ext} = $4; }\n        } elsif (!defined ${$rs_show_lang}         and /^(show_lang|show-lang)((=|\\s+)(.*))?s/){\n            if (!defined $4) { ${$rs_show_lang} =  0; }\n            else             { ${$rs_show_lang} = $4; }\n        } elsif (!defined ${$rs_strip_str_comments}  and /^(strip_str_comments|strip-str-comments)/)     { ${$rs_strip_str_comments} = 1;\n        } elsif (!defined ${$rs_file_encoding}       and /^(?:file_encoding|file-encoding)(=|\\s+)(\\S+)/) { ${$rs_file_encoding}      = $2;\n        } elsif (!defined ${$rs_docstring_as_code}   and /^(docstring_as_code|docstring-as-code)/)       { ${$rs_docstring_as_code}  = 1;\n        } elsif (!defined ${$rs_stat}                and /stat/)                                         { ${$rs_stat}               = 1;\n        } elsif (!defined ${$rs_thousands_delimiter} and /^ksep|thousands-delimiter(=|\\s+)(.*?)$/)       { ${$rs_thousands_delimiter}= $2;\n        } elsif (!defined ${$rs_show_errors}         and /show_errors|show-errors/)                      { ${$rs_show_errors}        = 1;\n        }\n\n    }\n} # 1}}}\nsub trick_pp_packer_encode {                 # {{{1\n    use Encode;\n    # PAR::Packer gives 'Unknown PerlIO layer \"encoding\"' unless it is\n    # forced into using this module.\n    my ($OUT, $JunkFile) = tempfile(UNLINK => 1);  # delete on exit\n    open($OUT, \"> :encoding(utf8)\", $JunkFile);\n    close($OUT);\n}\n# 1}}}\nsub really_is_smarty {                       # {{{1\n    # Given filename, returns TRUE if its contents look like Smarty template\n    my ($filename, ) = @_;\n\n    print \"-> really_is_smarty($filename)\\n\" if $opt_v > 2;\n\n    my @lines = read_file($filename);\n\n    my $points = 0;\n    foreach my $L (@lines) {\n        if (($L =~ /\\{(if|include)\\s/) or\n            ($L =~ /\\{\\/if\\}/)         or\n            ($L =~ /(\\{\\*|\\*\\})/)      or\n            ($L =~ /\\{\\$\\w/)) {\n            ++$points;\n        }\n        last if $points >= 2;\n    }\n    print \"<- really_is_smarty(points=$points)\\n\" if $opt_v > 2;\n    return $points >= 2;\n} # 1}}}\nsub check_alternate_config_files {           # {{{1\n    my ($list_file, $exclude_list_file, $read_lang_def,\n        $force_lang_def, $diff_list_file, ) = @_;\n    my $found_it = \"\";\n    foreach my $file ($list_file,\n                      $exclude_list_file,\n                      $read_lang_def,\n                      $force_lang_def,\n                      $diff_list_file ) {\n        next unless defined $file;\n        my $dir = dirname $file;\n        next unless can_read($dir) and is_dir($dir);\n        my $bn = basename $config_file;\n        if (can_read(\"$dir/$bn\")) {\n            $found_it = \"$dir/$bn\";\n            print \"Using configuration file $found_it\\n\" if $opt_v;\n            last;\n        }\n    }\n    return $found_it;\n}\n# 1}}}\nsub write_null_results {                     # {{{\n    my ($json, $xml, $report_file,) = @_;\n    print \"-> write_null_results\\n\" if $opt_v > 2;\n    if ((defined $json) or (defined $xml)) {\n        my $line = \"\";\n        if (defined $json) {\n            $line = \"{}\";\n        } else {\n            $line = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><results/>';\n        }\n        if (defined $report_file) {\n            open OUT, \">$report_file\" or die \"Cannot write to $report_file $!\\n\";\n            print OUT \"$line\\n\";\n            close OUT;\n        } else {\n            print \"$line\\n\";\n        }\n    }\n    print \"<- write_null_results\\n\" if $opt_v > 2;\n} # }}}\nsub glob2regex {                             # {{{\n    # convert simple xpath-style glob pattern to a regex\n    my $globstr = shift;\n    my $re = $globstr;\n    $re =~ s{^[\"']}{};\n    $re =~ s{^\\.\\/}{};\n    $re =~ s{[\"']$}{};\n    $re =~ s{\\.}{\\\\.}g;\n    $re =~ s{\\*\\*}{\\cx}g;  # ctrl x  = .*?\n    $re =~ s{\\*}{\\cy}g;    # ctrl y = [^/]*\n    $re =~ s{\\cx}{.*?}g;\n    $re =~ s{\\cy}{[^/]*}g;\n    return '^' . $re . '$';\n} # }}}\nsub load_json {                              # {{{1\n    #\n    # Load a cloc-generated JSON string into %contents\n    #   $contents{filename}{blank|comment|code|language} = value\n    # then print in a variety of formats.\n    #\n    my ($json_string, ) = @_;\n    print \"-> load_json()\\n\" if $opt_v > 2;\n\n    my %contents = ();\n    my $heading = undef;\n    foreach (split /\\n/, $json_string) {\n        if (/^{?\"(.*?)\"/) {\n            $heading = $1;\n        } else {\n            if (/^\\s+\"(.*?)\"\\s*:\\s+(\\d+(\\.\\d+)?)\\b/) {\n                # numeric value\n                $contents{$heading}{$1} = $2;\n            } elsif (/^\\s+\"(.*?)\"\\s*:\\s+\"(.*?)\"/) {\n                $contents{$heading}{$1} = $2;\n            }\n        }\n    }\n    my $url = $contents{'header'}{'cloc_url'};\n    my $ver = $contents{'header'}{'cloc_version'};\n    my $sec = $contents{'header'}{'elapsed_seconds'};\n    my $n_file = $contents{'header'}{'n_files'};\n    my $n_line = $contents{'header'}{'n_lines'};\n    $sec = $sec == 0 ? 1.0e-3 : $sec;\n    my $header = sprintf \"%s v %s T=%.2f s (%.1f files/s, %.1f lines/s)\",\n                          $url, $ver, $sec, $n_file/$sec, $n_line/$sec;\n    delete $contents{'header'};\n    delete $contents{'SUM'};\n\n    my @file_list = (sort { $contents{$b}{'code'} <=>\n                            $contents{$a}{'code'} } keys %contents );\n#die Dumper(\\%contents);\n    # Determine column widths for output\n    my $file_len = 0;\n    my $lang_len = 0;\n    foreach my $file (keys %contents) {\n        my $flen = length $file;\n        my $llen = length $contents{$file}{'language'};\n        $file_len = $file_len > $flen ? $file_len : $flen;\n        $lang_len = $lang_len > $llen ? $lang_len : $llen;\n    }\n    print \"<- load_json()\\n\" if $opt_v > 2;\n    return $file_len, $lang_len, $header, %contents;\n}\n# 1}}}\nsub print_format_n {                         # {{{1\n    # by file with\n    # format 1 : Language | files | blank | comment | code\n    # format 2 : Language | files | blank | comment | code | total\n    # format 3 : File | Language | blank | comment | code\n    # format 4 : File | blank | comment | code | total\n    # format 5 : File | Language | blank | comment | code | total\n    my ($format, $file_len, $lang_len, $header, %contents) = @_;\n    print \"-> print_format_n($format)\\n\" if $opt_v > 2;\n    my @prt_lines = ();\n\n    # 8 = characters in \"Language\"\n    $lang_len = max(8, $lang_len);\n    my %str_fmt = (\n        1 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        2 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        3 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n        4 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len),\n        5 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n    );\n    my %val_fmt = (\n        1 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        2 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s  %%7s\\n\", $lang_len),\n        3 => sprintf(\"%%-%ds  %%-%ds  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n        4 => sprintf(\"%%-%ds  %%7s  %%7s  %%7s  %%7s\\n\", $file_len),\n        5 => sprintf(\"%%-%ds  %%-%ds  %%7d  %%7s  %%7s  %%7s\\n\", $file_len, $lang_len),\n    );\n    my %language = ();\n    foreach my $file (keys %contents) {\n        my $lang = $contents{$file}{'language'};\n        $language{$lang}{'files'} += 1;\n        foreach my $category ('blank', 'comment', 'code',) {\n            $language{$lang}{$category} += $contents{$file}{$category};\n            $language{$lang}{'total'}   += $contents{$file}{$category};\n        }\n    }\n    my @file_list = (sort { $contents{$b}{'code'} <=>\n                            $contents{$a}{'code'} } keys %contents );\n    my @lang_list = (sort { $language{$b}{'code'} <=>\n                            $language{$a}{'code'} } keys %language );\n\n    my %hyphens = (\n        1 => \"-\" x ($lang_len + 4*9),\n        2 => \"-\" x ($lang_len + 5*9),\n        3 => \"-\" x ($lang_len + $file_len + 2 + 3*9),\n        4 => \"-\" x ($file_len + 4*9),\n        5 => \"-\" x ($lang_len + $file_len + 2 + 4*9),\n    );\n    my %col_headings = (\n        1 => [\"Language\", \"files\", \"blank\", \"comment\", \"code\"],\n        2 => [\"Language\", \"files\", \"blank\", \"comment\", \"code\", \"Total\"],\n        3 => [\"File\", \"Language\", \"blank\", \"comment\", \"code\"],\n        4 => [\"File\", \"blank\", \"comment\", \"code\", \"Total\"],\n        5 => [\"File\", \"Language\", \"blank\", \"comment\", \"code\", \"Total\"],\n    );\n\n    push @prt_lines, \"$header\\n\";\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    push @prt_lines, sprintf $str_fmt{$format}, @{$col_headings{$format}};\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    my ($n_files, $n_blank, $n_comment, $n_code, $n_total) = (0, 0, 0, 0, 0);\n    my @out;\n    my $sum;\n    if ($format < 3) {\n        # by language\n        foreach my $lang (@lang_list) {\n            my ($nF, $nB, $nCm, $nCo) = ($language{$lang}{'files'},\n                                         $language{$lang}{'blank'},\n                                         $language{$lang}{'comment'},\n                                         $language{$lang}{'code'});\n            $n_files   += $nF;\n            $n_blank   += $nB;\n            $n_comment += $nCm;\n            $n_code    += $nCo;\n            $n_total   += $nB + $nCm + $nCo;\n            $sum = $nB + $nCm + $nCo;\n            if ($opt_thousands_delimiter) {\n                $sum = separate_thousands($sum, $opt_thousands_delimiter);\n                $nF  = separate_thousands($nF,  $opt_thousands_delimiter);\n                $nB  = separate_thousands($nB,  $opt_thousands_delimiter);\n                $nCm = separate_thousands($nCm, $opt_thousands_delimiter);\n                $nCo = separate_thousands($nCo, $opt_thousands_delimiter);\n            }\n            if      ($format == 1) {\n                @out = ($lang, $nF, $nB, $nCm, $nCo);\n            } else {\n                @out = ($lang, $nF, $nB, $nCm, $nCo, $sum);\n            }\n            push @prt_lines, sprintf $str_fmt{$format}, @out;\n        }\n    } else {\n        # by file\n        foreach my $file (@file_list) {\n            my ($nB, $nCm, $nCo) = ($contents{$file}{'blank'},\n                                    $contents{$file}{'comment'},\n                                    $contents{$file}{'code'});\n            $n_blank   += $nB;\n            $n_comment += $nCm;\n            $n_code    += $nCo;\n            $n_total   += $nB + $nCm + $nCo;\n            $sum = $nB + $nCm + $nCo;\n            if ($opt_thousands_delimiter) {\n                $sum = separate_thousands($sum, $opt_thousands_delimiter);\n                $nB  = separate_thousands($nB,  $opt_thousands_delimiter);\n                $nCm = separate_thousands($nCm, $opt_thousands_delimiter);\n                $nCo = separate_thousands($nCo, $opt_thousands_delimiter);\n            }\n            my $lang = $contents{$file}{'language'};\n            if      ($format == 1) {\n            } elsif ($format == 3) {\n                @out = ($file, $lang, $nB, $nCm, $nCo);\n            } elsif ($format == 4) {\n                @out = ($file, $nB, $nCm, $nCo, $sum);\n            } else {\n                @out = ($file, $lang, $nB, $nCm, $nCo, $sum);\n            }\n            push @prt_lines, sprintf $str_fmt{$format}, @out;\n        }\n    }\n    push @prt_lines, \"$hyphens{$format}\\n\";\n    if (scalar @file_list > 1) {\n        if ($opt_thousands_delimiter) {\n            $n_files   = separate_thousands($n_files,   $opt_thousands_delimiter);\n            $n_blank   = separate_thousands($n_blank,   $opt_thousands_delimiter);\n            $n_comment = separate_thousands($n_comment, $opt_thousands_delimiter);\n            $n_code    = separate_thousands($n_code,    $opt_thousands_delimiter);\n            $n_total   = separate_thousands($n_total,   $opt_thousands_delimiter);\n        }\n        if      ($format == 1) {\n            @out = ( \"SUM\", $n_files, $n_blank, $n_comment, $n_code);\n        } elsif ($format == 2) {\n            @out = ( \"SUM\", $n_files, $n_blank, $n_comment, $n_code, $n_total);\n        } elsif ($format == 3) {\n            @out = ( \"SUM\", \" \", $n_blank, $n_comment, $n_code);\n        } elsif ($format == 4) {\n            @out = ( \"SUM\", $n_blank, $n_comment, $n_code, $n_total);\n        } else {\n            @out = ( \"SUM\", \" \", $n_blank, $n_comment, $n_code, $n_total);\n        }\n        push @prt_lines, sprintf $str_fmt{$format}, @out;\n        push @prt_lines, \"$hyphens{$format}\\n\";\n    }\n    return @prt_lines;\n    print \"<- print_format_n()\\n\" if $opt_v > 2;\n} # 1}}}\nsub parse_ignore_regex {                              # {{{1\n    #\n    # Convert the list of \"language(s)|regex\" into a hash\n    #   $ignore_regex{language} = [list of regex]\n\n    my ($ra_lang_regex           , # in, as given on command line\n        $rhaa_Filters_by_Language, # in, hash of filters by language\n        $rha_ignore_regex) = @_;\n    print \"-> parse_ignore_regex()\\n\" if $opt_v > 2;\n\n    foreach my $lang_regex (@{$ra_lang_regex}) {\n        die \"Missing '|' character in --ignore-regex '$lang_regex'\\n\"\n            unless $lang_regex =~ /\\|/;\n        my ($lang, $regex) = split(/\\|/, $lang_regex, 2);\n        die \"Invalid --ignore-regex: $lang_regex\\n\"\n            unless defined $lang and defined $regex;\n        my @languages = split(/,/, $lang);\n        foreach my $lang (@languages) {\n            if ($lang eq '*') {\n                foreach my $lang (keys %{$rhaa_Filters_by_Language}) {\n                    push @{$rha_ignore_regex->{$lang}}, $regex;\n                }\n            } else {\n                die \"Unknown language '$lang' in --ignore-regex '$lang_regex'\\n\"\n                    unless defined $rhaa_Filters_by_Language->{$lang};\n                push @{$rha_ignore_regex->{$lang}}, $regex;\n            }\n#print \"lang=$lang  regex=[$regex]\\n\";\n        }\n    }\n#use Data::Dumper;\n#print Dumper($rha_ignore_regex);\n    print \"<- parse_ignore_regex()\\n\" if $opt_v > 2;\n}\n# 1}}}\n# really_is_pascal, really_is_incpascal, really_is_php from SLOCCount\nmy %php_files    = ();  # really_is_php()\nsub really_is_pascal {                       # {{{1\n# Given filename, returns TRUE if its contents really are Pascal.\n\n# This isn't as obvious as it seems.\n# Many \".p\" files are Perl files\n# (such as /usr/src/redhat/BUILD/ispell-3.1/dicts/czech/glob.p),\n# others are C extractions\n# (such as /usr/src/redhat/BUILD/linux/include/linux/umsdos_fs.p\n# and some files in linuxconf).\n# However, test files in \"p2c\" really are Pascal, for example.\n\n# Note that /usr/src/redhat/BUILD/ucd-snmp-4.1.1/ov/bitmaps/UCD.20.p\n# is actually C code.  The heuristics determine that they're not Pascal,\n# but because it ends in \".p\" it's not counted as C code either.\n# I believe this is actually correct behavior, because frankly it\n# looks like it's automatically generated (it's a bitmap expressed as code).\n# Rather than guess otherwise, we don't include it in a list of\n# source files.  Let's face it, someone who creates C files ending in \".p\"\n# and expects them to be counted by default as C files in SLOCCount needs\n# their head examined.  I suggest examining their head\n# with a sucker rod (see syslogd(8) for more on sucker rods).\n\n# This heuristic counts as Pascal such files such as:\n#  /usr/src/redhat/BUILD/teTeX-1.0/texk/web2c/tangleboot.p\n# Which is hand-generated.  We don't count woven documents now anyway,\n# so this is justifiable.\n\n my $filename = shift;\n chomp($filename);\n\n# The heuristic is as follows: it's Pascal _IF_ it has all of the following\n# (ignoring {...} and (*...*) comments):\n# 1. \"^..program NAME\" or \"^..unit NAME\",\n# 2. \"procedure\", \"function\", \"^..interface\", or \"^..implementation\",\n# 3. a \"begin\", and\n# 4. it ends with \"end.\",\n#\n# Or it has all of the following:\n# 1. \"^..module NAME\" and\n# 2. it ends with \"end.\".\n#\n# Or it has all of the following:\n# 1. \"^..program NAME\",\n# 2. a \"begin\", and\n# 3. it ends with \"end.\".\n#\n# The \"end.\" requirements in particular filter out non-Pascal.\n#\n# Note (jgb): this does not detect Pascal main files in fpc, like\n# fpc-1.0.4/api/test/testterminfo.pas, which does not have \"program\" in\n# it\n\n my $is_pascal = 0;      # Value to determine.\n\n my $has_program = 0;\n my $has_unit = 0;\n my $has_module = 0;\n my $has_procedure_or_function = 0;\n my $found_begin = 0;\n my $found_terminating_end = 0;\n my $has_begin = 0;\n\n my $PASCAL_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's pascal.\\n\" if !defined $PASCAL_FILE;\n while(<$PASCAL_FILE>) {\n   s/\\{.*?\\}//g;  # Ignore {...} comments on this line; imperfect, but effective.\n   s/\\(\\*.*?\\*\\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.\n   if (m/\\bprogram\\s+[A-Za-z]/i)  {$has_program=1;}\n   if (m/\\bunit\\s+[A-Za-z]/i)     {$has_unit=1;}\n   if (m/\\bmodule\\s+[A-Za-z]/i)   {$has_module=1;}\n   if (m/\\bprocedure\\b/i)         { $has_procedure_or_function = 1; }\n   if (m/\\bfunction\\b/i)          { $has_procedure_or_function = 1; }\n   if (m/^\\s*interface\\s+/i)      { $has_procedure_or_function = 1; }\n   if (m/^\\s*implementation\\s+/i) { $has_procedure_or_function = 1; }\n   if (m/\\bbegin\\b/i) { $has_begin = 1; }\n   # Originally I said:\n   # \"This heuristic fails if there are multi-line comments after\n   # \"end.\"; I haven't seen that in real Pascal programs:\"\n   # But jgb found there are a good quantity of them in Debian, specially in\n   # fpc (at the end of a lot of files there is a multiline comment\n   # with the changelog for the file).\n   # Therefore, assume Pascal if \"end.\" appears anywhere in the file.\n   if (m/end\\.\\s*$/i) {$found_terminating_end = 1;}\n#   elsif (m/\\S/) {$found_terminating_end = 0;}\n }\n close($PASCAL_FILE);\n\n # Okay, we've examined the entire file looking for clues;\n # let's use those clues to determine if it's really Pascal:\n\n if ( ( ($has_unit || $has_program) && $has_procedure_or_function &&\n     $has_begin && $found_terminating_end ) ||\n      ( $has_module && $found_terminating_end ) ||\n      ( $has_program && $has_begin && $found_terminating_end ) )\n          {$is_pascal = 1;}\n\n return $is_pascal;\n} # 1}}}\nsub really_is_incpascal {                    # {{{1\n# Given filename, returns TRUE if its contents really are Pascal.\n# For .inc files (mainly seen in fpc)\n\n my $filename = shift;\n chomp($filename);\n\n# The heuristic is as follows: it is Pascal if any of the following:\n# 1. really_is_pascal returns true\n# 2. Any usual reserved word is found (program, unit, const, begin...)\n\n # If the general routine for Pascal files works, we have it\n if (really_is_pascal($filename)) {\n   return 1;\n }\n\n my $is_pascal = 0;      # Value to determine.\n my $found_begin = 0;\n\n my $PASCAL_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's pascal.\\n\" if !defined $PASCAL_FILE;\n while(<$PASCAL_FILE>) {\n   s/\\{.*?\\}//g;  # Ignore {...} comments on this line; imperfect, but effective.\n   s/\\(\\*.*?\\*\\)//g;  # Ignore (*...*) comments on this line; imperfect, but effective.\n   if (m/\\bprogram\\s+[A-Za-z]/i)  {$is_pascal=1;}\n   if (m/\\bunit\\s+[A-Za-z]/i)     {$is_pascal=1;}\n   if (m/\\bmodule\\s+[A-Za-z]/i)   {$is_pascal=1;}\n   if (m/\\bprocedure\\b/i)         {$is_pascal = 1; }\n   if (m/\\bfunction\\b/i)          {$is_pascal = 1; }\n   if (m/^\\s*interface\\s+/i)      {$is_pascal = 1; }\n   if (m/^\\s*implementation\\s+/i) {$is_pascal = 1; }\n   if (m/\\bconstant\\s+/i)         {$is_pascal=1;}\n   if (m/\\bbegin\\b/i) { $found_begin = 1; }\n   if ((m/end\\.\\s*$/i) && ($found_begin = 1)) {$is_pascal = 1;}\n   if ($is_pascal) {\n     last;\n   }\n }\n\n close($PASCAL_FILE);\n return $is_pascal;\n} # 1}}}\nsub really_is_php {                          # {{{1\n# Given filename, returns TRUE if its contents really is php.\n\n my $filename = shift;\n chomp($filename);\n\n my $is_php = 0;      # Value to determine.\n # Need to find a matching pair of surrounds, with ending after beginning:\n my $normal_surround = 0;  # <?; bit 0 = <?, bit 1 = ?>\n my $script_surround = 0;  # <script..>; bit 0 = <script language=\"php\">\n my $asp_surround = 0;     # <%; bit 0 = <%, bit 1 = %>\n\n # Return cached result, if available:\n if ($php_files{$filename}) { return $php_files{$filename};}\n\n my $PHP_FILE = open_file('<', $filename, 0);\n die \"Can't open $filename to determine if it's php.\\n\" if !defined $PHP_FILE;\n while(<$PHP_FILE>) {\n   if (m/\\<\\?/)                           { $normal_surround |= 1; }\n   if (m/\\?\\>/ && ($normal_surround & 1)) { $normal_surround |= 2; }\n   if (m/\\<script.*language=\"?php\"?/i)    { $script_surround |= 1; }\n   if (m/\\<\\/script\\>/i && ($script_surround & 1)) { $script_surround |= 2; }\n   if (m/\\<\\%/)                           { $asp_surround |= 1; }\n   if (m/\\%\\>/ && ($asp_surround & 1)) { $asp_surround |= 2; }\n }\n close($PHP_FILE);\n\n if ( ($normal_surround == 3) || ($script_surround == 3) ||\n      ($asp_surround == 3)) {\n   $is_php = 1;\n }\n\n $php_files{$filename} = $is_php; # Store result in cache.\n\n return $is_php;\n} # 1}}}\n# vendored modules\nsub Install_Regexp_Common {                  # {{{1\n    # Installs portions of Damian Conway's & Abigail's Regexp::Common\n    # module, version 2017060201 into a temporary directory for the\n    # duration of this run.\n    print \"-> Install_Regexp_Common v 2017060201 \\n\" if $opt_v > 2;\n    my %Regexp_Common_Contents = ();\n$Regexp_Common_Contents{'Common'} = <<'EOCommon'; # {{{2\npackage Regexp::Common;\n\nuse 5.10.0;\nuse strict;\n\nuse warnings;\nno  warnings 'syntax';\n\nour $VERSION = '2017060201';\nour %RE;\nour %sub_interface;\nour $AUTOLOAD;\n\n\nsub _croak {\n    require Carp;\n    goto &Carp::croak;\n}\n\nsub _carp {\n    require Carp;\n    goto &Carp::carp;\n}\n\nsub new {\n    my ($class, @data) = @_;\n    my %self;\n    tie %self, $class, @data;\n    return \\%self;\n}\n\nsub TIEHASH {\n    my ($class, @data) = @_;\n    bless \\@data, $class;\n}\n\nsub FETCH {\n    my ($self, $extra) = @_;\n    return bless ref($self)->new(@$self, $extra), ref($self);\n}\n\nmy %imports = map {$_ => \"Regexp::Common::$_\"}\n              qw /balanced CC     comment   delimited lingua list\n                  net      number profanity SEN       URI    whitespace\n                  zip/;\n\nsub import {\n    shift;  # Shift off the class.\n    tie %RE, __PACKAGE__;\n    {\n        no strict 'refs';\n        *{caller() . \"::RE\"} = \\%RE;\n    }\n\n    my $saw_import;\n    my $no_defaults;\n    my %exclude;\n    foreach my $entry (grep {!/^RE_/} @_) {\n        if ($entry eq 'pattern') {\n            no strict 'refs';\n            *{caller() . \"::pattern\"} = \\&pattern;\n            next;\n        }\n        # This used to prevent $; from being set. We still recognize it,\n        # but we won't do anything.\n        if ($entry eq 'clean') {\n            next;\n        }\n        if ($entry eq 'no_defaults') {\n            $no_defaults ++;\n            next;\n        }\n        if (my $module = $imports {$entry}) {\n            $saw_import ++;\n            eval \"require $module;\";\n            die $@ if $@;\n            next;\n        }\n        if ($entry =~ /^!(.*)/ && $imports {$1}) {\n            $exclude {$1} ++;\n            next;\n        }\n        # As a last resort, try to load the argument.\n        my $module = $entry =~ /^Regexp::Common/\n                            ? $entry\n                            : \"Regexp::Common::\" . $entry;\n        eval \"require $module;\";\n        die $@ if $@;\n    }\n\n    unless ($saw_import || $no_defaults) {\n        foreach my $module (values %imports) {\n            next if $exclude {$module};\n            eval \"require $module;\";\n            die $@ if $@;\n        }\n    }\n\n    my %exported;\n    foreach my $entry (grep {/^RE_/} @_) {\n        if ($entry =~ /^RE_(\\w+_)?ALL$/) {\n            my $m  = defined $1 ? $1 : \"\";\n            my $re = qr /^RE_${m}.*$/;\n            while (my ($sub, $interface) = each %sub_interface) {\n                next if $exported {$sub};\n                next unless $sub =~ /$re/;\n                {\n                    no strict 'refs';\n                    *{caller() . \"::$sub\"} = $interface;\n                }\n                $exported {$sub} ++;\n            }\n        }\n        else {\n            next if $exported {$entry};\n            _croak \"Can't export unknown subroutine &$entry\"\n                unless $sub_interface {$entry};\n            {\n                no strict 'refs';\n                *{caller() . \"::$entry\"} = $sub_interface {$entry};\n            }\n            $exported {$entry} ++;\n        }\n    }\n}\n\nsub AUTOLOAD { _croak \"Can't $AUTOLOAD\" }\n\nsub DESTROY {}\n\nmy %cache;\n\nmy $fpat = qr/^(-\\w+)/;\n\nsub _decache {\n        my @args = @{tied %{$_[0]}};\n        my @nonflags = grep {!/$fpat/} @args;\n        my $cache = get_cache(@nonflags);\n        _croak \"Can't create unknown regex: \\$RE{\"\n            . join(\"}{\",@args) . \"}\"\n                unless exists $cache->{__VAL__};\n        _croak \"Perl $] does not support the pattern \"\n            . \"\\$RE{\" . join(\"}{\",@args)\n            . \"}.\\nYou need Perl $cache->{__VAL__}{version} or later\"\n                unless ($cache->{__VAL__}{version}||0) <= $];\n        my %flags = ( %{$cache->{__VAL__}{default}},\n                      map { /$fpat\\Q$;\\E(.*)/ ? ($1 => $2)\n                          : /$fpat/           ? ($1 => undef)\n                          :                     ()\n                          } @args);\n        $cache->{__VAL__}->_clone_with(\\@args, \\%flags);\n}\n\nuse overload q{\"\"} => \\&_decache;\n\n\nsub get_cache {\n        my $cache = \\%cache;\n        foreach (@_) {\n                $cache = $cache->{$_}\n                      || ($cache->{$_} = {});\n        }\n        return $cache;\n}\n\nsub croak_version {\n        my ($entry, @args) = @_;\n}\n\nsub pattern {\n        my %spec = @_;\n        _croak 'pattern() requires argument: name => [ @list ]'\n                unless $spec{name} && ref $spec{name} eq 'ARRAY';\n        _croak 'pattern() requires argument: create => $sub_ref_or_string'\n                unless $spec{create};\n\n        if (ref $spec{create} ne \"CODE\") {\n                my $fixed_str = \"$spec{create}\";\n                $spec{create} = sub { $fixed_str }\n        }\n\n        my @nonflags;\n        my %default;\n        foreach ( @{$spec{name}} ) {\n                if (/$fpat=(.*)/) {\n                        $default{$1} = $2;\n                }\n                elsif (/$fpat\\s*$/) {\n                        $default{$1} = undef;\n                }\n                else {\n                        push @nonflags, $_;\n                }\n        }\n\n        my $entry = get_cache(@nonflags);\n\n        if ($entry->{__VAL__}) {\n                _carp \"Overriding \\$RE{\"\n                   . join(\"}{\",@nonflags)\n                   . \"}\";\n        }\n\n        $entry->{__VAL__} = bless {\n                                create  => $spec{create},\n                                match   => $spec{match} || \\&generic_match,\n                                subs    => $spec{subs}  || \\&generic_subs,\n                                version => $spec{version},\n                                default => \\%default,\n                            }, 'Regexp::Common::Entry';\n\n        foreach (@nonflags) {s/\\W/X/g}\n        my $subname = \"RE_\" . join (\"_\", @nonflags);\n        $sub_interface{$subname} = sub {\n                push @_ => undef if @_ % 2;\n                my %flags = @_;\n                my $pat = $spec{create}->($entry->{__VAL__},\n                               {%default, %flags}, \\@nonflags);\n                if (exists $flags{-keep}) { $pat =~ s/\\Q(?k:/(/g; }\n                else { $pat =~ s/\\Q(?k:/(?:/g; }\n                return exists $flags {-i} ? qr /(?i:$pat)/ : qr/$pat/;\n        };\n\n        return 1;\n}\n\nsub generic_match {$_ [1] =~  /$_[0]/}\nsub generic_subs  {$_ [1] =~ s/$_[0]/$_[2]/}\n\nsub matches {\n        my ($self, $str) = @_;\n        my $entry = $self -> _decache;\n        $entry -> {match} -> ($entry, $str);\n}\n\nsub subs {\n        my ($self, $str, $newstr) = @_;\n        my $entry = $self -> _decache;\n        $entry -> {subs} -> ($entry, $str, $newstr);\n        return $str;\n}\n\n\npackage Regexp::Common::Entry;\n# use Carp;\n\nuse overload\n    q{\"\"} => sub {\n        my ($self) = @_;\n        my $pat = $self->{create}->($self, $self->{flags}, $self->{args});\n        if (exists $self->{flags}{-keep}) {\n            $pat =~ s/\\Q(?k:/(/g;\n        }\n        else {\n            $pat =~ s/\\Q(?k:/(?:/g;\n        }\n        if (exists $self->{flags}{-i})   { $pat = \"(?i)$pat\" }\n        return $pat;\n    };\n\nsub _clone_with {\n    my ($self, $args, $flags) = @_;\n    bless { %$self, args=>$args, flags=>$flags }, ref $self;\n}\n\n1;\n\n__END__\n\n=pod\n\n=head1 NAME\n\nRegexp::Common - Provide commonly requested regular expressions\n\n=head1 SYNOPSIS\n\n # STANDARD USAGE\n\n use Regexp::Common;\n\n while (<>) {\n     /$RE{num}{real}/               and print q{a number};\n     /$RE{quoted}/                  and print q{a ['\"`] quoted string};\n    m[$RE{delimited}{-delim=>'/'}]  and print q{a /.../ sequence};\n     /$RE{balanced}{-parens=>'()'}/ and print q{balanced parentheses};\n     /$RE{profanity}/               and print q{a #*@%-ing word};\n }\n\n\n # SUBROUTINE-BASED INTERFACE\n\n use Regexp::Common 'RE_ALL';\n\n while (<>) {\n     $_ =~ RE_num_real()              and print q{a number};\n     $_ =~ RE_quoted()                and print q{a ['\"`] quoted string};\n     $_ =~ RE_delimited(-delim=>'/')  and print q{a /.../ sequence};\n     $_ =~ RE_balanced(-parens=>'()'} and print q{balanced parentheses};\n     $_ =~ RE_profanity()             and print q{a #*@%-ing word};\n }\n\n\n # IN-LINE MATCHING...\n\n if ( $RE{num}{int}->matches($text) ) {...}\n\n\n # ...AND SUBSTITUTION\n\n my $cropped = $RE{ws}{crop}->subs($uncropped);\n\n\n # ROLL-YOUR-OWN PATTERNS\n\n use Regexp::Common 'pattern';\n\n pattern name   => ['name', 'mine'],\n         create => '(?i:J[.]?\\s+A[.]?\\s+Perl-Hacker)',\n         ;\n\n my $name_matcher = $RE{name}{mine};\n\n pattern name    => [ 'lineof', '-char=_' ],\n         create  => sub {\n                        my $flags = shift;\n                        my $char = quotemeta $flags->{-char};\n                        return '(?:^$char+$)';\n                    },\n         match   => sub {\n                        my ($self, $str) = @_;\n                        return $str !~ /[^$self->{flags}{-char}]/;\n                    },\n         subs   => sub {\n                        my ($self, $str, $replacement) = @_;\n                        $_[1] =~ s/^$self->{flags}{-char}+$//g;\n                   },\n         ;\n\n my $asterisks = $RE{lineof}{-char=>'*'};\n\n # DECIDING WHICH PATTERNS TO LOAD.\n\n use Regexp::Common qw /comment number/;  # Comment and number patterns.\n use Regexp::Common qw /no_defaults/;     # Don't load any patterns.\n use Regexp::Common qw /!delimited/;      # All, but delimited patterns.\n\n\n=head1 DESCRIPTION\n\nBy default, this module exports a single hash (C<%RE>) that stores or generates\ncommonly needed regular expressions (see L<\"List of available patterns\">).\n\nThere is an alternative, subroutine-based syntax described in\nL<\"Subroutine-based interface\">.\n\n\n=head2 General syntax for requesting patterns\n\nTo access a particular pattern, C<%RE> is treated as a hierarchical hash of\nhashes (of hashes...), with each successive key being an identifier. For\nexample, to access the pattern that matches real numbers, you\nspecify:\n\n        $RE{num}{real}\n\nand to access the pattern that matches integers:\n\n        $RE{num}{int}\n\nDeeper layers of the hash are used to specify I<flags>: arguments that\nmodify the resulting pattern in some way. The keys used to access these\nlayers are prefixed with a minus sign and may have a value; if a value\nis given, it's done by using a multidimensional key.\nFor example, to access the pattern that\nmatches base-2 real numbers with embedded commas separating\ngroups of three digits (e.g. 10,101,110.110101101):\n\n        $RE{num}{real}{-base => 2}{-sep => ','}{-group => 3}\n\nThrough the magic of Perl, these flag layers may be specified in any order\n(and even interspersed through the identifier keys!)\nso you could get the same pattern with:\n\n        $RE{num}{real}{-sep => ','}{-group => 3}{-base => 2}\n\nor:\n\n        $RE{num}{-base => 2}{real}{-group => 3}{-sep => ','}\n\nor even:\n\n        $RE{-base => 2}{-group => 3}{-sep => ','}{num}{real}\n\netc.\n\nNote, however, that the relative order of amongst the identifier keys\nI<is> significant. That is:\n\n        $RE{list}{set}\n\nwould not be the same as:\n\n        $RE{set}{list}\n\n=head2 Flag syntax\n\nIn versions prior to 2.113, flags could also be written as\nC<{\"-flag=value\"}>. This no longer works, although C<{\"-flag$;value\"}>\nstill does. However, C<< {-flag => 'value'} >> is the preferred syntax.\n\n=head2 Universal flags\n\nNormally, flags are specific to a single pattern.\nHowever, there is two flags that all patterns may specify.\n\n=over 4\n\n=item C<-keep>\n\nBy default, the patterns provided by C<%RE> contain no capturing\nparentheses. However, if the C<-keep> flag is specified (it requires\nno value) then any significant substrings that the pattern matches\nare captured. For example:\n\n        if ($str =~ $RE{num}{real}{-keep}) {\n                $number   = $1;\n                $whole    = $3;\n                $decimals = $5;\n        }\n\nSpecial care is needed if a \"kept\" pattern is interpolated into a\nlarger regular expression, as the presence of other capturing\nparentheses is likely to change the \"number variables\" into which significant\nsubstrings are saved.\n\nSee also L<\"Adding new regular expressions\">, which describes how to create\nnew patterns with \"optional\" capturing brackets that respond to C<-keep>.\n\n=item C<-i>\n\nSome patterns or subpatterns only match lowercase or uppercase letters.\nIf one wants the do case insensitive matching, one option is to use\nthe C</i> regexp modifier, or the special sequence C<(?i)>. But if the\nfunctional interface is used, one does not have this option. The\nC<-i> switch solves this problem; by using it, the pattern will do\ncase insensitive matching.\n\n=back\n\n=head2 OO interface and inline matching/substitution\n\nThe patterns returned from C<%RE> are objects, so rather than writing:\n\n        if ($str =~ /$RE{some}{pattern}/ ) {...}\n\nyou can write:\n\n        if ( $RE{some}{pattern}->matches($str) ) {...}\n\nFor matching this would seem to have no great advantage apart from readability\n(but see below).\n\nFor substitutions, it has other significant benefits. Frequently you want to\nperform a substitution on a string without changing the original. Most people\nuse this:\n\n        $changed = $original;\n        $changed =~ s/$RE{some}{pattern}/$replacement/;\n\nThe more adept use:\n\n        ($changed = $original) =~ s/$RE{some}{pattern}/$replacement/;\n\nRegexp::Common allows you do write this:\n\n        $changed = $RE{some}{pattern}->subs($original=>$replacement);\n\nApart from reducing precedence-angst, this approach has the added\nadvantages that the substitution behaviour can be optimized from the\nregular expression, and the replacement string can be provided by\ndefault (see L<\"Adding new regular expressions\">).\n\nFor example, in the implementation of this substitution:\n\n        $cropped = $RE{ws}{crop}->subs($uncropped);\n\nthe default empty string is provided automatically, and the substitution is\noptimized to use:\n\n        $uncropped =~ s/^\\s+//;\n        $uncropped =~ s/\\s+$//;\n\nrather than:\n\n        $uncropped =~ s/^\\s+|\\s+$//g;\n\n\n=head2 Subroutine-based interface\n\nThe hash-based interface was chosen because it allows regexes to be\neffortlessly interpolated, and because it also allows them to be\n\"curried\". For example:\n\n        my $num = $RE{num}{int};\n\n        my $command    = $num->{-sep=>','}{-group=>3};\n        my $duodecimal = $num->{-base=>12};\n\n\nHowever, the use of tied hashes does make the access to Regexp::Common\npatterns slower than it might otherwise be. In contexts where impatience\noverrules laziness, Regexp::Common provides an additional\nsubroutine-based interface.\n\nFor each (sub-)entry in the C<%RE> hash (C<$RE{key1}{key2}{etc}>), there\nis a corresponding exportable subroutine: C<RE_key1_key2_etc()>. The name of\neach subroutine is the underscore-separated concatenation of the I<non-flag>\nkeys that locate the same pattern in C<%RE>. Flags are passed to the subroutine\nin its argument list. Thus:\n\n        use Regexp::Common qw( RE_ws_crop RE_num_real RE_profanity );\n\n        $str =~ RE_ws_crop() and die \"Surrounded by whitespace\";\n\n        $str =~ RE_num_real(-base=>8, -sep=>\" \") or next;\n\n        $offensive = RE_profanity(-keep);\n        $str =~ s/$offensive/$bad{$1}++; \"<expletive deleted>\"/ge;\n\nNote that, unlike the hash-based interface (which returns objects), these\nsubroutines return ordinary C<qr>'d regular expressions. Hence they do not\ncurry, nor do they provide the OO match and substitution inlining described\nin the previous section.\n\nIt is also possible to export subroutines for all available patterns like so:\n\n        use Regexp::Common 'RE_ALL';\n\nOr you can export all subroutines with a common prefix of keys like so:\n\n        use Regexp::Common 'RE_num_ALL';\n\nwhich will export C<RE_num_int> and C<RE_num_real> (and if you have\ncreate more patterns who have first key I<num>, those will be exported\nas well). In general, I<RE_key1_..._keyn_ALL> will export all subroutines\nwhose pattern names have first keys I<key1> ... I<keyn>.\n\n\n=head2 Adding new regular expressions\n\nYou can add your own regular expressions to the C<%RE> hash at run-time,\nusing the exportable C<pattern> subroutine. It expects a hash-like list of\nkey/value pairs that specify the behaviour of the pattern. The various\npossible argument pairs are:\n\n=over 4\n\n=item C<name =E<gt> [ @list ]>\n\nA required argument that specifies the name of the pattern, and any\nflags it may take, via a reference to a list of strings. For example:\n\n         pattern name => [qw( line of -char )],\n                 # other args here\n                 ;\n\nThis specifies an entry C<$RE{line}{of}>, which may take a C<-char> flag.\n\nFlags may also be specified with a default value, which is then used whenever\nthe flag is specified without an explicit value (but not when the flag is\nomitted). For example:\n\n         pattern name => [qw( line of -char=_ )],\n                 # default char is '_'\n                 # other args here\n                 ;\n\n\n=item C<create =E<gt> $sub_ref_or_string>\n\nA required argument that specifies either a string that is to be returned\nas the pattern:\n\n        pattern name    => [qw( line of underscores )],\n                create  => q/(?:^_+$)/\n                ;\n\nor a reference to a subroutine that will be called to create the pattern:\n\n        pattern name    => [qw( line of -char=_ )],\n                create  => sub {\n                                my ($self, $flags) = @_;\n                                my $char = quotemeta $flags->{-char};\n                                return '(?:^$char+$)';\n                            },\n                ;\n\nIf the subroutine version is used, the subroutine will be called with\nthree arguments: a reference to the pattern object itself, a reference\nto a hash containing the flags and their values,\nand a reference to an array containing the non-flag keys.\n\nWhatever the subroutine returns is stringified as the pattern.\n\nNo matter how the pattern is created, it is immediately postprocessed to\ninclude or exclude capturing parentheses (according to the value of the\nC<-keep> flag). To specify such \"optional\" capturing parentheses within\nthe regular expression associated with C<create>, use the notation\nC<(?k:...)>. Any parentheses of this type will be converted to C<(...)>\nwhen the C<-keep> flag is specified, or C<(?:...)> when it is not.\nIt is a Regexp::Common convention that the outermost capturing parentheses\nalways capture the entire pattern, but this is not enforced.\n\n\n=item C<match =E<gt> $sub_ref>\n\nAn optional argument that specifies a subroutine that is to be called when\nthe C<$RE{...}-E<gt>matches(...)> method of this pattern is invoked.\n\nThe subroutine should expect two arguments: a reference to the pattern object\nitself, and the string to be matched against.\n\nIt should return the same types of values as a C<m/.../> does.\n\n     pattern name    => [qw( line of -char )],\n             create  => sub {...},\n             match   => sub {\n                             my ($self, $str) = @_;\n                             $str !~ /[^$self->{flags}{-char}]/;\n                        },\n             ;\n\n\n=item C<subs =E<gt> $sub_ref>\n\nAn optional argument that specifies a subroutine that is to be called when\nthe C<$RE{...}-E<gt>subs(...)> method of this pattern is invoked.\n\nThe subroutine should expect three arguments: a reference to the pattern object\nitself, the string to be changed, and the value to be substituted into it.\nThe third argument may be C<undef>, indicating the default substitution is\nrequired.\n\nThe subroutine should return the same types of values as an C<s/.../.../> does.\n\nFor example:\n\n     pattern name    => [ 'lineof', '-char=_' ],\n             create  => sub {...},\n             subs    => sub {\n                          my ($self, $str, $ignore_replacement) = @_;\n                          $_[1] =~ s/^$self->{flags}{-char}+$//g;\n                        },\n             ;\n\nNote that such a subroutine will almost always need to modify C<$_[1]> directly.\n\n\n=item C<version =E<gt> $minimum_perl_version>\n\nIf this argument is given, it specifies the minimum version of perl required\nto use the new pattern. Attempts to use the pattern with earlier versions of\nperl will generate a fatal diagnostic.\n\n=back\n\n=head2 Loading specific sets of patterns.\n\nBy default, all the sets of patterns listed below are made available.\nHowever, it is possible to indicate which sets of patterns should\nbe made available - the wanted sets should be given as arguments to\nC<use>. Alternatively, it is also possible to indicate which sets of\npatterns should not be made available - those sets will be given as\nargument to the C<use> statement, but are preceded with an exclaimation\nmark. The argument I<no_defaults> indicates none of the default patterns\nshould be made available. This is useful for instance if all you want\nis the C<pattern()> subroutine.\n\nExamples:\n\n use Regexp::Common qw /comment number/;  # Comment and number patterns.\n use Regexp::Common qw /no_defaults/;     # Don't load any patterns.\n use Regexp::Common qw /!delimited/;      # All, but delimited patterns.\n\nIt's also possible to load your own set of patterns. If you have a\nmodule C<Regexp::Common::my_patterns> that makes patterns available,\nyou can have it made available with\n\n use Regexp::Common qw /my_patterns/;\n\nNote that the default patterns will still be made available - only if\nyou use I<no_defaults>, or mention one of the default sets explicitly,\nthe non mentioned defaults aren't made available.\n\n=head2 List of available patterns\n\nThe patterns listed below are currently available. Each set of patterns\nhas its own manual page describing the details. For each pattern set\nnamed I<name>, the manual page I<Regexp::Common::name> describes the\ndetails.\n\nCurrently available are:\n\n=over 4\n\n=item Regexp::Common::balanced\n\nProvides regexes for strings with balanced parenthesized delimiters.\n\n=item Regexp::Common::comment\n\nProvides regexes for comments of various languages (43 languages\ncurrently).\n\n=item Regexp::Common::delimited\n\nProvides regexes for delimited strings.\n\n=item Regexp::Common::lingua\n\nProvides regexes for palindromes.\n\n=item Regexp::Common::list\n\nProvides regexes for lists.\n\n=item Regexp::Common::net\n\nProvides regexes for IPv4, IPv6, and MAC addresses.\n\n=item Regexp::Common::number\n\nProvides regexes for numbers (integers and reals).\n\n=item Regexp::Common::profanity\n\nProvides regexes for profanity.\n\n=item Regexp::Common::whitespace\n\nProvides regexes for leading and trailing whitespace.\n\n=item Regexp::Common::zip\n\nProvides regexes for zip codes.\n\n=back\n\n=head2 Forthcoming patterns and features\n\nFuture releases of the module will also provide patterns for the following:\n\n        * email addresses\n        * HTML/XML tags\n        * more numerical matchers,\n        * mail headers (including multiline ones),\n        * more URLS\n        * telephone numbers of various countries\n        * currency (universal 3 letter format, Latin-1, currency names)\n        * dates\n        * binary formats (e.g. UUencoded, MIMEd)\n\nIf you have other patterns or pattern generators that you think would be\ngenerally useful, please send them to the maintainer -- preferably as source\ncode using the C<pattern> subroutine. Submissions that include a set of\ntests will be especially welcome.\n\n\n=head1 DIAGNOSTICS\n\n=over 4\n\n=item C<Can't export unknown subroutine %s>\n\nThe subroutine-based interface didn't recognize the requested subroutine.\nOften caused by a spelling mistake or an incompletely specified name.\n\n\n=item C<Can't create unknown regex: $RE{...}>\n\nRegexp::Common doesn't have a generator for the requested pattern.\nOften indicates a misspelt or missing parameter.\n\n=item\nC<Perl %f does not support the pattern $RE{...}.\nYou need Perl %f or later>\n\nThe requested pattern requires advanced regex features (e.g. recursion)\nthat not available in your version of Perl. Time to upgrade.\n\n=item C<< pattern() requires argument: name => [ @list ] >>\n\nEvery user-defined pattern specification must have a name.\n\n=item C<< pattern() requires argument: create => $sub_ref_or_string >>\n\nEvery user-defined pattern specification must provide a pattern creation\nmechanism: either a pattern string or a reference to a subroutine that\nreturns the pattern string.\n\n=item C<Base must be between 1 and 36>\n\nThe C<< $RE{num}{real}{-base=>'I<N>'} >> pattern uses the characters [0-9A-Z]\nto represent the digits of various bases. Hence it only produces\nregular expressions for bases up to hexatricensimal.\n\n=item C<Must specify delimiter in $RE{delimited}>\n\nThe pattern has no default delimiter.\nYou need to write: C<< $RE{delimited}{-delim=>I<X>'} >> for some character I<X>\n\n=back\n\n=head1 ACKNOWLEDGEMENTS\n\nDeepest thanks to the many people who have encouraged and contributed to this\nproject, especially: Elijah, Jarkko, Tom, Nat, Ed, and Vivek.\n\nFurther thanks go to: Alexandr Ciornii, Blair Zajac, Bob Stockdale,\nCharles Thomas, Chris Vertonghen, the CPAN Testers, David Hand,\nFany, Geoffrey Leach, Hermann-Marcus Behrens, Jerome Quelin, Jim Cromie,\nLars Wilke, Linda Julien, Mike Arms, Mike Castle, Mikko, Murat Uenalan,\nRafaE<235>l Garcia-Suarez, Ron Savage, Sam Vilain, Slaven Rezic, Smylers,\nTim Maher, and all the others I've forgotten.\n\n=head1 AUTHOR\n\nDamian Conway (damian@conway.org)\n\n=head1 MAINTENANCE\n\nThis package is maintained by Abigail S<(I<regexp-common@abigail.be>)>.\n\n=head1 BUGS AND IRRITATIONS\n\nBound to be plenty.\n\nFor a start, there are many common regexes missing.\nSend them in to I<regexp-common@abigail.be>.\n\nThere are some POD issues when installing this module using a pre-5.6.0 perl;\nsome manual pages may not install, or may not install correctly using a perl\nthat is that old. You might consider upgrading your perl.\n\n=head1 NOT A BUG\n\n=over 4\n\n=item *\n\nThe various patterns are not anchored. That is, a pattern like\nC<< $RE {num} {int} >> will match against \"abc4def\", because a\nsubstring of the subject matches. This is by design, and not a\nbug. If you want the pattern to be anchored, use something like:\n\n my $integer = $RE {num} {int};\n $subj =~ /^$integer$/ and print \"Matches!\\n\";\n\n=back\n\n=head1 LICENSE and COPYRIGHT\n\nThis software is Copyright (c) 2001 - 2017, Damian Conway and Abigail.\n\nThis module is free software, and maybe used under any of the following\nlicenses:\n\n 1) The Perl Artistic License.     See the file COPYRIGHT.AL.\n 2) The Perl Artistic License 2.0. See the file COPYRIGHT.AL2.\n 3) The BSD License.               See the file COPYRIGHT.BSD.\n 4) The MIT License.               See the file COPYRIGHT.MIT.\nEOCommon\n# 2}}}\n$Regexp_Common_Contents{'Common/comment'} = <<'EOC';   # {{{2\npackage Regexp::Common::comment;\n\nuse 5.10.0;\n\nuse strict;\nuse warnings;\nno  warnings 'syntax';\n\nuse Regexp::Common qw /pattern clean no_defaults/;\n\nour $VERSION = '2017060201';\n\nmy @generic = (\n    {languages => [qw /ABC Forth/],\n     to_eol    => ['\\\\\\\\']},   # This is for just a *single* backslash.\n\n    {languages => [qw /Ada Alan Eiffel lua/],\n     to_eol    => ['--']},\n\n    {languages => [qw /Advisor/],\n     to_eol    => ['#|//']},\n\n    {languages => [qw /Advsys CQL Lisp LOGO M MUMPS REBOL Scheme\n                       SMITH zonefile/],\n     to_eol    => [';']},\n\n    {languages => ['Algol 60'],\n     from_to   => [[qw /comment ;/]]},\n\n    {languages => [qw {ALPACA B C C-- LPC PL/I}],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw /awk fvwm2 Icon m4 mutt Perl Python QML\n                       R Ruby shell Tcl/],\n     to_eol    => ['#']},\n\n    {languages => [[BASIC => 'mvEnterprise']],\n     to_eol    => ['[*!]|REM']},\n\n    {languages => [qw /Befunge-98 Funge-98 Shelta/],\n     id        => [';']},\n\n    {languages => ['beta-Juliet', 'Crystal Report', 'Portia', 'Ubercode'],\n     to_eol    => ['//']},\n\n    {languages => ['BML'],\n     from_to   => [['<?_c', '_c?>']],\n    },\n\n    {languages => [qw /C++/, 'C#', 'X++', qw /Cg ECMAScript FPL Java JavaScript/],\n     to_eol    => ['//'],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw /CLU LaTeX slrn TeX/],\n     to_eol    => ['%']},\n\n    {languages => [qw /False/],\n     from_to   => [[qw !{ }!]]},\n\n    {languages => [qw /Fortran/],\n     to_eol    => ['!']},\n\n    {languages => [qw /Haifu/],\n     id        => [',']},\n\n    {languages => [qw /ILLGOL/],\n     to_eol    => ['NB']},\n\n    {languages => [qw /INTERCAL/],\n     to_eol    => [q{(?:(?:PLEASE(?:\\s+DO)?|DO)\\s+)?(?:NOT|N'T)}]},\n\n    {languages => [qw /J/],\n     to_eol    => ['NB[.]']},\n\n    {languages => [qw /JavaDoc/],\n     from_to   => [[qw {/** */}]]},\n\n    {languages => [qw /Nickle/],\n     to_eol    => ['#'],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw /Oberon/],\n     from_to   => [[qw /(* *)/]]},\n\n    {languages => [[qw /Pascal Delphi/], [qw /Pascal Free/], [qw /Pascal GPC/]],\n     to_eol    => ['//'],\n     from_to   => [[qw !{ }!], [qw !(* *)!]]},\n\n    {languages => [[qw /Pascal Workshop/]],\n     id        => [qw /\"/],\n     from_to   => [[qw !{ }!], [qw !(* *)!], [qw !/* */!]]},\n\n    {languages => [qw /PEARL/],\n     to_eol    => ['!'],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw /PHP/],\n     to_eol    => ['#', '//'],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw !PL/B!],\n     to_eol    => ['[.;]']},\n\n    {languages => [qw !PL/SQL!],\n     to_eol    => ['--'],\n     from_to   => [[qw {/* */}]]},\n\n    {languages => [qw /Q-BAL/],\n     to_eol    => ['`']},\n\n    {languages => [qw /Smalltalk/],\n     id        => ['\"']},\n\n    {languages => [qw /SQL/],\n     to_eol    => ['-{2,}']},\n\n    {languages => [qw /troff/],\n     to_eol    => ['\\\\\\\"']},\n\n    {languages => [qw /vi/],\n     to_eol    => ['\"']},\n\n    {languages => [qw /*W/],\n     from_to   => [[qw {|| !!}]]},\n\n    {languages => [qw /ZZT-OOP/],\n     to_eol    => [\"'\"]},\n);\n\nmy @plain_or_nested = (\n   [Caml         =>  undef,       \"(*\"  => \"*)\"],\n   [Dylan        =>  \"//\",        \"/*\"  => \"*/\"],\n   [DAML         =>  \"-{2,}\",     \"{-\"  => \"-}\"],\n   [Haskell      =>  \"-{2,}\",     \"{-\"  => \"-}\"],\n   [Hugo         =>  \"!(?!\\\\\\\\)\", \"!\\\\\" => \"\\\\!\"],\n   [SLIDE        =>  \"#\",         \"(*\"  => \"*)\"],\n  ['Modula-2'    =>  undef,       \"(*\"  => \"*)\"],\n  ['Modula-3'    =>  undef,       \"(*\"  => \"*)\"],\n);\n\n#\n# Helper subs.\n#\n\nsub combine      {\n    local $_ = join \"|\", @_;\n    if (@_ > 1) {\n        s/\\(\\?k:/(?:/g;\n        $_ = \"(?k:$_)\";\n    }\n    $_\n}\n\nsub to_eol  ($)  {\"(?k:(?k:$_[0])(?k:[^\\\\n]*)(?k:\\\\n))\"}\nsub id      ($)  {\"(?k:(?k:$_[0])(?k:[^$_[0]]*)(?k:$_[0]))\"}  # One char only!\nsub from_to      {\n    my ($begin, $end) = @_;\n\n    my $qb  = quotemeta $begin;\n    my $qe  = quotemeta $end;\n    my $fe  = quotemeta substr $end   => 0, 1;\n    my $te  = quotemeta substr $end   => 1;\n\n    \"(?k:(?k:$qb)(?k:(?:[^$fe]+|$fe(?!$te))*)(?k:$qe))\";\n}\n\n\nmy $count = 0;\nsub nested {\n    my ($begin, $end) = @_;\n\n    $count ++;\n    my $r = '(??{$Regexp::Common::comment ['. $count . ']})';\n\n    my $qb  = quotemeta $begin;\n    my $qe  = quotemeta $end;\n    my $fb  = quotemeta substr $begin => 0, 1;\n    my $fe  = quotemeta substr $end   => 0, 1;\n\n    my $tb  = quotemeta substr $begin => 1;\n    my $te  = quotemeta substr $end   => 1;\n\n    use re 'eval';\n\n    my $re;\n    if ($fb eq $fe) {\n        $re = qr /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|$r)*$qe)/;\n    }\n    else {\n        local $\"      =  \"|\";\n        my   @clauses =  \"(?>[^$fb$fe]+)\";\n        push @clauses => \"$fb(?!$tb)\" if length $tb;\n        push @clauses => \"$fe(?!$te)\" if length $te;\n        push @clauses =>  $r;\n        $re           =   qr /(?:$qb(?:@clauses)*$qe)/;\n    }\n\n    $Regexp::Common::comment [$count] = qr/$re/;\n}\n\n#\n# Process data.\n#\n\nforeach my $info (@plain_or_nested) {\n    my ($language, $mark, $begin, $end) = @$info;\n    pattern name    => [comment => $language],\n            create  =>\n                sub {my $re     = nested $begin => $end;\n                     my $prefix = defined $mark ? $mark . \"[^\\n]*\\n|\" : \"\";\n                     exists $_ [1] -> {-keep} ? qr /($prefix$re)/\n                                              : qr  /$prefix$re/\n                },\n            ;\n}\n\n\nforeach my $group (@generic) {\n    my $pattern = combine +(map {to_eol   $_} @{$group -> {to_eol}}),\n                           (map {from_to @$_} @{$group -> {from_to}}),\n                           (map {id       $_} @{$group -> {id}}),\n                  ;\n    foreach my $language  (@{$group -> {languages}}) {\n        pattern name    => [comment => ref $language ? @$language : $language],\n                create  => $pattern,\n                ;\n    }\n}\n\n\n\n#\n# Other languages.\n#\n\n# http://www.pascal-central.com/docs/iso10206.txt\npattern name    => [qw /comment Pascal/],\n        create  => '(?k:' . '(?k:[{]|[(][*])'\n                          . '(?k:[^}*]*(?:[*](?![)])[^}*]*)*)'\n                          . '(?k:[}]|[*][)])'\n                          . ')'\n        ;\n\n# http://www.templetons.com/brad/alice/language/\npattern name    =>  [qw /comment Pascal Alice/],\n        create  =>  '(?k:(?k:[{])(?k:[^}\\n]*)(?k:[}]))'\n        ;\n\n\n# http://westein.arb-phys.uni-dortmund.de/~wb/a68s.txt\npattern name    => [qw (comment), 'Algol 68'],\n        create  => q {(?k:(?:#[^#]*#)|}                           .\n                   q {(?:\\bco\\b(?:[^c]+|\\Bc|\\bc(?!o\\b))*\\bco\\b)|} .\n                   q {(?:\\bcomment\\b(?:[^c]+|\\Bc|\\bc(?!omment\\b))*\\bcomment\\b))}\n        ;\n\n\n# See rules 91 and 92 of ISO 8879 (SGML).\n# Charles F. Goldfarb: \"The SGML Handbook\".\n# Oxford: Oxford University Press. 1990. ISBN 0-19-853737-9.\n# Ch. 10.3, pp 390.\npattern name    => [qw (comment HTML)],\n        create  => q {(?k:(?k:<!)(?k:(?:--(?k:[^-]*(?:-[^-]+)*)--\\s*)*)(?k:>))},\n        ;\n\n\npattern name    => [qw /comment SQL MySQL/],\n        create  => q {(?k:(?:#|-- )[^\\n]*\\n|} .\n                   q {/\\*(?:(?>[^*;\"']+)|\"[^\"]*\"|'[^']*'|\\*(?!/))*(?:;|\\*/))},\n        ;\n\n# Anything that isn't <>[]+-.,\n# http://home.wxs.nl/~faase009/Ha_BF.html\npattern name    => [qw /comment Brainfuck/],\n        create  => '(?k:[^<>\\[\\]+\\-.,]+)'\n        ;\n\n# Squeak is a variant of Smalltalk-80.\n# http://www.squeak.\n# http://mucow.com/squeak-qref.html\npattern name    => [qw /comment Squeak/],\n        create  => '(?k:(?k:\")(?k:[^\"]*(?:\"\"[^\"]*)*)(?k:\"))'\n        ;\n\n#\n# Scores of less than 5 or above 17....\n# http://www.cliff.biffle.org/esoterica/beatnik.html\n@Regexp::Common::comment::scores = (1,  3,  3,  2,  1,  4,  2,  4,  1,  8,\n                                    5,  1,  3,  1,  1,  3, 10,  1,  1,  1,\n                                    1,  4,  4,  8,  4, 10);\n{\nmy ($s, $x);\npattern name    =>  [qw /comment Beatnik/],\n        create  =>  sub {\n            use re 'eval';\n            my $re = qr {\\b([A-Za-z]+)\\b\n                         (?(?{($s, $x) = (0, lc $^N);\n                              $s += $Regexp::Common::comment::scores\n                                    [ord (chop $x) - ord ('a')] while length $x;\n                              $s  >= 5 && $s < 18})XXX|)}x;\n            $re;\n        },\n        ;\n}\n\n\n# http://www.cray.com/craydoc/manuals/007-3692-005/html-007-3692-005/\n#  (Goto table of contents/3.3 Source Form)\n# Fortran, in fixed format. Comments start with a C, c or * in the first\n# column, or a ! anywhere, but the sixth column. Then end with a newline.\npattern name    =>  [qw /comment Fortran fixed/],\n        create  =>  '(?k:(?k:(?:^[Cc*]|(?<!^.....)!))(?k:[^\\n]*)(?k:\\n))'\n        ;\n\n\n# http://www.csis.ul.ie/cobol/Course/COBOLIntro.htm\n# Traditionally, comments in COBOL were indicated with an asterisk in\n# the seventh column. Modern compilers may be more lenient.\npattern name    =>  [qw /comment COBOL/],\n        create  =>  '(?<=^......)(?k:(?k:[*])(?k:[^\\n]*)(?k:\\n))',\n        ;\n\n1;\n\n\n__END__\n\n=pod\n\n=head1 NAME\n\nRegexp::Common::comment -- provide regexes for comments.\n\n=head1 SYNOPSIS\n\n    use Regexp::Common qw /comment/;\n\n    while (<>) {\n        /$RE{comment}{C}/       and  print \"Contains a C comment\\n\";\n        /$RE{comment}{C++}/     and  print \"Contains a C++ comment\\n\";\n        /$RE{comment}{PHP}/     and  print \"Contains a PHP comment\\n\";\n        /$RE{comment}{Java}/    and  print \"Contains a Java comment\\n\";\n        /$RE{comment}{Perl}/    and  print \"Contains a Perl comment\\n\";\n        /$RE{comment}{awk}/     and  print \"Contains an awk comment\\n\";\n        /$RE{comment}{HTML}/    and  print \"Contains an HTML comment\\n\";\n    }\n\n    use Regexp::Common qw /comment RE_comment_HTML/;\n\n    while (<>) {\n        $_ =~ RE_comment_HTML() and  print \"Contains an HTML comment\\n\";\n    }\n\n=head1 DESCRIPTION\n\nPlease consult the manual of L<Regexp::Common> for a general description\nof the works of this interface.\n\nDo not use this module directly, but load it via I<Regexp::Common>.\n\nThis modules gives you regular expressions for comments in various\nlanguages.\n\n=head2 THE LANGUAGES\n\nBelow, the comments of each of the languages are described.\nThe patterns are available as C<$RE{comment}{I<LANG>}>, foreach\nlanguage I<LANG>. Some languages have variants; it's described\nat the individual languages how to get the patterns for the variants.\nUnless mentioned otherwise,\nC<{-keep}> sets C<$1>, C<$2>, C<$3> and C<$4> to the entire comment,\nthe opening marker, the content of the comment, and the closing marker\n(for many languages, the latter is a newline) respectively.\n\n=over 4\n\n=item ABC\n\nComments in I<ABC> start with a backslash (C<\\>), and last till\nthe end of the line.\nSee L<http://homepages.cwi.nl/%7Esteven/abc/>.\n\n=item Ada\n\nComments in I<Ada> start with C<-->, and last till the end of the line.\n\n=item Advisor\n\nI<Advisor> is a language used by the HP product I<glance>. Comments for\nthis language start with either C<#> or C<//>, and last till the\nend of the line.\n\n=item Advsys\n\nComments for the I<Advsys> language start with C<;> and last till\nthe end of the line. See also L<http://www.wurb.com/if/devsys/12>.\n\n=item Alan\n\nI<Alan> comments start with C<-->, and last till the end of the line.\nSee also L<http://w1.132.telia.com/~u13207378/alan/manual/alanTOC.html>.\n\n=item Algol 60\n\nComments in the I<Algol 60> language start with the keyword C<comment>,\nand end with a C<;>. See L<http://www.masswerk.at/algol60/report.htm>.\n\n=item Algol 68\n\nIn I<Algol 68>, comments are either delimited by C<#>, or by one of the\nkeywords C<co> or C<comment>. The keywords should not be part of another\nword. See L<http://westein.arb-phys.uni-dortmund.de/~wb/a68s.txt>.\nWith C<{-keep}>, only C<$1> will be set, returning the entire comment.\n\n=item ALPACA\n\nThe I<ALPACA> language has comments starting with C</*> and ending with C<*/>.\n\n=item awk\n\nThe I<awk> programming language uses comments that start with C<#>\nand end at the end of the line.\n\n=item B\n\nThe I<B> language has comments starting with C</*> and ending with C<*/>.\n\n=item BASIC\n\nThere are various forms of BASIC around. Currently, we only support the\nvariant supported by I<mvEnterprise>, whose pattern is available as\nC<$RE{comment}{BASIC}{mvEnterprise}>. Comments in this language start with a\nC<!>, a C<*> or the keyword C<REM>, and end till the end of the line. See\nL<http://www.rainingdata.com/products/beta/docs/mve/50/ReferenceManual/Basic.pdf>.\n\n=item Beatnik\n\nThe esotoric language I<Beatnik> only uses words consisting of letters.\nWords are scored according to the rules of Scrabble. Words scoring less\nthan 5 points, or 18 points or more are considered comments (although\nthe compiler might mock at you if you score less than 5 points).\nRegardless whether C<{-keep}>, C<$1> will be set, and set to the\nentire comment. This pattern requires I<perl 5.8.0> or newer.\n\n=item beta-Juliet\n\nThe I<beta-Juliet> programming language has comments that start with\nC<//> and that continue till the end of the line. See also\nL<http://www.catseye.mb.ca/esoteric/b-juliet/index.html>.\n\n=item Befunge-98\n\nThe esotoric language I<Befunge-98> uses comments that start and end\nwith a C<;>. See L<http://www.catseye.mb.ca/esoteric/befunge/98/spec98.html>.\n\n=item BML\n\nI<BML>, or I<Better Markup Language> is an HTML templating language that\nuses comments starting with C<< <?c_ >>, and ending with C<< c_?> >>.\nSee L<http://www.livejournal.com/doc/server/bml.index.html>.\n\n=item Brainfuck\n\nThe minimal language I<Brainfuck> uses only eight characters,\nC<E<lt>>, C<E<gt>>, C<[>, C<]>, C<+>, C<->, C<.> and C<,>.\nAny other characters are considered comments. With C<{-keep}>,\nC<$1> is set to the entire comment.\n\n=item C\n\nThe I<C> language has comments starting with C</*> and ending with C<*/>.\n\n=item C--\n\nThe I<C--> language has comments starting with C</*> and ending with C<*/>.\nSee L<http://cs.uas.arizona.edu/classes/453/programs/C--Spec.html>.\n\n=item C++\n\nThe I<C++> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment.\n\n=item C#\n\nThe I<C#> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment.\nSee L<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_C.asp>.\n\n=item Caml\n\nComments in I<Caml> start with C<(*>, end with C<*)>, and can be nested.\nSee L<http://www.cs.caltech.edu/courses/cs134/cs134b/book.pdf> and\nL<http://pauillac.inria.fr/caml/index-eng.html>.\n\n=item Cg\n\nThe I<Cg> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment.\nSee L<http://developer.nvidia.com/attach/3722>.\n\n=item CLU\n\nIn C<CLU>, a comment starts with a procent sign (C<%>), and ends with the\nnext newline. See L<ftp://ftp.lcs.mit.edu:/pub/pclu/CLU-syntax.ps> and\nL<http://www.pmg.lcs.mit.edu/CLU.html>.\n\n=item COBOL\n\nTraditionally, comments in I<COBOL> are indicated by an asterisk in the\nseventh column. This is what the pattern matches. Modern compiler may\nmore lenient though. See L<http://www.csis.ul.ie/cobol/Course/COBOLIntro.htm>,\nand L<http://www.csis.ul.ie/cobol/default.htm>.\n\n=item CQL\n\nComments in the chess query language (I<CQL>) start with a semi colon\n(C<;>) and last till the end of the line. See L<http://www.rbnn.com/cql/>.\n\n=item Crystal Report\n\nThe formula editor in I<Crystal Reports> uses comments that start\nwith C<//>, and end with the end of the line.\n\n=item Dylan\n\nThere are two types of comments in I<Dylan>. They either start with\nC<//>, or are nested comments, delimited with C</*> and C<*/>.\nUnder C<{-keep}>, only C<$1> will be set, returning the entire comment.\nThis pattern requires I<perl 5.6.0> or newer.\n\n=item ECMAScript\n\nThe I<ECMAScript> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment. I<JavaScript> is Netscapes implementation\nof I<ECMAScript>. See\nL<http://www.ecma-international.org/publications/files/ecma-st/Ecma-262.pdf>,\nand L<http://www.ecma-international.org/publications/standards/Ecma-262.htm>.\n\n=item Eiffel\n\nI<Eiffel> comments start with C<-->, and last till the end of the line.\n\n=item False\n\nIn I<False>, comments start with C<{> and end with C<}>.\nSee L<http://wouter.fov120.com/false/false.txt>\n\n=item FPL\n\nThe I<FPL> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment.\n\n=item Forth\n\nComments in Forth start with C<\\>, and end with the end of the line.\nSee also L<http://docs.sun.com/sb/doc/806-1377-10>.\n\n=item Fortran\n\nThere are two forms of I<Fortran>. There's free form I<Fortran>, which\nhas comments that start with C<!>, and end at the end of the line.\nThe pattern for this is given by C<$RE{Fortran}>. Fixed form I<Fortran>,\nwhich has been obsoleted, has comments that start with C<C>, C<c> or\nC<*> in the first column, or with C<!> anywhere, but the sixth column.\nThe pattern for this are given by C<$RE{Fortran}{fixed}>.\n\nSee also L<http://www.cray.com/craydoc/manuals/007-3692-005/html-007-3692-005/>.\n\n=item Funge-98\n\nThe esotoric language I<Funge-98> uses comments that start and end with\na C<;>.\n\n=item fvwm2\n\nConfiguration files for I<fvwm2> have comments starting with a\nC<#> and lasting the rest of the line.\n\n=item Haifu\n\nI<Haifu>, an esotoric language using haikus, has comments starting and\nending with a C<,>.\nSee L<http://www.dangermouse.net/esoteric/haifu.html>.\n\n=item Haskell\n\nThere are two types of comments in I<Haskell>. They either start with\nat least two dashes, or are nested comments, delimited with C<{-> and C<-}>.\nUnder C<{-keep}>, only C<$1> will be set, returning the entire comment.\nThis pattern requires I<perl 5.6.0> or newer.\n\n=item HTML\n\nIn I<HTML>, comments only appear inside a I<comment declaration>.\nA comment declaration starts with a C<E<lt>!>, and ends with a\nC<E<gt>>. Inside this declaration, we have zero or more comments.\nComments starts with C<--> and end with C<-->, and are optionally\nfollowed by whitespace. The pattern C<$RE{comment}{HTML}> recognizes\nthose comment declarations (and hence more than a comment).\nNote that this is not the same as something that starts with\nC<E<lt>!--> and ends with C<--E<gt>>, because the following will\nbe matched completely:\n\n    <!--  First  Comment   --\n      --> Second Comment <!--\n      --  Third  Comment   -->\n\nDo not be fooled by what your favourite browser thinks is an HTML\ncomment.\n\nIf C<{-keep}> is used, the following are returned:\n\n=over 4\n\n=item $1\n\ncaptures the entire comment declaration.\n\n=item $2\n\ncaptures the MDO (markup declaration open), C<E<lt>!>.\n\n=item $3\n\ncaptures the content between the MDO and the MDC.\n\n=item $4\n\ncaptures the (last) comment, without the surrounding dashes.\n\n=item $5\n\ncaptures the MDC (markup declaration close), C<E<gt>>.\n\n=back\n\n=item Hugo\n\nThere are two types of comments in I<Hugo>. They either start with\nC<!> (which cannot be followed by a C<\\>), or are nested comments,\ndelimited with C<!\\> and C<\\!>.\nUnder C<{-keep}>, only C<$1> will be set, returning the entire comment.\nThis pattern requires I<perl 5.6.0> or newer.\n\n=item Icon\n\nI<Icon> has comments that start with C<#> and end at the next new line.\nSee L<http://www.toolsofcomputing.com/IconHandbook/IconHandbook.pdf>,\nL<http://www.cs.arizona.edu/icon/index.htm>, and\nL<http://burks.bton.ac.uk/burks/language/icon/index.htm>.\n\n=item ILLGOL\n\nThe esotoric language I<ILLGOL> uses comments starting with I<NB> and lasting\ntill the end of the line.\nSee L<http://www.catseye.mb.ca/esoteric/illgol/index.html>.\n\n=item INTERCAL\n\nComments in INTERCAL are single line comments. They start with one of\nthe keywords C<NOT> or C<N'T>, and can optionally be preceded by the\nkeywords C<DO> and C<PLEASE>. If both keywords are used, C<PLEASE>\nprecedes C<DO>. Keywords are separated by whitespace.\n\n=item J\n\nThe language I<J> uses comments that start with C<NB.>, and that last till\nthe end of the line. See\nL<http://www.jsoftware.com/books/help/primer/contents.htm>, and\nL<http://www.jsoftware.com/>.\n\n=item Java\n\nThe I<Java> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment.\n\n=item JavaDoc\n\nThe I<Javadoc> documentation syntax is demarked with a subset of\nordinary Java comments to separate it from code.  Comments start with\nC</**> end with C<*/>.  If C<{-keep}> is used, only C<$1> will be set,\nand set to the entire comment. See\nL<http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html#format>.\n\n=item JavaScript\n\nThe I<JavaScript> language has two forms of comments. Comments that start with\nC<//> and last till the end of the line, and comments that start with\nC</*>, and end with C<*/>. If C<{-keep}> is used, only C<$1> will be\nset, and set to the entire comment. I<JavaScript> is Netscapes implementation\nof I<ECMAScript>.\nSee L<http://www.mozilla.org/js/language/E262-3.pdf>,\nand L<http://www.mozilla.org/js/language/>.\n\n=item LaTeX\n\nThe documentation language I<LaTeX> uses comments starting with C<%>\nand ending at the end of the line.\n\n=item Lisp\n\nComments in I<Lisp> start with a semi-colon (C<;>) and last till the\nend of the line.\n\n=item LPC\n\nThe I<LPC> language has comments starting with C</*> and ending with C<*/>.\n\n=item LOGO\n\nComments for the language I<LOGO> start with C<;>, and last till the end\nof the line.\n\n=item lua\n\nComments for the I<lua> language start with C<-->, and last till the end\nof the line. See also L<http://www.lua.org/manual/manual.html>.\n\n=item M, MUMPS\n\nIn C<M> (aka C<MUMPS>), comments start with a semi-colon, and last\ntill the end of a line. The language specification requires the\nsemi-colon to be preceded by one or more I<linestart character>s.\nThose characters default to a space, but that's configurable. This\nrequirement, of preceding the comment with linestart characters is\nB<not> tested for. See\nL<ftp://ftp.intersys.com/pub/openm/ism/ism64docs.zip>,\nL<http://mtechnology.intersys.com/mproducts/openm/index.html>, and\nL<http://mcenter.com/mtrc/index.html>.\n\n=item m4\n\nBy default, the preprocessor language I<m4> uses single line comments,\nthat start with a C<#> and continue to the end of the line, including\nthe newline. The pattern C<$RE {comment} {m4}> matches such comments.\nIn I<m4>, it is possible to change the starting token though.\nSee L<http://wolfram.schneider.org/bsd/7thEdManVol2/m4/m4.pdf>,\nL<http://www.cs.stir.ac.uk/~kjt/research/pdf/expl-m4.pdf>, and\nL<http://www.gnu.org/software/m4/manual/>.\n\n=item Modula-2\n\nIn C<Modula-2>, comments start with C<(*>, and end with C<*)>. Comments\nmay be nested. See L<http://www.modula2.org/>.\n\n=item Modula-3\n\nIn C<Modula-3>, comments start with C<(*>, and end with C<*)>. Comments\nmay be nested. See L<http://www.m3.org/>.\n\n=item mutt\n\nConfiguration files for I<mutt> have comments starting with a\nC<#> and lasting the rest of the line.\n\n=item Nickle\n\nThe I<Nickle> language has one line comments starting with C<#>\n(like Perl), or multiline comments delimited by C</*> and C<*/>\n(like C). Under C<-keep>, only C<$1> will be set. See also\nL<http://www.nickle.org>.\n\n=item Oberon\n\nComments in I<Oberon> start with C<(*> and end with C<*)>.\nSee L<http://www.oberon.ethz.ch/oreport.html>.\n\n=item Pascal\n\nThere are many implementations of Pascal. This modules provides\npattern for comments of several implementations.\n\n=over 4\n\n=item C<$RE{comment}{Pascal}>\n\nThis is the pattern that recognizes comments according to the Pascal ISO\nstandard. This standard says that comments start with either C<{>, or\nC<(*>, and end with C<}> or C<*)>. This means that C<{*)> and C<(*}>\nare considered to be comments. Many Pascal applications don't allow this.\nSee L<http://www.pascal-central.com/docs/iso10206.txt>\n\n=item C<$RE{comment}{Pascal}{Alice}>\n\nThe I<Alice Pascal> compiler accepts comments that start with C<{>\nand end with C<}>. Comments are not allowed to contain newlines.\nSee L<http://www.templetons.com/brad/alice/language/>.\n\n=item C<$RE{comment}{Pascal}{Delphi}>, C<$RE{comment}{Pascal}{Free}>\nand C<$RE{comment}{Pascal}{GPC}>\n\nThe I<Delphi Pascal>, I<Free Pascal> and the I<Gnu Pascal Compiler>\nimplementations of Pascal all have comments that either start with\nC<//> and last till the end of the line, are delimited with C<{>\nand C<}> or are delimited with C<(*> and C<*)>. Patterns for those\ncomments are given by C<$RE{comment}{Pascal}{Delphi}>,\nC<$RE{comment}{Pascal}{Free}> and C<$RE{comment}{Pascal}{GPC}>\nrespectively. These patterns only set C<$1> when C<{-keep}> is used,\nwhich will then include the entire comment.\n\nSee L<http://info.borland.com/techpubs/delphi5/oplg/>,\nL<http://www.freepascal.org/docs-html/ref/ref.html> and\nL<http://www.gnu-pascal.de/gpc/>.\n\n=item C<$RE{comment}{Pascal}{Workshop}>\n\nThe I<Workshop Pascal> compiler, from SUN Microsystems, allows comments\nthat are delimited with either C<{> and C<}>, delimited with\nC<(*)> and C<*>), delimited with C</*>, and C<*/>, or starting\nand ending with a double quote (C<\">). When C<{-keep}> is used,\nonly C<$1> is set, and returns the entire comment.\n\nSee L<http://docs.sun.com/db/doc/802-5762>.\n\n=back\n\n=item PEARL\n\nComments in I<PEARL> start with a C<!> and last till the end of the\nline, or start with C</*> and end with C<*/>. With C<{-keep}>,\nC<$1> will be set to the entire comment.\n\n=item PHP\n\nComments in I<PHP> start with either C<#> or C<//> and last till the\nend of the line, or are delimited by C</*> and C<*/>. With C<{-keep}>,\nC<$1> will be set to the entire comment.\n\n=item PL/B\n\nIn I<PL/B>, comments start with either C<.> or C<;>, and end with the\nnext newline. See L<http://www.mmcctech.com/pl-b/plb-0010.htm>.\n\n=item PL/I\n\nThe I<PL/I> language has comments starting with C</*> and ending with C<*/>.\n\n=item PL/SQL\n\nIn I<PL/SQL>, comments either start with C<--> and run till the end\nof the line, or start with C</*> and end with C<*/>.\n\n=item Perl\n\nI<Perl> uses comments that start with a C<#>, and continue till the end\nof the line.\n\n=item Portia\n\nThe I<Portia> programming language has comments that start with C<//>,\nand last till the end of the line.\n\n=item Python\n\nI<Python> uses comments that start with a C<#>, and continue till the end\nof the line.\n\n=item Q-BAL\n\nComments in the I<Q-BAL> language start with C<`> (a backtick), and\ncontinue till the end of the line.\n\n=item QML\n\nIn C<QML>, comments start with C<#> and last till the end of the line.\nSee L<http://www.questionmark.com/uk/qml/overview.doc>.\n\n=item R\n\nThe statistical language I<R> uses comments that start with a C<#> and\nend with the following new line. See L<http://www.r-project.org/>.\n\n=item REBOL\n\nComments for the I<REBOL> language start with C<;> and last till the\nend of the line.\n\n=item Ruby\n\nComments in I<Ruby> start with C<#> and last till the end of the time.\n\n=item Scheme\n\nI<Scheme> comments start with C<;>, and last till the end of the line.\nSee L<http://schemers.org/>.\n\n=item shell\n\nComments in various I<shell>s start with a C<#> and end at the end of\nthe line.\n\n=item Shelta\n\nThe esotoric language I<Shelta> uses comments that start and end with\na C<;>. See L<http://www.catseye.mb.ca/esoteric/shelta/index.html>.\n\n=item SLIDE\n\nThe I<SLIDE> language has two forms of comments. First there is the\nline comment, which starts with a C<#> and includes the rest of the\nline (just like Perl). Second, there is the multiline, nested comment,\nwhich are delimited by C<(*> and C<*)>. Under C{-keep}>, only\nC<$1> is set, and is set to the entire comment. See\nL<http://www.cs.berkeley.edu/~ug/slide/docs/slide/spec/spec_frame_intro.shtml>.\n\n=item slrn\n\nConfiguration files for I<slrn> have comments starting with a\nC<%> and lasting the rest of the line.\n\n=item Smalltalk\n\nI<Smalltalk> uses comments that start and end with a double quote, C<\">.\n\n=item SMITH\n\nComments in the I<SMITH> language start with C<;>, and last till the\nend of the line.\n\n=item Squeak\n\nIn the Smalltalk variant I<Squeak>, comments start and end with\nC<\">. Double quotes can appear inside comments by doubling them.\n\n=item SQL\n\nStandard I<SQL> uses comments starting with two or more dashes, and\nending at the end of the line.\n\nI<MySQL> does not follow the standard. Instead, it allows comments\nthat start with a C<#> or C<-- > (that's two dashes and a space)\nending with the following newline, and comments starting with\nC</*>, and ending with the next C<;> or C<*/> that isn't inside\nsingle or double quotes. A pattern for this is returned by\nC<$RE{comment}{SQL}{MySQL}>. With C<{-keep}>, only C<$1> will\nbe set, and it returns the entire comment.\n\n=item Tcl\n\nIn I<Tcl>, comments start with C<#> and continue till the end of the line.\n\n=item TeX\n\nThe documentation language I<TeX> uses comments starting with C<%>\nand ending at the end of the line.\n\n=item troff\n\nThe document formatting language I<troff> uses comments starting\nwith C<\\\">, and continuing till the end of the line.\n\n=item Ubercode\n\nThe Windows programming language I<Ubercode> uses comments that start with\nC<//> and continue to the end of the line. See L<http://www.ubercode.com>.\n\n=item vi\n\nIn configuration files for the editor I<vi>, one can use comments\nstarting with C<\">, and ending at the end of the line.\n\n=item *W\n\nIn the language I<*W>, comments start with C<||>, and end with C<!!>.\n\n=item zonefile\n\nComments in DNS I<zonefile>s start with C<;>, and continue till the\nend of the line.\n\n=item ZZT-OOP\n\nThe in-game language I<ZZT-OOP> uses comments that start with a C<'>\ncharacter, and end at the following newline. See\nL<http://dave2.rocketjump.org/rad/zzthelp/lang.html>.\n\n=back\n\n=head1 REFERENCES\n\n=over 4\n\n=item B<[Go 90]>\n\nCharles F. Goldfarb: I<The SGML Handbook>. Oxford: Oxford University\nPress. B<1990>. ISBN 0-19-853737-9. Ch. 10.3, pp 390-391.\n\n=back\n\n=head1 SEE ALSO\n\nL<Regexp::Common> for a general description of how to use this interface.\n\n=head1 AUTHOR\n\nDamian Conway (damian@conway.org)\n\n=head1 MAINTENANCE\n\nThis package is maintained by Abigail S<(I<regexp-common@abigail.be>)>.\n\n=head1 BUGS AND IRRITATIONS\n\nBound to be plenty.\n\nFor a start, there are many common regexes missing.\nSend them in to I<regexp-common@abigail.be>.\n\n=head1 LICENSE and COPYRIGHT\n\nThis software is Copyright (c) 2001 - 2017, Damian Conway and Abigail.\n\nThis module is free software, and maybe used under any of the following\nlicenses:\n\n 1) The Perl Artistic License.     See the file COPYRIGHT.AL.\n 2) The Perl Artistic License 2.0. See the file COPYRIGHT.AL2.\n 3) The BSD License.               See the file COPYRIGHT.BSD.\n 4) The MIT License.               See the file COPYRIGHT.MIT.\n\n=cut\nEOC\n# 2}}}\n$Regexp_Common_Contents{'Common/balanced'} = <<'EOB';   # {{{2\npackage Regexp::Common::balanced; {\n\nuse 5.10.0;\n\nuse strict;\nuse warnings;\nno  warnings 'syntax';\n\nuse Regexp::Common qw /pattern clean no_defaults/;\n\nour $VERSION = '2017060201';\n\nmy %closer = ( '{'=>'}', '('=>')', '['=>']', '<'=>'>' );\nmy %cache;\n\nsub nested {\n    my ($start, $finish) = @_;\n\n    return $cache {$start} {$finish} if exists $cache {$start} {$finish};\n\n    my @starts   = map {s/\\\\(.)/$1/g; $_} grep {length}\n                        $start  =~ /([^|\\\\]+|\\\\.)+/gs;\n    my @finishes = map {s/\\\\(.)/$1/g; $_} grep {length}\n                        $finish =~ /([^|\\\\]+|\\\\.)+/gs;\n\n    push @finishes => ($finishes [-1]) x (@starts - @finishes);\n\n    my @re;\n    local $\" = \"|\";\n    foreach my $begin (@starts) {\n        my $end = shift @finishes;\n\n        my $qb  = quotemeta $begin;\n        my $qe  = quotemeta $end;\n        my $fb  = quotemeta substr $begin => 0, 1;\n        my $fe  = quotemeta substr $end   => 0, 1;\n\n        my $tb  = quotemeta substr $begin => 1;\n        my $te  = quotemeta substr $end   => 1;\n\n        my $add;\n        if ($fb eq $fe) {\n            push @re =>\n                   qq /(?:$qb(?:(?>[^$fb]+)|$fb(?!$tb)(?!$te)|(?-1))*$qe)/;\n        }\n        else {\n            my   @clauses =  \"(?>[^$fb$fe]+)\";\n            push @clauses => \"$fb(?!$tb)\" if length $tb;\n            push @clauses => \"$fe(?!$te)\" if length $te;\n            push @clauses => \"(?-1)\";\n            push @re      =>  qq /(?:$qb(?:@clauses)*$qe)/;\n        }\n    }\n\n    $cache {$start} {$finish} = qr /(@re)/;\n}\n\n\npattern name    => [qw /balanced -parens=() -begin= -end=/],\n        create  => sub {\n            my $flag = $_[1];\n            unless (defined $flag -> {-begin} && length $flag -> {-begin} &&\n                    defined $flag -> {-end}   && length $flag -> {-end}) {\n                my @open  = grep {index ($flag->{-parens}, $_) >= 0}\n                             ('[','(','{','<');\n                my @close = map {$closer {$_}} @open;\n                $flag -> {-begin} = join \"|\" => @open;\n                $flag -> {-end}   = join \"|\" => @close;\n            }\n            return nested @$flag {qw /-begin -end/};\n        },\n        ;\n\n}\n\n1;\n\n__END__\n\n=pod\n\n=head1 NAME\n\nRegexp::Common::balanced -- provide regexes for strings with balanced\nparenthesized delimiters or arbitrary delimiters.\n\n=head1 SYNOPSIS\n\n    use Regexp::Common qw /balanced/;\n\n    while (<>) {\n        /$RE{balanced}{-parens=>'()'}/\n                                   and print q{balanced parentheses\\n};\n    }\n\n\n=head1 DESCRIPTION\n\nPlease consult the manual of L<Regexp::Common> for a general description\nof the works of this interface.\n\nDo not use this module directly, but load it via I<Regexp::Common>.\n\n=head2 C<$RE{balanced}{-parens}>\n\nReturns a pattern that matches a string that starts with the nominated\nopening parenthesis or bracket, contains characters and properly nested\nparenthesized subsequences, and ends in the matching parenthesis.\n\nMore than one type of parenthesis can be specified:\n\n        $RE{balanced}{-parens=>'(){}'}\n\nin which case all specified parenthesis types must be correctly balanced within\nthe string.\n\nSince version 2013030901, C<< $1 >> will always be set (to the entire\nmatched substring), regardless whether C<< {-keep} >> is used or not.\n\n=head2 C<< $RE{balanced}{-begin => \"begin\"}{-end => \"end\"} >>\n\nReturns a pattern that matches a string that is properly balanced\nusing the I<begin> and I<end> strings as start and end delimiters.\nMultiple sets of begin and end strings can be given by separating\nthem by C<|>s (which can be escaped with a backslash).\n\n    qr/$RE{balanced}{-begin => \"do|if|case\"}{-end => \"done|fi|esac\"}/\n\nwill match properly balanced strings that either start with I<do> and\nend with I<done>, start with I<if> and end with I<fi>, or start with\nI<case> and end with I<esac>.\n\nIf I<-end> contains less cases than I<-begin>, the last case of I<-end>\nis repeated. If it contains more cases than I<-begin>, the extra cases\nare ignored. If either of I<-begin> or I<-end> isn't given, or is empty,\nI<< -begin => '(' >> and I<< -end => ')' >> are assumed.\n\nSince version 2013030901, C<< $1 >> will always be set (to the entire\nmatched substring), regardless whether C<< {-keep} >> is used or not.\n\n=head2 Note\n\nSince version 2013030901 the pattern will make of the recursive construct\nC<< (?-1) >>, instead of using the problematic C<< (??{ }) >> construct.\nThis fixes an problem that was introduced in the 5.17 development track.\n\n=head1 SEE ALSO\n\nL<Regexp::Common> for a general description of how to use this interface.\n\n=head1 AUTHOR\n\nDamian Conway (damian@conway.org)\n\n=head1 MAINTENANCE\n\nThis package is maintained by Abigail S<(I<regexp-common@abigail.be>)>.\n\n=head1 BUGS AND IRRITATIONS\n\nBound to be plenty.\n\nFor a start, there are many common regexes missing.\nSend them in to I<regexp-common@abigail.be>.\n\n=head1 LICENSE and COPYRIGHT\n\nThis software is Copyright (c) 2001 - 2017, Damian Conway and Abigail.\n\nThis module is free software, and maybe used under any of the following\nlicenses:\n\n 1) The Perl Artistic License.     See the file COPYRIGHT.AL.\n 2) The Perl Artistic License 2.0. See the file COPYRIGHT.AL2.\n 3) The BSD License.               See the file COPYRIGHT.BSD.\n 4) The MIT License.               See the file COPYRIGHT.MIT.\n\n=cut\nEOB\n# 2}}}\n$Regexp_Common_Contents{'Common/delimited'} = <<'EOD';   # {{{2\npackage Regexp::Common::delimited;\n\nuse 5.10.0;\n\nuse strict;\nuse warnings;\nno  warnings 'syntax';\n\nuse Regexp::Common qw /pattern clean no_defaults/;\n\nuse charnames ':full';\n\nour $VERSION = '2017060201';\n\nsub gen_delimited {\n\n    my ($dels, $escs, $cdels) = @_;\n    # return '(?:\\S*)' unless $dels =~ /\\S/;\n    if (defined $escs && length $escs) {\n        $escs  .= substr  ($escs, -1) x (length ($dels) - length  ($escs));\n    }\n    if (defined $cdels && length $cdels) {\n        $cdels .= substr ($cdels, -1) x (length ($dels) - length ($cdels));\n    }\n    else {\n        $cdels = $dels;\n    }\n\n    my @pat = ();\n    for (my $i = 0; $i < length $dels; $i ++) {\n        my $del  = quotemeta substr  ($dels, $i, 1);\n        my $cdel = quotemeta substr ($cdels, $i, 1);\n        my $esc  = defined $escs && length ($escs)\n                           ? quotemeta substr ($escs, $i, 1) : \"\";\n        if ($cdel eq $esc) {\n            push @pat =>\n                \"(?k:$del)(?k:[^$cdel]*(?:(?:$cdel$cdel)[^$cdel]*)*)(?k:$cdel)\";\n        }\n        elsif (length $esc) {\n            push @pat =>\n                \"(?k:$del)(?k:[^$esc$cdel]*(?:$esc.[^$esc$cdel]*)*)(?k:$cdel)\";\n        }\n        else {\n            push @pat => \"(?k:$del)(?k:[^$cdel]*)(?k:$cdel)\";\n        }\n    }\n    my $pat = join '|', @pat;\n    return \"(?k:(?|$pat))\";\n}\n\nsub _croak {\n    require Carp;\n    goto &Carp::croak;\n}\n\npattern name    => [qw( delimited -delim= -esc=\\\\ -cdelim= )],\n        create  => sub {my $flags = $_[1];\n                        _croak 'Must specify delimiter in $RE{delimited}'\n                              unless length $flags->{-delim};\n                        return gen_delimited (@{$flags}{-delim, -esc, -cdelim});\n                   },\n        ;\n\npattern name    => [qw( quoted -esc=\\\\ )],\n        create  => sub {my $flags = $_[1];\n                        return gen_delimited (q{\"'`}, $flags -> {-esc});\n                   },\n        ;\n\n\nmy @bracket_pairs;\nif ($] >= 5.014) {\n    #\n    # List from http://xahlee.info/comp/unicode_matching_brackets.html\n    #\n    @bracket_pairs =\n        map {ref $_ ? $_ :\n                /!/ ? [(do {my $x = $_; $x =~ s/!/TOP/;    $x},\n                        do {my $x = $_; $x =~ s/!/BOTTOM/; $x})]\n                    : [(do {my $x = $_; $x =~ s/\\?/LEFT/;  $x},\n                        do {my $x = $_; $x =~ s/\\?/RIGHT/; $x})]}\n            \"? PARENTHESIS\",\n            \"? SQUARE BRACKET\",\n            \"? CURLY BRACKET\",\n            \"? DOUBLE QUOTATION MARK\",\n            \"? SINGLE QUOTATION MARK\",\n            \"SINGLE ?-POINTING ANGLE QUOTATION MARK\",\n            \"?-POINTING DOUBLE ANGLE QUOTATION MARK\",\n            \"FULLWIDTH ? PARENTHESIS\",\n            \"FULLWIDTH ? SQUARE BRACKET\",\n            \"FULLWIDTH ? CURLY BRACKET\",\n            \"FULLWIDTH ? WHITE PARENTHESIS\",\n            \"? WHITE PARENTHESIS\",\n            \"? WHITE SQUARE BRACKET\",\n            \"? WHITE CURLY BRACKET\",\n            \"? CORNER BRACKET\",\n            \"? ANGLE BRACKET\",\n            \"? DOUBLE ANGLE BRACKET\",\n            \"? BLACK LENTICULAR BRACKET\",\n            \"? TORTOISE SHELL BRACKET\",\n            \"? BLACK TORTOISE SHELL BRACKET\",\n            \"? WHITE CORNER BRACKET\",\n            \"? WHITE LENTICULAR BRACKET\",\n            \"? WHITE TORTOISE SHELL BRACKET\",\n            \"HALFWIDTH ? CORNER BRACKET\",\n            \"MATHEMATICAL ? WHITE SQUARE BRACKET\",\n            \"MATHEMATICAL ? ANGLE BRACKET\",\n            \"MATHEMATICAL ? DOUBLE ANGLE BRACKET\",\n            \"MATHEMATICAL ? FLATTENED PARENTHESIS\",\n            \"MATHEMATICAL ? WHITE TORTOISE SHELL BRACKET\",\n            \"? CEILING\",\n            \"? FLOOR\",\n            \"Z NOTATION ? IMAGE BRACKET\",\n            \"Z NOTATION ? BINDING BRACKET\",\n            [   \"HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT\",\n                \"HEAVY SINGLE \" .   \"COMMA QUOTATION MARK ORNAMENT\", ],\n            [   \"HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT\",\n                \"HEAVY DOUBLE \" .   \"COMMA QUOTATION MARK ORNAMENT\", ],\n            \"MEDIUM ? PARENTHESIS ORNAMENT\",\n            \"MEDIUM FLATTENED ? PARENTHESIS ORNAMENT\",\n            \"MEDIUM ? CURLY BRACKET ORNAMENT\",\n            \"MEDIUM ?-POINTING ANGLE BRACKET ORNAMENT\",\n            \"HEAVY ?-POINTING ANGLE QUOTATION MARK ORNAMENT\",\n            \"HEAVY ?-POINTING ANGLE BRACKET ORNAMENT\",\n            \"LIGHT ? TORTOISE SHELL BRACKET ORNAMENT\",\n            \"ORNATE ? PARENTHESIS\",\n            \"! PARENTHESIS\",\n            \"! SQUARE BRACKET\",\n            \"! CURLY BRACKET\",\n            \"! TORTOISE SHELL BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? CORNER BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? WHITE CORNER BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? TORTOISE SHELL BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? BLACK LENTICULAR BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? WHITE LENTICULAR BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? ANGLE BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? DOUBLE ANGLE BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? SQUARE BRACKET\",\n            \"PRESENTATION FORM FOR VERTICAL ? CURLY BRACKET\",\n            \"?-POINTING ANGLE BRACKET\",\n            \"? ANGLE BRACKET WITH DOT\",\n            \"?-POINTING CURVED ANGLE BRACKET\",\n            \"SMALL ? PARENTHESIS\",\n            \"SMALL ? CURLY BRACKET\",\n            \"SMALL ? TORTOISE SHELL BRACKET\",\n            \"SUPERSCRIPT ? PARENTHESIS\",\n            \"SUBSCRIPT ? PARENTHESIS\",\n            \"? SQUARE BRACKET WITH UNDERBAR\",\n            [    \"LEFT SQUARE BRACKET WITH TICK IN TOP CORNER\",\n                \"RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER\", ],\n            [    \"LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER\",\n                \"RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER\", ],\n            \"? SQUARE BRACKET WITH QUILL\",\n            \"TOP ? HALF BRACKET\",\n            \"BOTTOM ? HALF BRACKET\",\n            \"? S-SHAPED BAG DELIMITER\",\n            [    \"LEFT ARC LESS-THAN BRACKET\",\n                \"RIGHT ARC GREATER-THAN BRACKET\",  ],\n            [    \"DOUBLE LEFT ARC GREATER-THAN BRACKET\",\n                \"DOUBLE RIGHT ARC LESS-THAN BRACKET\",  ],\n            \"? SIDEWAYS U BRACKET\",\n            \"? DOUBLE PARENTHESIS\",\n            \"? WIGGLY FENCE\",\n            \"? DOUBLE WIGGLY FENCE\",\n            \"? LOW PARAPHRASE BRACKET\",\n            \"? RAISED OMISSION BRACKET\",\n            \"? SUBSTITUTION BRACKET\",\n            \"? DOTTED SUBSTITUTION BRACKET\",\n            \"? TRANSPOSITION BRACKET\",\n            [   \"OGHAM FEATHER MARK\",\n                \"OGHAM REVERSED FEATHER MARK\",  ],\n            [   \"TIBETAN MARK GUG RTAGS GYON\",\n                \"TIBETAN MARK GUG RTAGS GYAS\",  ],\n            [   \"TIBETAN MARK ANG KHANG GYON\",\n                \"TIBETAN MARK ANG KHANG GYAS\",  ],\n    ;\n\n    #\n    # Filter out unknown characters; this may run on an older version\n    # of Perl with an old version of Unicode.\n    #\n    @bracket_pairs = grep {defined charnames::string_vianame ($$_ [0]) &&\n                           defined charnames::string_vianame ($$_ [1])}\n                     @bracket_pairs;\n\n    if (@bracket_pairs) {\n        my  $delims = join \"\" => map {charnames::string_vianame ($$_ [0])}\n                                     @bracket_pairs;\n        my $cdelims = join \"\" => map {charnames::string_vianame ($$_ [1])}\n                                     @bracket_pairs;\n\n        pattern name   => [qw (bquoted -esc=\\\\)],\n                create => sub {my $flags = $_ [1];\n                               return gen_delimited ($delims, $flags -> {-esc},\n                                                    $cdelims);\n                          },\n                version => 5.014,\n                ;\n    }\n}\n\n\n#\n# Return the Unicode names of the pairs of matching delimiters.\n#\nsub bracket_pairs {@bracket_pairs}\n\n1;\n\n__END__\n\n=pod\n\n=head1 NAME\n\nRegexp::Common::delimited -- provides a regex for delimited strings\n\n=head1 SYNOPSIS\n\n    use Regexp::Common qw /delimited/;\n\n    while (<>) {\n        /$RE{delimited}{-delim=>'\"'}/  and print 'a \\\" delimited string';\n        /$RE{delimited}{-delim=>'/'}/  and print 'a \\/ delimited string';\n    }\n\n\n=head1 DESCRIPTION\n\nPlease consult the manual of L<Regexp::Common> for a general description\nof the works of this interface.\n\nDo not use this module directly, but load it via I<Regexp::Common>.\n\n=head2 C<$RE{delimited}{-delim}{-cdelim}{-esc}>\n\nReturns a pattern that matches a single-character-delimited substring,\nwith optional internal escaping of the delimiter.\n\nWhen C<-delim => I<S>> is specified, each character in the sequence I<S> is\na possible delimiter. There is no default delimiter, so this flag must always\nbe specified.\n\nBy default, the closing delimiter is the same character as the opening\ndelimiter. If this is not wanted, for instance, if you want to match\na string with symmetric delimiters, you can specify the closing delimiter(s)\nwith C<-cdelim => I<S>>. Each character in I<S> is matched with the\ncorresponding character supplied with the C<-delim> option. If the C<-cdelim>\noption has less characters than the C<-delim> option, the last character\nis repeated as often as necessary. If the C<-cdelim> option has more\ncharacters than the C<-delim> option, the extra characters are ignored.\n\nIf C<-esc => I<S>> is specified, each character in the sequence I<S> is\nthe delimiter for the corresponding character in the C<-delim=I<S>> list.\nThe default escape is backslash.\n\nFor example:\n\n   $RE{delimited}{-delim=>'\"'}               # match \"a \\\" delimited string\"\n   $RE{delimited}{-delim=>'\"'}{-esc=>'\"'}    # match \"a \"\" delimited string\"\n   $RE{delimited}{-delim=>'/'}               # match /a \\/ delimited string/\n   $RE{delimited}{-delim=>q{'\"}}             # match \"string\" or 'string'\n   $RE{delimited}{-delim=>\"(\"}{-cdelim=>\")\"} # match (string)\n\nUnder C<-keep> (See L<Regexp::Common>):\n\n=over 4\n\n=item $1\n\ncaptures the entire match\n\n=item $2\n\ncaptures the opening delimiter\n\n=item $3\n\ncaptures delimited portion of the string\n\n=item $4\n\ncaptures the closing delimiter\n\n=back\n\n=head2 $RE{quoted}{-esc}\n\nA synonym for C<< $RE {delimited} {-delim => q {'\"`}} {...} >>.\n\n=head2 $RE {bquoted} {-esc}\n\nThis is a pattern which matches delimited strings, where the delimiters\nare a set of matching brackets. Currently, this comes 85 pairs. This\nincludes the 60 pairs of bidirection paired brackets, as listed\nin L<< http://www.unicode.org/Public/UNIDATA/BidiBrackets.txt >>.\n\nThe other 25 pairs are the quotation marks, the double quotation\nmarks, the single and double pointing quoation marks, the heavy\nsingle and double commas, 4 pairs of top-bottom parenthesis and\nbrackets, 9 pairs of presentation form for vertical brackets,\nand the low paraphrase, raised omission, substitution, double\nsubstitution, and transposition brackets.\n\nIn a future update, pairs may be added (or deleted).\n\nThis pattern requires perl 5.14.0 or higher.\n\nFor a full list of bracket pairs, inspect the output of\nC<< Regexp::Common::delimited::bracket_pair () >>, which returns\na list of two element arrays, each holding the Unicode names of\nmatching pair of delimiters.\n\nThe C<< {-esc => I<S> } >> works as in the C<< $RE {delimited} >> pattern.\n\nIf C<< {-keep} >> is given, the following things will be captured:\n\n=over 4\n\n=item $1\n\ncaptures the entire match\n\n=item $2\n\ncaptures the opening delimiter\n\n=item $3\n\ncaptures delimited portion of the string\n\n=item $4\n\ncaptures the closing delimiter\n\n=back\n\n=head1 SEE ALSO\n\nL<Regexp::Common> for a general description of how to use this interface.\n\n=head1 AUTHOR\n\nDamian Conway (damian@conway.org)\n\n=head1 MAINTENANCE\n\nThis package is maintained by Abigail S<(I<regexp-common@abigail.be>)>.\n\n=head1 BUGS AND IRRITATIONS\n\nBound to be plenty.\n\nFor a start, there are many common regexes missing.\nSend them in to I<regexp-common@abigail.be>.\n\n=head1 LICENSE and COPYRIGHT\n\nThis software is Copyright (c) 2001 - 2017, Damian Conway and Abigail.\n\nThis module is free software, and maybe used under any of the following\nlicenses:\n\n 1) The Perl Artistic License.     See the file COPYRIGHT.AL.\n 2) The Perl Artistic License 2.0. See the file COPYRIGHT.AL2.\n 3) The BSD License.               See the file COPYRIGHT.BSD.\n 4) The MIT License.               See the file COPYRIGHT.MIT.\n\n=cut\nEOD\n# 2}}}\n    my $problems        = 0;\n    $HAVE_Rexexp_Common = 0;\n    my $dir             = \"\";\n    if ($opt_sdir) {\n        ++$TEMP_OFF;\n        $dir = \"$opt_sdir/$TEMP_OFF\";\n        File::Path::rmtree($dir) if     is_dir($dir);\n        File::Path::mkpath($dir) unless is_dir($dir);\n    } else {\n        # let File::Temp create a suitable temporary directory\n        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n        $TEMP_INST{ $dir } = \"Regexp::Common\";\n    }\n    print \"Using temp dir [$dir] to install Regexp::Common\\n\" if $opt_v;\n    my $Regexp_dir        = \"$dir/Regexp\";\n    my $Regexp_Common_dir = \"$dir/Regexp/Common\";\n    mkdir $Regexp_dir       ;\n    mkdir $Regexp_Common_dir;\n\n    foreach my $module_file (keys %Regexp_Common_Contents) {\n        my $OUT = open_file('>', \"$dir/Regexp/${module_file}.pm\", 1);\n        if (defined $OUT) {\n            print $OUT $Regexp_Common_Contents{$module_file};\n            $OUT->close;\n        } else {\n            warn \"Failed to install Regexp::${module_file}.pm\\n\";\n            $problems = 1;\n        }\n    }\n\n    push @INC, $dir;\n    eval \"use Regexp::Common qw /comment RE_comment_HTML balanced/\";\n    $HAVE_Rexexp_Common = 1 unless $problems;\n    print \"<- Install_Regexp_Common\\n\" if $opt_v > 2;\n} # 1}}}\nsub Install_Algorithm_Diff {                 # {{{1\n    # Installs Tye McQueen's Algorithm::Diff module, v1.1902, into a\n    # temporary directory for the duration of this run.\n    print \"-> Install_Algorithm_Diff v1.1902\\n\" if $opt_v > 2;\n\nmy $Algorithm_Diff_Contents = <<'EOAlgDiff'; # {{{2\npackage Algorithm::Diff;\n# Skip to first \"=head\" line for documentation.\nuse strict;\n\nuse integer;    # see below in _replaceNextLargerWith() for mod to make\n                # if you don't use this\nuse vars qw( $VERSION @EXPORT_OK );\n$VERSION = 1.19_02;\n#          ^ ^^ ^^-- Incremented at will\n#          | \\+----- Incremented for non-trivial changes to features\n#          \\-------- Incremented for fundamental changes\nrequire Exporter;\n*import    = \\&Exporter::import;\n@EXPORT_OK = qw(\n    prepare LCS LCSidx LCS_length\n    diff sdiff compact_diff\n    traverse_sequences traverse_balanced\n);\n\n# McIlroy-Hunt diff algorithm\n# Adapted from the Smalltalk code of Mario I. Wolczko, <mario@wolczko.com>\n# by Ned Konz, perl@bike-nomad.com\n# Updates by Tye McQueen, http://perlmonks.org/?node=tye\n\n# Create a hash that maps each element of $aCollection to the set of\n# positions it occupies in $aCollection, restricted to the elements\n# within the range of indexes specified by $start and $end.\n# The fourth parameter is a subroutine reference that will be called to\n# generate a string to use as a key.\n# Additional parameters, if any, will be passed to this subroutine.\n#\n# my $hashRef = _withPositionsOfInInterval( \\@array, $start, $end, $keyGen );\n\nsub _withPositionsOfInInterval\n{\n    my $aCollection = shift;    # array ref\n    my $start       = shift;\n    my $end         = shift;\n    my $keyGen      = shift;\n    my %d;\n    my $index;\n    for ( $index = $start ; $index <= $end ; $index++ )\n    {\n        my $element = $aCollection->[$index];\n        my $key = &$keyGen( $element, @_ );\n        if ( exists( $d{$key} ) )\n        {\n            unshift ( @{ $d{$key} }, $index );\n        }\n        else\n        {\n            $d{$key} = [$index];\n        }\n    }\n    return wantarray ? %d : \\%d;\n}\n\n# Find the place at which aValue would normally be inserted into the\n# array. If that place is already occupied by aValue, do nothing, and\n# return undef. If the place does not exist (i.e., it is off the end of\n# the array), add it to the end, otherwise replace the element at that\n# point with aValue.  It is assumed that the array's values are numeric.\n# This is where the bulk (75%) of the time is spent in this module, so\n# try to make it fast!\n\nsub _replaceNextLargerWith\n{\n    my ( $array, $aValue, $high ) = @_;\n    $high ||= $#$array;\n\n    # off the end?\n    if ( $high == -1 || $aValue > $array->[-1] )\n    {\n        push ( @$array, $aValue );\n        return $high + 1;\n    }\n\n    # binary search for insertion point...\n    my $low = 0;\n    my $index;\n    my $found;\n    while ( $low <= $high )\n    {\n        $index = ( $high + $low ) / 2;\n\n        # $index = int(( $high + $low ) / 2);  # without 'use integer'\n        $found = $array->[$index];\n\n        if ( $aValue == $found )\n        {\n            return undef;\n        }\n        elsif ( $aValue > $found )\n        {\n            $low = $index + 1;\n        }\n        else\n        {\n            $high = $index - 1;\n        }\n    }\n\n    # now insertion point is in $low.\n    $array->[$low] = $aValue;    # overwrite next larger\n    return $low;\n}\n\n# This method computes the longest common subsequence in $a and $b.\n\n# Result is array or ref, whose contents is such that\n#   $a->[ $i ] == $b->[ $result[ $i ] ]\n# foreach $i in ( 0 .. $#result ) if $result[ $i ] is defined.\n\n# An additional argument may be passed; this is a hash or key generating\n# function that should return a string that uniquely identifies the given\n# element.  It should be the case that if the key is the same, the elements\n# will compare the same. If this parameter is undef or missing, the key\n# will be the element as a string.\n\n# By default, comparisons will use \"eq\" and elements will be turned into keys\n# using the default stringizing operator '\"\"'.\n\n# Additional parameters, if any, will be passed to the key generation\n# routine.\n\nsub _longestCommonSubsequence\n{\n    my $a        = shift;    # array ref or hash ref\n    my $b        = shift;    # array ref or hash ref\n    my $counting = shift;    # scalar\n    my $keyGen   = shift;    # code ref\n    my $compare;             # code ref\n\n    if ( ref($a) eq 'HASH' )\n    {                        # prepared hash must be in $b\n        my $tmp = $b;\n        $b = $a;\n        $a = $tmp;\n    }\n\n    # Check for bogus (non-ref) argument values\n    if ( !ref($a) || !ref($b) )\n    {\n        my @callerInfo = caller(1);\n        die 'error: must pass array or hash references to ' . $callerInfo[3];\n    }\n\n    # set up code refs\n    # Note that these are optimized.\n    if ( !defined($keyGen) )    # optimize for strings\n    {\n        $keyGen = sub { $_[0] };\n        $compare = sub { my ( $a, $b ) = @_; $a eq $b };\n    }\n    else\n    {\n        $compare = sub {\n            my $a = shift;\n            my $b = shift;\n            &$keyGen( $a, @_ ) eq &$keyGen( $b, @_ );\n        };\n    }\n\n    my ( $aStart, $aFinish, $matchVector ) = ( 0, $#$a, [] );\n    my ( $prunedCount, $bMatches ) = ( 0, {} );\n\n    if ( ref($b) eq 'HASH' )    # was $bMatches prepared for us?\n    {\n        $bMatches = $b;\n    }\n    else\n    {\n        my ( $bStart, $bFinish ) = ( 0, $#$b );\n\n        # First we prune off any common elements at the beginning\n        while ( $aStart <= $aFinish\n            and $bStart <= $bFinish\n            and &$compare( $a->[$aStart], $b->[$bStart], @_ ) )\n        {\n            $matchVector->[ $aStart++ ] = $bStart++;\n            $prunedCount++;\n        }\n\n        # now the end\n        while ( $aStart <= $aFinish\n            and $bStart <= $bFinish\n            and &$compare( $a->[$aFinish], $b->[$bFinish], @_ ) )\n        {\n            $matchVector->[ $aFinish-- ] = $bFinish--;\n            $prunedCount++;\n        }\n\n        # Now compute the equivalence classes of positions of elements\n        $bMatches =\n          _withPositionsOfInInterval( $b, $bStart, $bFinish, $keyGen, @_ );\n    }\n    my $thresh = [];\n    my $links  = [];\n\n    my ( $i, $ai, $j, $k );\n    for ( $i = $aStart ; $i <= $aFinish ; $i++ )\n    {\n        $ai = &$keyGen( $a->[$i], @_ );\n        if ( exists( $bMatches->{$ai} ) )\n        {\n            $k = 0;\n            for $j ( @{ $bMatches->{$ai} } )\n            {\n\n                # optimization: most of the time this will be true\n                if ( $k and $thresh->[$k] > $j and $thresh->[ $k - 1 ] < $j )\n                {\n                    $thresh->[$k] = $j;\n                }\n                else\n                {\n                    $k = _replaceNextLargerWith( $thresh, $j, $k );\n                }\n\n                # oddly, it's faster to always test this (CPU cache?).\n                if ( defined($k) )\n                {\n                    $links->[$k] =\n                      [ ( $k ? $links->[ $k - 1 ] : undef ), $i, $j ];\n                }\n            }\n        }\n    }\n\n    if (@$thresh)\n    {\n        return $prunedCount + @$thresh if $counting;\n        for ( my $link = $links->[$#$thresh] ; $link ; $link = $link->[0] )\n        {\n            $matchVector->[ $link->[1] ] = $link->[2];\n        }\n    }\n    elsif ($counting)\n    {\n        return $prunedCount;\n    }\n\n    return wantarray ? @$matchVector : $matchVector;\n}\n\nsub traverse_sequences\n{\n    my $a                 = shift;          # array ref\n    my $b                 = shift;          # array ref\n    my $callbacks         = shift || {};\n    my $keyGen            = shift;\n    my $matchCallback     = $callbacks->{'MATCH'} || sub { };\n    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };\n    my $finishedACallback = $callbacks->{'A_FINISHED'};\n    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };\n    my $finishedBCallback = $callbacks->{'B_FINISHED'};\n    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );\n\n    # Process all the lines in @$matchVector\n    my $lastA = $#$a;\n    my $lastB = $#$b;\n    my $bi    = 0;\n    my $ai;\n\n    for ( $ai = 0 ; $ai <= $#$matchVector ; $ai++ )\n    {\n        my $bLine = $matchVector->[$ai];\n        if ( defined($bLine) )    # matched\n        {\n            &$discardBCallback( $ai, $bi++, @_ ) while $bi < $bLine;\n            &$matchCallback( $ai,    $bi++, @_ );\n        }\n        else\n        {\n            &$discardACallback( $ai, $bi, @_ );\n        }\n    }\n\n    # The last entry (if any) processed was a match.\n    # $ai and $bi point just past the last matching lines in their sequences.\n\n    while ( $ai <= $lastA or $bi <= $lastB )\n    {\n\n        # last A?\n        if ( $ai == $lastA + 1 and $bi <= $lastB )\n        {\n            if ( defined($finishedACallback) )\n            {\n                &$finishedACallback( $lastA, @_ );\n                $finishedACallback = undef;\n            }\n            else\n            {\n                &$discardBCallback( $ai, $bi++, @_ ) while $bi <= $lastB;\n            }\n        }\n\n        # last B?\n        if ( $bi == $lastB + 1 and $ai <= $lastA )\n        {\n            if ( defined($finishedBCallback) )\n            {\n                &$finishedBCallback( $lastB, @_ );\n                $finishedBCallback = undef;\n            }\n            else\n            {\n                &$discardACallback( $ai++, $bi, @_ ) while $ai <= $lastA;\n            }\n        }\n\n        &$discardACallback( $ai++, $bi, @_ ) if $ai <= $lastA;\n        &$discardBCallback( $ai, $bi++, @_ ) if $bi <= $lastB;\n    }\n\n    return 1;\n}\n\nsub traverse_balanced\n{\n    my $a                 = shift;              # array ref\n    my $b                 = shift;              # array ref\n    my $callbacks         = shift || {};\n    my $keyGen            = shift;\n    my $matchCallback     = $callbacks->{'MATCH'} || sub { };\n    my $discardACallback  = $callbacks->{'DISCARD_A'} || sub { };\n    my $discardBCallback  = $callbacks->{'DISCARD_B'} || sub { };\n    my $changeCallback    = $callbacks->{'CHANGE'};\n    my $matchVector = _longestCommonSubsequence( $a, $b, 0, $keyGen, @_ );\n\n    # Process all the lines in match vector\n    my $lastA = $#$a;\n    my $lastB = $#$b;\n    my $bi    = 0;\n    my $ai    = 0;\n    my $ma    = -1;\n    my $mb;\n\n    while (1)\n    {\n\n        # Find next match indices $ma and $mb\n        do {\n            $ma++;\n        } while(\n                $ma <= $#$matchVector\n            &&  !defined $matchVector->[$ma]\n        );\n\n        last if $ma > $#$matchVector;    # end of matchVector?\n        $mb = $matchVector->[$ma];\n\n        # Proceed with discard a/b or change events until\n        # next match\n        while ( $ai < $ma || $bi < $mb )\n        {\n\n            if ( $ai < $ma && $bi < $mb )\n            {\n\n                # Change\n                if ( defined $changeCallback )\n                {\n                    &$changeCallback( $ai++, $bi++, @_ );\n                }\n                else\n                {\n                    &$discardACallback( $ai++, $bi, @_ );\n                    &$discardBCallback( $ai, $bi++, @_ );\n                }\n            }\n            elsif ( $ai < $ma )\n            {\n                &$discardACallback( $ai++, $bi, @_ );\n            }\n            else\n            {\n\n                # $bi < $mb\n                &$discardBCallback( $ai, $bi++, @_ );\n            }\n        }\n\n        # Match\n        &$matchCallback( $ai++, $bi++, @_ );\n    }\n\n    while ( $ai <= $lastA || $bi <= $lastB )\n    {\n        if ( $ai <= $lastA && $bi <= $lastB )\n        {\n\n            # Change\n            if ( defined $changeCallback )\n            {\n                &$changeCallback( $ai++, $bi++, @_ );\n            }\n            else\n            {\n                &$discardACallback( $ai++, $bi, @_ );\n                &$discardBCallback( $ai, $bi++, @_ );\n            }\n        }\n        elsif ( $ai <= $lastA )\n        {\n            &$discardACallback( $ai++, $bi, @_ );\n        }\n        else\n        {\n\n            # $bi <= $lastB\n            &$discardBCallback( $ai, $bi++, @_ );\n        }\n    }\n\n    return 1;\n}\n\nsub prepare\n{\n    my $a       = shift;    # array ref\n    my $keyGen  = shift;    # code ref\n\n    # set up code ref\n    $keyGen = sub { $_[0] } unless defined($keyGen);\n\n    return scalar _withPositionsOfInInterval( $a, 0, $#$a, $keyGen, @_ );\n}\n\nsub LCS\n{\n    my $a = shift;                  # array ref\n    my $b = shift;                  # array ref or hash ref\n    my $matchVector = _longestCommonSubsequence( $a, $b, 0, @_ );\n    my @retval;\n    my $i;\n    for ( $i = 0 ; $i <= $#$matchVector ; $i++ )\n    {\n        if ( defined( $matchVector->[$i] ) )\n        {\n            push ( @retval, $a->[$i] );\n        }\n    }\n    return wantarray ? @retval : \\@retval;\n}\n\nsub LCS_length\n{\n    my $a = shift;                          # array ref\n    my $b = shift;                          # array ref or hash ref\n    return _longestCommonSubsequence( $a, $b, 1, @_ );\n}\n\nsub LCSidx\n{\n    my $a= shift @_;\n    my $b= shift @_;\n    my $match= _longestCommonSubsequence( $a, $b, 0, @_ );\n    my @am= grep defined $match->[$_], 0..$#$match;\n    my @bm= @{$match}[@am];\n    return \\@am, \\@bm;\n}\n\nsub compact_diff\n{\n    my $a= shift @_;\n    my $b= shift @_;\n    my( $am, $bm )= LCSidx( $a, $b, @_ );\n    my @cdiff;\n    my( $ai, $bi )= ( 0, 0 );\n    push @cdiff, $ai, $bi;\n    while( 1 ) {\n        while(  @$am  &&  $ai == $am->[0]  &&  $bi == $bm->[0]  ) {\n            shift @$am;\n            shift @$bm;\n            ++$ai, ++$bi;\n        }\n        push @cdiff, $ai, $bi;\n        last   if  ! @$am;\n        $ai = $am->[0];\n        $bi = $bm->[0];\n        push @cdiff, $ai, $bi;\n    }\n    push @cdiff, 0+@$a, 0+@$b\n        if  $ai < @$a || $bi < @$b;\n    return wantarray ? @cdiff : \\@cdiff;\n}\n\nsub diff\n{\n    my $a      = shift;    # array ref\n    my $b      = shift;    # array ref\n    my $retval = [];\n    my $hunk   = [];\n    my $discard = sub {\n        push @$hunk, [ '-', $_[0], $a->[ $_[0] ] ];\n    };\n    my $add = sub {\n        push @$hunk, [ '+', $_[1], $b->[ $_[1] ] ];\n    };\n    my $match = sub {\n        push @$retval, $hunk\n            if 0 < @$hunk;\n        $hunk = []\n    };\n    traverse_sequences( $a, $b,\n        { MATCH => $match, DISCARD_A => $discard, DISCARD_B => $add }, @_ );\n    &$match();\n    return wantarray ? @$retval : $retval;\n}\n\nsub sdiff\n{\n    my $a      = shift;    # array ref\n    my $b      = shift;    # array ref\n    my $retval = [];\n    my $discard = sub { push ( @$retval, [ '-', $a->[ $_[0] ], \"\" ] ) };\n    my $add = sub { push ( @$retval, [ '+', \"\", $b->[ $_[1] ] ] ) };\n    my $change = sub {\n        push ( @$retval, [ 'c', $a->[ $_[0] ], $b->[ $_[1] ] ] );\n    };\n    my $match = sub {\n        push ( @$retval, [ 'u', $a->[ $_[0] ], $b->[ $_[1] ] ] );\n    };\n    traverse_balanced(\n        $a,\n        $b,\n        {\n            MATCH     => $match,\n            DISCARD_A => $discard,\n            DISCARD_B => $add,\n            CHANGE    => $change,\n        },\n        @_\n    );\n    return wantarray ? @$retval : $retval;\n}\n\n########################################\nmy $Root= __PACKAGE__;\npackage Algorithm::Diff::_impl;\nuse strict;\n\nsub _Idx()  { 0 } # $me->[_Idx]: Ref to array of hunk indices\n            # 1   # $me->[1]: Ref to first sequence\n            # 2   # $me->[2]: Ref to second sequence\nsub _End()  { 3 } # $me->[_End]: Diff between forward and reverse pos\nsub _Same() { 4 } # $me->[_Same]: 1 if pos 1 contains unchanged items\nsub _Base() { 5 } # $me->[_Base]: Added to range's min and max\nsub _Pos()  { 6 } # $me->[_Pos]: Which hunk is currently selected\nsub _Off()  { 7 } # $me->[_Off]: Offset into _Idx for current position\nsub _Min() { -2 } # Added to _Off to get min instead of max+1\n\nsub Die\n{\n    require Carp;\n    Carp::confess( @_ );\n}\n\nsub _ChkPos\n{\n    my( $me )= @_;\n    return   if  $me->[_Pos];\n    my $meth= ( caller(1) )[3];\n    Die( \"Called $meth on 'reset' object\" );\n}\n\nsub _ChkSeq\n{\n    my( $me, $seq )= @_;\n    return $seq + $me->[_Off]\n        if  1 == $seq  ||  2 == $seq;\n    my $meth= ( caller(1) )[3];\n    Die( \"$meth: Invalid sequence number ($seq); must be 1 or 2\" );\n}\n\nsub getObjPkg\n{\n    my( $us )= @_;\n    return ref $us   if  ref $us;\n    return $us . \"::_obj\";\n}\n\nsub new\n{\n    my( $us, $seq1, $seq2, $opts ) = @_;\n    my @args;\n    for( $opts->{keyGen} ) {\n        push @args, $_   if  $_;\n    }\n    for( $opts->{keyGenArgs} ) {\n        push @args, @$_   if  $_;\n    }\n    my $cdif= Algorithm::Diff::compact_diff( $seq1, $seq2, @args );\n    my $same= 1;\n    if(  0 == $cdif->[2]  &&  0 == $cdif->[3]  ) {\n        $same= 0;\n        splice @$cdif, 0, 2;\n    }\n    my @obj= ( $cdif, $seq1, $seq2 );\n    $obj[_End] = (1+@$cdif)/2;\n    $obj[_Same] = $same;\n    $obj[_Base] = 0;\n    my $me = bless \\@obj, $us->getObjPkg();\n    $me->Reset( 0 );\n    return $me;\n}\n\nsub Reset\n{\n    my( $me, $pos )= @_;\n    $pos= int( $pos || 0 );\n    $pos += $me->[_End]\n        if  $pos < 0;\n    $pos= 0\n        if  $pos < 0  ||  $me->[_End] <= $pos;\n    $me->[_Pos]= $pos || !1;\n    $me->[_Off]= 2*$pos - 1;\n    return $me;\n}\n\nsub Base\n{\n    my( $me, $base )= @_;\n    my $oldBase= $me->[_Base];\n    $me->[_Base]= 0+$base   if  defined $base;\n    return $oldBase;\n}\n\nsub Copy\n{\n    my( $me, $pos, $base )= @_;\n    my @obj= @$me;\n    my $you= bless \\@obj, ref($me);\n    $you->Reset( $pos )   if  defined $pos;\n    $you->Base( $base );\n    return $you;\n}\n\nsub Next {\n    my( $me, $steps )= @_;\n    $steps= 1   if  ! defined $steps;\n    if( $steps ) {\n        my $pos= $me->[_Pos];\n        my $new= $pos + $steps;\n        $new= 0   if  $pos  &&  $new < 0;\n        $me->Reset( $new )\n    }\n    return $me->[_Pos];\n}\n\nsub Prev {\n    my( $me, $steps )= @_;\n    $steps= 1   if  ! defined $steps;\n    my $pos= $me->Next(-$steps);\n    $pos -= $me->[_End]   if  $pos;\n    return $pos;\n}\n\nsub Diff {\n    my( $me )= @_;\n    $me->_ChkPos();\n    return 0   if  $me->[_Same] == ( 1 & $me->[_Pos] );\n    my $ret= 0;\n    my $off= $me->[_Off];\n    for my $seq ( 1, 2 ) {\n        $ret |= $seq\n            if  $me->[_Idx][ $off + $seq + _Min ]\n            <   $me->[_Idx][ $off + $seq ];\n    }\n    return $ret;\n}\n\nsub Min {\n    my( $me, $seq, $base )= @_;\n    $me->_ChkPos();\n    my $off= $me->_ChkSeq($seq);\n    $base= $me->[_Base] if !defined $base;\n    return $base + $me->[_Idx][ $off + _Min ];\n}\n\nsub Max {\n    my( $me, $seq, $base )= @_;\n    $me->_ChkPos();\n    my $off= $me->_ChkSeq($seq);\n    $base= $me->[_Base] if !defined $base;\n    return $base + $me->[_Idx][ $off ] -1;\n}\n\nsub Range {\n    my( $me, $seq, $base )= @_;\n    $me->_ChkPos();\n    my $off = $me->_ChkSeq($seq);\n    if( !wantarray ) {\n        return  $me->[_Idx][ $off ]\n            -   $me->[_Idx][ $off + _Min ];\n    }\n    $base= $me->[_Base] if !defined $base;\n    return  ( $base + $me->[_Idx][ $off + _Min ] )\n        ..  ( $base + $me->[_Idx][ $off ] - 1 );\n}\n\nsub Items {\n    my( $me, $seq )= @_;\n    $me->_ChkPos();\n    my $off = $me->_ChkSeq($seq);\n    if( !wantarray ) {\n        return  $me->[_Idx][ $off ]\n            -   $me->[_Idx][ $off + _Min ];\n    }\n    return\n        @{$me->[$seq]}[\n                $me->[_Idx][ $off + _Min ]\n            ..  ( $me->[_Idx][ $off ] - 1 )\n        ];\n}\n\nsub Same {\n    my( $me )= @_;\n    $me->_ChkPos();\n    return wantarray ? () : 0\n        if  $me->[_Same] != ( 1 & $me->[_Pos] );\n    return $me->Items(1);\n}\n\nmy %getName;\nBEGIN {\n    %getName= (\n        same => \\&Same,\n        diff => \\&Diff,\n        base => \\&Base,\n        min  => \\&Min,\n        max  => \\&Max,\n        range=> \\&Range,\n        items=> \\&Items, # same thing\n    );\n}\n\nsub Get\n{\n    my $me= shift @_;\n    $me->_ChkPos();\n    my @value;\n    for my $arg (  @_  ) {\n        for my $word (  split ' ', $arg  ) {\n            my $meth;\n            if(     $word !~ /^(-?\\d+)?([a-zA-Z]+)([12])?$/\n                ||  not  $meth= $getName{ lc $2 }\n            ) {\n                Die( $Root, \", Get: Invalid request ($word)\" );\n            }\n            my( $base, $name, $seq )= ( $1, $2, $3 );\n            push @value, scalar(\n                4 == length($name)\n                    ? $meth->( $me )\n                    : $meth->( $me, $seq, $base )\n            );\n        }\n    }\n    if(  wantarray  ) {\n        return @value;\n    } elsif(  1 == @value  ) {\n        return $value[0];\n    }\n    Die( 0+@value, \" values requested from \",\n        $Root, \"'s Get in scalar context\" );\n}\n\n\nmy $Obj= getObjPkg($Root);\nno strict 'refs';\n\nfor my $meth (  qw( new getObjPkg )  ) {\n    *{$Root.\"::\".$meth} = \\&{$meth};\n    *{$Obj .\"::\".$meth} = \\&{$meth};\n}\nfor my $meth (  qw(\n    Next Prev Reset Copy Base Diff\n    Same Items Range Min Max Get\n    _ChkPos _ChkSeq\n)  ) {\n    *{$Obj.\"::\".$meth} = \\&{$meth};\n}\n\n1;\n# This version released by Tye McQueen (http://perlmonks.org/?node=tye).\n#\n# =head1 LICENSE\n#\n# Parts Copyright (c) 2000-2004 Ned Konz.  All rights reserved.\n# Parts by Tye McQueen.\n#\n# This program is free software; you can redistribute it and/or modify it\n# under the same terms as Perl.\n#\n# =head1 MAILING LIST\n#\n# Mark-Jason still maintains a mailing list.  To join a low-volume mailing\n# list for announcements related to diff and Algorithm::Diff, send an\n# empty mail message to mjd-perl-diff-request@plover.com.\n# =head1 CREDITS\n#\n# Versions through 0.59 (and much of this documentation) were written by:\n#\n# Mark-Jason Dominus, mjd-perl-diff@plover.com\n#\n# This version borrows some documentation and routine names from\n# Mark-Jason's, but Diff.pm's code was completely replaced.\n#\n# This code was adapted from the Smalltalk code of Mario Wolczko\n# <mario@wolczko.com>, which is available at\n# ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st\n#\n# C<sdiff> and C<traverse_balanced> were written by Mike Schilli\n# <m@perlmeister.com>.\n#\n# The algorithm is that described in\n# I<A Fast Algorithm for Computing Longest Common Subsequences>,\n# CACM, vol.20, no.5, pp.350-353, May 1977, with a few\n# minor improvements to improve the speed.\n#\n# Much work was done by Ned Konz (perl@bike-nomad.com).\n#\n# The OO interface and some other changes are by Tye McQueen.\n#\nEOAlgDiff\n# 2}}}\n    my $problems        = 0;\n    $HAVE_Algorithm_Diff = 0;\n    my $dir             = \"\";\n    if ($opt_sdir) {\n        ++$TEMP_OFF;\n        $dir = \"$opt_sdir/$TEMP_OFF\";\n        File::Path::rmtree($dir) if     is_dir($dir);\n        File::Path::mkpath($dir) unless is_dir($dir);\n    } else {\n        # let File::Temp create a suitable temporary directory\n        $dir = tempdir( CLEANUP => 1 );  # 1 = delete on exit\n        $TEMP_INST{ $dir } = \"Algorithm::Diff\";\n    }\n    print \"Using temp dir [$dir] to install Algorithm::Diff\\n\" if $opt_v;\n    my $Algorithm_dir      = \"$dir/Algorithm\";\n    my $Algorithm_Diff_dir = \"$dir/Algorithm/Diff\";\n    mkdir $Algorithm_dir     ;\n    mkdir $Algorithm_Diff_dir;\n\n    my $OUT = open_file('>', \"$dir/Algorithm/Diff.pm\", 1);\n    if (defined $OUT) {\n        print $OUT $Algorithm_Diff_Contents;\n        $OUT->close;\n    } else {\n        warn \"Failed to install Algorithm/Diff.pm\\n\";\n        $problems = 1;\n    }\n\n    push @INC, $dir;  # between this & Regexp::Common only need to do once\n    eval \"use Algorithm::Diff qw / sdiff /\";\n    $HAVE_Algorithm_Diff = 1 unless $problems;\n    print \"<- Install_Algorithm_Diff\\n\" if $opt_v > 2;\n} # 1}}}\nEND { # {{{1\n    # Temp files might have been created\n    #   - on Windows if running with --fmt\n    #   - on POSIX if using process substitution, eg, cloc <(cat cloc)\n    if ($tmp_file_to_delete) {\n        print \"-> END unlink $tmp_file_to_delete\\n\" if $opt_v > 2;\n        unlink($tmp_file_to_delete)\n    }\n} # 1}}}\n__END__\nmode values (stat $item)[2]\n       Unix    Windows\nfile:  33188   33206\ndir :  16832   16895\nlink:  33261   33206\npipe:   4544    null\n"
  },
  {
    "path": "sqlite_formatter",
    "content": "#!/usr/bin/env perl\nuse warnings;\nuse strict;\n#\n# Pretty printer for from sqlite3 output.\n# Assumes column headers are enabled with\n#   .header on\n# in ~/.sqliterc\n# al.danial@gmail.com  March 2010\n#\n# This program reads input from STDIN and writes to STDOUT.  A typical\n# invocation looks like this:\n#   sqlite3 code.db 'select project,file,nCode from t' | sqlite_formatter\n\nmy $sqlite_separator = '\\|';\n\nmy @lines = ();\n\n# ingest all lines\nwhile (<>) {\n    next if /^\\s*$/;  # skip blank\n    next if /^--\\s+/; # skip comments\n    chomp;\n    push @lines, $_;\n}\n\n# split on |, the default sqlite3 output separator\nmy @column_width = ();\nmy $nCols        =  0;\nmy @data         = ();  # $data[$row][$column] = SQLite result\nfor (my $row = 0; $row < scalar @lines; $row++) {\n    my @cols = split($sqlite_separator, $lines[$row]);\n    $nCols =  scalar @cols;\n    for (my $col = 0; $col < $nCols; $col++) {\n        $data[$row][$col] = $cols[$col];\n        $column_width[$col] = 0 unless defined $column_width[$col];\n        $column_width[$col] = length($cols[$col]) if\n            $column_width[$col] < length($cols[$col]);\n    }\n}\n\n# write the results\nmy $format_str = \"\";\nfor (my $row = 0; $row < scalar @data; $row++) {\n    # insert a separator row \n    if ($row == 1) {\n        for (my $col = 0; $col < $nCols; $col++) {\n            print '_' x $column_width[$col], \" \";\n        }\n        print \"\\n\";\n    }\n    for (my $col = 0; $col < $nCols; $col++) {\n        if ($data[$row][$col] =~ /^[-]?\\d+$/) {\n            # an integer, align to right\n            $format_str = \"%\" . $column_width[$col] . \"d \";\n        } else {\n            $format_str = \"%-\" . $column_width[$col] . \"s \";\n        } # could use something for floating point numbers too...\n        printf $format_str, $data[$row][$col];\n    }\n    print \"\\n\";\n}\n"
  },
  {
    "path": "tests/README",
    "content": "To run the tests:\n  cd ../Unix\n  make test\n\nUnless you see a clear error message, all tests have been executed\nsuccessfully.\n\nTests 21 through 24 in t/01_opts.t exercise cloc's ability to work\nwith git submodules (specifically, to ignore code in these).  If \nyou're working with a git repo clone you will need to clone the\nsubmodule via\n  cd ../Unix\n  git clone https://github.com/AlDanial/cloc_submodule_test.git\n  \nIf the directory already exists, then update by\n  git pull\n"
  },
  {
    "path": "tests/inputs/955.bpmn",
    "content": "<!DOCTYPE html>\n    <!-- Activiti Business Process -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Expandable Table with Sortable Sub-rows</title>\n    <!-- Styles\n         :\n         -->\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n    <!-- body\n         :\n         -->\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            padding: 40px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n        }\n\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <h1>abc</h1>\n        <p>def</p>\n        </div>\n</body>\n</html>\n\n"
  },
  {
    "path": "tests/inputs/955.hbm.xml",
    "content": "<!DOCTYPE html>\n    <!-- Hibernate -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Expandable Table with Sortable Sub-rows</title>\n    <!-- Styles\n         :\n         -->\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n    <!-- body\n         :\n         -->\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            padding: 40px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n        }\n\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <h1>abc</h1>\n        <p>def</p>\n        </div>\n</body>\n</html>\n\n"
  },
  {
    "path": "tests/inputs/955.jrxml",
    "content": "<!DOCTYPE html>\n    <!-- Jasper Report XML/Template -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Expandable Table with Sortable Sub-rows</title>\n    <!-- Styles\n         :\n         -->\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n    <!-- body\n         :\n         -->\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            padding: 40px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n        }\n\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <h1>abc</h1>\n        <p>def</p>\n        </div>\n</body>\n</html>\n\n"
  },
  {
    "path": "tests/inputs/955.lb.xml",
    "content": "<!DOCTYPE html>\n    <!-- Liquibase -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Expandable Table with Sortable Sub-rows</title>\n    <!-- Styles\n         :\n         -->\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n    <!-- body\n         :\n         -->\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            padding: 40px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n        }\n\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <h1>abc</h1>\n        <p>def</p>\n        </div>\n</body>\n</html>\n\n"
  },
  {
    "path": "tests/inputs/955.tld",
    "content": "<!DOCTYPE html>\n    <!-- JSP Tag Library Definition -->\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Expandable Table with Sortable Sub-rows</title>\n    <!-- Styles\n         :\n         -->\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n    <!-- body\n         :\n         -->\n        body {\n            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n            padding: 40px;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n        }\n\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <h1>abc</h1>\n        <p>def</p>\n        </div>\n</body>\n</html>\n\n"
  },
  {
    "path": "tests/inputs/AnsProlog.lp",
    "content": "% ASP logic program for cloc tests.\n% Demonstrates the use of different types of comments in .lp files.\n%\n% There should be:\n% 18 lines of comments\n% 12 lines of whitespace (one inside a multi-line comment)\n% 19 lines of code\n%\n% There are 49 total lines.\n%\n\n% This is a single line comment\nbaz(X) :- bar(X).   % This counts as a line of code\n\n    % This is a slightly more indented single line comment\nfoo(X) :- baz(X).   % This counts as a line of code as well.\n\nbar(a).\n\n% Here are some choice rules and cardinality rules.\n1 { bar(b); bar(c); bar(d) } 3.\n1 { garply(X) : foo(X) } 2.\n\nallow(a).\nallow(b).\nallow(c).\n\n% conditional rule\nconditional(X) :-\n     garply(X);\n     foo(X) : allow(X).\n\nweight(1) :- conditional(a).\nweight(2) :- conditional(b).\nweight(3) :- conditional(c).\nweight(4) :- conditional(d).\n\n\n%* This is a multi-line comment with one whitespace line in it\nquux(X) :- foo(X).  % This shouldn't be counted as it is in a multi-line comment.\nthis is a line inside a comment\n\n*%\n\n#minimize {\n    X@0: weight(X)\n}.\n\n#show garply/1.\n"
  },
  {
    "path": "tests/inputs/Application_Data_Test.feature.cs",
    "content": "// ------------------------------------------------------------------------------\n//  <auto-generated>\n//      This code was generated by SpecFlow (https://www.specflow.org/).\n//      SpecFlow Version:3.9.0.0\n//      SpecFlow Generator Version:3.9.0.0\n// \n//      Changes to this file may cause incorrect behavior and will be lost if\n//      the code is regenerated.\n//  </auto-generated>\n// ------------------------------------------------------------------------------\n#region Designer generated code\n#pragma warning disable\nnamespace Foo_Bar.FeatureFiles\n{\n    using TechTalk.SpecFlow;\n    using System;\n    using System.Linq;\n    \n    \n    [System.CodeDom.Compiler.GeneratedCodeAttribute(\"TechTalk.SpecFlow\", \"3.9.0.0\")]\n    [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [NUnit.Framework.TestFixtureAttribute()]\n    [NUnit.Framework.DescriptionAttribute(\"Application Data_Test\")]\n    public partial class ApplicationData_Test\n    {\n        // ...\n    }\n}\n#pragma warning restore\n#endregion\n"
  },
  {
    "path": "tests/inputs/Arturo.art",
    "content": "; this is a comment\n; this is another comment\n\n;---------------------------------\n; VARIABLES & VALUES\n;---------------------------------\n\n; numbers\na1: 2\na2: 3.14\na3: to :complex [1 2.0]     ; 1.0+2.0i\n\n; strings\nc1: \"this is a string\"\nc2: {\n    this is a multiline string\n    that is indentation-agnostic\n}\nc3: {:\n    this is \n        a verbatim\n            multiline string\n                which will remain exactly\n                    as the original\n:}\n\n; characters\nch: `c`\n\n; blocks/arrays\nd: [1 2 3]\n\n; dictionaries\ne: #[\n    name: \"John\"\n    surname: \"Doe\"\n    age: 34\n    likes: [pizza spaghetti]\n]\n\n; yes, functions are values too\nf: function [x][\n    2 * x\n]\n\n; colors - right, you can directly define them as well!\ng1: #red\ng2: #0077BF\n\n; dates\nh: now              ; 2021-05-03T17:10:48+02:00\n\n; logical values\ni1: true\ni2: false\ni3: maybe\n\n;---------------------------------\n; BASIC OPERATORS\n;---------------------------------\n\n; simple arithmetic\n1 + 1       ; => 2\n8 - 1       ; => 7\n4.2 - 1.1   ; => 3.1\n10 * 2      ; => 20\n35 / 4      ; => 8\n35 // 4     ; => 8.75\n2 ^ 5       ; => 32\n5 % 3       ; => 2\n\n; bitwise operators\nand 3 5     ; => 1\nor 3 5      ; => 7\nxor 3 5     ; => 6\n\n; pre-defined constants\npi          ; => 3.141592653589793\nepsilon     ; => 2.718281828459045\nnull        ; => null\ntrue        ; => true\nfalse       ; => false\n\n;---------------------------------\n; COMPARISON OPERATORS\n;---------------------------------\n\n; equality\n1 = 1       ; => true\n2 = 1       ; => false\n\n; inequality\n1 <> 1      ; => false\n2 <> 1      ; => true\n\n; more comparisons\n1 < 10      ; => true\n1 =< 10     ; => true\n10 =< 10    ; => true\n1 > 10      ; => false\n1 >= 10     ; => false\n11 >= 10    ; => true\n\n;---------------------------------\n; CONDITIONALS\n;---------------------------------\n\n; logical operators\nand? true true      ; => true\nand? true false     ; => false\nor? true false      ; => true\nor? false false     ; => false\n\nand? [1=2][2<3]     ; => false \n                    ; (the second block will not be evaluated)\n\n; simple if statements\nif 2 > 1 [ print \"yes!\"]    ; yes!\nif 3 <> 2 -> print \"true!\"  ; true!\n\n; if/else statements\n; note it's 'if?' not 'if'\nif? 2 > 3 -> print \"2 is greater than 3\"\nelse -> print \"2 is not greater than 3\"         ; 2 is not greater than 3\n\n; switch statements\nswitch 2 > 3 -> print \"2 is greater than 3\"\n             -> print \"2 is not greater than 3\" ; 2 is not greater than 3\n\na: (2 > 3)?[\"yes\"][\"no\"]         ; a: \"no\"\na: (2 > 3)? -> \"yes\" -> \"no\"    ; a: \"no\" (exactly the same as above)\n\n; case/when statements\ncase [1]\n    when? [>2] -> print \"1 is greater than 2. what?!\"\n    when? [<0] -> print \"1 is less than 0. nope...\"\n    else -> print \"here we are!\"                ; here we are!\n\n;---------------------------------\n; LOOPS\n;---------------------------------\n\n; with `loop`\narr: [1 4 5 3]\nloop arr 'x [\n    print [\"x =\" x]\n]\n; x = 1\n; x = 4\n; x = 5\n; x = 3\n\n; with loop and custom index\nloop.with:'i arr 'x [\n    print [\"item at position\" i \"=>\" x]\n]\n; item at position 0 => 1\n; item at position 1 => 4\n; item at position 2 => 5\n; item at position 3 => 3\n\n; using ranges\nloop 1..3 'x ->         ; since it's a single statement\n    print x             ; there's no need for [block] notation\n                        ; we can wrap it up using the `->` syntactic sugar\n\nloop `a`..`c` 'ch ->\n    print ch\n; a\n; b\n; c\n\n; picking multiple items\nloop 1..10 [x y] ->\n    print [\"x =\" x \", y =\" y]\n; x = 1 , y = 2 \n; x = 3 , y = 4 \n; x = 5 , y = 6 \n; x = 7 , y = 8 \n; x = 9 , y = 10 \n\n; looping through a dictionary\ndict: #[name: \"John\", surname: \"Doe\", age: 34]\nloop dict [key value][\n    print [key \"->\" value]\n]\n; name -> John \n; surname -> Doe \n; age -> 34 \n                    \n; while loops\ni: new 0\nwhile [i<3][\n    print [\"i =\" i]\n    inc 'i\n]\n; i = 0\n; i = 1\n; i = 2\n \n;---------------------------------\n; STRINGS\n;---------------------------------\n\n; case\na: \"tHis Is a stRinG\"\nprint upper a               ; THIS IS A STRING\nprint lower a               ; this is a string\nprint capitalize a          ; THis Is a stRinG\n\n; concatenation\na: \"Hello \" ++ \"World!\"     ; a: \"Hello World!\"\n\n; strings as an array\nsplit \"hello\"               ; => [h e l l o]\nsplit.words \"hello world\"   ; => [hello world]\n\nprint first \"hello\"         ; h\nprint last \"hello\"          ; o\n\n; conversion\nto :string 123              ; => \"123\"\nto :integer \"123\"           ; => 123\n\n; joining strings together\njoin [\"hello\" \"world\"]              ; => \"helloworld\"\njoin.with:\"-\" [\"hello\" \"world\"]     ; => \"hello-world\"\n\n; string interpolation\nx: 2\nprint ~\"x = |x|\"            ; x = 2\n\n; interpolation with `print`\nprint [\"x =\" x]             ; x = 2\n                            ; (`print` works by calculating the given block\n                            ;  and joining the different values as strings\n                            ;  with a single space between them)\n\n; templates\nprint render.template {\n    <||= switch x=2 [ ||>\n        Yes, x = 2\n    <||][||>\n        No, x is not 2\n    <||]||> \n} ; Yes, x = 2\n\n; matching\nprefix? \"hello\" \"he\"        ; => true\nsuffix? \"hello\" \"he\"        ; => false\n\ncontains? \"hello\" \"ll\"      ; => true\ncontains? \"hello\" \"he\"      ; => true\ncontains? \"hello\" \"x\"       ; => false\n\nin? \"ll\" \"hello\"            ; => true \nin? \"x\" \"hello\"             ; => false\n\n;---------------------------------\n; BLOCKS\n;---------------------------------\n\n; calculate a block\narr: [1 1+1 1+1+1]\n@arr                        ; => [1 2 3]\n\n; execute a block\nsth: [print \"Hello world\"]  ; this is perfectly valid,\n                            ; could contain *anything*\n                            ; and will not be executed...\n\ndo sth                      ; Hello world\n                            ; (...until we tell it to)\n\n; array indexing\narr: [\"zero\" \"one\" \"two\" \"three\"]\nprint first arr             ; zero\nprint arr\\0                 ; zero\nprint last arr              ; three\nprint arr\\3                 ; three\n\nx: 2\nprint get arr x             ; two\nprint arr\\[x]               ; two\n\n; setting an array element\narr\\0: \"nada\"\nset arr 2 \"dos\"\nprint arr                   ; nada one dos three\n\n; adding elements to an array\narr: new []\n'arr ++ \"one\"\n'arr ++ \"two\"\nprint arr                   ; one two\n\n; remove elements from an array\narr: new [\"one\" \"two\" \"three\" \"four\"]\n'arr -- \"two\"               ; arr: [\"one\" \"three\" \"four\"]\nremove 'arr .index 0        ; arr: [\"three\" \"four\"]\n\n; getting the size of an array\narr: [\"one\" 2 \"three\" 4]\nprint size arr              ; 4\n\n; getting a slice of an array\nprint slice [\"one\" \"two\" \"three\" \"four\"] 0 1        ; one two\n\n; check if array contains a specific element\nprint contains? arr \"one\"   ; true\nprint contains? arr \"five\"  ; false\n\n; sorting array\narr: [1 5 3 2 4]\nsort arr                    ; => [1 2 3 4 5]\nsort.descending arr         ; => [5 4 3 2 1]\n\n; mapping values\nmap 1..10 [x][2*x]          ; => [2 4 6 8 10 12 14 16 18 20]\nmap 1..10 'x -> 2*x         ; same as above\nmap 1..10 => [2*&]          ; same as above\nmap 1..10 => [2*]           ; same as above\n\n; selecting/filtering array values\nselect 1..10 [x][odd? x]    ; => [1 3 5 7 9]\nselect 1..10 => odd?        ; same as above\n\nfilter 1..10 => odd?        ; => [2 4 6 8 10]\n                            ; (now, we leave out all odd numbers - \n                            ;  while select keeps them)\n\n; misc operations\narr: [\"one\" 2 \"three\" 4]\nreverse arr                 ; => [4 \"three\" 2 \"one\"]\nshuffle arr                 ; => [2 4 \"three\" \"one\"]\nunique [1 2 3 2 3 1]        ; => [1 2 3]\npermutate [1 2 3]           ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]]\ntake 1..10 3                ; => [1 2 3]\nrepeat [1 2] 3              ; => [1 2 1 2 1 2]\n\n;---------------------------------\n; FUNCTIONS\n;---------------------------------\n\n; declaring a function\nf: function [x][ 2*x ]\nf: function [x]-> 2*x       ; same as above\nf: $[x]->2*x                ; same as above (only using the `$` alias \n                            ;  for the `function`... function)\n\n; calling a function\nf 10                        ; => 20\n\n; returning a value\ng: function [x][\n    if x < 2 -> return 0\n\n    res: 0\n    loop 0..x 'z [\n        res: res + z\n    ]\n    return res\n]\n\n;---------------------------------\n; CUSTOM TYPES\n;---------------------------------\n\n; defining a custom type\ndefine :person [\n    ; with custom post-construction initializer\n    init: method [name, surname, age][\n        this\\name: capitalize name\n        this\\surname: surname\n        this\\age: age\n    ]\n\n    ; custom print function\n    string: method [][\n        render \"NAME: |this\\name|, SURNAME: |this\\surname|, AGE: |this\\age|\"\n    ]\n\n    ; custom comparison operator\n    compare: sortable 'age\n\n    ; create a method for our custom type\n    sayHello: method [][\n        print [\"Hello\" this\\name]\n    ]\n]\n\n; create new objects of our custom type\na: to :person [\"John\" \"Doe\" 34]!                ; let's create 2 \"Person\"s\nb: to :person [\"jane\" \"Doe\" 33]!                ; and another one\n\n; call inner method\na\\sayHello                                      ; Hello John                       \nb\\sayHello                                      ; Hello Jane\n\n; access object fields\nprint [\"The first person's name is:\" a\\name]    ; The first person's name is: John\nprint [\"The second person's name is:\" b\\name]   ; The second person's name is: Jane\n\n; changing object fields\na\\name: \"Bob\"                                   \na\\sayHello                                      ; Hello Bob\n\n; verifying object type\nprint type a                                    ; :person\nprint is? :person a                             ; true\n\n; printing objects\nprint a                                         ; NAME: John, SURNAME: Doe, AGE: 34\n\n; sorting user objects (using custom comparator)\nsort @[a b]                                     ; Jane..., John...\nsort.descending @[a b]                          ; John..., Jane...       "
  },
  {
    "path": "tests/inputs/Assembler-Intel.asm",
    "content": "; Hello World for Intel Assembler (MSDOS)\n; from http://www.roesler-ac.de/wolfram/hello.htm\n\nmov ax,cs\nmov ds,ax\nmov ah,9\nmov dx, offset Hello\nint 21h\nxor ax,ax\nint 21h\n\nHello:\n  db \"Hello World!\",13,10,\"$\"\n"
  },
  {
    "path": "tests/inputs/Assembly-sysv.S",
    "content": "/*\n Python-3.5.2/Modules/_ctypes/libffi/src/m68k/sysv.S\n */\n/* -----------------------------------------------------------------------\n\n\t\n   sysv.S - Copyright (c) 2012 Alan Hourihane\n\t    Copyright (c) 1998, 2012 Andreas Schwab\n\t    Copyright (c) 2008 Red Hat, Inc.\n\t    Copyright (c) 2012 Thorsten Glaser\n\n   m68k Foreign Function Interface\n\n   Permission is hereby granted, free of charge, to any person obtaining\n   a copy of this software and associated documentation files (the\n   ``Software''), to deal in the Software without restriction, including\n   without limitation the rights to use, copy, modify, merge, publish,\n   distribute, sublicense, and/or sell copies of the Software, and to\n   permit persons to whom the Software is furnished to do so, subject to\n   the following conditions:\n\n   The above copyright notice and this permission notice shall be included\n   in all copies or substantial portions of the Software.\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\n   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n   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\n   DEALINGS IN THE SOFTWARE.\n   ----------------------------------------------------------------------- */\n\n#define LIBFFI_ASM\t\n#include <fficonfig.h>\n#include <ffi.h>\n\n#ifdef HAVE_AS_CFI_PSEUDO_OP\n#define CFI_STARTPROC()\t\t.cfi_startproc\n#define CFI_OFFSET(reg,off)\t.cfi_offset\treg,off\n#define CFI_DEF_CFA(reg,off)\t.cfi_def_cfa\treg,off\n#define CFI_ENDPROC()\t\t.cfi_endproc\n#else\n#define CFI_STARTPROC()\n#define CFI_OFFSET(reg,off)\n#define CFI_DEF_CFA(reg,off)\n#define CFI_ENDPROC()\n#endif\n\n#ifdef __MINT__\n#define CALLFUNC(funcname) _ ## funcname\n#else\n#define CALLFUNC(funcname) funcname\n#endif\n\n\t.text\n\n\t.globl\tCALLFUNC(ffi_call_SYSV)\n\t.type\tCALLFUNC(ffi_call_SYSV),@function\n\t.align\t4\n\nCALLFUNC(ffi_call_SYSV):\n\tCFI_STARTPROC()\n\tlink\t%fp,#0\n\tCFI_OFFSET(14,-8)\n\tCFI_DEF_CFA(14,8)\n\tmove.l\t%d2,-(%sp)\n\tCFI_OFFSET(2,-12)\n\n\t| Make room for all of the new args.\n\tsub.l\t12(%fp),%sp\n\n\t| Call ffi_prep_args\n\tmove.l\t8(%fp),-(%sp)\n\tpea\t4(%sp)\n#if !defined __PIC__\n\tjsr\tCALLFUNC(ffi_prep_args)\n#else\n\tbsr.l\tCALLFUNC(ffi_prep_args@PLTPC)\n#endif\n\taddq.l\t#8,%sp\t\n\n\t| Pass pointer to struct value, if any\n#ifdef __MINT__\n\tmove.l\t%d0,%a1\n#else\n\tmove.l\t%a0,%a1\n#endif\n\n\t| Call the function\n\tmove.l\t24(%fp),%a0\n\tjsr\t(%a0)\n\n\t| Remove the space we pushed for the args\n\tadd.l\t12(%fp),%sp\n\n\t| Load the pointer to storage for the return value\n\tmove.l\t20(%fp),%a1\n\n\t| Load the return type code \n\tmove.l\t16(%fp),%d2\n\n\t| If the return value pointer is NULL, assume no return value.\n\t| NOTE: On the mc68000, tst on an address register is not supported.\n#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)\n\tcmp.w\t#0, %a1\n#else\n\ttst.l\t%a1\n#endif\n\tjbeq\tnoretval\n\n\tbtst\t#0,%d2\n\tjbeq\tretlongint\n\tmove.l\t%d0,(%a1)\n\tjbra\tepilogue\n\nretlongint:\n\tbtst\t#1,%d2\n\tjbeq\tretfloat\n\tmove.l\t%d0,(%a1)\n\tmove.l\t%d1,4(%a1)\n\tjbra\tepilogue\n\nretfloat:\n\tbtst\t#2,%d2\n\tjbeq\tretdouble\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.s\t%fp0,(%a1)\n#else\n\tmove.l\t%d0,(%a1)\n#endif\n\tjbra\tepilogue\n\nretdouble:\n\tbtst\t#3,%d2\n\tjbeq\tretlongdouble\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.d\t%fp0,(%a1)\n#else\n\tmove.l\t%d0,(%a1)+\n\tmove.l\t%d1,(%a1)\n#endif\n\tjbra\tepilogue\n\nretlongdouble:\n\tbtst\t#4,%d2\n\tjbeq\tretpointer\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.x\t%fp0,(%a1)\n#else\n\tmove.l\t%d0,(%a1)+\n\tmove.l\t%d1,(%a1)+\n\tmove.l\t%d2,(%a1)\n#endif\n\tjbra\tepilogue\n\nretpointer:\n\tbtst\t#5,%d2\n\tjbeq\tretstruct1\n#ifdef __MINT__\n\tmove.l\t%d0,(%a1)\n#else\n\tmove.l\t%a0,(%a1)\n#endif\n\tjbra\tepilogue\n\nretstruct1:\n\tbtst\t#6,%d2\n\tjbeq\tretstruct2\n\tmove.b\t%d0,(%a1)\n\tjbra\tepilogue\n\nretstruct2:\n\tbtst\t#7,%d2\n\tjbeq\tretsint8\n\tmove.w\t%d0,(%a1)\n\tjbra\tepilogue\n\nretsint8:\n\tbtst\t#8,%d2\n\tjbeq\tretsint16\n\t| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.\n#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)\n\text.w\t%d0\n\text.l\t%d0\n#else\n\textb.l\t%d0\n#endif\n\tmove.l\t%d0,(%a1)\n\tjbra\tepilogue\n\nretsint16:\n\tbtst\t#9,%d2\n\tjbeq\tnoretval\n\text.l\t%d0\n\tmove.l\t%d0,(%a1)\n\nnoretval:\nepilogue:\n\tmove.l\t(%sp)+,%d2\n\tunlk\t%fp\n\trts\n\tCFI_ENDPROC()\n\t.size\tCALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV)\n\n\t.globl\tCALLFUNC(ffi_closure_SYSV)\n\t.type\tCALLFUNC(ffi_closure_SYSV), @function\n\t.align\t4\n\nCALLFUNC(ffi_closure_SYSV):\n\tCFI_STARTPROC()\n\tlink\t%fp,#-12\n\tCFI_OFFSET(14,-8)\n\tCFI_DEF_CFA(14,8)\n\tmove.l\t%sp,-12(%fp)\n\tpea\t8(%fp)\n\tpea\t-12(%fp)\n\tmove.l\t%a0,-(%sp)\n#if !defined __PIC__\n\tjsr\tCALLFUNC(ffi_closure_SYSV_inner)\n#else\n\tbsr.l\tCALLFUNC(ffi_closure_SYSV_inner@PLTPC)\n#endif\n\n\tlsr.l\t#1,%d0\n\tjne\t1f\n\tjcc\t.Lcls_epilogue\n\t| CIF_FLAGS_INT\n\tmove.l\t-12(%fp),%d0\n.Lcls_epilogue:\n\t| no CIF_FLAGS_*\n\tunlk\t%fp\n\trts\n1:\n\tlea\t-12(%fp),%a0\n\tlsr.l\t#2,%d0\n\tjne\t1f\n\tjcs\t.Lcls_ret_float\n\t| CIF_FLAGS_DINT\n\tmove.l\t(%a0)+,%d0\n\tmove.l\t(%a0),%d1\n\tjra\t.Lcls_epilogue\n.Lcls_ret_float:\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.s\t(%a0),%fp0\n#else\n\tmove.l\t(%a0),%d0\n#endif\n\tjra\t.Lcls_epilogue\n1:\n\tlsr.l\t#2,%d0\n\tjne\t1f\n\tjcs\t.Lcls_ret_ldouble\n\t| CIF_FLAGS_DOUBLE\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.d\t(%a0),%fp0\n#else\n\tmove.l\t(%a0)+,%d0\n\tmove.l\t(%a0),%d1\n#endif\n\tjra\t.Lcls_epilogue\n.Lcls_ret_ldouble:\n#if defined(__MC68881__) || defined(__HAVE_68881__)\n\tfmove.x\t(%a0),%fp0\n#else\n\tmove.l\t(%a0)+,%d0\n\tmove.l\t(%a0)+,%d1\n\tmove.l\t(%a0),%d2\n#endif\n\tjra\t.Lcls_epilogue\n1:\n\tlsr.l\t#2,%d0\n\tjne\t1f\n\tjcs\t.Lcls_ret_struct1\n\t| CIF_FLAGS_POINTER\n\tmove.l\t(%a0),%a0\n\tmove.l\t%a0,%d0\n\tjra\t.Lcls_epilogue\n.Lcls_ret_struct1:\n\tmove.b\t(%a0),%d0\n\tjra\t.Lcls_epilogue\n1:\n\tlsr.l\t#2,%d0\n\tjne\t1f\n\tjcs\t.Lcls_ret_sint8\n\t| CIF_FLAGS_STRUCT2\n\tmove.w\t(%a0),%d0\n\tjra\t.Lcls_epilogue\n.Lcls_ret_sint8:\n\tmove.l\t(%a0),%d0\n\t| NOTE: On the mc68000, extb is not supported. 8->16, then 16->32.\n#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__)\n\text.w\t%d0\n\text.l\t%d0\n#else\n\textb.l\t%d0\n#endif\n\tjra\t.Lcls_epilogue\n1:\n\t| CIF_FLAGS_SINT16\n\tmove.l\t(%a0),%d0\n\text.l\t%d0\n\tjra\t.Lcls_epilogue\n\tCFI_ENDPROC()\n\n\t.size\tCALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV)\n\n\t.globl\tCALLFUNC(ffi_closure_struct_SYSV)\n\t.type\tCALLFUNC(ffi_closure_struct_SYSV), @function\n\t.align\t4\n\nCALLFUNC(ffi_closure_struct_SYSV):\n\tCFI_STARTPROC()\n\tlink\t%fp,#0\n\tCFI_OFFSET(14,-8)\n\tCFI_DEF_CFA(14,8)\n\tmove.l\t%sp,-12(%fp)\n\tpea\t8(%fp)\n\tmove.l\t%a1,-(%sp)\n\tmove.l\t%a0,-(%sp)\n#if !defined __PIC__\n\tjsr\tCALLFUNC(ffi_closure_SYSV_inner)\n#else\n\tbsr.l\tCALLFUNC(ffi_closure_SYSV_inner@PLTPC)\n#endif\n\tunlk\t%fp\n\trts\n\tCFI_ENDPROC()\n\t.size\tCALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV)\n\n#if defined __ELF__ && defined __linux__\n\t.section\t.note.GNU-stack,\"\",@progbits\n#endif\n"
  },
  {
    "path": "tests/inputs/BUILD",
    "content": "# https://github.com/bazelbuild/bazel/raw/master/examples/cpp/BUILD\n\npackage(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_cc//cc:defs.bzl\", \"cc_binary\", \"cc_library\", \"cc_test\")\n\ncc_library(\n    name = \"hello-lib\",\n    srcs = [\"hello-lib.cc\"],\n    hdrs = [\"hello-lib.h\"],\n)\n\ncc_binary(\n    name = \"hello-world\",\n    srcs = [\"hello-world.cc\"],\n    deps = [\":hello-lib\"],\n)\n\ncc_test(\n    name = \"hello-success_test\",\n    srcs = [\"hello-world.cc\"],\n    deps = [\":hello-lib\"],\n)\n\ncc_test(\n    name = \"hello-fail_test\",\n    srcs = [\"hello-fail.cc\"],\n    deps = [\":hello-lib\"],\n)\n\nfilegroup(\n    name = \"srcs\",\n    srcs = glob([\"**\"]),\n)\n"
  },
  {
    "path": "tests/inputs/BasicPlane.Figures-Rectangle.ixx",
    "content": "/*\nhttps://docs.microsoft.com/en-us/cpp/cpp/tutorial-named-modules-cpp?view=msvc-170\n*/\nexport module BasicPlane.Figures:Rectangle; // defines the module partition Rectangle\n\nimport :Point;\n\nexport struct Rectangle // make this struct visible to importers\n{\n    Point ul, lr;\n};\n\n// These functions are declared, but will\n// be defined in a module implementation file\nexport int area(const Rectangle& r);\nexport int height(const Rectangle& r);\nexport int width(const Rectangle& r);\n"
  },
  {
    "path": "tests/inputs/BoxWidget.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<interface>\n\t<template class=\"AtbBoxWidget\" parent=\"GtkBox\">\n\t\t<property name=\"margin-start\">10</property>\n\t\t<property name=\"margin-end\">10</property>\n\t</template>\n</interface>\n"
  },
  {
    "path": "tests/inputs/Buchberger.cocoa5",
    "content": "define Buchberger(F)\r\n  -- Make all monic for (sometimes) nicer GB :)\r\n  G := [monic(f) | f in F];\r\n  r := len(G);\r\n  B := [x in tuples(1..r, 2) | 1 <= x[1] and x[1] < x[2] and x[2] <= r];\r\n  while B <> [] do\r\n    p := B[1];\r\n    remove(ref B, 1);\r\n    gj := G[p[1]];\r\n    gk := G[p[2]];\r\n\r\n    // Optimization: Skip if LTs are coprime\r\n    if IsCoprime(LT(gj), LT(gk)) then\r\n      continue;\r\n    endif;\r\n\r\n    t := lcm(LT(gj), LT(gk));\r\n    Sjk := (t / LM(gj)) * gj - (t / LM(gk)) * gk;\r\n    R := NR(Sjk, G);\r\n    if R <> 0 then\r\n      // Append monic for (sometimes) nicer GB :)\r\n      append(ref G, monic(R));\r\n      r := len(G);\r\n      B := concat(B, [[i, r] | i in 1..(r-1)]);\r\n    endif;\r\n  endwhile;\r\n  return G;\r\nenddefine; -- Buchberger\r\n\r\ndefine BuchbergerOnIdeal(I)\r\n  return Buchberger(gens(I));\r\nenddefine; -- BuchbergerOnIdeal\r\n\r\ndefine TestBuchberger(F)\r\n  println \"===== INPUT: \", F, \" =====\";\r\n  B1 := Buchberger(F);\r\n  B2 := GBasis(ideal(F));\r\n  println \"Basis:     \", B1;\r\n  eq := EqSet(B1, B2);\r\n  println \"Equals?    \", eq;\r\n  if not(eq) then\r\n    // If the reduced GBs are equal, the Buchberger-computed GB\r\n    // is most likely also a correct one.\r\n    req := ReducedGBasis(ideal(B1)) = ReducedGBasis(ideal(B2));\r\n    println \"Red GB eq? \", req;\r\n    if not(req) then println \"Correct:   \", B2; endif;\r\n  endif;\r\nenddefine; -- TestBuchberger\r\n\r\n/*\r\nTest cases can be found here!\r\nFirst, some using a \"normal\" term order.\r\nThen, some using an elimination ordering.\r\n*/\r\n\r\nuse QQ[x,y,z], DegRevLex;\r\nTestBuchberger([x^10,x^8*y^6,x^7*y^7,x^6*y^8,y^10]);\r\nTestBuchberger([x^3-3,y^5-5,z^7-7]);\r\nTestBuchberger([5*y^2+4*y*z-2*y-4,4*y^2-3*y*z+5*z^2-5*z]);\r\nTestBuchberger([8*x^3+x^2*y-2*z^2+4,7*x^3+6*x^2*z-5*x*y*z-5*y^2]);\r\nTestBuchberger([x^5+x*y^4+y^2*z^3+z^5,x^4*y+x^3*y^2+x^4*z+x^2*z^3]);\r\nuse QQ[x,y,z], Lex;\r\nprintln \"===== INPUT: \", [x^2*y*z+x*y^3*z-1,x^4*y*z-1,x*y^4+x*y*z-1] , \" =====\";\r\nprintln \"Basis:     \", Buchberger([x^2*y*z+x*y^3*z-1,x^4*y*z-1,x*y^4+x*y*z-1]);\r\n"
  },
  {
    "path": "tests/inputs/C#.cs",
    "content": "// from http://www.roesler-ac.de/wolfram/hello.htm\r\n// Hello World in Microsoft C# (\"C-Sharp\").\r\n\r\nusing System;\r\n\r\nclass HelloWorld\r\n{\r\n    public static int Main(String[] args)\r\n    {\r\n        Console.WriteLine(\"Hello, World!\");\r\n        return 0;\r\n    }\r\n}\r\n"
  },
  {
    "path": "tests/inputs/C++-MFC.cc",
    "content": "// Hello World in C++ for Microsoft Foundation Classes\n// (Microsoft Visual C++).\n// from http://www.roesler-ac.de/wolfram/hello.htm\n\n#include <afxwin.h>\n\nclass CHello : public CFrameWnd\n{\npublic:\n    CHello()\n    {\n        Create(NULL,_T(\"Hello World!\"),WS_OVERLAPPEDWINDOW,rectDefault);\n    }\n};\n\nclass CHelloApp : public CWinApp\n{\npublic:\n    virtual BOOL InitInstance();\n};\n\nBOOL CHelloApp::InitInstance()\n{\n    m_pMainWnd = new CHello();\n    m_pMainWnd->ShowWindow(m_nCmdShow);\n    m_pMainWnd->UpdateWindow();\n    return TRUE;\n}\n\nCHelloApp theApp;\n"
  },
  {
    "path": "tests/inputs/C++-uppercase.CPP",
    "content": "// Comment\n\nint main() {}\n\n"
  },
  {
    "path": "tests/inputs/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/C.g4",
    "content": "/* https://github.com/antlr/grammars-v4/raw/master/c/C.g4\n [The \"BSD licence\"]\n Copyright (c) 2013 Sam Harwell\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 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 3. The name of the author may not 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR\n IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n NOT 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 OF\n THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\n/** C 2011 grammar built from the C11 Spec */\ngrammar C;\n\nprimaryExpression\n    :   Identifier\n    |   Constant\n    |   StringLiteral+\n    |   '(' expression ')'\n    |   genericSelection\n    |   '__extension__'? '(' compoundStatement ')' // Blocks (GCC extension)\n    |   '__builtin_va_arg' '(' unaryExpression ',' typeName ')'\n    |   '__builtin_offsetof' '(' typeName ',' unaryExpression ')'\n    ;\n\ngenericSelection\n    :   '_Generic' '(' assignmentExpression ',' genericAssocList ')'\n    ;\n\ngenericAssocList\n    :   genericAssociation\n    |   genericAssocList ',' genericAssociation\n    ;\n\ngenericAssociation\n    :   typeName ':' assignmentExpression\n    |   'default' ':' assignmentExpression\n    ;\n\npostfixExpression\n    :   primaryExpression\n    |   postfixExpression '[' expression ']'\n    |   postfixExpression '(' argumentExpressionList? ')'\n    |   postfixExpression '.' Identifier\n    |   postfixExpression '->' Identifier\n    |   postfixExpression '++'\n    |   postfixExpression '--'\n    |   '(' typeName ')' '{' initializerList '}'\n    |   '(' typeName ')' '{' initializerList ',' '}'\n    |   '__extension__' '(' typeName ')' '{' initializerList '}'\n    |   '__extension__' '(' typeName ')' '{' initializerList ',' '}'\n    ;\n\nargumentExpressionList\n    :   assignmentExpression\n    |   argumentExpressionList ',' assignmentExpression\n    ;\n\nunaryExpression\n    :   postfixExpression\n    |   '++' unaryExpression\n    |   '--' unaryExpression\n    |   unaryOperator castExpression\n    |   'sizeof' unaryExpression\n    |   'sizeof' '(' typeName ')'\n    |   '_Alignof' '(' typeName ')'\n    |   '&&' Identifier // GCC extension address of label\n    ;\n\nunaryOperator\n    :   '&' | '*' | '+' | '-' | '~' | '!'\n    ;\n\ncastExpression\n    :   unaryExpression\n    |   '(' typeName ')' castExpression\n    |   '__extension__' '(' typeName ')' castExpression\n    |   DigitSequence // for\n    ;\n\nmultiplicativeExpression\n    :   castExpression\n    |   multiplicativeExpression '*' castExpression\n    |   multiplicativeExpression '/' castExpression\n    |   multiplicativeExpression '%' castExpression\n    ;\n\nadditiveExpression\n    :   multiplicativeExpression\n    |   additiveExpression '+' multiplicativeExpression\n    |   additiveExpression '-' multiplicativeExpression\n    ;\n\nshiftExpression\n    :   additiveExpression\n    |   shiftExpression '<<' additiveExpression\n    |   shiftExpression '>>' additiveExpression\n    ;\n\nrelationalExpression\n    :   shiftExpression\n    |   relationalExpression '<' shiftExpression\n    |   relationalExpression '>' shiftExpression\n    |   relationalExpression '<=' shiftExpression\n    |   relationalExpression '>=' shiftExpression\n    ;\n\nequalityExpression\n    :   relationalExpression\n    |   equalityExpression '==' relationalExpression\n    |   equalityExpression '!=' relationalExpression\n    ;\n\nandExpression\n    :   equalityExpression\n    |   andExpression '&' equalityExpression\n    ;\n\nexclusiveOrExpression\n    :   andExpression\n    |   exclusiveOrExpression '^' andExpression\n    ;\n\ninclusiveOrExpression\n    :   exclusiveOrExpression\n    |   inclusiveOrExpression '|' exclusiveOrExpression\n    ;\n\nlogicalAndExpression\n    :   inclusiveOrExpression\n    |   logicalAndExpression '&&' inclusiveOrExpression\n    ;\n\nlogicalOrExpression\n    :   logicalAndExpression\n    |   logicalOrExpression '||' logicalAndExpression\n    ;\n\nconditionalExpression\n    :   logicalOrExpression ('?' expression ':' conditionalExpression)?\n    ;\n\nassignmentExpression\n    :   conditionalExpression\n    |   unaryExpression assignmentOperator assignmentExpression\n    |   DigitSequence // for\n    ;\n\nassignmentOperator\n    :   '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='\n    ;\n\nexpression\n    :   assignmentExpression\n    |   expression ',' assignmentExpression\n    ;\n\nconstantExpression\n    :   conditionalExpression\n    ;\n\ndeclaration\n    :   declarationSpecifiers initDeclaratorList ';'\n\t| \tdeclarationSpecifiers ';'\n    |   staticAssertDeclaration\n    ;\n\ndeclarationSpecifiers\n    :   declarationSpecifier+\n    ;\n\ndeclarationSpecifiers2\n    :   declarationSpecifier+\n    ;\n\ndeclarationSpecifier\n    :   storageClassSpecifier\n    |   typeSpecifier\n    |   typeQualifier\n    |   functionSpecifier\n    |   alignmentSpecifier\n    ;\n\ninitDeclaratorList\n    :   initDeclarator\n    |   initDeclaratorList ',' initDeclarator\n    ;\n\ninitDeclarator\n    :   declarator\n    |   declarator '=' initializer\n    ;\n\nstorageClassSpecifier\n    :   'typedef'\n    |   'extern'\n    |   'static'\n    |   '_Thread_local'\n    |   'auto'\n    |   'register'\n    ;\n\ntypeSpecifier\n    :   ('void'\n    |   'char'\n    |   'short'\n    |   'int'\n    |   'long'\n    |   'float'\n    |   'double'\n    |   'signed'\n    |   'unsigned'\n    |   '_Bool'\n    |   '_Complex'\n    |   '__m128'\n    |   '__m128d'\n    |   '__m128i')\n    |   '__extension__' '(' ('__m128' | '__m128d' | '__m128i') ')'\n    |   atomicTypeSpecifier\n    |   structOrUnionSpecifier\n    |   enumSpecifier\n    |   typedefName\n    |   '__typeof__' '(' constantExpression ')' // GCC extension\n    ;\n\nstructOrUnionSpecifier\n    :   structOrUnion Identifier? '{' structDeclarationList '}'\n    |   structOrUnion Identifier\n    ;\n\nstructOrUnion\n    :   'struct'\n    |   'union'\n    ;\n\nstructDeclarationList\n    :   structDeclaration\n    |   structDeclarationList structDeclaration\n    ;\n\nstructDeclaration\n    :   specifierQualifierList structDeclaratorList? ';'\n    |   staticAssertDeclaration\n    ;\n\nspecifierQualifierList\n    :   typeSpecifier specifierQualifierList?\n    |   typeQualifier specifierQualifierList?\n    ;\n\nstructDeclaratorList\n    :   structDeclarator\n    |   structDeclaratorList ',' structDeclarator\n    ;\n\nstructDeclarator\n    :   declarator\n    |   declarator? ':' constantExpression\n    ;\n\nenumSpecifier\n    :   'enum' Identifier? '{' enumeratorList '}'\n    |   'enum' Identifier? '{' enumeratorList ',' '}'\n    |   'enum' Identifier\n    ;\n\nenumeratorList\n    :   enumerator\n    |   enumeratorList ',' enumerator\n    ;\n\nenumerator\n    :   enumerationConstant\n    |   enumerationConstant '=' constantExpression\n    ;\n\nenumerationConstant\n    :   Identifier\n    ;\n\natomicTypeSpecifier\n    :   '_Atomic' '(' typeName ')'\n    ;\n\ntypeQualifier\n    :   'const'\n    |   'restrict'\n    |   'volatile'\n    |   '_Atomic'\n    ;\n\nfunctionSpecifier\n    :   ('inline'\n    |   '_Noreturn'\n    |   '__inline__' // GCC extension\n    |   '__stdcall')\n    |   gccAttributeSpecifier\n    |   '__declspec' '(' Identifier ')'\n    ;\n\nalignmentSpecifier\n    :   '_Alignas' '(' typeName ')'\n    |   '_Alignas' '(' constantExpression ')'\n    ;\n\ndeclarator\n    :   pointer? directDeclarator gccDeclaratorExtension*\n    ;\n\ndirectDeclarator\n    :   Identifier\n    |   '(' declarator ')'\n    |   directDeclarator '[' typeQualifierList? assignmentExpression? ']'\n    |   directDeclarator '[' 'static' typeQualifierList? assignmentExpression ']'\n    |   directDeclarator '[' typeQualifierList 'static' assignmentExpression ']'\n    |   directDeclarator '[' typeQualifierList? '*' ']'\n    |   directDeclarator '(' parameterTypeList ')'\n    |   directDeclarator '(' identifierList? ')'\n    |   Identifier ':' DigitSequence  // bit field\n    ;\n\ngccDeclaratorExtension\n    :   '__asm' '(' StringLiteral+ ')'\n    |   gccAttributeSpecifier\n    ;\n\ngccAttributeSpecifier\n    :   '__attribute__' '(' '(' gccAttributeList ')' ')'\n    ;\n\ngccAttributeList\n    :   gccAttribute (',' gccAttribute)*\n    |   // empty\n    ;\n\ngccAttribute\n    :   ~(',' | '(' | ')') // relaxed def for \"identifier or reserved word\"\n        ('(' argumentExpressionList? ')')?\n    |   // empty\n    ;\n\nnestedParenthesesBlock\n    :   (   ~('(' | ')')\n        |   '(' nestedParenthesesBlock ')'\n        )*\n    ;\n\npointer\n    :   '*' typeQualifierList?\n    |   '*' typeQualifierList? pointer\n    |   '^' typeQualifierList? // Blocks language extension\n    |   '^' typeQualifierList? pointer // Blocks language extension\n    ;\n\ntypeQualifierList\n    :   typeQualifier\n    |   typeQualifierList typeQualifier\n    ;\n\nparameterTypeList\n    :   parameterList\n    |   parameterList ',' '...'\n    ;\n\nparameterList\n    :   parameterDeclaration\n    |   parameterList ',' parameterDeclaration\n    ;\n\nparameterDeclaration\n    :   declarationSpecifiers declarator\n    |   declarationSpecifiers2 abstractDeclarator?\n    ;\n\nidentifierList\n    :   Identifier\n    |   identifierList ',' Identifier\n    ;\n\ntypeName\n    :   specifierQualifierList abstractDeclarator?\n    ;\n\nabstractDeclarator\n    :   pointer\n    |   pointer? directAbstractDeclarator gccDeclaratorExtension*\n    ;\n\ndirectAbstractDeclarator\n    :   '(' abstractDeclarator ')' gccDeclaratorExtension*\n    |   '[' typeQualifierList? assignmentExpression? ']'\n    |   '[' 'static' typeQualifierList? assignmentExpression ']'\n    |   '[' typeQualifierList 'static' assignmentExpression ']'\n    |   '[' '*' ']'\n    |   '(' parameterTypeList? ')' gccDeclaratorExtension*\n    |   directAbstractDeclarator '[' typeQualifierList? assignmentExpression? ']'\n    |   directAbstractDeclarator '[' 'static' typeQualifierList? assignmentExpression ']'\n    |   directAbstractDeclarator '[' typeQualifierList 'static' assignmentExpression ']'\n    |   directAbstractDeclarator '[' '*' ']'\n    |   directAbstractDeclarator '(' parameterTypeList? ')' gccDeclaratorExtension*\n    ;\n\ntypedefName\n    :   Identifier\n    ;\n\ninitializer\n    :   assignmentExpression\n    |   '{' initializerList '}'\n    |   '{' initializerList ',' '}'\n    ;\n\ninitializerList\n    :   designation? initializer\n    |   initializerList ',' designation? initializer\n    ;\n\ndesignation\n    :   designatorList '='\n    ;\n\ndesignatorList\n    :   designator\n    |   designatorList designator\n    ;\n\ndesignator\n    :   '[' constantExpression ']'\n    |   '.' Identifier\n    ;\n\nstaticAssertDeclaration\n    :   '_Static_assert' '(' constantExpression ',' StringLiteral+ ')' ';'\n    ;\n\nstatement\n    :   labeledStatement\n    |   compoundStatement\n    |   expressionStatement\n    |   selectionStatement\n    |   iterationStatement\n    |   jumpStatement\n    |   ('__asm' | '__asm__') ('volatile' | '__volatile__') '(' (logicalOrExpression (',' logicalOrExpression)*)? (':' (logicalOrExpression (',' logicalOrExpression)*)?)* ')' ';'\n    ;\n\nlabeledStatement\n    :   Identifier ':' statement\n    |   'case' constantExpression ':' statement\n    |   'default' ':' statement\n    ;\n\ncompoundStatement\n    :   '{' blockItemList? '}'\n    ;\n\nblockItemList\n    :   blockItem\n    |   blockItemList blockItem\n    ;\n\nblockItem\n    :   declaration\n    |   statement\n    ;\n\nexpressionStatement\n    :   expression? ';'\n    ;\n\nselectionStatement\n    :   'if' '(' expression ')' statement ('else' statement)?\n    |   'switch' '(' expression ')' statement\n    ;\n\niterationStatement\n    :   While '(' expression ')' statement\n    |   Do statement While '(' expression ')' ';'\n    |   For '(' forCondition ')' statement\n    ;\n\n//    |   'for' '(' expression? ';' expression?  ';' forUpdate? ')' statement\n//    |   For '(' declaration  expression? ';' expression? ')' statement\n\nforCondition\n\t:   forDeclaration ';' forExpression? ';' forExpression?\n\t|   expression? ';' forExpression? ';' forExpression?\n\t;\n\nforDeclaration\n    :   declarationSpecifiers initDeclaratorList\n\t| \tdeclarationSpecifiers\n    ;\n\nforExpression\n    :   assignmentExpression\n    |   forExpression ',' assignmentExpression\n    ;\n\njumpStatement\n    :   'goto' Identifier ';'\n    |   'continue' ';'\n    |   'break' ';'\n    |   'return' expression? ';'\n    |   'goto' unaryExpression ';' // GCC extension\n    ;\n\ncompilationUnit\n    :   translationUnit? EOF\n    ;\n\ntranslationUnit\n    :   externalDeclaration\n    |   translationUnit externalDeclaration\n    ;\n\nexternalDeclaration\n    :   functionDefinition\n    |   declaration\n    |   ';' // stray ;\n    ;\n\nfunctionDefinition\n    :   declarationSpecifiers? declarator declarationList? compoundStatement\n    ;\n\ndeclarationList\n    :   declaration\n    |   declarationList declaration\n    ;\n\nAuto : 'auto';\nBreak : 'break';\nCase : 'case';\nChar : 'char';\nConst : 'const';\nContinue : 'continue';\nDefault : 'default';\nDo : 'do';\nDouble : 'double';\nElse : 'else';\nEnum : 'enum';\nExtern : 'extern';\nFloat : 'float';\nFor : 'for';\nGoto : 'goto';\nIf : 'if';\nInline : 'inline';\nInt : 'int';\nLong : 'long';\nRegister : 'register';\nRestrict : 'restrict';\nReturn : 'return';\nShort : 'short';\nSigned : 'signed';\nSizeof : 'sizeof';\nStatic : 'static';\nStruct : 'struct';\nSwitch : 'switch';\nTypedef : 'typedef';\nUnion : 'union';\nUnsigned : 'unsigned';\nVoid : 'void';\nVolatile : 'volatile';\nWhile : 'while';\n\nAlignas : '_Alignas';\nAlignof : '_Alignof';\nAtomic : '_Atomic';\nBool : '_Bool';\nComplex : '_Complex';\nGeneric : '_Generic';\nImaginary : '_Imaginary';\nNoreturn : '_Noreturn';\nStaticAssert : '_Static_assert';\nThreadLocal : '_Thread_local';\n\nLeftParen : '(';\nRightParen : ')';\nLeftBracket : '[';\nRightBracket : ']';\nLeftBrace : '{';\nRightBrace : '}';\n\nLess : '<';\nLessEqual : '<=';\nGreater : '>';\nGreaterEqual : '>=';\nLeftShift : '<<';\nRightShift : '>>';\n\nPlus : '+';\nPlusPlus : '++';\nMinus : '-';\nMinusMinus : '--';\nStar : '*';\nDiv : '/';\nMod : '%';\n\nAnd : '&';\nOr : '|';\nAndAnd : '&&';\nOrOr : '||';\nCaret : '^';\nNot : '!';\nTilde : '~';\n\nQuestion : '?';\nColon : ':';\nSemi : ';';\nComma : ',';\n\nAssign : '=';\n// '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='\nStarAssign : '*=';\nDivAssign : '/=';\nModAssign : '%=';\nPlusAssign : '+=';\nMinusAssign : '-=';\nLeftShiftAssign : '<<=';\nRightShiftAssign : '>>=';\nAndAssign : '&=';\nXorAssign : '^=';\nOrAssign : '|=';\n\nEqual : '==';\nNotEqual : '!=';\n\nArrow : '->';\nDot : '.';\nEllipsis : '...';\n\nIdentifier\n    :   IdentifierNondigit\n        (   IdentifierNondigit\n        |   Digit\n        )*\n    ;\n\nfragment\nIdentifierNondigit\n    :   Nondigit\n    |   UniversalCharacterName\n    //|   // other implementation-defined characters...\n    ;\n\nfragment\nNondigit\n    :   [a-zA-Z_]\n    ;\n\nfragment\nDigit\n    :   [0-9]\n    ;\n\nfragment\nUniversalCharacterName\n    :   '\\\\u' HexQuad\n    |   '\\\\U' HexQuad HexQuad\n    ;\n\nfragment\nHexQuad\n    :   HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit\n    ;\n\nConstant\n    :   IntegerConstant\n    |   FloatingConstant\n    //|   EnumerationConstant\n    |   CharacterConstant\n    ;\n\nfragment\nIntegerConstant\n    :   DecimalConstant IntegerSuffix?\n    |   OctalConstant IntegerSuffix?\n    |   HexadecimalConstant IntegerSuffix?\n    |\tBinaryConstant\n    ;\n\nfragment\nBinaryConstant\n\t:\t'0' [bB] [0-1]+\n\t;\n\nfragment\nDecimalConstant\n    :   NonzeroDigit Digit*\n    ;\n\nfragment\nOctalConstant\n    :   '0' OctalDigit*\n    ;\n\nfragment\nHexadecimalConstant\n    :   HexadecimalPrefix HexadecimalDigit+\n    ;\n\nfragment\nHexadecimalPrefix\n    :   '0' [xX]\n    ;\n\nfragment\nNonzeroDigit\n    :   [1-9]\n    ;\n\nfragment\nOctalDigit\n    :   [0-7]\n    ;\n\nfragment\nHexadecimalDigit\n    :   [0-9a-fA-F]\n    ;\n\nfragment\nIntegerSuffix\n    :   UnsignedSuffix LongSuffix?\n    |   UnsignedSuffix LongLongSuffix\n    |   LongSuffix UnsignedSuffix?\n    |   LongLongSuffix UnsignedSuffix?\n    ;\n\nfragment\nUnsignedSuffix\n    :   [uU]\n    ;\n\nfragment\nLongSuffix\n    :   [lL]\n    ;\n\nfragment\nLongLongSuffix\n    :   'll' | 'LL'\n    ;\n\nfragment\nFloatingConstant\n    :   DecimalFloatingConstant\n    |   HexadecimalFloatingConstant\n    ;\n\nfragment\nDecimalFloatingConstant\n    :   FractionalConstant ExponentPart? FloatingSuffix?\n    |   DigitSequence ExponentPart FloatingSuffix?\n    ;\n\nfragment\nHexadecimalFloatingConstant\n    :   HexadecimalPrefix HexadecimalFractionalConstant BinaryExponentPart FloatingSuffix?\n    |   HexadecimalPrefix HexadecimalDigitSequence BinaryExponentPart FloatingSuffix?\n    ;\n\nfragment\nFractionalConstant\n    :   DigitSequence? '.' DigitSequence\n    |   DigitSequence '.'\n    ;\n\nfragment\nExponentPart\n    :   'e' Sign? DigitSequence\n    |   'E' Sign? DigitSequence\n    ;\n\nfragment\nSign\n    :   '+' | '-'\n    ;\n\nfragment\nDigitSequence\n    :   Digit+\n    ;\n\nfragment\nHexadecimalFractionalConstant\n    :   HexadecimalDigitSequence? '.' HexadecimalDigitSequence\n    |   HexadecimalDigitSequence '.'\n    ;\n\nfragment\nBinaryExponentPart\n    :   'p' Sign? DigitSequence\n    |   'P' Sign? DigitSequence\n    ;\n\nfragment\nHexadecimalDigitSequence\n    :   HexadecimalDigit+\n    ;\n\nfragment\nFloatingSuffix\n    :   'f' | 'l' | 'F' | 'L'\n    ;\n\nfragment\nCharacterConstant\n    :   '\\'' CCharSequence '\\''\n    |   'L\\'' CCharSequence '\\''\n    |   'u\\'' CCharSequence '\\''\n    |   'U\\'' CCharSequence '\\''\n    ;\n\nfragment\nCCharSequence\n    :   CChar+\n    ;\n\nfragment\nCChar\n    :   ~['\\\\\\r\\n]\n    |   EscapeSequence\n    ;\n\nfragment\nEscapeSequence\n    :   SimpleEscapeSequence\n    |   OctalEscapeSequence\n    |   HexadecimalEscapeSequence\n    |   UniversalCharacterName\n    ;\n\nfragment\nSimpleEscapeSequence\n    :   '\\\\' ['\"?abfnrtv\\\\]\n    ;\n\nfragment\nOctalEscapeSequence\n    :   '\\\\' OctalDigit\n    |   '\\\\' OctalDigit OctalDigit\n    |   '\\\\' OctalDigit OctalDigit OctalDigit\n    ;\n\nfragment\nHexadecimalEscapeSequence\n    :   '\\\\x' HexadecimalDigit+\n    ;\n\nStringLiteral\n    :   EncodingPrefix? '\"' SCharSequence? '\"'\n    ;\n\nfragment\nEncodingPrefix\n    :   'u8'\n    |   'u'\n    |   'U'\n    |   'L'\n    ;\n\nfragment\nSCharSequence\n    :   SChar+\n    ;\n\nfragment\nSChar\n    :   ~[\"\\\\\\r\\n]\n    |   EscapeSequence\n    |   '\\\\\\n'   // Added line\n    |   '\\\\\\r\\n' // Added line\n    ;\n\nComplexDefine\n    :   '#' Whitespace? 'define'  ~[#]*\n        -> skip\n    ;\n         \n// ignore the following asm blocks:\n/*\n    asm\n    {\n        mfspr x, 286;\n    }\n */\nAsmBlock\n    :   'asm' ~'{'* '{' ~'}'* '}'\n\t-> skip\n    ;\n\t\n// ignore the lines generated by c preprocessor                                   \n// sample line : '#line 1 \"/home/dm/files/dk1.h\" 1'                           \nLineAfterPreprocessing\n    :   '#line' Whitespace* ~[\\r\\n]*\n        -> skip\n    ;  \n\nLineDirective\n    :   '#' Whitespace? DecimalConstant Whitespace? StringLiteral ~[\\r\\n]*\n        -> skip\n    ;\n\nPragmaDirective\n    :   '#' Whitespace? 'pragma' Whitespace ~[\\r\\n]*\n        -> skip\n    ;\n\nWhitespace\n    :   [ \\t]+\n        -> skip\n    ;\n\nNewline\n    :   (   '\\r' '\\n'?\n        |   '\\n'\n        )\n        -> skip\n    ;\n\nBlockComment\n    :   '/*' .*? '*/'\n        -> skip\n    ;\n\nLineComment\n    :   '//' ~[\\r\\n]*\n        -> skip\n    ;\n"
  },
  {
    "path": "tests/inputs/ChangeProperties.il",
    "content": ";; This is SKILL\n;; https://www.mics.ece.vt.edu/ICDesign/Tutorials/Cadence/layout_pg5.html\n\n/*\n  This procedure will change the bulk node values of nfet3 and pfet3\n  to be vss! and vdd!, respectively.\n*/\n\nprocedure(cb(lib cell)\n;let will allow you to access the cv and newlabel variables outside\n;of this procedure\nlet((cv newLabel)\n;open the cellview as a database object and assign it to cv\ncv = dbOpenCellViewByType(lib cell \"schematic\" \"\" \"a\")\n;for loop to go through all instances in this cellview\nforeach(instancecv~>instances\n;open the property window -- this will display the window!\ngeSelectObjectNoFilter(instance)\nschHiObjectProperty()\n;check the cellname and change the bulk node (bn) property\nif(schObjPropForm->cellName->value == \"nfet3\"\nthen\nschObjPropForm->bn->value = \"vss!\"\nif(schObjPropForm->cellName->value == \"pfet3\"\nthen\nschObjPropForm->bn->value = \"vdd!\"\n;close the form\nhiFormDone(schObjPropForm)\ngeDeselectAll()\n);end foreach\n);end of let\n);end procedure\n"
  },
  {
    "path": "tests/inputs/Chapel.chpl",
    "content": "// \"Production-grade\" hello world\n// From https://github.com/chapel-lang/chapel/blob/release/1.16/test/release/examples/hello2-module.chpl\n\n/* This program is conceptually very similar to :ref:`hello.chpl\n   <primers-hello>`, but it uses a more structured programming style,\n   explicitly defining a module, a configuration constant, and a\n   main() procedure.\n */\n\n//\n// The following statement declares a module named 'Hello'.  If a\n// source file contains no module declarations, the filename minus its\n// ``.chpl`` extension serves as the module name for the code it\n// contains.  Thus, 'hello' would be the automatic module name for the\n// previous :ref:`hello.chpl <primers-hello>` example.\n//\nmodule Hello {\n\n//\n// This next statement declares a `configuration constant` named\n// `message`.  The type is inferred to be a string since the\n// initializing expression is a string literal.  Users may override\n// the default values of configuration constants and variables on the\n// executable's command-line.  For example, we could change the\n// default message for a given run using the command line: ``./hello\n// --message=\"hiya!\"``.\n//\n  config const message = \"Hello, world!\";\n\n\n// Any top-level code in a module is executed as part of the module's\n// initialization when the program begins executing.  Thus, in the\n// previous one-line :ref:`hello.chpl <primers-hello>`, the presence\n// of a `writeln()` at the file scope formed the implicit `hello`\n// module's initialization and would be executed at program startup.\n// Since there was no explicit `main()` function or any other\n// top-level code, that's all that the program would do.\n\n\n//\n// In this program, we define an entry point for the program by\n// defining a procedure named `main()`.  This will be invoked after\n// this module and all the modules it uses are initialized.\n//\n  proc main() {\n    writeln(message);\n  }\n}\n"
  },
  {
    "path": "tests/inputs/Cobol.cbl",
    "content": "      * from http://www.roesler-ac.de/wolfram/hello.htm\n      * Hello World in Cobol\n\n*****************************\nIDENTIFICATION DIVISION.\nPROGRAM-ID. HELLO.\nENVIRONMENT DIVISION.\nDATA DIVISION.\nPROCEDURE DIVISION.\nMAIN SECTION.\nDISPLAY \"Hello World!\"\nSTOP RUN.\n****************************\n"
  },
  {
    "path": "tests/inputs/CodeQL.ql",
    "content": "/**\n * @name Find unused variables\n * @description Finds local variables that are defined but never used.\n * @kind problem\n * @problem.severity warning\n */\n\nimport javascript\n\n// Find all variable declarations\nfrom Variable v, DeclStmt decl\nwhere\n  decl.getADecl().getBindingPattern() = v.getADeclaration() and\n  not exists(VarAccess access | access.getVariable() = v) and\n  not v.getName().matches(\"\\\\_%\")\nselect v, \"Variable '\" + v.getName() + \"' is declared but never used.\"\n"
  },
  {
    "path": "tests/inputs/ColdFusion.cfm",
    "content": "<!--- from http://www.roesler-ac.de/wolfram/hello.htm --->\r\n<!---Hello world in ColdFusion--->\r\n\r\n<cfset message = \"Hello World\">\r\n<cfoutput> #message#</cfoutput>\r\n"
  },
  {
    "path": "tests/inputs/Combinators.idr",
    "content": "-- https://github.com/ziman/lightyear/raw/master/Lightyear/Combinators.idr\n-- --------------------------------------------------------- [ Combinators.idr ]\n-- Module      : Lightyear.Combinators\n-- Description : Generic Combinators\n--\n-- This code is distributed under the BSD 2-clause license.\n-- See the file LICENSE in the root directory for its full text.\n-- --------------------------------------------------------------------- [ EOH ]\nmodule Lightyear.Combinators\n\nimport Data.Vect\n\nimport Lightyear.Core\n\n%access export\n\n-- --------------------------------------------------------------- [ Operators ]\ninfixr 3 :::\nprivate\n(:::) : a -> List a -> List a\n(:::) x xs = x :: xs\n\ninfixr 3 ::.\nprivate\n(::.) : a -> Vect n a -> Vect (S n) a\n(::.) x xs = x :: xs\n\n-- -------------------------------------------------- [ Any Token and No Token ]\n\n||| Parse a single arbitrary token. Returns the parsed token.\n|||\n||| This parser will fail if and only if the input stream is empty.\nanyToken : (Monad m, Stream tok str) => ParserT str m tok\nanyToken = satisfy (const True) <?> \"any token\"\n\n||| Parse the end of input.\n|||\n||| This parser will succeed if and only if the input stream is empty.\neof : (Monad m, Stream tok str) => ParserT str m ()\neof = requireFailure anyToken <?> \"end of input\"\n\n-- ---------------------------------------------------- [ Multiple Expressions ]\n\n||| Run some parser as many times as possible, collecting a list of\n||| successes.\nmany : Monad m => ParserT str m a -> ParserT str m (List a)\nmany p = (pure (:::) <*> p <*>| many p) <|> pure List.Nil\n\n||| Run the specified parser precisely `n` times, returning a vector\n||| of successes.\nntimes : Monad m => (n : Nat)\n                 -> ParserT str m a\n                 -> ParserT str m (Vect n a)\nntimes    Z  p = pure Vect.Nil\nntimes (S n) p = [| p ::. ntimes n p |]\n\n||| Like `many`, but the parser must succeed at least once\nsome : Monad m => ParserT str m a -> ParserT str m (List a)\nsome p = [| p ::: many p |]\n\n-- --------------------------------------------------- [ Separated Expressions ]\n\n||| Parse repeated instances of at least one `p`, separated by `s`,\n||| returning a list of successes.\n|||\n||| @ p the parser for items\n||| @ s the parser for separators\nsepBy1 : Monad m => (p : ParserT str m a)\n                 -> (s : ParserT str m b)\n                 -> ParserT str m (List a)\nsepBy1 p s = [| p ::: many (s *> p) |]\n\n||| Parse zero or more `p`s, separated by `s`s, returning a list of\n||| successes.\n|||\n||| @ p the parser for items\n||| @ s the parser for separators\nsepBy : Monad m => (p : ParserT str m a)\n                -> (s : ParserT str m b)\n                -> ParserT str m (List a)\nsepBy p s = (p `sepBy1` s) <|> pure List.Nil\n\n||| Parse precisely `n` `p`s, separated by `s`s, returning a vect of\n||| successes.\n|||\n||| @ n how many to parse\n||| @ p the parser for items\n||| @ s the parser for separators\nsepByN : Monad m => (n : Nat)\n                 -> (p : ParserT str m a)\n                 -> (s : ParserT str m b)\n                 -> ParserT str m (Vect n a)\nsepByN    Z  p s = pure Vect.Nil\nsepByN (S n) p s = [| p ::. ntimes n (s *> p) |]\n\n||| Parse one or more `p`s, separated by `op`s. Return a value that is\n||| the left associative application of the functions returned by `op`.\n|||\n||| @ p  the parser\n||| @ op the parser for operators\nchainl1 : Monad m => (p : ParserT str m a)\n                  -> (op: ParserT str m (a -> a -> a))\n                  -> ParserT str m a\nchainl1 p op = p >>= rest\n  where rest a1 = (do f <- op\n                      a2 <- p\n                      rest (f a1 a2)) <|> pure a1\n\n||| Parse zero or more `p`s, separated by `op`s. Return a value that is\n||| the left associative application of the functions returned by `op`.\n||| Return `a` when there are zero occurences of `p`.\n|||\n||| @ p  the parser\n||| @ op the parser for operators\nchainl : Monad m => (p : ParserT str m a)\n                 -> (op : ParserT str m (a -> a -> a))\n                 -> a\n                 -> ParserT str m a\nchainl p op a = (p `chainl1` op) <|> pure a\n\n||| Parse one or more `p`s, separated by `op`s. Return a value that is\n||| the right associative application of the functions returned by `op`.\n|||\n||| @ p  the parser\n||| @ op the parser for operators\nchainr1 : Monad m => (p : ParserT str m a)\n                  -> (op: ParserT str m (a -> a -> a))\n                  -> ParserT str m a\nchainr1 p op = p >>= rest\n  where rest a1 = (do f <- op\n                      a2 <- p >>= rest\n                      rest (f a1 a2)) <|> pure a1\n\n||| Parse zero or more `p`s, separated by `op`s. Return a value that is\n||| the right associative application of the functions returned by `op`.\n||| Return `a` when there are zero occurences of `p`.\n|||\n||| @ p  the parser\n||| @ op the parser for operators\nchainr : Monad m => (p : ParserT str m a)\n                 -> (op : ParserT str m (a -> a -> a))\n                 -> a\n                 -> ParserT str m a\nchainr p op a = (p `chainr1` op) <|> pure a\n\n||| Alternate between matches of `p` and `s`, starting with `p`,\n||| returning a list of successes from both.\nalternating : Monad m => (p : ParserT str m a)\n                      -> (s : ParserT str m a)\n                      -> ParserT str m (List a)\nalternating p s = (pure (:::) <*> p <*>| alternating s p) <|> pure List.Nil\n\n||| Throw away the result from a parser\nskip : Monad m => ParserT str m a -> ParserT str m ()\nskip = map (const ())\n\n||| Attempt to parse `p`. If it succeeds, then return the value. If it\n||| fails, continue parsing.\nopt : Monad m => (p : ParserT str m a) -> ParserT str m (Maybe a)\nopt p = map Just p <|> pure Nothing\n\n||| Parse open, then p, then close. Returns the result of `p`.\n|||\n||| @open The opening parser.\n||| @close The closing parser.\n||| @p The parser for the middle part.\nbetween : Monad m => (open : ParserT str m a)\n                  -> (close : ParserT str m a)\n                  -> (p : ParserT str m b)\n                  -> ParserT str m b\nbetween open close p = open *> p <* close\n\n-- The following names are inspired by the cut operator from Prolog\n\n-- ---------------------------------------------------- [ Monad-like Operators ]\n\ninfixr 5 >!=\n||| Committing bind\n(>!=) : Monad m => ParserT str m a\n                -> (a -> ParserT str m b)\n                -> ParserT str m b\nx >!= f = x >>= commitTo . f\n\ninfixr 5 >!\n||| Committing sequencing\n(>!) : Monad m => ParserT str m a\n               -> ParserT str m b\n               -> ParserT str m b\nx >! y = x >>= \\_ => commitTo y\n\n-- ---------------------------------------------- [ Applicative-like Operators ]\n\ninfixl 2 <*!>\n||| Committing application\n(<*!>) : Monad m => ParserT str m (a -> b)\n                 -> ParserT str m a\n                 -> ParserT str m b\nf <*!> x = f <*> commitTo x\n\ninfixl 2 <*!\n(<*!) : Monad m => ParserT str m a\n                -> ParserT str m b\n                -> ParserT str m a\nx <*! y = x <* commitTo y\n\ninfixl 2 *!>\n(*!>) : Monad m => ParserT str m a\n                -> ParserT str m b\n                -> ParserT str m b\nx *!> y = x *> commitTo y\n\n-- ---------------------------------------------------------- [ Lazy Operators ]\n\ninfixl 2 <*|\n(<*|) : Monad m => ParserT str m a\n                -> Lazy (ParserT str m b)\n                -> ParserT str m a\nx <*| y = pure const <*> x <*>| y\n\ninfixl 2 *>|\n(*>|) : Monad m => ParserT str m a\n                -> Lazy (ParserT str m b)\n                -> ParserT str m b\nx *>| y = pure (const id) <*> x <*>| y\n-- ---------------------------------------------------------------------- [ EF ]\n"
  },
  {
    "path": "tests/inputs/Containerfile",
    "content": "# this is a copy of tests/inputs/Dockerfile\n\nFROM centos:centos6\n\n# just a comment\n\nRUN yum clean all && \\\n    yum -y install epel-release && \\\n    yum -y install \\\n    acl \\\n    asciidoc \\\n    bzip2 \\\n    file \\\n    gcc \\\n    git \\\n    make \\\n    mercurial \\\n    mysql \\\n    MySQL-python \\\n    mysql-server \\\n    openssh-clients \\\n    openssh-server \\\n    python-coverage \\\n    python-devel \\\n    python-httplib2 \\\n    python-keyczar \\\n    python-mock \\\n    python-nose \\\n    python-paramiko \\\n    python-passlib \\\n    python-pip \\\n    python-setuptools \\\n    python-virtualenv \\\n    PyYAML \\\n    rpm-build \\\n    rubygems \\\n    sed \\\n    subversion \\\n    sudo \\\n    unzip \\\n    which \\\n    zip \\\n    && \\\n    yum clean all\n\nRUN rpm -e --nodeps python-crypto && pip install --upgrade jinja2 pycrypto\n\nRUN /bin/sed -i -e 's/^\\(Defaults\\s*requiretty\\)/#--- \\1/'  /etc/sudoers\nRUN mkdir /etc/ansible/\nRUN /bin/echo -e '[local]\\nlocalhost ansible_connection=local' > /etc/ansible/hosts\nVOLUME /sys/fs/cgroup /run /tmp\nRUN ssh-keygen -q -t rsa1 -N '' -f /etc/ssh/ssh_host_key && \\\n    ssh-keygen -q -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key && \\\n    ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key && \\\n    ssh-keygen -q -t rsa -N '' -f /root/.ssh/id_rsa && \\\n    cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys && \\\n    for key in /etc/ssh/ssh_host_*_key.pub; do echo \"localhost $(cat ${key})\" >> /root/.ssh/known_hosts; done\nRUN pip install junit-xml\nENV container=docker\nCMD [\"/sbin/init\"]\n"
  },
  {
    "path": "tests/inputs/Counter.razor",
    "content": "@*\n    https://docs.microsoft.com/en-us/aspnet/core/tutorials/build-your-first-blazor-app?view=aspnetcore-3.1\n*@\n@page \"/counter\"\n\n<h1>Counter</h1>\n\n<p>Current count: @currentCount</p>\n\n<button class=\"btn btn-primary\" @onclick=\"IncrementCount\">Click me</button>\n\n@code {\n    private int currentCount = 0;\n\n    [Parameter]\n    public int IncrementAmount { get; set; } = 1;\n\n    private void IncrementCount()\n    {\n        currentCount += IncrementAmount;\n    }\n}\n"
  },
  {
    "path": "tests/inputs/DIEnumerator-10.0.ll",
    "content": "; https://github.com/llvm/llvm-project/raw/master/llvm/test/Bitcode/DIEnumerator-10.0.ll\n;; DIEnumerator-10.0.ll.bc was generated by llvm-as 10.0.0\n; RUN: llvm-dis < %s.bc | FileCheck %s\n; RUN: verify-uselistorder < %s.bc\n\n!named = !{!0, !1}\n\n; CHECK: !DIEnumerator(name: \"A0\", value: 9223372036854775807)\n!0 = !DIEnumerator(name: \"A0\", value: 9223372036854775807)\n; CHECK: !DIEnumerator(name: \"B0\", value: -9223372036854775808)\n!1 = !DIEnumerator(name: \"B0\", value: -9223372036854775808)\n"
  },
  {
    "path": "tests/inputs/DocTest.thrift",
    "content": "// https://github.com/apache/thrift/raw/master/test/DocTest.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,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n/**\n * Program doctext.\n *\n * Seriously, this is the documentation for this whole program.\n */\n\nnamespace java thrift.test\nnamespace cpp thrift.test\n\n// C++ comment\n/* c style comment */\n\n# the new unix comment\n\n/** Some doc text goes here.  Wow I am [nesting these] (no more nesting.) */\nenum Numberz\n{\n\n  /** This is how to document a parameter */\n  ONE = 1,\n\n  /** And this is a doc for a parameter that has no specific value assigned */\n  TWO,\n\n  THREE,\n  FIVE = 5,\n  SIX,\n  EIGHT = 8\n}\n\n/** This is how you would do a typedef doc */\ntypedef i64 UserId\n\n/** And this is where you would document a struct */\nstruct Xtruct\n{\n\n  /** And the members of a struct */\n  1:  string string_thing\n\n  /** doct text goes before a comma */\n  4:  i8     byte_thing,\n\n  9:  i32    i32_thing,\n  11: i64    i64_thing\n}\n\n/**\n * You can document constants now too.  Yeehaw!\n */\nconst i32 INT32CONSTANT = 9853\nconst i16 INT16CONSTANT = 1616\n/** Everyone get in on the docu-action! */\nconst map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}\n\nstruct Xtruct2\n{\n  1: i8     byte_thing,\n  2: Xtruct struct_thing,\n  3: i32    i32_thing\n}\n\n/** Struct insanity */\nstruct Insanity\n{\n\n  /** This is doc for field 1 */\n  1: map<Numberz, UserId> userMap,\n\n  /** And this is doc for field 2 */\n  2: list<Xtruct> xtructs\n}\n\nexception Xception {\n  1: i32 errorCode,\n  2: string message\n}\n\nexception Xception2 {\n  1: i32 errorCode,\n  2: Xtruct struct_thing\n}\n\n/* C1 */\n/** Doc */\n/* C2 */\n/* C3 */\nstruct EmptyStruct {}\n\nstruct OneField {\n  1: EmptyStruct field\n}\n\n/** This is where you would document a Service */\nservice ThriftTest\n{\n\n  /** And this is how you would document functions in a service */\n  void         testVoid(),\n  string       testString(1: string thing),\n  i8           testByte(1: byte thing),\n  i32          testI32(1: i32 thing),\n\n  /** Like this one */\n  i64          testI64(1: i64 thing),\n  double       testDouble(1: double thing),\n  Xtruct       testStruct(1: Xtruct thing),\n  Xtruct2      testNest(1: Xtruct2 thing),\n  map<i32,i32> testMap(1: map<i32,i32> thing),\n  set<i32>     testSet(1: set<i32> thing),\n  list<i32>    testList(1: list<i32> thing),\n\n  /** This is an example of a function with params documented */\n  Numberz      testEnum(\n\n    /** This param is a thing */\n    1: Numberz thing\n\n  ),\n\n  UserId       testTypedef(1: UserId thing),\n\n  map<i32,map<i32,i32>> testMapMap(1: i32 hello),\n\n  /* So you think you've got this all worked, out eh? */\n  map<UserId, map<Numberz,Insanity>> testInsanity(1: Insanity argument),\n\n}\n\n/// This style of Doxy-comment doesn't work.\ntypedef i32 SorryNoGo\n\n/**\n * This is a trivial example of a multiline docstring.\n */\ntypedef i32 TrivialMultiLine\n\n/**\n * This is the canonical example\n * of a multiline docstring.\n */\ntypedef i32 StandardMultiLine\n\n/**\n * The last line is non-blank.\n * I said non-blank! */\ntypedef i32 LastLine\n\n/** Both the first line\n * are non blank. ;-)\n * and the last line */\ntypedef i32 FirstAndLastLine\n\n/**\n *    INDENTED TITLE\n * The text is less indented.\n */\ntypedef i32 IndentedTitle\n\n/**       First line indented.\n * Unfortunately, this does not get indented.\n */\ntypedef i32 FirstLineIndent\n\n\n/**\n * void code_in_comment() {\n *   printf(\"hooray code!\");\n * }\n */\ntypedef i32 CodeInComment\n\n    /**\n     * Indented Docstring.\n     * This whole docstring is indented.\n     *   This line is indented further.\n     */\ntypedef i32 IndentedDocstring\n\n/** Irregular docstring.\n * We will have to punt\n  * on this thing */\ntypedef i32 Irregular1\n\n/**\n * note the space\n * before these lines\n* but not this\n * one\n */\ntypedef i32 Irregular2\n\n/**\n* Flush against\n* the left.\n*/\ntypedef i32 Flush\n\n/**\n  No stars in this one.\n  It should still work fine, though.\n    Including indenting.\n    */\ntypedef i32 NoStars\n\n/** Trailing whitespace   \nSloppy trailing whitespace   \nis truncated.   */\ntypedef i32 TrailingWhitespace\n\n/**\n * This is a big one.\n *\n * We'll have some blank lines in it.\n * \n * void as_well_as(some code) {\n *   puts(\"YEEHAW!\");\n * }\n */\ntypedef i32 BigDog\n\n/**\n*\n*\n*/\ntypedef i32 TotallyDegenerate\n\n/**no room for newline here*/\n\n/* * / */\ntypedef i32 TestFor3501a\n\n/**\n * /\n */\ntypedef i32 TestFor3501b\n\n\n/* Comment-end tokens can of course have more than one asterisk */\nstruct TestFor3709_00 { /* ? */ 1: i32 foo }\n/* Comment-end tokens can of course have more than one asterisk **/\nstruct TestFor3709_01 { /* ? */ 1: i32 foo }\n/* Comment-end tokens can of course have more than one asterisk ***/\nstruct TestFor3709_02 { /* ? */ 1: i32 foo }\n/** Comment-end tokens can of course have more than one asterisk */\nstruct TestFor3709_03 { /* ? */ 1: i32 foo }\n/** Comment-end tokens can of course have more than one asterisk **/\nstruct TestFor3709_04 { /* ? */ 1: i32 foo }\n/** Comment-end tokens can of course have more than one asterisk ***/\nstruct TestFor3709_05 { /* ? */ 1: i32 foo }\n/*** Comment-end tokens can of course have more than one asterisk */\nstruct TestFor3709_06 { /* ? */ 1: i32 foo }\n/*** Comment-end tokens can of course have more than one asterisk **/\nstruct TestFor3709_07 { /* ? */ 1: i32 foo }\n/*** Comment-end tokens can of course have more than one asterisk ***/\nstruct TestFor3709_08 { /* ? */ 1: i32 foo }\n\nstruct TestFor3709 {\n  /** This is a comment */\n  1: required string id,\n  /** This is also a comment **/\n  2: required string typeId,\n  /** Yet another comment! */\n  3: required i32 endTimestamp\n}\n\n\n/* THE END */\n"
  },
  {
    "path": "tests/inputs/Dockerfile",
    "content": "FROM centos:centos6\n\n# just a comment\n\nRUN yum clean all && \\\n    yum -y install epel-release && \\\n    yum -y install \\\n    acl \\\n    asciidoc \\\n    bzip2 \\\n    file \\\n    gcc \\\n    git \\\n    make \\\n    mercurial \\\n    mysql \\\n    MySQL-python \\\n    mysql-server \\\n    openssh-clients \\\n    openssh-server \\\n    python-coverage \\\n    python-devel \\\n    python-httplib2 \\\n    python-keyczar \\\n    python-mock \\\n    python-nose \\\n    python-paramiko \\\n    python-passlib \\\n    python-pip \\\n    python-setuptools \\\n    python-virtualenv \\\n    PyYAML \\\n    rpm-build \\\n    rubygems \\\n    sed \\\n    subversion \\\n    sudo \\\n    unzip \\\n    which \\\n    zip \\\n    && \\\n    yum clean all\n\nRUN rpm -e --nodeps python-crypto && pip install --upgrade jinja2 pycrypto\n\nRUN /bin/sed -i -e 's/^\\(Defaults\\s*requiretty\\)/#--- \\1/'  /etc/sudoers\nRUN mkdir /etc/ansible/\nRUN /bin/echo -e '[local]\\nlocalhost ansible_connection=local' > /etc/ansible/hosts\nVOLUME /sys/fs/cgroup /run /tmp\nRUN ssh-keygen -q -t rsa1 -N '' -f /etc/ssh/ssh_host_key && \\\n    ssh-keygen -q -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key && \\\n    ssh-keygen -q -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key && \\\n    ssh-keygen -q -t rsa -N '' -f /root/.ssh/id_rsa && \\\n    cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys && \\\n    for key in /etc/ssh/ssh_host_*_key.pub; do echo \"localhost $(cat ${key})\" >> /root/.ssh/known_hosts; done\nRUN pip install junit-xml\nENV container=docker\nCMD [\"/sbin/init\"]\n"
  },
  {
    "path": "tests/inputs/ERC20.cairo",
    "content": "// https://raw.githubusercontent.com/OpenZeppelin/cairo-contracts/main/src/openzeppelin/token/erc20/presets/ERC20.cairo\n// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts for Cairo v0.4.0b (token/erc20/presets/ERC20.cairo)\n\n%lang starknet\n\nfrom starkware.cairo.common.cairo_builtins import HashBuiltin\nfrom starkware.cairo.common.uint256 import Uint256\n\nfrom openzeppelin.token.erc20.library import ERC20\n\n@constructor\nfunc constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    name: felt, symbol: felt, decimals: felt, initial_supply: Uint256, recipient: felt\n) {\n    ERC20.initializer(name, symbol, decimals);\n    ERC20._mint(recipient, initial_supply);\n    return ();\n}\n\n//\n// Getters\n//\n\n@view\nfunc name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (name: felt) {\n    return ERC20.name();\n}\n\n@view\nfunc symbol{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (symbol: felt) {\n    return ERC20.symbol();\n}\n\n@view\nfunc totalSupply{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (\n    totalSupply: Uint256\n) {\n    let (totalSupply: Uint256) = ERC20.total_supply();\n    return (totalSupply=totalSupply);\n}\n\n@view\nfunc decimals{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (\n    decimals: felt\n) {\n    return ERC20.decimals();\n}\n\n@view\nfunc balanceOf{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(account: felt) -> (\n    balance: Uint256\n) {\n    return ERC20.balance_of(account);\n}\n\n@view\nfunc allowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    owner: felt, spender: felt\n) -> (remaining: Uint256) {\n    return ERC20.allowance(owner, spender);\n}\n\n//\n// Externals\n//\n\n@external\nfunc transfer{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    recipient: felt, amount: Uint256\n) -> (success: felt) {\n    return ERC20.transfer(recipient, amount);\n}\n\n@external\nfunc transferFrom{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    sender: felt, recipient: felt, amount: Uint256\n) -> (success: felt) {\n    return ERC20.transfer_from(sender, recipient, amount);\n}\n\n@external\nfunc approve{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    spender: felt, amount: Uint256\n) -> (success: felt) {\n    return ERC20.approve(spender, amount);\n}\n\n@external\nfunc increaseAllowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    spender: felt, added_value: Uint256\n) -> (success: felt) {\n    return ERC20.increase_allowance(spender, added_value);\n}\n\n@external\nfunc decreaseAllowance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(\n    spender: felt, subtracted_value: Uint256\n) -> (success: felt) {\n    return ERC20.decrease_allowance(spender, subtracted_value);\n}\n"
  },
  {
    "path": "tests/inputs/ExprParser.g",
    "content": "// https://github.com/apache/drill/raw/master/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g\nparser grammar ExprParser;\n\noptions{\n  output=AST;\n  language=Java;\n  tokenVocab=ExprLexer;\n  backtrack=true;\n  memoize=true;\n}\n\n\n\n@header {\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\npackage org.apache.drill.common.expression.parser;\n  \n//Explicit import...\nimport org.antlr.runtime.BitSet;\nimport java.util.*;\nimport org.apache.drill.common.expression.*;\nimport org.apache.drill.common.expression.PathSegment.NameSegment;\nimport org.apache.drill.common.expression.PathSegment.ArraySegment;\nimport org.apache.drill.common.types.*;\nimport org.apache.drill.common.types.TypeProtos.*;\nimport org.apache.drill.common.types.TypeProtos.DataMode;\nimport org.apache.drill.common.types.TypeProtos.MajorType;\nimport org.apache.drill.common.exceptions.ExpressionParsingException;\n}\n\n@members{\n  private String fullExpression;\n  private int tokenPos;\n\n  public static void p(String s){\n    System.out.println(s);\n  }\n  \n  public ExpressionPosition pos(Token token){\n    return new ExpressionPosition(fullExpression, token.getTokenIndex());\n  }\n  \n  @Override    \n  public void displayRecognitionError(String[] tokenNames, RecognitionException e) {\n\tString hdr = getErrorHeader(e);\n    String msg = getErrorMessage(e, tokenNames);\n    throw new ExpressionParsingException(\"Expression has syntax error! \" + hdr + \":\" + msg);\n  }\n}\n\nparse returns [LogicalExpression e]\n  :  expression EOF {\n    $e = $expression.e; \n    if(fullExpression == null) fullExpression = $expression.text;\n    tokenPos = $expression.start.getTokenIndex();\n  }\n  ;\n \nfunctionCall returns [LogicalExpression e]\n  :  Identifier OParen exprList? CParen {$e = FunctionCallFactory.createExpression($Identifier.text, pos($Identifier), $exprList.listE);  }\n  ;\n\nconvertCall returns [LogicalExpression e]\n  :  Convert OParen expression Comma String CParen\n      { $e = FunctionCallFactory.createConvert($Convert.text, $String.text, $expression.e, pos($Convert));}\n  ;\n\ncastCall returns [LogicalExpression e]\n\t@init{\n  \t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  ExpressionPosition p = null;\n\t}  \n  :  Cast OParen expression As dataType repeat? CParen \n      {  if ($repeat.isRep!=null && $repeat.isRep.compareTo(Boolean.TRUE)==0)\n           $e = FunctionCallFactory.createCast(TypeProtos.MajorType.newBuilder().mergeFrom($dataType.type).setMode(DataMode.REPEATED).build(), pos($Cast), $expression.e);\n         else\n           $e = FunctionCallFactory.createCast($dataType.type, pos($Cast), $expression.e);}\n  ;\n\nrepeat returns [Boolean isRep]\n  : Repeat { $isRep = Boolean.TRUE;}\n  ;\n\ndataType returns [MajorType type]\n\t: numType  {$type =$numType.type;}\n\t| charType {$type =$charType.type;}\n\t| dateType {$type =$dateType.type;}\n\t| booleanType {$type =$booleanType.type;}\n\t;\n\nbooleanType returns [MajorType type]\n\t: BIT { $type = Types.required(TypeProtos.MinorType.BIT); }\n\t;\n\nnumType returns [MajorType type]\n\t: INT    { $type = Types.required(TypeProtos.MinorType.INT); }\n\t| BIGINT { $type = Types.required(TypeProtos.MinorType.BIGINT); }\n\t| FLOAT4 { $type = Types.required(TypeProtos.MinorType.FLOAT4); }\n\t| FLOAT8 { $type = Types.required(TypeProtos.MinorType.FLOAT8); }\n\t| DECIMAL9 OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL9).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t| DECIMAL18 OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL18).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t| DECIMAL28DENSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL28DENSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t| DECIMAL28SPARSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL28SPARSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t| DECIMAL38DENSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL38DENSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t| DECIMAL38SPARSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL38SPARSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); }\n\t;\n\ncharType returns [MajorType type]\n\t:  VARCHAR typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARCHAR).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build(); }\n\t|  VARBINARY typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARBINARY).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build();}\t\n\t;\n\nprecision returns [Integer value]\n    : Number {$value = Integer.parseInt($Number.text); }\n    ;\n\nscale returns [Integer value]\n    : Number {$value = Integer.parseInt($Number.text); }\n    ;\n\ndateType returns [MajorType type]\n    : DATE { $type = Types.required(TypeProtos.MinorType.DATE); }\n    | TIMESTAMP   { $type = Types.required(TypeProtos.MinorType.TIMESTAMP); }\n    | TIME   { $type = Types.required(TypeProtos.MinorType.TIME); }\n    | TIMESTAMPTZ   { $type = Types.required(TypeProtos.MinorType.TIMESTAMPTZ); }\n    | INTERVAL { $type = Types.required(TypeProtos.MinorType.INTERVAL); }\n    | INTERVALYEAR { $type = Types.required(TypeProtos.MinorType.INTERVALYEAR); }\n    | INTERVALDAY { $type = Types.required(TypeProtos.MinorType.INTERVALDAY); }\n    ;\n\ntypeLen returns [Integer length]\n    : OParen Number CParen {$length = Integer.parseInt($Number.text);}\n    ;\n\nifStatement returns [LogicalExpression e]\n\t@init {\n\t  IfExpression.Builder s = IfExpression.newBuilder();\n\t}\n\t@after {\n\t  $e = s.build();\n\t}  \n  :  i1=ifStat {s.setIfCondition($i1.i); s.setPosition(pos($i1.start)); } (elseIfStat { s.setIfCondition($elseIfStat.i); } )* Else expression { s.setElse($expression.e); }End\n  ;\n\nifStat returns [IfExpression.IfCondition i]\n  : If e1=expression Then e2=expression { $i = new IfExpression.IfCondition($e1.e, $e2.e); }\n  ;\nelseIfStat returns [IfExpression.IfCondition i]\n  : Else If e1=expression Then e2=expression { $i = new IfExpression.IfCondition($e1.e, $e2.e); }\n  ;\n\ncaseStatement returns [LogicalExpression e]\n\t@init {\n\t  IfExpression.Builder s = IfExpression.newBuilder();\n\t}\n\t@after {\n\t  $e = s.build();\n\t}  \n  : Case (caseWhenStat {s.setIfCondition($caseWhenStat.e); }) + caseElseStat { s.setElse($caseElseStat.e); } End\n  ;\n  \ncaseWhenStat returns [IfExpression.IfCondition e]\n  : When e1=expression Then e2=expression {$e = new IfExpression.IfCondition($e1.e, $e2.e); }\n  ;\n  \ncaseElseStat returns [LogicalExpression e]\n  : Else expression {$e = $expression.e; }\n  ;\n  \nexprList returns [List<LogicalExpression> listE]\n\t@init{\n\t  $listE = new ArrayList<LogicalExpression>();\n\t}\n  :  e1=expression {$listE.add($e1.e); } (Comma e2=expression {$listE.add($e2.e); } )*\n  ;\n\nexpression returns [LogicalExpression e]  \n  :  ifStatement {$e = $ifStatement.e; }\n  |  caseStatement {$e = $caseStatement.e; }\n  |  condExpr {$e = $condExpr.e; }\n  ;\n\ncondExpr returns [LogicalExpression e]\n  :  orExpr {$e = $orExpr.e; }\n  ;\n\norExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  if(exprs.size() == 1){\n\t    $e = exprs.get(0);\n\t  }else{\n\t    $e = FunctionCallFactory.createBooleanOperator(\"or\", p, exprs);\n\t  }\n\t}\n  :  a1=andExpr { exprs.add($a1.e); p = pos( $a1.start );} (Or a2=andExpr { exprs.add($a2.e); })*\n  ;\n\nandExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  if(exprs.size() == 1){\n\t    $e = exprs.get(0);\n\t  }else{\n\t    $e = FunctionCallFactory.createBooleanOperator(\"and\", p, exprs);\n\t  }\n\t}\n  :  e1=equExpr { exprs.add($e1.e); p = pos( $e1.start );  } ( And e2=equExpr { exprs.add($e2.e);  })*\n  ;\n\nequExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  List<String> cmps = new ArrayList();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  $e = FunctionCallFactory.createByOp(exprs, p, cmps);\n\t}\n  :  r1=relExpr { exprs.add($r1.e); p = pos( $r1.start );\n    } ( cmpr= ( Equals | NEquals ) r2=relExpr {exprs.add($r2.e); cmps.add($cmpr.text); })*\n  ;\n\nrelExpr returns [LogicalExpression e]\n  :  left=addExpr {$e = $left.e; } (cmpr = (GTEquals | LTEquals | GT | LT) right=addExpr {$e = FunctionCallFactory.createExpression($cmpr.text, pos($left.start), $left.e, $right.e); } )?\n  ;\n\naddExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  List<String> ops = new ArrayList();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  $e = FunctionCallFactory.createByOp(exprs, p, ops);\n\t}\n  :  m1=mulExpr  {exprs.add($m1.e); p = pos($m1.start); } ( op=(Plus|Minus) m2=mulExpr {exprs.add($m2.e); ops.add($op.text); })* \n  ;\n\nmulExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  List<String> ops = new ArrayList();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  $e = FunctionCallFactory.createByOp(exprs, p, ops);\n\t}\n  :  p1=xorExpr  {exprs.add($p1.e); p = pos($p1.start);} (op=(Asterisk|ForwardSlash|Percent) p2=xorExpr {exprs.add($p2.e); ops.add($op.text); } )*\n  ;\n\nxorExpr returns [LogicalExpression e]\n\t@init{\n\t  List<LogicalExpression> exprs = new ArrayList<LogicalExpression>();\n\t  List<String> ops = new ArrayList();\n\t  ExpressionPosition p = null;\n\t}\n\t@after{\n\t  $e = FunctionCallFactory.createByOp(exprs, p, ops);\n\t}\n  :  u1=unaryExpr {exprs.add($u1.e); p = pos($u1.start);} (Caret u2=unaryExpr {exprs.add($u2.e); ops.add($Caret.text);} )*\n  ;\n  \nunaryExpr returns [LogicalExpression e]\n  :  sign=(Plus|Minus)? Number {$e = ValueExpressions.getNumericExpression($sign.text, $Number.text, pos(($sign != null) ? $sign : $Number)); }\n  |  Minus atom {$e = FunctionCallFactory.createExpression(\"u-\", pos($Minus), $atom.e); }\n  |  Excl atom {$e= FunctionCallFactory.createExpression(\"!\", pos($Excl), $atom.e); }\n  |  atom {$e = $atom.e; }\n  ;\n\natom returns [LogicalExpression e]\n  :  Bool {$e = new ValueExpressions.BooleanExpression($Bool.text, pos($Bool)); }\n  |  lookup {$e = $lookup.e; }\n  ;\n\npathSegment returns [NameSegment seg]\n  : s1=nameSegment {$seg = $s1.seg;}\n  ;\n\nnameSegment returns [NameSegment seg]\n  : QuotedIdentifier ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new NameSegment($QuotedIdentifier.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); }\n  | Identifier ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new NameSegment($Identifier.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); }\n  ;\n  \narraySegment returns [PathSegment seg]\n  :  OBracket Number CBracket ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new ArraySegment($Number.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); }\n  ;\n\n\nlookup returns [LogicalExpression e]\n  :  functionCall {$e = $functionCall.e ;}\n  | convertCall {$e = $convertCall.e; }\n  | castCall {$e = $castCall.e; }\n  | pathSegment {$e = new SchemaPath($pathSegment.seg, pos($pathSegment.start) ); }\n  | String {$e = new ValueExpressions.QuotedString($String.text, pos($String) ); }\n  | OParen expression CParen  {$e = $expression.e; }\n  | SingleQuote Identifier SingleQuote {$e = new SchemaPath($Identifier.text, pos($Identifier) ); }\n  ;\n  \n  \n  \n"
  },
  {
    "path": "tests/inputs/FOCUS.focexec",
    "content": "-* from http://www.roesler-ac.de/wolfram/hello.htm\r\n-* Hello World in FOCUS\r\n\r\n-TYPE Hello world\r\n"
  },
  {
    "path": "tests/inputs/Fortran77.f",
    "content": "C from http://www.roesler-ac.de/wolfram/hello.htm\nC     Hello World in Fortran 77\n\n      PROGRAM HELLO\n      PRINT*, 'Hello World!'\n      END\n"
  },
  {
    "path": "tests/inputs/Fortran90.f90",
    "content": "! from http://www.roesler-ac.de/wolfram/hello.htm\r\n! Hello World in Fortran 90, 95, and 2003\r\n\r\nPROGRAM HelloWorld\r\n     WRITE(*,*)  \"Hello World!\"\r\nEND PROGRAM\r\n"
  },
  {
    "path": "tests/inputs/FreemarkerTemplate.ftl",
    "content": "<html>\n<head>\n  <title>Welcome!</title>\n</head>\n<body>\n  <#-- Greet the user with his/her name -->\n  <h1>Welcome ${user <#-- The name of user -->}!</h1>\n  <p>We have these animals:\n  <ul>\n  <#list <#-- some comment... --> animals as <#-- again... --> animal>\n    <li>${animal.name} for ${animal.price} Euros\n  </#list>\n  </ul>\n</body>\n</html><html>\n<head>\n  <title>Welcome!</title>\n</head>\n<body>\n  <#-- Greet the user with his/her name -->\n  <h1>Welcome ${user}!</h1>\n  <p>We have these animals:\n  <ul>\n  <#list animals as animal>\n    <li>${animal.name} for ${animal.price} Euros\n  </#list>\n  </ul>\n</body>\n</html>"
  },
  {
    "path": "tests/inputs/GamePanel.tscn",
    "content": "; https://github.com/zacryol/spindle-of-serendipity/raw/develop/godot/game/GamePanel.tscn\n[gd_scene load_steps=19 format=2]\n\n[ext_resource path=\"res://game/components/PlayersPanel.tscn\" type=\"PackedScene\" id=1]\n[ext_resource path=\"res://game/components/Keyboard.tscn\" type=\"PackedScene\" id=2]\n[ext_resource path=\"res://game/components/EntryDisplay.tscn\" type=\"PackedScene\" id=3]\n[ext_resource path=\"res://game/components/Spindle.tscn\" type=\"PackedScene\" id=4]\n[ext_resource path=\"res://game/GamePanel.gd\" type=\"Script\" id=5]\n[ext_resource path=\"res://GameTheme.theme\" type=\"Theme\" id=6]\n[ext_resource path=\"res://game/VScreen.tscn\" type=\"PackedScene\" id=7]\n[ext_resource path=\"res://Xolonium-Bold.otf\" type=\"DynamicFontData\" id=8]\n[ext_resource path=\"res://game/RoundSign.gd\" type=\"Script\" id=9]\n[ext_resource path=\"res://tex/star_04.png\" type=\"Texture\" id=10]\n\n[sub_resource type=\"StyleBoxFlat\" id=1]\nbg_color = Color( 0.0862745, 0.0862745, 0.101961, 0.631373 )\ncorner_radius_top_left = 25\ncorner_radius_top_right = 25\ncorner_radius_bottom_right = 25\ncorner_radius_bottom_left = 25\nshadow_color = Color( 0.0862745, 0.0862745, 0.101961, 0.74902 )\nshadow_size = 50\n\n; [sub_resource type=\"DynamicFont\" id=2]\n; size = 100\n; outline_size = 5\n; outline_color = Color( 0, 0, 0, 1 )\n; use_mipmaps = true\n; use_filter = true\n; font_data = ExtResource( 8 )\n\n[sub_resource type=\"Animation\" id=3]\nresource_name = \"In\"\nlength = 0.2\ntracks/0/type = \"value\"\ntracks/0/path = NodePath(\"Main:rect_position\")\ntracks/0/interp = 1\ntracks/0/loop_wrap = true\ntracks/0/imported = false\ntracks/0/enabled = true\ntracks/0/keys = {\n\"times\": PoolRealArray( 0, 0.2 ),\n\"transitions\": PoolRealArray( 1, 0.329877 ),\n\"update\": 0,\n\"values\": [ Vector2( 1280, 0 ), Vector2( 0, 0 ) ]\n}\n"
  },
  {
    "path": "tests/inputs/Gencat-NLS.msg",
    "content": "$ Base file borrowed from $FreeBSD$\n$ freebsd/usr.bin/grep/nls/C.msg\n$ \n\n$set 1\n$quote \"\n1 \"(standard input)\"\n2 \"cannot read bzip2 compressed file\"\n3 \"unknown %s option\"\n4 \"usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]]\\n\"\n5 \"\\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\\n\"\n6 \"\\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\\n\"\n7 \"\\t[--null] [pattern] [file ...]\\n\"\n8 \"Binary file %s matches\\n\"\n9 \"%s (BSD grep) %s\\n\"\n10 \"cloc \\ but not a line continued\"\n11 \"cloc a line is continued\\\nuntil the bitter end\"\n12 \"cloc \\\\ but not a line continued\"\n$ cloc should give empty:1 comment:4 code:15\n"
  },
  {
    "path": "tests/inputs/Haskell.hs",
    "content": "-- from http://www.roesler-ac.de/wolfram/hello.htm\r\n-- Hello World in Haskell\r\n\r\nmodule Hello where\r\nhello::String\r\nhello = \"Hello World!\"\r\n"
  },
  {
    "path": "tests/inputs/Hello.lidr",
    "content": "http://docs.idris-lang.org/en/latest/tutorial/miscellany.html\n> module literate\n\nThis is a comment. The main program is below\n\n> main : IO ()\n> main = putStrLn \"Hello literate world!\\n\"\n"
  },
  {
    "path": "tests/inputs/HelpersView.axaml",
    "content": "﻿<!--\nhttps://github.com/kikipoulet/SukiUI/raw/b1d624b2472ebd9e442b4870e6e53b8852b86345/SukiUI.Demo/Features/Helpers/HelpersView.axaml\n -->\n<UserControl\n    d:DesignHeight=\"450\"\n    d:DesignWidth=\"800\"\n    mc:Ignorable=\"d\"\n    x:Class=\"SukiUI.Demo.Features.Helpers.HelpersView\"\n    x:DataType=\"helpers:HelpersViewModel\"\n    xmlns=\"https://github.com/avaloniaui\"\n    xmlns:X=\"clr-namespace:SukiUI.Helpers.ConditionalXAML;assembly=SukiUI\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:glassMorphism=\"clr-namespace:SukiUI.Controls.GlassMorphism;assembly=SukiUI\"\n    xmlns:helpers=\"clr-namespace:SukiUI.Demo.Features.Helpers\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:suki=\"https://github.com/kikipoulet/SukiUI\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">\n    <UserControl.Styles>\n        <Style Selector=\"suki|SukiSideMenu /template/ suki|GlassCard#Glass\">\n            <Setter Property=\"Opacity\" Value=\"0.75\" />\n        </Style>\n    </UserControl.Styles>\n    <suki:SukiSideMenu Margin=\"0\">\n        <suki:SukiSideMenu.Items>\n            <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Syntax Helpers\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon\n                        Data=\"{x:Static suki:Icons.ChevronRight}\"\n                        Foreground=\"{DynamicResource SukiLowText}\"\n                        Height=\"13\"\n                        HorizontalAlignment=\"Center\"\n                        VerticalAlignment=\"Center\"\n                        Width=\"13\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n\n                    <helpers:SyntaxHelpers />\n\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>\n\n\n            <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Easy Animations\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon\n                        Data=\"{x:Static suki:Icons.ChevronRight}\"\n                        Foreground=\"{DynamicResource SukiLowText}\"\n                        Height=\"13\"\n                        HorizontalAlignment=\"Center\"\n                        VerticalAlignment=\"Center\"\n                        Width=\"13\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n                    <ScrollViewer>\n                        <helpers:Easy_Animations />\n                    </ScrollViewer>\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>\n\n            <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Suki Easings\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon\n                        Data=\"{x:Static suki:Icons.ChevronRight}\"\n                        Foreground=\"{DynamicResource SukiLowText}\"\n                        Height=\"13\"\n                        HorizontalAlignment=\"Center\"\n                        VerticalAlignment=\"Center\"\n                        Width=\"13\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n                    <ScrollViewer>\n                        <helpers:CustomEasings />\n                    </ScrollViewer>\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>\n\n            <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Spring Easing\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon\n                        Data=\"{x:Static suki:Icons.ChevronRight}\"\n                        Foreground=\"{DynamicResource SukiLowText}\"\n                        Height=\"13\"\n                        HorizontalAlignment=\"Center\"\n                        VerticalAlignment=\"Center\"\n                        Width=\"13\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n                    <ScrollViewer>\n                        <helpers:SpringEasing />\n                    </ScrollViewer>\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>\n\n            <!-- <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Organic Move\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon Width=\"13\"\n                              Height=\"13\"\n                              HorizontalAlignment=\"Center\"\n                              VerticalAlignment=\"Center\"\n                              Data=\"{x:Static suki:Icons.ChevronRight}\"\n                              Foreground=\"{DynamicResource SukiLowText}\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n                    <ScrollViewer>\n                        <helpers:OrganicMove />\n                    </ScrollViewer>\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>-->\n\n            <suki:SukiSideMenuItem Classes=\"Compact\" Header=\"Squish Effect\">\n                <suki:SukiSideMenuItem.Icon>\n                    <PathIcon\n                        Data=\"{x:Static suki:Icons.ChevronRight}\"\n                        Foreground=\"{DynamicResource SukiLowText}\"\n                        Height=\"13\"\n                        HorizontalAlignment=\"Center\"\n                        VerticalAlignment=\"Center\"\n                        Width=\"13\" />\n\n                </suki:SukiSideMenuItem.Icon>\n                <suki:SukiSideMenuItem.PageContent>\n                    <ScrollViewer>\n                        <helpers:PullingEffect />\n                    </ScrollViewer>\n                </suki:SukiSideMenuItem.PageContent>\n            </suki:SukiSideMenuItem>\n\n            <!--  Other Pages  -->\n\n        </suki:SukiSideMenu.Items>\n\n\n        <suki:SukiSideMenu.HeaderContent>\n            <Panel />\n        </suki:SukiSideMenu.HeaderContent>\n\n        <suki:SukiSideMenu.FooterContent>\n            <Panel />\n        </suki:SukiSideMenu.FooterContent>\n    </suki:SukiSideMenu>\n</UserControl>\n"
  },
  {
    "path": "tests/inputs/IDL.idl",
    "content": "; Hello World in IDL (Interactive Data Language)\r\n; from http://www.roesler-ac.de/wolfram/hello.htm\r\nprint, \"Hello World\"\r\n"
  },
  {
    "path": "tests/inputs/ItemView.vue",
    "content": "<!-- https://github.com/vuejs/vue-hackernews/raw/gh-pages/src/components/ItemView.vue -->\n<template>\n  <div class=\"item-view\" v-show=\"item\">\n    <item :item=\"item\"></item>\n    <p class=\"itemtext\" v-if=\"hasText\" v-html=\"item.text\"></p>\n    <ul class=\"poll-options\" v-if=\"pollOptions\">\n      <li v-for=\"option in pollOptions\">\n        <p>{{option.text}}</p>\n        <p class=\"subtext\">{{option.score}} points</p>\n      </li>\n    </ul>\n    <ul class=\"comments\" v-if=\"comments\">\n      <comment\n        v-for=\"comment in comments\"\n        :comment=\"comment\">\n      </comment>\n    </ul>\n    <p v-show=\"!comments.length && !isJob\">No comments yet.</p>\n  </div>\n</template>\n\n<script>\nimport store from '../store'\nimport Item from './Item.vue'\nimport Comment from './Comment.vue'\n\nexport default {\n\n  name: 'ItemView',\n\n  components: {\n    Item,\n    Comment\n  },\n\n  data () {\n    return {\n      item: {},\n      comments: [],\n      pollOptions: null\n    }\n  },\n\n  route: {\n    data ({ to }) {\n      return store.fetchItem(to.params.id).then(item => {\n        document.title = item.title + ' | Vue.js HN Clone'\n        return {\n          item,\n          // the final resolved data can further contain Promises\n          comments: store.fetchItems(item.kids),\n          pollOptions: item.type === 'poll'\n            ? store.fetchItems(item.parts)\n            : null\n        }\n      })\n    }\n  },\n\n  computed: {\n    isJob () {\n      return this.item.type === 'job'\n    },\n\n    hasText () {\n      return this.item.hasOwnProperty('text')\n    }\n  }\n}\n</script>\n\n<style lang=\"stylus\">\n@import \"../variables.styl\"\n\n.item-view\n  .item\n    padding-left 0\n    margin-bottom 30px\n    .index\n      display none\n  .poll-options\n    margin-left 30px\n    margin-bottom 40px\n    li\n      margin 12px 0\n    p\n      margin 8px 0\n    .subtext\n      color $gray\n      font-size 11px\n  .itemtext\n    color $gray\n    margin-top 0\n    margin-bottom 30px\n  .itemtext p\n    margin 10px 0\n</style>\n"
  },
  {
    "path": "tests/inputs/Java.java",
    "content": "// from http://www.roesler-ac.de/wolfram/hello.htm\n// Hello World in Java\n\n// 2016-12-02:  additional code by https://github.com/filippucher1\n// to test /* within quoted string github issue #140\n\n@Controller\n@RequestMapping( \"/path/*\" )\npublic class ControllerClass {\n/** \n* javadoc\n* style\n*/\n\n/* block comment 1 - on one line */\n\n/* \n  block comment 2\n*/\n\n/* \n* block comment 3\n*/\n\nimport java.io.*;\nclass HelloWorld {\n  static public void main( String args[] ) {\n    System.out.println( \"Hello World!\" );\n  }\n}\n"
  },
  {
    "path": "tests/inputs/JetCar.cls",
    "content": "' https://github.com/badcodes/vb6.git NextPage/JetCar.cls\r\n\r\nVERSION 1.0 CLASS\r\nBEGIN\r\n  MultiUse = -1  'True\r\n  Persistable = 0  'NotPersistable\r\n  DataBindingBehavior = 0  'vbNone\r\n  DataSourceBehavior  = 0  'vbNone\r\n  MTSTransactionMode  = 0  'NotAnMTSObject\r\nEND\r\nAttribute VB_Name = \"JetCar\"\r\nAttribute VB_GlobalNameSpace = False\r\nAttribute VB_Creatable = True\r\nAttribute VB_PredeclaredId = False\r\nAttribute VB_Exposed = True\r\n\r\nOption Explicit\r\n\r\nPublic Sub AddUrlList(params)\r\nDim l As Long\r\nDim pCount As Long\r\n\r\nDim fTmp As String\r\n\r\nDo\r\nfTmp = BuildPath(Environ$(\"temp\"), \"NextPage.\" & Int(Rnd(Time) * 1000 + 1))\r\nLoop While PathExists(fTmp)\r\n\r\nIf PathExists(fTmp) Then Kill fTmp\r\n\r\nOpen fTmp For Output As #10\r\n\r\npCount = UBound(params)\r\n\r\nFor l = 0 To pCount\r\nPrint #10, params(l)\r\nNext\r\n\r\nClose #10\r\n\r\nShell BuildPath(App.Path, \"NextPage.exe\") & \" \" & fTmp, vbNormalFocus\r\n\r\n\r\n'JetCarCatch.AddUrlList params\r\nEnd Sub\r\n\r\nPublic Sub AddUrl(URL)\r\n\r\n\r\nDim fTmp As String\r\nDo\r\nfTmp = BuildPath(Environ$(\"temp\"), \"NextPage.\" & Int(Rnd(Time) * 1000 + 1))\r\nLoop While PathExists(fTmp)\r\nIf PathExists(fTmp) Then Kill fTmp\r\n\r\nOpen fTmp For Output As #10\r\nPrint #10, URL\r\nClose #10\r\n\r\nShell BuildPath(App.Path, \"NextPage.exe\") & \" \" & fTmp, vbNormalFocus\r\n\r\nEnd Sub\r\n"
  },
  {
    "path": "tests/inputs/LaTeX.tex",
    "content": "% ftp://tug.ctan.org/tex-archive/macros/latex/base/sample2e.tex\n% This is a sample LaTeX input file.  (Version of 12 August 2004.)\n%\n% A '%' character causes TeX to ignore all remaining text on the line,\n% and is used for comments like this one.\n\n\\documentclass{article}      % Specifies the document class\n\n                             % The preamble begins here.\n\\title{An Example Document}  % Declares the document's title.\n\\author{Leslie Lamport}      % Declares the author's name.\n\\date{January 21, 1994}      % Deleting this command produces today's date.\n\n\\newcommand{\\ip}[2]{(#1, #2)}\n                             % Defines \\ip{arg1}{arg2} to mean\n                             % (arg1, arg2).\n\n%\\newcommand{\\ip}[2]{\\langle #1 | #2\\rangle}\n                             % This is an alternative definition of\n                             % \\ip that is commented out.\n\n\\begin{document}             % End of preamble and beginning of text.\n\n\\maketitle                   % Produces the title.\n\nThis is an example input file.  Comparing it with\nthe output it generates can show you how to\nproduce a simple document of your own.\n\n\\section{Ordinary Text}      % Produces section heading.  Lower-level\n                             % sections are begun with similar \n                             % \\subsection and \\subsubsection commands.\n\nThe ends  of words and sentences are marked \n  by   spaces. It  doesn't matter how many \nspaces    you type; one is as good as 100.  The\nend of   a line counts as a space.\n\nOne   or more   blank lines denote the  end \nof  a paragraph.  \n\nSince any number of consecutive spaces are treated\nlike a single one, the formatting of the input\nfile makes no difference to\n      \\LaTeX,                % The \\LaTeX command generates the LaTeX logo.\nbut it makes a difference to you.  When you use\n\\LaTeX, making your input file as easy to read \nas possible will be a great help as you write \nyour document and when you change it.  This sample \nfile shows how you can add comments to your own input \nfile.\n\nBecause printing is different from typewriting,\nthere are a number of things that you have to do\ndifferently when preparing an input file than if\nyou were just typing the document directly.\nQuotation marks like\n       ``this'' \nhave to be handled specially, as do quotes within\nquotes:\n       ``\\,`this'            % \\, separates the double and single quote.\n        is what I just \n        wrote, not  `that'\\,''.  \n\nDashes come in three sizes: an \n       intra-word \ndash, a medium dash for number ranges like \n       1--2, \nand a punctuation \n       dash---like \nthis.\n\nA sentence-ending space should be larger than the\nspace between words within a sentence.  You\nsometimes have to type special commands in\nconjunction with punctuation characters to get\nthis right, as in the following sentence.\n       Gnats, gnus, etc.\\ all  % `\\ ' makes an inter-word space.\n       begin with G\\@.         % \\@ marks end-of-sentence punctuation.\nYou should check the spaces after periods when\nreading your output to make sure you haven't\nforgotten any special cases.  Generating an\nellipsis\n       \\ldots\\               % `\\ ' is needed after `\\ldots' because TeX \n                             % ignores spaces after command names like \\ldots \n                             % made from \\ + letters.\n                             %\n                             % Note how a `%' character causes TeX to ignore \n                             % the end of the input line, so these blank lines \n                             % do not start a new paragraph.\n                             %\nwith the right spacing around the periods requires\na special command.\n\n\\LaTeX\\ interprets some common characters as\ncommands, so you must type special commands to\ngenerate them.  These characters include the\nfollowing:\n       \\$ \\& \\% \\# \\{ and \\}.\n\nIn printing, text is usually emphasized with an\n       \\emph{italic}  \ntype style.  \n\n\\begin{em}\n   A long segment of text can also be emphasized \n   in this way.  Text within such a segment can be \n   given \\emph{additional} emphasis.\n\\end{em}\n\nIt is sometimes necessary to prevent \\LaTeX\\ from\nbreaking a line where it might otherwise do so.\nThis may be at a space, as between the ``Mr.''\\ and\n``Jones'' in\n       ``Mr.~Jones'',        % ~ produces an unbreakable interword space.\nor within a word---especially when the word is a\nsymbol like\n       \\mbox{\\emph{itemnum}} \nthat makes little sense when hyphenated across\nlines.\n\nFootnotes\\footnote{This is an example of a footnote.}\npose no problem.\n\n\\LaTeX\\ is good at typesetting mathematical formulas\nlike\n       \\( x-3y + z = 7 \\) \nor\n       \\( a_{1} > x^{2n} + y^{2n} > x' \\)\nor  \n       \\( \\ip{A}{B} = \\sum_{i} a_{i} b_{i} \\).\nThe spaces you type in a formula are \nignored.  Remember that a letter like\n       $x$                   % $ ... $  and  \\( ... \\)  are equivalent\nis a formula when it denotes a mathematical\nsymbol, and it should be typed as one.\n\n\\section{Displayed Text}\n\nText is displayed by indenting it from the left\nmargin.  Quotations are commonly displayed.  There\nare short quotations\n\\begin{quote}\n   This is a short quotation.  It consists of a \n   single paragraph of text.  See how it is formatted.\n\\end{quote}\nand longer ones.\n\\begin{quotation}\n   This is a longer quotation.  It consists of two\n   paragraphs of text, neither of which are\n   particularly interesting.\n\n   This is the second paragraph of the quotation.  It\n   is just as dull as the first paragraph.\n\\end{quotation}\nAnother frequently-displayed structure is a list.\nThe following is an example of an \\emph{itemized}\nlist.\n\\begin{itemize}\n   \\item This is the first item of an itemized list.\n         Each item in the list is marked with a ``tick''.\n         You don't have to worry about what kind of tick\n         mark is used.\n\n   \\item This is the second item of the list.  It\n         contains another list nested inside it.  The inner\n         list is an \\emph{enumerated} list.\n         \\begin{enumerate}\n            \\item This is the first item of an enumerated \n                  list that is nested within the itemized list.\n\n            \\item This is the second item of the inner list.  \n                  \\LaTeX\\ allows you to nest lists deeper than \n                  you really should.\n         \\end{enumerate}\n         This is the rest of the second item of the outer\n         list.  It is no more interesting than any other\n         part of the item.\n   \\item This is the third item of the list.\n\\end{itemize}\nYou can even display poetry.\n\\begin{verse}\n   There is an environment \n    for verse \\\\             % The \\\\ command separates lines\n   Whose features some poets % within a stanza.\n   will curse.   \n\n                             % One or more blank lines separate stanzas.\n\n   For instead of making\\\\\n   Them do \\emph{all} line breaking, \\\\\n   It allows them to put too many words on a line when they'd rather be \n   forced to be terse.\n\\end{verse}\n\nMathematical formulas may also be displayed.  A\ndisplayed formula \nis \none-line long; multiline\nformulas require special formatting instructions.\n   \\[  \\ip{\\Gamma}{\\psi'} = x'' + y^{2} + z_{i}^{n}\\]\nDon't start a paragraph with a displayed equation,\nnor make one a paragraph by itself.\n\n\\end{document}               % End of document.\n"
  },
  {
    "path": "tests/inputs/Lanczos.m",
    "content": "function [phiKM, AscendingLambda] = Lanczos(K, M, sigma, Jmax)\n[rows,cols] = size(K);                                                       \nif (rows ~= cols)                                                       \n  fprintf('Lanczos needs square matrices');                \nend                                                       \nZ       = K - sigma*M;                               % initialize some\nQ       = zeros(rows,Jmax+1);                        % variables\nT       = zeros(Jmax,Jmax);                          %\nrRand   = randn(rows,1);                             %\nrOld = rRand;\nbetaOld = sqrt(rOld'*M*rOld);                        %\nfor j = 1:Jmax,                                      %\n  Q(:,j+1) = rOld/betaOld;                           %\n  u = Z \\ (M*Q(:,j+1) - Z*Q(:,j)*betaOld);           % D.S.Scott's formulation\n  alpha = Q(:,j+1)'*M*u;                             % of the recurrence\n  r     = u - alpha*Q(:,j+1);                        %\n  for i=1:3,                                         %\n    sum = zeros(rows,1);                             % repeat a full orhto-\n    for k=2:j+1,                                     % gonalization three\n      sum = sum + (Q(:,k)'*M*r)*Q(:,k);              % times to ensure\n    end;                                             % high quality\n    r = r - sum;                                     % solutions\n  end;                                               %\n  beta = sqrt(r'*M*r);                               %\n  T(j,j)   = alpha;                                  %\n  if (j ~= Jmax)                                     % augment [T] with new\n    T(j+1,j) = beta;                                 % alpha_i, beta_i+1\n    T(j,j+1) = beta;                                 %\n  end;                                               %\n  Jactual = j;                                       %\n  if (abs(beta) < 1.0e-12)                           % singular beta; going\n    break                                            % any more will introduce\n  end                                                % spurious modes\n  betaOld = beta;                                    %\n  rOld    = r;                                       %\nend                                                  %\n[phiT,lambdaT] = eig(T(1:Jactual,1:Jactual));        % solve [T]{y} = L{y}\nlambdaKM   = zeros(Jactual,1);                       %\nfor j = 1:Jactual,                                   % invert and shift the\n  lambdaKM(j) = sigma + 1/lambdaT(j,j);              % eigenvalues to the\nend                                                  % user's domain\n[AscendingLambda, ordering] = sort(lambdaKM);        %\nphiKM      = zeros(rows,Jactual);                    % sort the eigenvalues\nUnOrdphiKM = zeros(rows,Jactual);                    % in ascending order\nUnOrdphiKM = Q(:,2:Jactual+1)*phiT;                  %\nfor j = 1:Jactual,                                   % resequence the e-vectors\n  phiKM(:,j) = UnOrdphiKM(:,ordering(j));            % to correspond to the\nend                                                  % e-values\n"
  },
  {
    "path": "tests/inputs/LogMain.re",
    "content": "/* LogMain.re */\n/*\n * Example from http://2ality.com/2017/12/modules-reasonml.html\n */\n\nlet () = Log.make()\n  |> Log.logStr(\" /* Hello\")  /* another comment */\n  |> Log.logStr(\"everyone\")\n  |> Log.print;\n\n/* Output:\nHello\neveryone\n*/\n"
  },
  {
    "path": "tests/inputs/Lookup.agda",
    "content": "{- \nhttps://raw.githubusercontent.com/agda/agda/master/examples/Lookup.agda\n -}\nmodule Lookup where\n\ndata Bool : Set where\n  false : Bool\n  true  : Bool\n\ndata IsTrue : Bool -> Set where\n  isTrue : IsTrue true\n\ndata List (A : Set) : Set where\n  []   : List A\n  _::_ : A -> List A -> List A\n\ndata _×_ (A B : Set) : Set where\n  _,_ : A -> B -> A × B\n\nmodule Map {- comment -}\n  (Key  : Set)\n  (_==_ : Key -> Key -> Bool)\n  (Code : Set)\n  (Val  : Code -> Set) where\n\n  infixr 40 _⟼_,_\n  infix  20 _∈_\n\n  data Map : List Code -> Set where\n    ε     : Map []\n    _⟼_,_ : forall {c cs} ->\n            Key -> Val c -> Map cs -> Map (c :: cs)\n\n  _∈_ : forall {cs} -> Key -> Map cs -> Bool\n  k ∈ ε            = false\n  k ∈ (k' ⟼ _ , m) with k == k'\n  ...              | true  = true\n  ...              | false = k ∈ m\n\n  Lookup : forall {cs} -> (k : Key)(m : Map cs) -> IsTrue (k ∈ m) -> Set\n  Lookup k ε ()\n  Lookup k (_⟼_,_ {c} k' _ m) p with k == k'\n  ... | true  = Val c\n  ... | false = Lookup k m p\n\n  lookup : {cs : List Code}(k : Key)(m : Map cs)(p : IsTrue (k ∈ m)) ->\n           Lookup k m p\n  lookup k ε ()\n  lookup k (k' ⟼ v , m) p with k == k'\n  ... | true  = v\n  ... | false = lookup k m p\n"
  },
  {
    "path": "tests/inputs/MSDOS.bat",
    "content": "REM from http://www.roesler-ac.de/wolfram/hello.htm\n@ECHO OFF\nREM Hello World for DOS batch\n\nECHO Hello World!\n"
  },
  {
    "path": "tests/inputs/Makefile",
    "content": "############################################################################\n#\n#  Program:         ARPACK\n#\n#  Module:          Makefile\n#\n#  Purpose:         Sources Makefile\n#\n#  Creation date:   February 22, 1996\n#\n#  Modified:a       September 9, 1996\n#\n#  Send bug reports, comments or suggestions to arpack.caam.rice.edu\n#\n############################################################################\n#\\SCCS Information: @(#) \n# FILE: Makefile   SID: 2.2   DATE OF SID: 9/24/96   RELEASE: 2\n \ninclude ../ARmake.inc\n \n############################################################################\n#  To create or add to the library, enter make followed by one or\n#  more of the precisions desired.  Targets sdrv, ddrv, cdrv,\n#  zdrv are used to add to the library LAPACK routines needed by driver\n#  programs in the EXAMPLES directory.\n#\n#  Some examples:\n#       make single\n#       make single sdrv\n#       make single complex\n#       make single double complex complex16\n#  Alternatively, the command\n#       make\n#  without any arguments creates a library of all four precisions.\n#  The library also contains all extra BLAS routines used by driver\n#  programs in the EXAMPLES directory.\n#\n#  The name of the library is defined by $(ARPACKLIB) in\n#  ../ARmake.inc and is created at the next higher directory level.\n#\n#\nSOBJ  = sgeqr2.o slabad.o slacon.o slacpy.o sladiv.o slae2.o slaev2.o\\\n        slaexc.o slagtm.o slahqr.o slaln2.o slamch.o slange.o slanhs.o\\\n        slanst.o slanv2.o slaptm.o slapy2.o slapy3.o slaran.o slarf.o\\\n        slarfg.o slarfx.o slarnd.o slarnv.o slartg.o slaruv.o slascl.o\\\n        slaset.o slasr.o  slasrt.o slassq.o slasy2.o sorm2r.o ssteqr.o\\\n        strevc.o strexc.o strsen.o strsyl.o\n\nDOBJ  = dgeqr2.o dlabad.o dlacon.o dlacpy.o dladiv.o dlae2.o dlaev2.o\\\n        dlaexc.o dlagtm.o dlahqr.o dlaln2.o dlamch.o dlange.o dlanhs.o\\\n        dlanst.o dlanv2.o dlaptm.o dlapy2.o dlapy3.o dlaran.o dlarf.o\\\n        dlarfg.o dlarfx.o dlarnd.o dlarnv.o dlartg.o dlaruv.o dlascl.o\\\n        dlaset.o dlasr.o  dlasrt.o dlassq.o dlasy2.o dorm2r.o dsteqr.o\\\n        dtrevc.o dtrexc.o dtrsen.o dtrsyl.o\n\nIOBJ  = ilaenv.o lsame.o lsamen.o xerbla.o xlaenv.o\n\nCIOBJ = icmax1.o \n\nZIOBJ = izmax1.o\n\nCOBJ  = cgeqr2.o clacon.o clacpy.o cladiv.o clahqr.o clange.o clanhs.o\\\n        clarf.o  clarfg.o clarnv.o clartg.o clascl.o claset.o classq.o\\\n        clatrs.o cmach.o  crot.o   ctrevc.o ctrexc.o ctrsen.o ctrsyl.o\\\n        cunm2r.o\\\n        scsum1.o slabad.o sladiv.o slamch.o slapy2.o slapy3.o slaruv.o\n\nZOBJ  = zgeqr2.o zlacon.o zlacpy.o zladiv.o zlahqr.o zlange.o zlanhs.o\\\n        zlarf.o  zlarfg.o zlarnv.o zlartg.o zlascl.o zlaset.o zlassq.o\\\n        zlatrs.o zmach.o  zrot.o   ztrevc.o ztrexc.o ztrsen.o ztrsyl.o\\\n        zunm2r.o\\\n        dzsum1.o dlabad.o dladiv.o dlamch.o dlapy2.o dlapy3.o dlaruv.o\n#\n# The following LAPACK routines are not needed by ARPACK\n# source code.  They are used by the drivers in EXAMPLES\n# directory.\n#\nSDRVOBJ = sgbtf2.o sgbtrf.o sgbtrs.o sgttrf.o sgttrs.o spttrf.o spttrs.o\\\n          slaswp.o  \n\nDDRVOBJ = dgbtf2.o dgbtrf.o dgbtrs.o dgttrf.o dgttrs.o dpttrf.o dpttrs.o\\\n          dlaswp.o\n\nCDRVOBJ = cgbtf2.o cgbtrf.o cgbtrs.o cgttrf.o cgttrs.o claswp.o clacgv.o\n\nZDRVOBJ = zgbtrf.o zgbtrs.o zgbtf2.o zgttrf.o zgttrs.o zlaswp.o zlacgv.o\n\n.SUFFIXES:      .o .F .f\n\n.f.o:\n\t$(FC) $(FFLAGS) -c $<\n\nall: single double complex complex16 sdrv ddrv cdrv zdrv\n \nsingle: $(SOBJ) $(IOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(SOBJ) $(IOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n \ndouble: $(DOBJ) $(IOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(DOBJ) $(IOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\ncomplex: $(COBJ) $(CIOBJ) $(IOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(COBJ) $(CIOBJ) $(IOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\ncomplex16: $(ZOBJ) $(ZIOBJ) $(IOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(ZOBJ) $(ZIOBJ) $(IOBJ)\n\t$(RANLIB) $(ARPACKLIB) \n#\n# Add routines needed by driver programs (in the EXAMPLES\n# directory) to $(ARPACKLIB).\n#\nsdrv: $(SDRVOBJ) $(CDRVOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(SDRVOBJ) $(CDRVOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\nddrv: $(DDRVOBJ) $(ZDRVOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(DDRVOBJ) $(ZDRVOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\ncdrv: $(CDRVOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(CDRVOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\nzdrv: $(ZDRVOBJ)\n\t$(AR) $(ARFLAGS) $(ARPACKLIB) $(ZDRVOBJ)\n\t$(RANLIB) $(ARPACKLIB)\n\n#  clean\t- remove all object files\n#\nclean:\n\trm -f *.o a.out core\n"
  },
  {
    "path": "tests/inputs/Mako.mako",
    "content": "## This is the test file for mako extenstion\n## As Mako can be used as a template to render almost any other\n## language we only count mako comments as comments.\n\n<ol>\n% for x in range(10):\n    <!-- This is a HTML comment but will be counted -->\n    <li>${strong(x)}</li>\n% endfor\n</ol>\n\n<%def name=\"strong(x)\">\n  <strong>${x}</strong>\n</%def>\n\n## Result:\n## Lines: 20\n## Code: 9\n## Comment: 8\n## Blank: 3\n"
  },
  {
    "path": "tests/inputs/Mathematica_1.m",
    "content": "(* http://spot.colorado.edu/~sitelic/samplecode/mathematica/imagesfile.html\n *)\n\nimage = Import[\"denise.png\",\"PNG\"]   (* or *)\n\nimage = Import[\"denise.gif\",\"GIF\"]\n\nA = image[[1,1]]/255.;\nListDensityPlot[A,Mesh->False, AspectRatio->Automatic]\n\n(*\n        -- or -- \n *)\n\nShow[Graphics[Raster[A]], AspectRatio->Automatic]\n\n\nblurA = ListConvolve[Table[1/25,{5},{5}],A];\n\nShow[Graphics[Raster[blurA]], AspectRatio->Automatic]\nB = Fourier[A];\n\n(*\n          delete\n    higher frequencies *)\n\nB[[Range[30,278],All]]=0;\n\nB[[All,Range[30,202]]]=0;\n\nShow[Graphics[Raster[ Re[InverseFourier[B]] ]], AspectRatio->Automatic]\n"
  },
  {
    "path": "tests/inputs/Mathematica_2.wlt",
    "content": "(* \n    http://spot.colorado.edu/~sitelic/samplecode/mathematica/imagesfile.html\n *)\n\nimage = Import[\"denise.png\",\"PNG\"]   (* or *)\n\nimage = Import[\"denise.gif\",\"GIF\"]\n\nA = image[[1,1]]/255.;\nListDensityPlot[A,Mesh->False, AspectRatio->Automatic]\n\n(*\n        -- or -- \n *)\n\nShow[Graphics[Raster[A]], AspectRatio->Automatic]\n\n\nblurA = ListConvolve[Table[1/25,{5},{5}],A];\n\nShow[Graphics[Raster[blurA]], AspectRatio->Automatic]\nB = Fourier[A];\n\n(*\n          delete\n    higher frequencies *)\n\nB[[Range[30,278],All]]=0;\n\nB[[All,Range[30,202]]]=0;\n\nShow[Graphics[Raster[ Re[InverseFourier[B]] ]], AspectRatio->Automatic]\n"
  },
  {
    "path": "tests/inputs/Mojo.mojom",
    "content": "// Mojo files usually start with a multiline comment and/or copyright\n// statement.  They are otherwise quite close to C++ files.\n\nmodule example_service.mojom;\n\nimport \"mojo/public/mojom/base/time.mojom\";\nimport \"some/other/project/base.mojom\";\n\nenum BasicEnum {\n  kField1,\n  kField2,\n};\n\nstruct BasicStruct {\n  // Comment about a field.\n  mojo_base.mojom.TimeDelta duration;\n};\n\n[annotation]\ninterface ExampleInterface {\n  // Returns a thing from a place using its arguments.\n  DecodeInput(array<uint8> input_data, BasicEnum value, bool flag,\n              int64 size_of_the_thing)\n      => (BasicStruct? result_maybe);\n\n  Frobnicate(map<StringPair, map<int32, array<map<string, string>?>?>?> ridiculous) => (array<unit64, 2> guid);\n};\n"
  },
  {
    "path": "tests/inputs/Mumps.mps",
    "content": "; from http://www.roesler-ac.de/wolfram/hello.htm\r\n; Hello World in Mumps-M\r\n w !,\"Hello World\"\r\n"
  },
  {
    "path": "tests/inputs/Octave.m",
    "content": "% from http://www.roesler-ac.de/wolfram/hello.htm\r\n#Hello World in Octave (http://www.octave.org/)\r\nprintf(\"Hello World\\n\");\r\n"
  },
  {
    "path": "tests/inputs/Once.HC",
    "content": "/*\nhttps://raw.githubusercontent.com/cia-foundation/TempleOS/archive/Once.HC\n*/\n//Place this file in /Home and change\n//anything you want.\n\n//This file is executed by the\n//first terminal window upon start-up.\n//See $LK,\"Once\",A=\"FF:~/HomeSys.HC,Once\"$ and $LK,\"Home Files\",A=\"FF:::/Doc/GuideLines.DD,/Home Files\"$.\n\n//Delete the rest from this file.\n\nU0 Tmp()\n{\n  OnceExe;\n  switch (sys_boot_src.u16[0]) {\n    case BOOT_SRC_ROM:\n      \"Continue booting hard drive \";\n      if (YorN) {\n\tDocBottom;\n\tExeFile(\"C:/Home/Once\");\n      }\n      break;\n    case BOOT_SRC_DVD:\n      \"\\nIf you answer 'No' you can play with\\n\"\n\t    \"the live CD without installing.\\n\\n\"\n\t    \"Install onto hard drive \";\n      if (YorN) {\n\tDocBottom;\n\tRunFile(\"::/Misc/OSInstall\",,TRUE);\n      }\n      if (FileFind(\"::/Misc/Tour\")) {\n\t\"\\nTake Tour\";\n\tif (YorN) {\n\t  DocBottom;\n\t  Cd(\"::/Misc/Tour\");\n\t  InFile(\"Tour\");\n\t}\n      }\n      break;\n/*  case BOOT_SRC_RAM:\n    case BOOT_SRC_HARDDRV:\n      \"$$PURPLE$$$$TX+CX,\\\"Tip of the Day\\\"$$$$FG$$\\n\";\n      TipOfDay;\n      Type(\"::/Doc/Customize.DD\");\n      if */ (FileFind(\"::/Misc/Tour\")) {\n\t\"\\nTake Tour\";\n\tif (YorN) {\n\t  DocBottom;\n\t  Cd(\"::/Misc/Tour\");\n\t  InFile(\"Tour\");\n\t}\n      }\n      break;\n  }\n}\n\nTmp;\n"
  },
  {
    "path": "tests/inputs/Pascal.p",
    "content": "(* from http://www.roesler-ac.de/wolfram/hello.htm *)\n{Hello World in Pascal}\n\nprogram HelloWorld(output);\nbegin\n  WriteLn('Hello World!');\nend.\n"
  },
  {
    "path": "tests/inputs/Pascal.pas",
    "content": "(* from http://www.roesler-ac.de/wolfram/hello.htm *)\n{Hello World in Pascal}\n\nprogram HelloWorld(output);\nbegin\n  WriteLn('Hello World!');\nend.\n"
  },
  {
    "path": "tests/inputs/Pascal.pp",
    "content": "(* from http://www.roesler-ac.de/wolfram/hello.htm *)\n{Hello World in Pascal}\n{! compiler directive, not a comment}\n\nprogram HelloWorld(output);\nbegin \n  WriteLn('Hello World!');  (*\n  *)\nend.\n"
  },
  {
    "path": "tests/inputs/PlusCalExample.tla",
    "content": "---- MODULE PlusCalExample ----\n(* TLA+/PlusCal example program. *)\n(* Multi-line\n   (* nested *)\n   comment *)\n\\* Single-line comment\n\n\\* The code below appears to be a TLA+ comment but is PlusCal code which should\n\\* always be line-counted.\n\\* Grammar rules for PlusCal are specified in appendices A and C of A PlusCal\n\\* User's Manual: https://lamport.azurewebsites.net/tla/c-manual.pdf\n(*\nPlusCal options (-sf)\n--algorithm Example {\n  process (A = 0) {\n    Start: skip;\n  }\n}\nThis is a comment line.\n*)\n\n\\* The code between BEGIN( )TRANSLATION and END( )TRANSLATION should be\n\\* line-counted as generated code.\n\\* BEGIN TRANSLATION (chksum(pcal) = \"7bf2389f\" /\\ chksum(tla) = \"dd78b4d4\")\nVARIABLE pc\n\nvars == << pc >>\n\nProcSet == {0}\n\nInit == /\\ pc = [self \\in ProcSet |-> \"Start\"]\n\nStart == /\\ pc[0] = \"Start\"\n         /\\ TRUE\n         /\\ pc' = [pc EXCEPT ![0] = \"Done\"]\n\nA == Start\n\n(* Allow infinite stuttering to prevent deadlock on termination. *)\nTerminating == /\\ \\A self \\in ProcSet: pc[self] = \"Done\"\n               /\\ UNCHANGED vars\n\nNext == A\n           \\/ Terminating\n\nSpec == /\\ Init /\\ [][Next]_vars\n        /\\ SF_vars(A)\n\nTermination == <>(\\A self \\in ProcSet: pc[self] = \"Done\")\n\n\\* END TRANSLATION\n\n====\n"
  },
  {
    "path": "tests/inputs/Prelude.dhall",
    "content": "{- https://github.com/dhall-lang/dhall-nethack/raw/master/Prelude.dhall\n   This file provides a central `Prelude` import for the rest of the library to\n   use so that the integrity check only needs to be updated in one place\n   whenever upgrading the interpreter.\n\n   This allows the user to provide their own Prelude import using the\n   `DHALL_PRELUDE` environment variable, like this:\n\n   ```\n   $ export DHALL_PRELUDE='https://prelude.dhall-lang.org/package.dhall sha256:...'\n   ```\n\n   Note that overriding the Prelude in this way only works if this repository\n   is imported locally.  Remote imports do not have access to environment\n   variables and any attempt to import one will fall back to the next available\n   import.  To learn more, read:\n\n   * https://github.com/dhall-lang/dhall-lang/wiki/Safety-guarantees#cross-site-scripting-xss\n\n   This file also provides an import without the integrity check as a slower\n   fallback if the user is using a different version of the Dhall interpreter.\n-}\n\n  env:DHALL_PRELUDE\n? https://raw.githubusercontent.com/dhall-lang/dhall-lang/v8.0.0/Prelude/package.dhall sha256:0c04cbe34f1f2d408e8c8b8cb0aa3ff4d5656336910f7e86190a6d14326f966d\n? https://raw.githubusercontent.com/dhall-lang/dhall-lang/v8.0.0/Prelude/package.dhall\n"
  },
  {
    "path": "tests/inputs/ProcessPO.odx",
    "content": "﻿#if __DESIGNER_DATA\n#error Do not define __DESIGNER_DATA.\n<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<om:MetaModel MajorVersion=\"1\" MinorVersion=\"3\" Core=\"2b131234-7959-458d-834f-2dc0769ce683\" ScheduleModel=\"66366196-361d-448d-976f-cab5e87496d2\" xmlns:om=\"http://schemas.microsoft.com/BizTalk/2003/DesignerData\">\n    <om:Element Type=\"Module\" OID=\"ea5a519c-7132-4909-a82e-52fcc2c7f48d\" LowerBound=\"1.1\" HigherBound=\"42.1\">\n        <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n        <om:Property Name=\"Name\" Value=\"BTSJSON\" />\n        <om:Property Name=\"Signal\" Value=\"False\" />\n        <om:Element Type=\"PortType\" OID=\"30bf9479-f8dc-4f4e-a1d1-267e27f14bac\" ParentLink=\"Module_PortType\" LowerBound=\"4.1\" HigherBound=\"11.1\">\n            <om:Property Name=\"Synchronous\" Value=\"False\" />\n            <om:Property Name=\"TypeModifier\" Value=\"Internal\" />\n            <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n            <om:Property Name=\"Name\" Value=\"PortType_1\" />\n            <om:Property Name=\"Signal\" Value=\"False\" />\n            <om:Element Type=\"OperationDeclaration\" OID=\"9c523d5a-3294-42a6-88f3-4ae49ae83db0\" ParentLink=\"PortType_OperationDeclaration\" LowerBound=\"6.1\" HigherBound=\"10.1\">\n                <om:Property Name=\"OperationType\" Value=\"OneWay\" />\n                <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n                <om:Property Name=\"Name\" Value=\"Operation_1\" />\n                <om:Property Name=\"Signal\" Value=\"False\" />\n                <om:Element Type=\"MessageRef\" OID=\"5b477a6e-462a-4c09-a6bd-9e9b26ae5ad1\" ParentLink=\"OperationDeclaration_RequestMessageRef\" LowerBound=\"8.13\" HigherBound=\"8.15\">\n                    <om:Property Name=\"Ref\" Value=\"BTSJSON.PO\" />\n                    <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n                    <om:Property Name=\"Name\" Value=\"Request\" />\n                    <om:Property Name=\"Signal\" Value=\"False\" />\n                </om:Element>\n            </om:Element>\n        </om:Element>\n        <om:Element Type=\"ServiceDeclaration\" OID=\"e74dc54e-2016-4417-a28b-4c3e45dff411\" ParentLink=\"Module_ServiceDeclaration\" LowerBound=\"18.1\" HigherBound=\"41.1\">\n            <om:Property Name=\"InitializedTransactionType\" Value=\"False\" />\n            <om:Property Name=\"IsInvokable\" Value=\"False\" />\n            <om:Property Name=\"TypeModifier\" Value=\"Internal\" />\n            <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n            <om:Property Name=\"Name\" Value=\"ProcessPO\" />\n            <om:Property Name=\"Signal\" Value=\"False\" />\n            <om:Element Type=\"MessageDeclaration\" OID=\"f706cdf4-1710-4dc4-a4b6-6004486cda37\" ParentLink=\"ServiceDeclaration_MessageDeclaration\" LowerBound=\"25.1\" HigherBound=\"26.1\">\n                <om:Property Name=\"Type\" Value=\"BTSJSON.PO\" />\n                <om:Property Name=\"ParamDirection\" Value=\"In\" />\n                <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n                <om:Property Name=\"Name\" Value=\"PurchaseOrder\" />\n                <om:Property Name=\"Signal\" Value=\"True\" />\n            </om:Element>\n            <om:Element Type=\"MessageDeclaration\" OID=\"b4715502-31b6-45fe-b7fc-820880b05a6b\" ParentLink=\"ServiceDeclaration_MessageDeclaration\" LowerBound=\"26.1\" HigherBound=\"27.1\">\n                <om:Property Name=\"Type\" Value=\"BTSJSON.Invoice\" />\n                <om:Property Name=\"ParamDirection\" Value=\"In\" />\n                <om:Property Name=\"ReportToAnalyst\" Value=\"True\" />\n                <om:Property Name=\"Name\" Value=\"InvoiceMsg\" />\n                <om:Property Name=\"Signal\" Value=\"True\" />\n            </om:Element>\n        </om:Element>\n    </om:Element>\n</om:MetaModel>\n#endif // __DESIGNER_DATA\n[Microsoft.XLANGs.BaseTypes.BPELExportable(false)]\nmodule BTSJSON\n{\n    internal porttype PortType_1\n    {\n        oneway Operation_1\n        {\n            PO\n        };\n    };\n    internal porttype PortType_2\n    {\n        oneway Operation_1\n        {\n            Invoice\n        };\n    };\n    [Microsoft.XLANGs.BaseTypes.BPELExportable(false)]\n    internal service ProcessPO\n    {\n        [Microsoft.XLANGs.BaseTypes.LogicalBinding()]\n        port implements PortType_1 ReceiveJSONPO;\n        [Microsoft.XLANGs.BaseTypes.LogicalBinding()]\n        port uses PortType_2 SendJSONInvoice;\n        message PO PurchaseOrder;\n        message Invoice InvoiceMsg;\n        body ()\n        {\n            [Microsoft.XLANGs.BaseTypes.DesignerPosition(\"d478ac91-37ac-418c-b2c8-2f778319667c\")]\n            activate receive (ReceiveJSONPO.Operation_1, PurchaseOrder);\n            [Microsoft.XLANGs.BaseTypes.DesignerPosition(\"959a30c2-92c8-47d1-8df6-7243e961bb23\")]\n            construct InvoiceMsg\n            {\n                [Microsoft.XLANGs.BaseTypes.DesignerPosition(\"ac70f963-dad1-4533-85c1-e8ecd4117659\")]\n                transform (InvoiceMsg) = BTSJSON.POToInvoice (PurchaseOrder);\n            }\n            [Microsoft.XLANGs.BaseTypes.DesignerPosition(\"61187953-153a-45c9-bc90-b537e4765026\")]\n            send (SendJSONInvoice.Operation_1, InvoiceMsg);\n        }\n    }\n}\n\n"
  },
  {
    "path": "tests/inputs/RedBlackTree.res",
    "content": "// a portion of https://github.com/github/linguist/raw/master/samples/ReScript/RedBlackTree.res\n\n/*\nCredit to Wikipedia's article on [Red-black\ntree](http://en.wikipedia.org/wiki/Red–black_tree)\n\n**Note:** doesn't handle duplicate entries. This is by design.\n\n## Overview example:\n\n```\nvar rbt = new RedBlackTree([7, 5, 1, 8])\nrbt.add(2) // => 2\nrbt.add(10) // => 10\nrbt.has(5) // => true\nrbt.remove(8) // => 8\n```\n\n## Properties:\n\n- size: The total number of items.\n*/\n\ntype nodeColor =\n  | Red\n  | Black\n\n/*\nProperty of a red-black tree, taken from Wikipedia:\n1. A node is either red or black.\n2. Root is black.\n3. Leaves are all null and considered black.\n4. Both children of a red node are black.\n5. Every path from a node to any of its descendent leaves contains the same\nnumber of black nodes.\n*/\n\ntype rec node<'value> = {\n  mutable left: option<node<'value>>,\n  mutable right: option<node<'value>>,\n  mutable parent: option<node<'value>>,\n  mutable sum: float,\n  mutable color : nodeColor,\n  mutable height: float,\n  mutable value: 'value,\n}\n\ntype t<'value> = {\n  mutable size: int,\n  mutable root: option<node<'value>>,\n  compare: (. 'value, 'value) => int,\n}\n\nlet createNode = (~color, ~value, ~height) =>\n  {left:None, right:None, parent:None, sum:0., height, value, color}\n\nexternal castNotOption: option<'a> => 'a = \"%identity\"\n\nlet updateSum = (node) => {\n  let leftSum = switch node.left {\n  | None => 0.\n  | Some(left) => left.sum\n  }\n  let rightSum = switch node.right {\n  | None => 0.\n  | Some(right) => right.sum\n  }\n  node.sum = leftSum +. rightSum +. node.height\n}\n\n/* Update the sum for the node and parents recursively. */\nlet rec updateSumRecursive = (rbt, node) => {\n  updateSum(node)\n  switch node.parent {\n  | None => ()\n  | Some(parent) =>\n    rbt->updateSumRecursive(parent)\n  }\n}\n\nlet grandParentOf = node => {\n  switch node.parent {\n  | None => None\n  | Some(ref_) => ref_.parent\n  }\n}\n\nlet isLeft = node => {\n  switch node.parent {\n  | None => false\n  | Some(parent) => Some(node) === parent.left\n  }\n}\n\nlet leftOrRightSet = (~node, x, value) => {\n  isLeft(node) ? x.left=value : x.right=value\n}\n\nlet siblingOf = node => {\n  if isLeft(node) {\n    castNotOption(node.parent).right\n  } else {\n    castNotOption(node.parent).left\n  }\n}\n\nlet uncleOf = node => {\n  switch grandParentOf(node) {\n  | None => None\n  | Some(grandParentOfNode) =>\n    if isLeft(castNotOption(node.parent)) {\n      grandParentOfNode.right\n    } else {\n      grandParentOfNode.left\n    }\n  }\n}\n\nlet rec findNode = (rbt, node, value) => {\n  switch node {\n  | None => None\n  | Some(node) =>\n    let cmp = rbt.compare(. value, node.value)\n    if cmp === 0 {\n      Some(node)\n    } else if cmp < 0 {\n      findNode(rbt, node.left, value)\n    } else {\n      findNode(rbt, node.right, value)\n    }\n  }\n}\n\nlet has = (rbt, value) => findNode(rbt, rbt.root, value) !== None\n\nlet rec peekMinNode = node => switch node {\n  | None => None\n  | Some(node) =>\n    node.left === None ? Some(node) : node.left->peekMinNode\n}\n\nlet rec peekMaxNode = node => switch node {\n  | None => None\n  | Some(node) =>\n    node.right === None ? Some(node) : node.right->peekMaxNode\n}\n\nlet rotateLeft = (rbt, node) => {\n  let parent = node.parent\n  let right = node.right\n  switch parent {\n    | Some(parent) =>\n      parent->leftOrRightSet(~node, right)\n    | None =>\n      rbt.root = right\n  }\n  node.parent = right\n  let right = right->castNotOption // precondition\n  let rightLeft = right.left\n  node.right = rightLeft\n  switch rightLeft {\n    | Some(rightLeft) =>\n      rightLeft.parent = Some(node)\n    | None =>\n      ()\n  }\n  right.parent = parent\n  right.left = Some(node)\n  updateSum(node)\n  updateSum(right)\n}\n\n// After adding the node, we need to operate on it to preserve the tree's\n// properties by filtering it through a series of cases. It'd be easier if\n// there's tail recursion in JavaScript, as some cases fix the node but\n// restart the cases on the node's ancestor. We'll have to use loops for now.\n\nlet rec _addLoop = (rbt, currentNode) => {\n  // Case 1: node is root. Violates 1. Paint it black.\n  if Some(currentNode) === rbt.root {\n    currentNode.color = Black\n  }\n\n  // Case 2: parent black. No properties violated. After that, parent is sure\n  // to be red.\n  else if (currentNode.parent->castNotOption).color === Black {\n    ()\n  }\n\n  // Case 3: if node's parent and uncle are red, they are painted black.\n  // Their parent (node's grandparent) should be painted red, and the\n  // grandparent red. Note that node certainly has a grandparent, since at\n  // this point, its parent's red, which can't be the root.\n\n  // After the painting, the grandparent might violate 2 or 4.\n  else if({\n      let uncle = uncleOf(currentNode)\n      uncle !== None && (uncle->castNotOption).color === Red\n    }) {\n    (currentNode.parent->castNotOption).color = Black\n    (uncleOf(currentNode)->castNotOption).color = Black\n    (grandParentOf(currentNode)->castNotOption).color = Red\n    _addLoop(rbt, grandParentOf(currentNode)->castNotOption)\n  }\n  else {\n    // At this point, uncle is either black or doesn't exist.\n\n    // Case 4: parent red, uncle black, node is right child, parent is left\n    // child. Do a left rotation. Then, former parent passes through case 5.\n    let currentNode =\n      if !isLeft(currentNode) && isLeft(currentNode.parent->castNotOption) {\n        rotateLeft(rbt, currentNode.parent->castNotOption)\n        currentNode.left->castNotOption\n      } else if isLeft(currentNode) && !isLeft(currentNode.parent->castNotOption) {\n        rotateRight(rbt, currentNode.parent->castNotOption)\n        currentNode.right->castNotOption\n      } else {\n        currentNode\n      }\n\n    // Case 5: parent red, uncle black, node is left child, parent is left\n    // child. Right rotation. Switch parent and grandparent's color.\n    (currentNode.parent->castNotOption).color = Black\n    (grandParentOf(currentNode)->castNotOption).color = Red\n    if isLeft(currentNode) {\n      rotateRight(rbt, grandParentOf(currentNode)->castNotOption)\n    } else {\n      rotateLeft(rbt, grandParentOf(currentNode)->castNotOption)\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/RemoteSiteHelperTest.cls",
    "content": "// https://github.com/financialforcedev/apex-mdapi.git\n//      apex-mdapi/apex-mdapi/src/classes/RemoteSiteHelperTest.cls\n@IsTest\nprivate class RemoteSiteHelperTest \n{\n\t@IsTest\n\tprivate static void testCheckMetadataAPIConnection()\n\t{\t\t\t\n    \t// Metadata API web Service mock implementation for tests\n        Test.setMock(WebServiceMock.class, new WebServiceMockImpl());\n\t\t\n\t\tRemoteSiteHelperController controller = new RemoteSiteHelperController();\n\t\tSystem.assertEquals(true, controller.MetadataConnectionWarning);\t\t\n\t\tcontroller.MetadataResponse = '';\n\t\tcontroller.displayMetadataResponse();\n\t\tSystem.assertEquals(false, controller.MetadataConnectionWarning);\n\t\tcontroller.MetadataResponse = 'Some Error Creating Remote Site Setting';\n\t\tcontroller.displayMetadataResponse();\n\t\tSystem.assertEquals(true, controller.MetadataConnectionWarning);\n\t}\n\t\n    /**\n     * Metadata API web service mock class for tests above\n     **/\n\tprivate class WebServiceMockImpl implements WebServiceMock \n\t{\n\t\tpublic void doInvoke(\n\t\t\tObject stub, Object request, Map<String, Object> response,\n\t\t\tString endpoint, String soapAction, String requestName,\n\t\t\tString responseNS, String responseName, String responseType) \n\t\t{\n\t\t\tthrow new TestException();\n\t\t}\n\t}\n\t\n\tpublic class TestException extends Exception { }\n}\n"
  },
  {
    "path": "tests/inputs/RenderTest.metal",
    "content": "//\n//  RenderTest.metal\n//  RenderTest\n//\n\n#include <metal_stdlib>\nusing namespace metal;\n#include \"RenderTest.h\"\n\n// Vertex Shader Output\nstruct RenderTestVertexOut {\n    float4 position [[position]];\n    float pointSize [[point_size]];\n    float3 color;\n};\n\nvertex RenderTestVertexOut renderPointVertex(uint vertexID [[vertex_id]],\n                                    constant RenderTestUniforms &uniforms [[buffer(0)]],\n                                    constant TestPoint *points [[buffer(1)]]) {\n    \n    RenderPointVertexOut out;\n    out.position = points[vertexID].position;\n    out.pointSize = uniforms.particleSize;\n    out.color = float3(1,0,0);\n     \n    return out;\n}\n\nfragment float4 renderTestFragment(RenderTestVertexOut in [[stage_in]]) {\n    return float4(in.color, 1);\n}\n//\n//  RenderTest.metal\n//  RenderTest\n//\n\n#include <metal_stdlib>\nusing namespace metal;\n#include \"RenderTest.h\"\n\n// Vertex Shader Output\nstruct RenderTestVertexOut {\n    float4 position [[position]];\n    float pointSize [[point_size]];\n    float3 color;\n};\n\nvertex RenderTestVertexOut renderPointVertex(uint vertexID [[vertex_id]],\n                                    constant RenderTestUniforms &uniforms [[buffer(0)]],\n                                    constant TestPoint *points [[buffer(1)]]) {\n    \n    RenderPointVertexOut out;\n    out.position = points[vertexID].position;\n    out.pointSize = uniforms.particleSize;\n    out.color = float3(1,0,0);\n     \n    return out;\n}\n\nfragment float4 renderTestFragment(RenderTestVertexOut in [[stage_in]]) {\n    return float4(in.color, 1);\n}\n\n"
  },
  {
    "path": "tests/inputs/Rounds.scad",
    "content": "// https://raw.githubusercontent.com/UBaer21/UB.scad/main/examples/UBexamples/Rounds.scad\r\ninclude<ub.scad>//https://github.com/UBaer21/UB.scad\r\n/*[Hidden]*/\r\n  useVersion=22.016;\r\n  designVersion=1.1;\r\n  info=true;\r\n\r\n/*[ Round Objects ]*/\r\nr=[16,8,4,2]; // corner 1-4 radius - can also be just a number\r\n\r\n\r\nLinEx(20) Quad(20);\r\n\r\nLinEx() Quad([25,30],r=r);\r\nTz(20)LinEx2()Rund(1,2)Stern(5,r1=12,r2=5);\r\n\r\nRundrum(x=30,y=40,r=r)Quad(x=15,y=20,r=r/2,center=false);\r\nTz(30)Rundrum(x=15,eck=3,r=3)Quad(x=5,y=3,r=1,center=false);\r\n\r\nT(50)Pille(l=20,d=10);\r\nT(65)Pille(l=20,d=10,rad=[1,15]);\r\nT(80)Pille(l=20,d=10,rad=1);\r\n\r\n\r\n\r\nT(-50) {\r\n  RotEx()T(10)Pille();\r\n  RotEx()T(-8)Pille();\r\n}\r\nT(-80) Kassette(gon=3,r=5,help=1);\r\nT(-80,30) Kassette(gon=4,r=[5,2,4,1],mitte=false,help=1);\r\n\r\nT(-80,60)Rundrum(20,20,r=5,grad=60,grad2=120)rotate(90)Vollwelle(extrude=1);\r\n\r\nT(-50,30) RotEx()T(10)Quad(5);\r\n\r\nT(y=-60){\r\n  \r\n  Prisma(10,20,30,c1=5,s=3);\r\n  T(15)Prisma(10,20,30,x2=5,y2=10,c1=5,s=3);\r\n  T(30)Prisma(10,20,30,x2=5,y2=10,x2d=10,c1=5,s=3);\r\n  T(60) Box(20,z=20,eck=5,s=5,c=10,outer=false);// outer = x= side radius or edge\r\n  \r\n  T(-30) Tz(15)Superellipse(r=[10,20,30]/2,help=1);\r\n  T(-50) Tz(15)Superellipse(r=[10,20,30]/2,n=10);\r\n  T(-70) Tz(15)Superellipse(r=[10,20,30]/2,n=4,n3=20);\r\n  \r\n}\r\n\r\n\r\nT(y=90){\r\n  Torus(trx=5,help=1);\r\n  Torus(dia=30,d=5,end=true);\r\n  Torus(dia=43,d=5,end=1,grad=270);\r\n  Torus(dia=59,d=5,end=+10,grad=270)Quad($d,10);\r\n  Torus(dia=79,trxEnd=-9,d=5,end=1,grad=270)Quad($d,10);\r\n  T(80) Polar(3)RingSeg(120,r=15,help=1,size=3,h=5,fn2=16);\r\n}\r\n\r\nT(y=160){\r\n  RStern();\r\n  T(x=50) RStern(messpunkt=0)circle();\r\n}\r\n"
  },
  {
    "path": "tests/inputs/Sample.mc",
    "content": "; /* http://msdn.microsoft.com/en-us/library/windows/desktop/dd996907%28v=vs.85%29.aspx \n;  more comments\n; */\n\n; // ***** Sample.mc *****\n; // This is the header section.\n\nMessageIdTypedef=DWORD\n\nSeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS\nInformational=0x1:STATUS_SEVERITY_INFORMATIONAL\nWarning=0x2:STATUS_SEVERITY_WARNING\nError=0x3:STATUS_SEVERITY_ERROR\n)\n\nFacilityNames=(System=0x0:FACILITY_SYSTEM\nRuntime=0x2:FACILITY_RUNTIME\nStubs=0x3:FACILITY_STUBS\nIo=0x4:FACILITY_IO_ERROR_CODE\n)\n\nLanguageNames=(English=0x409:MSG00409)\nLanguageNames=(Japanese=0x411:MSG00411)\n\n; // The following are message definitions.\n\nMessageId=0x1\nSeverity=Error\nFacility=Runtime\nSymbolicName=MSG_BAD_COMMAND\nLanguage=English\nYou have chosen an incorrect command.\n.\n\nLanguage=Japanese\n<Japanese message string goes here>\n.\n\nMessageId=0x2\nSeverity=Warning\nFacility=Io\nSymbolicName=MSG_BAD_PARM1\nLanguage=English\nCannot reconnect to the server.\n.\n\nLanguage=Japanese\n<Japanese message string goes here>\n.\n\nMessageId=0x3\nSeverity=Success\nFacility=System\nSymbolicName=MSG_STRIKE_ANY_KEY\nLanguage=English\nPress any key to continue . . . %0\n.\n\nLanguage=Japanese\n<Japanese message string goes here>\n.\n\nMessageId=0x4\nSeverity=Error\nFacility=System\nSymbolicName=MSG_CMD_DELETE\nLanguage=English\nFile %1 contains %2 which is in error.\n.\n\nLanguage=Japanese\n<Japanese message string goes here>\n.\n\nMessageId=0x5\nSeverity=Informational\nFacility=System\nSymbolicName=MSG_RETRYS\nLanguage=English\nThere have been %1!d! attempts with %2!d!%% success%! Disconnect from \nthe server and try again later.\n.\n\nLanguage=Japanese\n<Japanese message string goes here>\n.\n"
  },
  {
    "path": "tests/inputs/SimpleODE.mo",
    "content": "/*\nbased on\nhttps://raw.githubusercontent.com/casella/ScalableTestSuite/master/ScalableTestSuite/Elementary/SimpleODE.mo\n\n*/\n\nwithin ScalableTestSuite.Elementary;\npackage SimpleODE \"Models with simple ODE systems\"\n  package Models\n    model CascadedFirstOrder\n      \"N cascaded first order systems, approximating a pure delay\"\n      parameter Integer N = 10 \"Order of the system\";\n      parameter Modelica.Units.SI.Time T=1 \"System delay\";\n      final parameter Modelica.Units.SI.Time tau=T/N \"Individual time constant\";\n      Real x[N]( each start = 0, each fixed = true) \"State array\";\n      Real u = 1 \"Cascaded system input\";\n    equation\n      tau*der(x[1]) = u - x[1];\n      for i in 2:N loop\n        tau*der(x[i]) = x[i-1] - x[i];\n      end for;\n    annotation(\n      experiment(StopTime = 2,Tolerance = 1e-6),\n      Documentation(info = \"<html><p>This model is meant to try out  the tool\n        performance with ODE systems of possibly very large size, with high\n        sparsity degree.</p>\n        <p> The model is a cascaded connection of first order linear systems,\n        approximating a pure delay of <tt>T</tt> seconds as <tt>N</tt> approaches\n        infinity. It contains exactly <tt>N</tt> state variables and <tt>N</tt>\n        differential equations.</p></html>\"));\n    end CascadedFirstOrder;\n  end Models;\n\n  package ScaledExperiments\n    model CascadedFirstOrder_N_100\n      extends Models.CascadedFirstOrder(N=100);\n    annotation(experiment(StopTime = 2, Tolerance = 1e-6),\n               __OpenModelica_simulationFlags(s = \"ida\"));\n    end CascadedFirstOrder_N_100;\n\n//  model CascadedFirstOrder_N_200\n//    extends Models.CascadedFirstOrder(N=200);\n//  annotation(experiment(StopTime = 2, Tolerance = 1e-6),\n//             __OpenModelica_simulationFlags(s = \"ida\"));\n//  end CascadedFirstOrder_N_200;\n\n    model CascadedFirstOrder_N_400\n      extends Models.CascadedFirstOrder(N=400);\n    annotation(experiment(StopTime = 2, Tolerance = 1e-6),\n               __OpenModelica_simulationFlags(s = \"ida\"));\n    end CascadedFirstOrder_N_400;\n\n    model CascadedFirstOrder_N_25600\n      extends Models.CascadedFirstOrder(N=25600);\n    annotation(experiment(StopTime = 2, Tolerance = 1e-6),\n               __OpenModelica_simulationFlags(s = \"ida\"));\n    end CascadedFirstOrder_N_25600;\n  end ScaledExperiments;\nend SimpleODE;\n"
  },
  {
    "path": "tests/inputs/Slim.html.slim",
    "content": "<div class=\"widget-test-holder\"></div>\n<ul class=\"widget-test-items\">\n  - @test.each do |test|\n    <li>\n      <a href=\"#{chamada.conteudo_url}\">\n        - if test.midia and test.midia.add(params[:arg1]).present?\n          <img src=\"#{test.midia.add(params[:arg1])}\" alt=\"#{strip_tags(test.title)}\" />\n      </a>\n    </li>\n    /\n     this is a comment\n     block\n</ul>\n"
  },
  {
    "path": "tests/inputs/Slint-helloworld.slint",
    "content": "component MyButton inherits Text {\n    color: black;\n    // ...\n}\n\nexport component MyApp inherits Window {\n    preferred-width: 200px;\n    preferred-height: 100px;\n    Rectangle {\n        width: 200px;\n        height: 100px;\n        background: green;\n        \n    }/* */\n    MyButton { \n        x:0;y:0;    // hello\n        text: \"hello\";\n    }\n    MyButton {  // world\n        y:0;\n        x: 50px;\n        text: \"world\";\n    }\n}"
  },
  {
    "path": "tests/inputs/Snakefile",
    "content": "\"\"\"\nA sample Snakefile for testing line counting\n\"\"\"\n\nSAMPLES = [\"A\", \"B\"]\n\n\n# This is a\n# multiline\n# comment\nrule all:\n    input:\n        \"plots/quals.svg\"\n\n\nrule bwa_map:\n    input:\n        \"data/genome.fa\",  # Inline comments are also supported\n        \"data/samples/{sample}.fastq\"\n    output:\n        \"mapped_reads/{sample}.bam\"\n    shell:\n        \"bwa mem {input} | samtools view -Sb - > {output}\"\n\n\nrule samtools_sort:\n    input:\n        \"mapped_reads/{sample}.bam\"\n    output:\n        \"sorted_reads/{sample}.bam\"\n    shell:\n        \"samtools sort -T sorted_reads/{wildcards.sample} \"\n        \"-O bam {input} > {output}\"\n\n\nrule samtools_index:\n    input:\n        \"sorted_reads/{sample}.bam\"\n    output:\n        \"sorted_reads/{sample}.bam.bai\"\n    shell:\n        \"samtools index {input}\"\n\n\nrule bcftools_call:\n    input:\n        fa=\"data/genome.fa\",\n        bam=expand(\"sorted_reads/{sample}.bam\", sample=SAMPLES),\n        bai=expand(\"sorted_reads/{sample}.bam.bai\", sample=SAMPLES)\n    output:\n        \"calls/all.vcf\"\n    shell:\n        \"bcftools mpileup -f {input.fa} {input.bam} | \"\n        \"bcftools call -mv - > {output}\"\n\n\nrule plot_quals:\n    input:\n        \"calls/all.vcf\"\n    output:\n        \"plots/quals.svg\"\n    script:\n        \"scripts/plot-quals.py\"\n"
  },
  {
    "path": "tests/inputs/Splice.hs-boot",
    "content": "-- https://gitlab.haskell.org/ghc/ghc.git\n-- ghc/compiler/GHC/Tc/Gen/Splice.hs-boot\n\n{-# LANGUAGE TypeFamilies #-}\n\nmodule GHC.Tc.Gen.Splice where\n\nimport GHC.Prelude\nimport GHC.Types.Name\nimport GHC.Hs.Expr ( PendingRnSplice, DelayedSplice )\nimport GHC.Tc.Types( TcM , SpliceType )\nimport GHC.Tc.Utils.TcType   ( ExpRhoType )\nimport GHC.Types.Annotations ( Annotation, CoreAnnTarget )\nimport GHC.Hs.Extension ( GhcRn, GhcPs, GhcTc )\n\nimport GHC.Hs ( HsQuote, HsExpr, LHsExpr, LHsType, LPat, LHsDecl, ThModFinalizers, HsUntypedSpliceResult, HsTypedSpliceResult, HsTypedSplice )\nimport qualified GHC.Boot.TH.Syntax as TH\nimport qualified GHC.Boot.TH.Monad as TH\n\ntcTypedSplice :: HsTypedSpliceResult\n              -> HsTypedSplice GhcRn\n              -> ExpRhoType\n              -> TcM (HsExpr GhcTc)\n\ntcTypedBracket :: HsExpr GhcRn\n               -> LHsExpr GhcRn\n               -> ExpRhoType\n               -> TcM (HsExpr GhcTc)\ntcUntypedBracket :: HsExpr GhcRn\n                 -> HsQuote GhcRn\n                 -> [PendingRnSplice]\n                 -> ExpRhoType\n\n                 -> TcM (HsExpr GhcTc)\n\n\nrunTopSplice :: DelayedSplice -> TcM (HsExpr GhcTc)\n\nrunAnnotation        :: CoreAnnTarget -> LHsExpr GhcRn -> TcM Annotation\ngetUntypedSpliceBody :: HsUntypedSpliceResult (HsExpr GhcRn) -> TcM (HsExpr GhcRn)\n\ntcTopSpliceExpr :: SpliceType -> TcM (LHsExpr GhcTc) -> TcM (LHsExpr GhcTc)\n\nrunMetaE :: LHsExpr GhcTc -> TcM (LHsExpr GhcPs)\nrunMetaP :: LHsExpr GhcTc -> TcM (LPat GhcPs)\nrunMetaT :: LHsExpr GhcTc -> TcM (LHsType GhcPs)\nrunMetaD :: LHsExpr GhcTc -> TcM [LHsDecl GhcPs]\n\nlookupThName_maybe :: TH.Name -> TcM (Maybe Name)\nrunQuasi :: TH.Q a -> TcM a\nrunRemoteModFinalizers :: ThModFinalizers -> TcM ()\nfinishTH :: TcM ()\n"
  },
  {
    "path": "tests/inputs/Sys.hx",
    "content": "/*\n https://raw.githubusercontent.com/HaxeFoundation/haxe/development/std/Sys.hx\n * Copyright (C)2005-2016 Haxe Foundation\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 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\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n/**\n\tThis class gives you access to many base functionalities of system platforms. Looks in `sys` sub packages for more system APIs.\n**/\n@:require(sys)\nextern class Sys {\n\n\t/**\n\t\tPrint any value on the standard output.\n\t**/\n\tstatic function print( v : Dynamic ) : Void;\n\n\t/**\n\t\tPrint any value on the standard output, followed by a newline.\n\t**/\n\tstatic function println( v : Dynamic ) : Void;\n\n\t/**\n\t\tReturns all the arguments that were passed by the commandline.\n\t**/\n\tstatic function args() : Array<String>;\n\n\t/**\n\t\tReturns the value of the given environment variable.\n\t**/\n\tstatic function getEnv( s : String ) : String;\n\n\t/**\n\t\tSet the value of the given environment variable.\n\t**/\n\tstatic function putEnv( s : String, v : String ) : Void;\n\n\t/**\n\t\tReturns the whole environement variables.\n\t**/\n\tstatic function environment() : Map<String,String>;\n\n\t/**\n\t\tSuspend the current execution for the given time (in seconds).\n\t**/\n\tstatic function sleep( seconds : Float ) : Void;\n\n\t/**\n\t\tChange the current time locale, which will affect `DateTools.format` date formating.\n\t\tReturns true if the locale was successfully changed\n\t**/\n\tstatic function setTimeLocale( loc : String ) : Bool;\n\n\t/**\n\t\tGet the current working directory (usually the one in which the program was started)\n\t**/\n\tstatic function getCwd() : String;\n\n\t/**\n\t\tChange the current working directory.\n\t**/\n\tstatic function setCwd( s : String ) : Void;\n\n\t/**\n\t\tReturns the name of the system you are running on. For instance :\n\t\t\t\"Windows\", \"Linux\", \"BSD\" and \"Mac\" depending on your desktop OS.\n\t**/\n\tstatic function systemName() : String;\n\n\t/**\n\t\tRun the given command. The command output will be printed on the same output as the current process.\n\t\tThe current process will block until the command terminates and it will return the command result (0 if there was no error).\n\n\t\tCommand arguments can be passed in two ways: 1. using `args`, 2. appending to `cmd` and leaving `args` as `null`.\n\n\t\t 1. When using `args` to pass command arguments, each argument will be automatically quoted, and shell meta-characters will be escaped if needed.\n\t\t`cmd` should be an executable name that can be located in the `PATH` environment variable, or a path to an executable.\n\n\t\t 2. When `args` is not given or is `null`, command arguments can be appended to `cmd`. No automatic quoting/escaping will be performed. `cmd` should be formatted exactly as it would be when typed at the command line.\n\t\tIt can run executables, as well as shell commands that are not executables (e.g. on Windows: `dir`, `cd`, `echo` etc).\n\n\t\tRead the `sys.io.Process` api for a more complete way to start background processes.\n\t**/\n\tstatic function command( cmd : String, ?args : Array<String> ) : Int;\n\n\t/**\n\t\tExit the current process with the given error code.\n\t**/\n\tstatic function exit( code : Int ) : Void;\n\n\t/**\n\t\tGives the most precise timestamp value (in seconds).\n\t**/\n\tstatic function time() : Float;\n\n\t/**\n\t\tGives the most precise timestamp value (in seconds) but only account for the actual time spent running on the CPU for the current thread/process.\n\t**/\n\tstatic function cpuTime() : Float;\n\n\t/**\n\t\tReturns the path to the current executable that we are running.\n\t**/\n\t@:deprecated(\"Use programPath instead\") static function executablePath() : String;\n\n\t/**\n\t\tReturns the absolute path to the current program file that we are running.\n\t\tConcretely, for an executable binary, it returns the path to the binary.\n\t\tFor a script (e.g. a PHP file), it returns the path to the script.\n\t**/\n\tstatic function programPath() : String;\n\n\t/**\n\t\tRead a single input character from the standard input (without blocking) and returns it. Setting `echo` to true will also display it on the output.\n\t**/\n\tstatic function getChar( echo : Bool ) : Int;\n\n\t/**\n\t\tReturns the process standard input, from which you can read what user enters. Usually it will block until the user send a full input line. See `getChar` for an alternative.\n\t**/\n\tstatic function stdin() : haxe.io.Input;\n\n\t/**\n\t\tReturns the process standard output on which you can write.\n\t**/\n\tstatic function stdout() : haxe.io.Output;\n\n\t/**\n\t\tReturns the process standard error on which you can write.\n\t**/\n\tstatic function stderr() : haxe.io.Output;\n\n}\n"
  },
  {
    "path": "tests/inputs/TLAExample.tla",
    "content": "---- MODULE TLAExample ----\n(* TLA+ example program. *)\n(* Multi-line\n   (* nested *)\n   comment *)\n\\* Single-line comment\n\nVARIABLES tlaIsCool\n\nInit == tlaIsCool = TRUE\n\nNext == tlaIsCool = TRUE /\\ tlaIsCool' = TRUE\n====\n"
  },
  {
    "path": "tests/inputs/TableGen-ARM.td",
    "content": "//===-- ARM.td - Describe the ARM Target Machine -----------*- tablegen -*-===//\n//\n// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.\n// See https://llvm.org/LICENSE.txt for license information.\n// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n//\n//===----------------------------------------------------------------------===//\n//\n//\n//===----------------------------------------------------------------------===//\n\n//===----------------------------------------------------------------------===//\n// Target-independent interfaces which we are implementing\n//===----------------------------------------------------------------------===//\n\ninclude \"llvm/Target/Target.td\"\n\n//===----------------------------------------------------------------------===//\n// ARM Subtarget state.\n//\n\ndef ModeThumb             : SubtargetFeature<\"thumb-mode\", \"InThumbMode\",\n                                             \"true\", \"Thumb mode\">;\n\ndef ModeSoftFloat         : SubtargetFeature<\"soft-float\",\"UseSoftFloat\",\n                                             \"true\", \"Use software floating \"\n                                             \"point features.\">;\n\n\n//===----------------------------------------------------------------------===//\n// ARM Subtarget features.\n//\n\n// Floating Point, HW Division and Neon Support\n\n// FP loads/stores/moves, shared between VFP and MVE (even in the integer-only\n// version).\ndef FeatureFPRegs         : SubtargetFeature<\"fpregs\", \"HasFPRegs\", \"true\",\n                                             \"Enable FP registers\">;\n\n// 16-bit FP loads/stores/moves, shared between VFP (with the v8.2A FP16\n// extension) and MVE (even in the integer-only version).\ndef FeatureFPRegs16       : SubtargetFeature<\"fpregs16\", \"HasFPRegs16\", \"true\",\n                                             \"Enable 16-bit FP registers\",\n                                             [FeatureFPRegs]>;\n\ndef FeatureFPRegs64       : SubtargetFeature<\"fpregs64\", \"HasFPRegs64\", \"true\",\n                                             \"Enable 64-bit FP registers\",\n                                             [FeatureFPRegs]>;\n\ndef FeatureFP64           : SubtargetFeature<\"fp64\", \"HasFP64\", \"true\",\n                                             \"Floating point unit supports \"\n                                             \"double precision\",\n                                             [FeatureFPRegs64]>;\n\ndef FeatureD32            : SubtargetFeature<\"d32\", \"HasD32\", \"true\",\n                                             \"Extend FP to 32 double registers\">;\n\nmulticlass VFPver<string name, string query, string description,\n                  list<SubtargetFeature> prev,\n                  list<SubtargetFeature> otherimplies,\n                  list<SubtargetFeature> vfp2prev = []> {\n  def _D16_SP: SubtargetFeature<\n    name#\"d16sp\", query#\"D16SP\", \"true\",\n    description#\" with only 16 d-registers and no double precision\",\n    !foreach(v, prev, !cast<SubtargetFeature>(v # \"_D16_SP\")) #\n      !foreach(v, vfp2prev, !cast<SubtargetFeature>(v # \"_SP\")) #\n      otherimplies>;\n  def _SP: SubtargetFeature<\n    name#\"sp\", query#\"SP\", \"true\",\n    description#\" with no double precision\",\n    !foreach(v, prev, !cast<SubtargetFeature>(v # \"_SP\")) #\n      otherimplies # [FeatureD32, !cast<SubtargetFeature>(NAME # \"_D16_SP\")]>;\n  def _D16: SubtargetFeature<\n    name#\"d16\", query#\"D16\", \"true\",\n    description#\" with only 16 d-registers\",\n    !foreach(v, prev, !cast<SubtargetFeature>(v # \"_D16\")) #\n      vfp2prev #\n      otherimplies # [FeatureFP64, !cast<SubtargetFeature>(NAME # \"_D16_SP\")]>;\n  def \"\": SubtargetFeature<\n    name, query, \"true\", description,\n    prev # otherimplies # [\n        !cast<SubtargetFeature>(NAME # \"_D16\"),\n        !cast<SubtargetFeature>(NAME # \"_SP\")]>;\n}\n\ndef FeatureVFP2_SP        : SubtargetFeature<\"vfp2sp\", \"HasVFPv2SP\", \"true\",\n                                             \"Enable VFP2 instructions with \"\n                                             \"no double precision\",\n                                             [FeatureFPRegs]>;\n\ndef FeatureVFP2           : SubtargetFeature<\"vfp2\", \"HasVFPv2\", \"true\",\n                                             \"Enable VFP2 instructions\",\n                                             [FeatureFP64, FeatureVFP2_SP]>;\n\ndefm FeatureVFP3: VFPver<\"vfp3\", \"HasVFPv3\", \"Enable VFP3 instructions\",\n                         [], [], [FeatureVFP2]>;\n\ndef FeatureNEON           : SubtargetFeature<\"neon\", \"HasNEON\", \"true\",\n                                             \"Enable NEON instructions\",\n                                             [FeatureVFP3]>;\n\ndef FeatureFP16           : SubtargetFeature<\"fp16\", \"HasFP16\", \"true\",\n                                             \"Enable half-precision \"\n                                             \"floating point\">;\n\ndefm FeatureVFP4: VFPver<\"vfp4\", \"HasVFPv4\", \"Enable VFP4 instructions\",\n                         [FeatureVFP3], [FeatureFP16]>;\n\ndefm FeatureFPARMv8: VFPver<\"fp-armv8\", \"HasFPARMv8\", \"Enable ARMv8 FP\",\n                         [FeatureVFP4], []>;\n\ndef FeatureFullFP16       : SubtargetFeature<\"fullfp16\", \"HasFullFP16\", \"true\",\n                                             \"Enable full half-precision \"\n                                             \"floating point\",\n                                             [FeatureFPARMv8_D16_SP, FeatureFPRegs16]>;\n\ndef FeatureFP16FML        : SubtargetFeature<\"fp16fml\", \"HasFP16FML\", \"true\",\n                                             \"Enable full half-precision \"\n                                             \"floating point fml instructions\",\n                                             [FeatureFullFP16]>;\n\ndef FeatureHWDivThumb     : SubtargetFeature<\"hwdiv\",\n                                             \"HasHardwareDivideInThumb\", \"true\",\n                                             \"Enable divide instructions in Thumb\">;\n\ndef FeatureHWDivARM       : SubtargetFeature<\"hwdiv-arm\",\n                                             \"HasHardwareDivideInARM\", \"true\",\n                                             \"Enable divide instructions in ARM mode\">;\n\n// Atomic Support\ndef FeatureDB             : SubtargetFeature<\"db\", \"HasDataBarrier\", \"true\",\n                                             \"Has data barrier (dmb/dsb) instructions\">;\n\ndef FeatureV7Clrex        : SubtargetFeature<\"v7clrex\", \"HasV7Clrex\", \"true\",\n                                             \"Has v7 clrex instruction\">;\n\ndef FeatureDFB  : SubtargetFeature<\"dfb\", \"HasFullDataBarrier\", \"true\",\n                                   \"Has full data barrier (dfb) instruction\">;\n\ndef FeatureAcquireRelease : SubtargetFeature<\"acquire-release\",\n                                             \"HasAcquireRelease\", \"true\",\n                                             \"Has v8 acquire/release (lda/ldaex \"\n                                             \" etc) instructions\">;\n\n\ndef FeatureSlowFPBrcc     : SubtargetFeature<\"slow-fp-brcc\", \"SlowFPBrcc\", \"true\",\n                                             \"FP compare + branch is slow\">;\n\ndef FeaturePerfMon        : SubtargetFeature<\"perfmon\", \"HasPerfMon\", \"true\",\n                                             \"Enable support for Performance \"\n                                             \"Monitor extensions\">;\n\n\n// TrustZone Security Extensions\ndef FeatureTrustZone      : SubtargetFeature<\"trustzone\", \"HasTrustZone\", \"true\",\n                                             \"Enable support for TrustZone \"\n                                             \"security extensions\">;\n\ndef Feature8MSecExt       : SubtargetFeature<\"8msecext\", \"Has8MSecExt\", \"true\",\n                                             \"Enable support for ARMv8-M \"\n                                             \"Security Extensions\">;\n\ndef FeatureSHA2           : SubtargetFeature<\"sha2\", \"HasSHA2\", \"true\",\n                                             \"Enable SHA1 and SHA256 support\", [FeatureNEON]>;\n\ndef FeatureAES            : SubtargetFeature<\"aes\", \"HasAES\", \"true\",\n                                             \"Enable AES support\", [FeatureNEON]>;\n\ndef FeatureCrypto         : SubtargetFeature<\"crypto\", \"HasCrypto\", \"true\",\n                                             \"Enable support for \"\n                                             \"Cryptography extensions\",\n                                             [FeatureNEON, FeatureSHA2, FeatureAES]>;\n\ndef FeatureCRC            : SubtargetFeature<\"crc\", \"HasCRC\", \"true\",\n                                             \"Enable support for CRC instructions\">;\n\ndef FeatureDotProd        : SubtargetFeature<\"dotprod\", \"HasDotProd\", \"true\",\n                                             \"Enable support for dot product instructions\",\n                                             [FeatureNEON]>;\n\n// Not to be confused with FeatureHasRetAddrStack (return address stack)\ndef FeatureRAS            : SubtargetFeature<\"ras\", \"HasRAS\", \"true\",\n                                             \"Enable Reliability, Availability \"\n                                             \"and Serviceability extensions\">;\n\n// Fast computation of non-negative address offsets\ndef FeatureFPAO           : SubtargetFeature<\"fpao\", \"HasFPAO\", \"true\",\n                                             \"Enable fast computation of \"\n                                             \"positive address offsets\">;\n\n// Fast execution of AES crypto operations\ndef FeatureFuseAES        : SubtargetFeature<\"fuse-aes\", \"HasFuseAES\", \"true\",\n                                             \"CPU fuses AES crypto operations\">;\n\n// Fast execution of bottom and top halves of literal generation\ndef FeatureFuseLiterals   : SubtargetFeature<\"fuse-literals\", \"HasFuseLiterals\", \"true\",\n                                             \"CPU fuses literal generation operations\">;\n\n// The way of reading thread pointer                                             \ndef FeatureReadTp :  SubtargetFeature<\"read-tp-hard\", \"ReadTPHard\", \"true\",\n                                      \"Reading thread pointer from register\">;\n\n// Cyclone can zero VFP registers in 0 cycles.\ndef FeatureZCZeroing      : SubtargetFeature<\"zcz\", \"HasZeroCycleZeroing\", \"true\",\n                                             \"Has zero-cycle zeroing instructions\">;\n\n// Whether it is profitable to unpredicate certain instructions during if-conversion\ndef FeatureProfUnpredicate : SubtargetFeature<\"prof-unpr\",\n                                              \"IsProfitableToUnpredicate\", \"true\",\n                                              \"Is profitable to unpredicate\">;\n\n// Some targets (e.g. Swift) have microcoded VGETLNi32.\ndef FeatureSlowVGETLNi32  : SubtargetFeature<\"slow-vgetlni32\",\n                                             \"HasSlowVGETLNi32\", \"true\",\n                                             \"Has slow VGETLNi32 - prefer VMOV\">;\n\n// Some targets (e.g. Swift) have microcoded VDUP32.\ndef FeatureSlowVDUP32     : SubtargetFeature<\"slow-vdup32\", \"HasSlowVDUP32\",\n                                             \"true\",\n                                             \"Has slow VDUP32 - prefer VMOV\">;\n\n// Some targets (e.g. Cortex-A9) prefer VMOVSR to VMOVDRR even when using NEON\n// for scalar FP, as this allows more effective execution domain optimization.\ndef FeaturePreferVMOVSR   : SubtargetFeature<\"prefer-vmovsr\", \"PreferVMOVSR\",\n                                             \"true\", \"Prefer VMOVSR\">;\n\n// Swift has ISHST barriers compatible with Atomic Release semantics but weaker\n// than ISH\ndef FeaturePrefISHSTBarrier : SubtargetFeature<\"prefer-ishst\", \"PreferISHST\",\n                                               \"true\", \"Prefer ISHST barriers\">;\n\n// Some targets (e.g. Cortex-A9) have muxed AGU and NEON/FPU.\ndef FeatureMuxedUnits     : SubtargetFeature<\"muxed-units\", \"HasMuxedUnits\",\n                                             \"true\",\n                                             \"Has muxed AGU and NEON/FPU\">;\n\n// Whether VLDM/VSTM starting with odd register number need more microops\n// than single VLDRS\ndef FeatureSlowOddRegister : SubtargetFeature<\"slow-odd-reg\", \"SlowOddRegister\",\n                                              \"true\", \"VLDM/VSTM starting \"\n                                              \"with an odd register is slow\">;\n\n// Some targets have a renaming dependency when loading into D subregisters.\ndef FeatureSlowLoadDSubreg : SubtargetFeature<\"slow-load-D-subreg\",\n                                              \"SlowLoadDSubregister\", \"true\",\n                                              \"Loading into D subregs is slow\">;\n\ndef FeatureUseWideStrideVFP : SubtargetFeature<\"wide-stride-vfp\",\n                                               \"UseWideStrideVFP\", \"true\",\n                                               \"Use a wide stride when allocating VFP registers\">;\n\n// Some targets (e.g. Cortex-A15) never want VMOVS to be widened to VMOVD.\ndef FeatureDontWidenVMOVS : SubtargetFeature<\"dont-widen-vmovs\",\n                                             \"DontWidenVMOVS\", \"true\",\n                                             \"Don't widen VMOVS to VMOVD\">;\n\n// Some targets (e.g. Cortex-A15) prefer to avoid mixing operations on different\n// VFP register widths.\ndef FeatureSplatVFPToNeon : SubtargetFeature<\"splat-vfp-neon\",\n                                             \"SplatVFPToNeon\", \"true\",\n                                             \"Splat register from VFP to NEON\",\n                                             [FeatureDontWidenVMOVS]>;\n\n// Whether or not it is profitable to expand VFP/NEON MLA/MLS instructions.\ndef FeatureExpandMLx      : SubtargetFeature<\"expand-fp-mlx\",\n                                             \"ExpandMLx\", \"true\",\n                                             \"Expand VFP/NEON MLA/MLS instructions\">;\n\n// Some targets have special RAW hazards for VFP/NEON VMLA/VMLS.\ndef FeatureHasVMLxHazards : SubtargetFeature<\"vmlx-hazards\", \"HasVMLxHazards\",\n                                             \"true\", \"Has VMLx hazards\">;\n\n// Some targets (e.g. Cortex-A9) want to convert VMOVRS, VMOVSR and VMOVS from\n// VFP to NEON, as an execution domain optimization.\ndef FeatureNEONForFPMovs  : SubtargetFeature<\"neon-fpmovs\",\n                                             \"UseNEONForFPMovs\", \"true\",\n                                             \"Convert VMOVSR, VMOVRS, \"\n                                             \"VMOVS to NEON\">;\n\n// Some processors benefit from using NEON instructions for scalar\n// single-precision FP operations. This affects instruction selection and should\n// only be enabled if the handling of denormals is not important.\ndef FeatureNEONForFP      : SubtargetFeature<\"neonfp\",\n                                             \"UseNEONForSinglePrecisionFP\",\n                                             \"true\",\n                                             \"Use NEON for single precision FP\">;\n\n// On some processors, VLDn instructions that access unaligned data take one\n// extra cycle. Take that into account when computing operand latencies.\ndef FeatureCheckVLDnAlign : SubtargetFeature<\"vldn-align\", \"CheckVLDnAlign\",\n                                             \"true\",\n                                             \"Check for VLDn unaligned access\">;\n\n// Some processors have a nonpipelined VFP coprocessor.\ndef FeatureNonpipelinedVFP : SubtargetFeature<\"nonpipelined-vfp\",\n                                              \"NonpipelinedVFP\", \"true\",\n                                              \"VFP instructions are not pipelined\">;\n\n// Some processors have FP multiply-accumulate instructions that don't\n// play nicely with other VFP / NEON instructions, and it's generally better\n// to just not use them.\ndef FeatureHasSlowFPVMLx  : SubtargetFeature<\"slowfpvmlx\", \"SlowFPVMLx\", \"true\",\n                                             \"Disable VFP / NEON MAC instructions\">;\n\n// VFPv4 added VFMA instructions that can similar be fast or slow.\ndef FeatureHasSlowFPVFMx  : SubtargetFeature<\"slowfpvfmx\", \"SlowFPVFMx\", \"true\",\n                                             \"Disable VFP / NEON FMA instructions\">;\n\n// Cortex-A8 / A9 Advanced SIMD has multiplier accumulator forwarding.\ndef FeatureVMLxForwarding : SubtargetFeature<\"vmlx-forwarding\",\n                                             \"HasVMLxForwarding\", \"true\",\n                                             \"Has multiplier accumulator forwarding\">;\n\n// Disable 32-bit to 16-bit narrowing for experimentation.\ndef FeaturePref32BitThumb : SubtargetFeature<\"32bit\", \"Pref32BitThumb\", \"true\",\n                                             \"Prefer 32-bit Thumb instrs\">;\n\ndef FeaturePrefLoopAlign32 : SubtargetFeature<\"loop-align\", \"PrefLoopLogAlignment\",\"2\",\n                                              \"Prefer 32-bit alignment for loops\">;\n\ndef FeatureMVEVectorCostFactor1 : SubtargetFeature<\"mve1beat\", \"MVEVectorCostFactor\", \"1\",\n                        \"Model MVE instructions as a 1 beat per tick architecture\">;\n\ndef FeatureMVEVectorCostFactor2 : SubtargetFeature<\"mve2beat\", \"MVEVectorCostFactor\", \"2\",\n                        \"Model MVE instructions as a 2 beats per tick architecture\">;\n\ndef FeatureMVEVectorCostFactor4 : SubtargetFeature<\"mve4beat\", \"MVEVectorCostFactor\", \"4\",\n                        \"Model MVE instructions as a 4 beats per tick architecture\">;\n\n/// Some instructions update CPSR partially, which can add false dependency for\n/// out-of-order implementation, e.g. Cortex-A9, unless each individual bit is\n/// mapped to a separate physical register. Avoid partial CPSR update for these\n/// processors.\ndef FeatureAvoidPartialCPSR : SubtargetFeature<\"avoid-partial-cpsr\",\n                                               \"AvoidCPSRPartialUpdate\", \"true\",\n                                 \"Avoid CPSR partial update for OOO execution\">;\n\n/// Disable +1 predication cost for instructions updating CPSR.\n/// Enabled for Cortex-A57.\ndef FeatureCheapPredicableCPSR : SubtargetFeature<\"cheap-predicable-cpsr\",\n                                                  \"CheapPredicableCPSRDef\",\n                                                  \"true\",\n                  \"Disable +1 predication cost for instructions updating CPSR\">;\n\ndef FeatureAvoidMOVsShOp  : SubtargetFeature<\"avoid-movs-shop\",\n                                             \"AvoidMOVsShifterOperand\", \"true\",\n                                             \"Avoid movs instructions with \"\n                                             \"shifter operand\">;\n\n// Some processors perform return stack prediction. CodeGen should avoid issue\n// \"normal\" call instructions to callees which do not return.\ndef FeatureHasRetAddrStack : SubtargetFeature<\"ret-addr-stack\",\n                                              \"HasRetAddrStack\", \"true\",\n                                              \"Has return address stack\">;\n\n// Some processors have no branch predictor, which changes the expected cost of\n// taking a branch which affects the choice of whether to use predicated\n// instructions.\ndef FeatureHasNoBranchPredictor : SubtargetFeature<\"no-branch-predictor\",\n                                                   \"HasBranchPredictor\", \"false\",\n                                                   \"Has no branch predictor\">;\n\n/// DSP extension.\ndef FeatureDSP            : SubtargetFeature<\"dsp\", \"HasDSP\", \"true\",\n                                             \"Supports DSP instructions in \"\n                                             \"ARM and/or Thumb2\">;\n\n// Multiprocessing extension.\ndef FeatureMP             : SubtargetFeature<\"mp\", \"HasMPExtension\", \"true\",\n                                        \"Supports Multiprocessing extension\">;\n\n// Virtualization extension - requires HW divide (ARMv7-AR ARMARM - 4.4.8).\ndef FeatureVirtualization : SubtargetFeature<\"virtualization\",\n                                             \"HasVirtualization\", \"true\",\n                                             \"Supports Virtualization extension\",\n                                             [FeatureHWDivThumb, FeatureHWDivARM]>;\n\n// Special TRAP encoding for NaCl, which looks like a TRAP in Thumb too.\n// See ARMInstrInfo.td for details.\ndef FeatureNaClTrap       : SubtargetFeature<\"nacl-trap\", \"UseNaClTrap\", \"true\",\n                                             \"NaCl trap\">;\n\ndef FeatureStrictAlign    : SubtargetFeature<\"strict-align\",\n                                             \"StrictAlign\", \"true\",\n                                             \"Disallow all unaligned memory \"\n                                             \"access\">;\n\ndef FeatureLongCalls      : SubtargetFeature<\"long-calls\", \"GenLongCalls\", \"true\",\n                                             \"Generate calls via indirect call \"\n                                             \"instructions\">;\n\ndef FeatureExecuteOnly    : SubtargetFeature<\"execute-only\",\n                                             \"GenExecuteOnly\", \"true\",\n                                             \"Enable the generation of \"\n                                             \"execute only code.\">;\n\ndef FeatureReserveR9      : SubtargetFeature<\"reserve-r9\", \"ReserveR9\", \"true\",\n                                             \"Reserve R9, making it unavailable\"\n                                             \" as GPR\">;\n\ndef FeatureNoMovt         : SubtargetFeature<\"no-movt\", \"NoMovt\", \"true\",\n                                             \"Don't use movt/movw pairs for \"\n                                             \"32-bit imms\">;\n\ndef FeatureNoNegativeImmediates\n                          : SubtargetFeature<\"no-neg-immediates\",\n                                             \"NegativeImmediates\", \"false\",\n                                             \"Convert immediates and instructions \"\n                                             \"to their negated or complemented \"\n                                             \"equivalent when the immediate does \"\n                                             \"not fit in the encoding.\">;\n\n// Use the MachineScheduler for instruction scheduling for the subtarget.\ndef FeatureUseMISched: SubtargetFeature<\"use-misched\", \"UseMISched\", \"true\",\n                                        \"Use the MachineScheduler\">;\n\ndef FeatureNoPostRASched : SubtargetFeature<\"disable-postra-scheduler\",\n    \"DisablePostRAScheduler\", \"true\",\n    \"Don't schedule again after register allocation\">;\n\n// Armv8.5-A extensions\n\ndef FeatureSB       : SubtargetFeature<\"sb\", \"HasSB\", \"true\",\n  \"Enable v8.5a Speculation Barrier\" >;\n\n// Armv8.6-A extensions\ndef FeatureBF16     : SubtargetFeature<\"bf16\", \"HasBF16\", \"true\",\n  \"Enable support for BFloat16 instructions\",  [FeatureNEON]>;\n\ndef FeatureMatMulInt8 : SubtargetFeature<\"i8mm\", \"HasMatMulInt8\",\n    \"true\", \"Enable Matrix Multiply Int8 Extension\", [FeatureNEON]>;\n\n// Armv8.1-M extensions\n\ndef FeatureLOB            : SubtargetFeature<\"lob\", \"HasLOB\", \"true\",\n                                             \"Enable Low Overhead Branch \"\n                                             \"extensions\">;\n\ndef FeatureFixCMSE_CVE_2021_35465 : SubtargetFeature<\"fix-cmse-cve-2021-35465\",\n                                        \"FixCMSE_CVE_2021_35465\", \"true\",\n                                        \"Mitigate against the cve-2021-35465 \"\n                                        \"security vulnurability\">;\n\ndef FeaturePACBTI         : SubtargetFeature<\"pacbti\", \"HasPACBTI\", \"true\",\n                                             \"Enable Pointer Authentication and Branch \"\n                                             \"Target Identification\">;\n\ndef FeatureNoBTIAtReturnTwice : SubtargetFeature<\"no-bti-at-return-twice\",\n                                                 \"NoBTIAtReturnTwice\", \"true\",\n                                                 \"Don't place a BTI instruction \"\n                                                 \"after a return-twice\">;\n\n//===----------------------------------------------------------------------===//\n// ARM architecture class\n//\n\n// A-series ISA\ndef FeatureAClass : SubtargetFeature<\"aclass\", \"ARMProcClass\", \"AClass\",\n                                     \"Is application profile ('A' series)\">;\n\n// R-series ISA\ndef FeatureRClass : SubtargetFeature<\"rclass\", \"ARMProcClass\", \"RClass\",\n                                     \"Is realtime profile ('R' series)\">;\n\n// M-series ISA\ndef FeatureMClass : SubtargetFeature<\"mclass\", \"ARMProcClass\", \"MClass\",\n                                     \"Is microcontroller profile ('M' series)\">;\n\n\ndef FeatureThumb2 : SubtargetFeature<\"thumb2\", \"HasThumb2\", \"true\",\n                                     \"Enable Thumb2 instructions\">;\n\ndef FeatureNoARM  : SubtargetFeature<\"noarm\", \"NoARM\", \"true\",\n                                     \"Does not support ARM mode execution\">;\n\n//===----------------------------------------------------------------------===//\n// ARM ISAa.\n//\n\ndef HasV4TOps   : SubtargetFeature<\"v4t\", \"HasV4TOps\", \"true\",\n                                   \"Support ARM v4T instructions\">;\n\ndef HasV5TOps   : SubtargetFeature<\"v5t\", \"HasV5TOps\", \"true\",\n                                   \"Support ARM v5T instructions\",\n                                   [HasV4TOps]>;\n\ndef HasV5TEOps  : SubtargetFeature<\"v5te\", \"HasV5TEOps\", \"true\",\n                                   \"Support ARM v5TE, v5TEj, and \"\n                                   \"v5TExp instructions\",\n                                   [HasV5TOps]>;\n\ndef HasV6Ops    : SubtargetFeature<\"v6\", \"HasV6Ops\", \"true\",\n                                   \"Support ARM v6 instructions\",\n                                   [HasV5TEOps]>;\n\ndef HasV6MOps   : SubtargetFeature<\"v6m\", \"HasV6MOps\", \"true\",\n                                   \"Support ARM v6M instructions\",\n                                   [HasV6Ops]>;\n\ndef HasV8MBaselineOps : SubtargetFeature<\"v8m\", \"HasV8MBaselineOps\", \"true\",\n                                         \"Support ARM v8M Baseline instructions\",\n                                         [HasV6MOps]>;\n\ndef HasV6KOps   : SubtargetFeature<\"v6k\", \"HasV6KOps\", \"true\",\n                                   \"Support ARM v6k instructions\",\n                                   [HasV6Ops]>;\n\ndef HasV6T2Ops  : SubtargetFeature<\"v6t2\", \"HasV6T2Ops\", \"true\",\n                                   \"Support ARM v6t2 instructions\",\n                                   [HasV8MBaselineOps, HasV6KOps, FeatureThumb2]>;\n\ndef HasV7Ops    : SubtargetFeature<\"v7\", \"HasV7Ops\", \"true\",\n                                   \"Support ARM v7 instructions\",\n                                   [HasV6T2Ops, FeaturePerfMon,\n                                    FeatureV7Clrex]>;\n\ndef HasV8MMainlineOps :\n                  SubtargetFeature<\"v8m.main\", \"HasV8MMainlineOps\", \"true\",\n                                   \"Support ARM v8M Mainline instructions\",\n                                   [HasV7Ops]>;\n\ndef HasV8Ops    : SubtargetFeature<\"v8\", \"HasV8Ops\", \"true\",\n                                   \"Support ARM v8 instructions\",\n                                   [HasV7Ops, FeatureAcquireRelease]>;\n\ndef HasV8_1aOps : SubtargetFeature<\"v8.1a\", \"HasV8_1aOps\", \"true\",\n                                   \"Support ARM v8.1a instructions\",\n                                   [HasV8Ops]>;\n\ndef HasV8_2aOps : SubtargetFeature<\"v8.2a\", \"HasV8_2aOps\", \"true\",\n                                   \"Support ARM v8.2a instructions\",\n                                   [HasV8_1aOps]>;\n\ndef HasV8_3aOps   : SubtargetFeature<\"v8.3a\", \"HasV8_3aOps\", \"true\",\n                                   \"Support ARM v8.3a instructions\",\n                                   [HasV8_2aOps]>;\n\ndef HasV8_4aOps   : SubtargetFeature<\"v8.4a\", \"HasV8_4aOps\", \"true\",\n                                   \"Support ARM v8.4a instructions\",\n                                   [HasV8_3aOps, FeatureDotProd]>;\n\ndef HasV8_5aOps   : SubtargetFeature<\"v8.5a\", \"HasV8_5aOps\", \"true\",\n                                   \"Support ARM v8.5a instructions\",\n                                   [HasV8_4aOps, FeatureSB]>;\n\ndef HasV8_6aOps   : SubtargetFeature<\"v8.6a\", \"HasV8_6aOps\", \"true\",\n                                   \"Support ARM v8.6a instructions\",\n                                   [HasV8_5aOps, FeatureBF16,\n                                    FeatureMatMulInt8]>;\n\ndef HasV8_7aOps   : SubtargetFeature<\"v8.7a\", \"HasV8_7aOps\", \"true\",\n                                   \"Support ARM v8.7a instructions\",\n                                   [HasV8_6aOps]>;\n\ndef HasV9_0aOps   : SubtargetFeature<\"v9a\", \"HasV9_0aOps\", \"true\",\n                                   \"Support ARM v9a instructions\",\n                                   [HasV8_5aOps]>;\n\ndef HasV9_1aOps   : SubtargetFeature<\"v9.1a\", \"HasV9_1aOps\", \"true\",\n                                   \"Support ARM v9.1a instructions\",\n                                   [HasV8_6aOps, HasV9_0aOps]>;\n\ndef HasV9_2aOps   : SubtargetFeature<\"v9.2a\", \"HasV9_2aOps\", \"true\",\n                                   \"Support ARM v9.2a instructions\",\n                                   [HasV8_7aOps, HasV9_1aOps]>;\n\ndef HasV8_1MMainlineOps : SubtargetFeature<\n               \"v8.1m.main\", \"HasV8_1MMainlineOps\", \"true\",\n               \"Support ARM v8-1M Mainline instructions\",\n               [HasV8MMainlineOps]>;\ndef HasMVEIntegerOps : SubtargetFeature<\n               \"mve\", \"HasMVEIntegerOps\", \"true\",\n               \"Support M-Class Vector Extension with integer ops\",\n               [HasV8_1MMainlineOps, FeatureDSP, FeatureFPRegs16, FeatureFPRegs64]>;\ndef HasMVEFloatOps : SubtargetFeature<\n               \"mve.fp\", \"HasMVEFloatOps\", \"true\",\n               \"Support M-Class Vector Extension with integer and floating ops\",\n               [HasMVEIntegerOps, FeatureFPARMv8_D16_SP, FeatureFullFP16]>;\n\ndef HasCDEOps : SubtargetFeature<\"cde\", \"HasCDEOps\", \"true\",\n                                 \"Support CDE instructions\",\n                                 [HasV8MMainlineOps]>;\n\nforeach i = {0-7} in\n    def FeatureCoprocCDE#i : SubtargetFeature<\"cdecp\"#i,\n                                              \"CoprocCDE[\"#i#\"]\", \"true\",\n                                              \"Coprocessor \"#i#\" ISA is CDEv1\",\n                                              [HasCDEOps]>;\n\n//===----------------------------------------------------------------------===//\n// Control codegen mitigation against Straight Line Speculation vulnerability.\n//===----------------------------------------------------------------------===//\n\ndef FeatureHardenSlsRetBr : SubtargetFeature<\"harden-sls-retbr\",\n  \"HardenSlsRetBr\", \"true\",\n  \"Harden against straight line speculation across RETurn and BranchRegister \"\n  \"instructions\">;\ndef FeatureHardenSlsBlr : SubtargetFeature<\"harden-sls-blr\",\n  \"HardenSlsBlr\", \"true\",\n  \"Harden against straight line speculation across indirect calls\">;\ndef FeatureHardenSlsNoComdat : SubtargetFeature<\"harden-sls-nocomdat\",\n  \"HardenSlsNoComdat\", \"true\",\n  \"Generate thunk code for SLS mitigation in the normal text section\">;\n\n//===----------------------------------------------------------------------===//\n// ARM Processor subtarget features.\n//\n\ndef ProcA5      : SubtargetFeature<\"a5\", \"ARMProcFamily\", \"CortexA5\",\n                                   \"Cortex-A5 ARM processors\", []>;\ndef ProcA7      : SubtargetFeature<\"a7\", \"ARMProcFamily\", \"CortexA7\",\n                                   \"Cortex-A7 ARM processors\", []>;\ndef ProcA8      : SubtargetFeature<\"a8\", \"ARMProcFamily\", \"CortexA8\",\n                                   \"Cortex-A8 ARM processors\", []>;\ndef ProcA9      : SubtargetFeature<\"a9\", \"ARMProcFamily\", \"CortexA9\",\n                                   \"Cortex-A9 ARM processors\", []>;\ndef ProcA12     : SubtargetFeature<\"a12\", \"ARMProcFamily\", \"CortexA12\",\n                                   \"Cortex-A12 ARM processors\", []>;\ndef ProcA15     : SubtargetFeature<\"a15\", \"ARMProcFamily\", \"CortexA15\",\n                                   \"Cortex-A15 ARM processors\", []>;\ndef ProcA17     : SubtargetFeature<\"a17\", \"ARMProcFamily\", \"CortexA17\",\n                                   \"Cortex-A17 ARM processors\", []>;\ndef ProcA32     : SubtargetFeature<\"a32\", \"ARMProcFamily\", \"CortexA32\",\n                                   \"Cortex-A32 ARM processors\", []>;\ndef ProcA35     : SubtargetFeature<\"a35\", \"ARMProcFamily\", \"CortexA35\",\n                                   \"Cortex-A35 ARM processors\", []>;\ndef ProcA53     : SubtargetFeature<\"a53\", \"ARMProcFamily\", \"CortexA53\",\n                                   \"Cortex-A53 ARM processors\", []>;\ndef ProcA55     : SubtargetFeature<\"a55\", \"ARMProcFamily\", \"CortexA55\",\n                                   \"Cortex-A55 ARM processors\", []>;\ndef ProcA57     : SubtargetFeature<\"a57\", \"ARMProcFamily\", \"CortexA57\",\n                                   \"Cortex-A57 ARM processors\", []>;\ndef ProcA72     : SubtargetFeature<\"a72\", \"ARMProcFamily\", \"CortexA72\",\n                                   \"Cortex-A72 ARM processors\", []>;\ndef ProcA73     : SubtargetFeature<\"a73\", \"ARMProcFamily\", \"CortexA73\",\n                                   \"Cortex-A73 ARM processors\", []>;\ndef ProcA75     : SubtargetFeature<\"a75\", \"ARMProcFamily\", \"CortexA75\",\n                                   \"Cortex-A75 ARM processors\", []>;\ndef ProcA76     : SubtargetFeature<\"a76\", \"ARMProcFamily\", \"CortexA76\",\n                                   \"Cortex-A76 ARM processors\", []>;\ndef ProcA77     : SubtargetFeature<\"a77\", \"ARMProcFamily\", \"CortexA77\",\n                                   \"Cortex-A77 ARM processors\", []>;\ndef ProcA78     : SubtargetFeature<\"cortex-a78\", \"ARMProcFamily\", \"CortexA78\",\n                                   \"Cortex-A78 ARM processors\", []>;\ndef ProcA78C    : SubtargetFeature<\"a78c\", \"ARMProcFamily\", \"CortexA78C\",\n                                   \"Cortex-A78C ARM processors\", []>;\ndef ProcA710    : SubtargetFeature<\"cortex-a710\", \"ARMProcFamily\",\n                                   \"CortexA710\", \"Cortex-A710 ARM processors\", []>;\ndef ProcX1      : SubtargetFeature<\"cortex-x1\", \"ARMProcFamily\", \"CortexX1\",\n                                   \"Cortex-X1 ARM processors\", []>;\n\ndef ProcV1      : SubtargetFeature<\"neoverse-v1\", \"ARMProcFamily\",\n                                   \"NeoverseV1\", \"Neoverse-V1 ARM processors\", []>;\n\ndef ProcKrait   : SubtargetFeature<\"krait\", \"ARMProcFamily\", \"Krait\",\n                                   \"Qualcomm Krait processors\", []>;\ndef ProcKryo    : SubtargetFeature<\"kryo\", \"ARMProcFamily\", \"Kryo\",\n                                   \"Qualcomm Kryo processors\", []>;\ndef ProcSwift   : SubtargetFeature<\"swift\", \"ARMProcFamily\", \"Swift\",\n                                   \"Swift ARM processors\", []>;\n\ndef ProcExynos  : SubtargetFeature<\"exynos\", \"ARMProcFamily\", \"Exynos\",\n                                   \"Samsung Exynos processors\",\n                                   [FeatureZCZeroing,\n                                    FeatureUseWideStrideVFP,\n                                    FeatureSplatVFPToNeon,\n                                    FeatureSlowVGETLNi32,\n                                    FeatureSlowVDUP32,\n                                    FeatureSlowFPBrcc,\n                                    FeatureProfUnpredicate,\n                                    FeatureHWDivThumb,\n                                    FeatureHWDivARM,\n                                    FeatureHasSlowFPVMLx,\n                                    FeatureHasSlowFPVFMx,\n                                    FeatureHasRetAddrStack,\n                                    FeatureFuseLiterals,\n                                    FeatureFuseAES,\n                                    FeatureExpandMLx,\n                                    FeatureCrypto,\n                                    FeatureCRC]>;\n\ndef ProcR4      : SubtargetFeature<\"r4\", \"ARMProcFamily\", \"CortexR4\",\n                                   \"Cortex-R4 ARM processors\", []>;\ndef ProcR5      : SubtargetFeature<\"r5\", \"ARMProcFamily\", \"CortexR5\",\n                                   \"Cortex-R5 ARM processors\", []>;\ndef ProcR7      : SubtargetFeature<\"r7\", \"ARMProcFamily\", \"CortexR7\",\n                                   \"Cortex-R7 ARM processors\", []>;\ndef ProcR52     : SubtargetFeature<\"r52\", \"ARMProcFamily\", \"CortexR52\",\n                                   \"Cortex-R52 ARM processors\", []>;\n\ndef ProcM3      : SubtargetFeature<\"m3\", \"ARMProcFamily\", \"CortexM3\",\n                                   \"Cortex-M3 ARM processors\", []>;\ndef ProcM7      : SubtargetFeature<\"m7\", \"ARMProcFamily\", \"CortexM7\",\n                                   \"Cortex-M7 ARM processors\", []>;\n\n//===----------------------------------------------------------------------===//\n// ARM Helper classes.\n//\n\nclass Architecture<string fname, string aname, list<SubtargetFeature> features>\n  : SubtargetFeature<fname, \"ARMArch\", aname,\n                     !strconcat(aname, \" architecture\"), features>;\n\nclass ProcNoItin<string Name, list<SubtargetFeature> Features>\n  : Processor<Name, NoItineraries, Features>;\n\n\n//===----------------------------------------------------------------------===//\n// ARM architectures\n//\n\ndef ARMv2     : Architecture<\"armv2\",     \"ARMv2\",    []>;\n\ndef ARMv2a    : Architecture<\"armv2a\",    \"ARMv2a\",   []>;\n\ndef ARMv3     : Architecture<\"armv3\",     \"ARMv3\",    []>;\n\ndef ARMv3m    : Architecture<\"armv3m\",    \"ARMv3m\",   []>;\n\ndef ARMv4     : Architecture<\"armv4\",     \"ARMv4\",    []>;\n\ndef ARMv4t    : Architecture<\"armv4t\",    \"ARMv4t\",   [HasV4TOps]>;\n\ndef ARMv5t    : Architecture<\"armv5t\",    \"ARMv5t\",   [HasV5TOps]>;\n\ndef ARMv5te   : Architecture<\"armv5te\",   \"ARMv5te\",  [HasV5TEOps]>;\n\ndef ARMv5tej  : Architecture<\"armv5tej\",  \"ARMv5tej\", [HasV5TEOps]>;\n\ndef ARMv6     : Architecture<\"armv6\",     \"ARMv6\",    [HasV6Ops,\n                                                       FeatureDSP]>;\n\ndef ARMv6t2   : Architecture<\"armv6t2\",   \"ARMv6t2\",  [HasV6T2Ops,\n                                                       FeatureDSP]>;\n\ndef ARMv6k    : Architecture<\"armv6k\",    \"ARMv6k\",   [HasV6KOps]>;\n\ndef ARMv6kz   : Architecture<\"armv6kz\",   \"ARMv6kz\",  [HasV6KOps,\n                                                       FeatureTrustZone]>;\n\ndef ARMv6m    : Architecture<\"armv6-m\",   \"ARMv6m\",   [HasV6MOps,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureMClass,\n                                                       FeatureStrictAlign]>;\n\ndef ARMv6sm   : Architecture<\"armv6s-m\",  \"ARMv6sm\",  [HasV6MOps,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureMClass,\n                                                       FeatureStrictAlign]>;\n\ndef ARMv7a    : Architecture<\"armv7-a\",   \"ARMv7a\",   [HasV7Ops,\n                                                       FeatureNEON,\n                                                       FeatureDB,\n                                                       FeatureDSP,\n                                                       FeatureAClass]>;\n\ndef ARMv7ve   : Architecture<\"armv7ve\",   \"ARMv7ve\",  [HasV7Ops,\n                                                       FeatureNEON,\n                                                       FeatureDB,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureAClass]>;\n\ndef ARMv7r    : Architecture<\"armv7-r\",   \"ARMv7r\",   [HasV7Ops,\n                                                       FeatureDB,\n                                                       FeatureDSP,\n                                                       FeatureHWDivThumb,\n                                                       FeatureRClass]>;\n\ndef ARMv7m    : Architecture<\"armv7-m\",   \"ARMv7m\",   [HasV7Ops,\n                                                       FeatureThumb2,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureHWDivThumb,\n                                                       FeatureMClass]>;\n\ndef ARMv7em   : Architecture<\"armv7e-m\",  \"ARMv7em\",  [HasV7Ops,\n                                                       FeatureThumb2,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureHWDivThumb,\n                                                       FeatureMClass,\n                                                       FeatureDSP]>;\n\ndef ARMv8a    : Architecture<\"armv8-a\",   \"ARMv8a\",   [HasV8Ops,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC]>;\n\ndef ARMv81a   : Architecture<\"armv8.1-a\", \"ARMv81a\",  [HasV8_1aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC]>;\n\ndef ARMv82a   : Architecture<\"armv8.2-a\", \"ARMv82a\",  [HasV8_2aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS]>;\n\ndef ARMv83a   : Architecture<\"armv8.3-a\", \"ARMv83a\",  [HasV8_3aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS]>;\n\ndef ARMv84a   : Architecture<\"armv8.4-a\", \"ARMv84a\",  [HasV8_4aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\n\ndef ARMv85a   : Architecture<\"armv8.5-a\", \"ARMv85a\",  [HasV8_5aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\ndef ARMv86a   : Architecture<\"armv8.6-a\", \"ARMv86a\",  [HasV8_6aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\ndef ARMv87a   : Architecture<\"armv8.7-a\", \"ARMv87a\",  [HasV8_7aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCrypto,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\n\ndef ARMv9a   : Architecture<\"armv9-a\", \"ARMv9a\",       [HasV9_0aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\ndef ARMv91a   : Architecture<\"armv9.1-a\", \"ARMv91a\",   [HasV9_1aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\ndef ARMv92a   : Architecture<\"armv9.2-a\", \"ARMv92a\",  [HasV9_2aOps,\n                                                       FeatureAClass,\n                                                       FeatureDB,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON,\n                                                       FeatureDSP,\n                                                       FeatureTrustZone,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureCRC,\n                                                       FeatureRAS,\n                                                       FeatureDotProd]>;\n\ndef ARMv8r    : Architecture<\"armv8-r\",   \"ARMv8r\",   [HasV8Ops,\n                                                       FeatureRClass,\n                                                       FeatureDB,\n                                                       FeatureDFB,\n                                                       FeatureDSP,\n                                                       FeatureCRC,\n                                                       FeatureMP,\n                                                       FeatureVirtualization,\n                                                       FeatureFPARMv8,\n                                                       FeatureNEON]>;\n\ndef ARMv8mBaseline : Architecture<\"armv8-m.base\", \"ARMv8mBaseline\",\n                                                      [HasV8MBaselineOps,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureHWDivThumb,\n                                                       FeatureV7Clrex,\n                                                       Feature8MSecExt,\n                                                       FeatureAcquireRelease,\n                                                       FeatureMClass,\n                                                       FeatureStrictAlign]>;\n\ndef ARMv8mMainline : Architecture<\"armv8-m.main\", \"ARMv8mMainline\",\n                                                      [HasV8MMainlineOps,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureHWDivThumb,\n                                                       Feature8MSecExt,\n                                                       FeatureAcquireRelease,\n                                                       FeatureMClass]>;\n\ndef ARMv81mMainline : Architecture<\"armv8.1-m.main\", \"ARMv81mMainline\",\n                                                      [HasV8_1MMainlineOps,\n                                                       FeatureNoARM,\n                                                       ModeThumb,\n                                                       FeatureDB,\n                                                       FeatureHWDivThumb,\n                                                       Feature8MSecExt,\n                                                       FeatureAcquireRelease,\n                                                       FeatureMClass,\n                                                       FeatureRAS,\n                                                       FeatureLOB]>;\n\n// Aliases\ndef IWMMXT   : Architecture<\"iwmmxt\",      \"ARMv5te\",  [ARMv5te]>;\ndef IWMMXT2  : Architecture<\"iwmmxt2\",     \"ARMv5te\",  [ARMv5te]>;\ndef XScale   : Architecture<\"xscale\",      \"ARMv5te\",  [ARMv5te]>;\ndef ARMv6j   : Architecture<\"armv6j\",      \"ARMv7a\",   [ARMv6]>;\ndef ARMv7k   : Architecture<\"armv7k\",      \"ARMv7a\",   [ARMv7a]>;\ndef ARMv7s   : Architecture<\"armv7s\",      \"ARMv7a\",   [ARMv7a]>;\n\n//===----------------------------------------------------------------------===//\n// Register File Description\n//===----------------------------------------------------------------------===//\n\ninclude \"ARMRegisterInfo.td\"\ninclude \"ARMRegisterBanks.td\"\ninclude \"ARMCallingConv.td\"\n\n//===----------------------------------------------------------------------===//\n// ARM schedules.\n//===----------------------------------------------------------------------===//\n//\ninclude \"ARMPredicates.td\"\ninclude \"ARMSchedule.td\"\n\n//===----------------------------------------------------------------------===//\n// Instruction Descriptions\n//===----------------------------------------------------------------------===//\n\ninclude \"ARMInstrInfo.td\"\ndef ARMInstrInfo : InstrInfo;\n\n//===----------------------------------------------------------------------===//\n// ARM schedules\n//\ninclude \"ARMScheduleV6.td\"\ninclude \"ARMScheduleA8.td\"\ninclude \"ARMScheduleA9.td\"\ninclude \"ARMScheduleSwift.td\"\ninclude \"ARMScheduleR52.td\"\ninclude \"ARMScheduleA57.td\"\ninclude \"ARMScheduleM4.td\"\ninclude \"ARMScheduleM7.td\"\n\n//===----------------------------------------------------------------------===//\n// ARM processors\n//\n// Dummy CPU, used to target architectures\ndef : ProcessorModel<\"generic\",     CortexA8Model,      []>;\n\n// FIXME: Several processors below are not using their own scheduler\n// model, but one of similar/previous processor. These should be fixed.\n\ndef : ProcNoItin<\"arm8\",                                [ARMv4]>;\ndef : ProcNoItin<\"arm810\",                              [ARMv4]>;\ndef : ProcNoItin<\"strongarm\",                           [ARMv4]>;\ndef : ProcNoItin<\"strongarm110\",                        [ARMv4]>;\ndef : ProcNoItin<\"strongarm1100\",                       [ARMv4]>;\ndef : ProcNoItin<\"strongarm1110\",                       [ARMv4]>;\n\ndef : ProcNoItin<\"arm7tdmi\",                            [ARMv4t]>;\ndef : ProcNoItin<\"arm7tdmi-s\",                          [ARMv4t]>;\ndef : ProcNoItin<\"arm710t\",                             [ARMv4t]>;\ndef : ProcNoItin<\"arm720t\",                             [ARMv4t]>;\ndef : ProcNoItin<\"arm9\",                                [ARMv4t]>;\ndef : ProcNoItin<\"arm9tdmi\",                            [ARMv4t]>;\ndef : ProcNoItin<\"arm920\",                              [ARMv4t]>;\ndef : ProcNoItin<\"arm920t\",                             [ARMv4t]>;\ndef : ProcNoItin<\"arm922t\",                             [ARMv4t]>;\ndef : ProcNoItin<\"arm940t\",                             [ARMv4t]>;\ndef : ProcNoItin<\"ep9312\",                              [ARMv4t]>;\n\ndef : ProcNoItin<\"arm10tdmi\",                           [ARMv5t]>;\ndef : ProcNoItin<\"arm1020t\",                            [ARMv5t]>;\n\ndef : ProcNoItin<\"arm9e\",                               [ARMv5te]>;\ndef : ProcNoItin<\"arm926ej-s\",                          [ARMv5te]>;\ndef : ProcNoItin<\"arm946e-s\",                           [ARMv5te]>;\ndef : ProcNoItin<\"arm966e-s\",                           [ARMv5te]>;\ndef : ProcNoItin<\"arm968e-s\",                           [ARMv5te]>;\ndef : ProcNoItin<\"arm10e\",                              [ARMv5te]>;\ndef : ProcNoItin<\"arm1020e\",                            [ARMv5te]>;\ndef : ProcNoItin<\"arm1022e\",                            [ARMv5te]>;\ndef : ProcNoItin<\"xscale\",                              [ARMv5te]>;\ndef : ProcNoItin<\"iwmmxt\",                              [ARMv5te]>;\n\ndef : Processor<\"arm1136j-s\",       ARMV6Itineraries,   [ARMv6]>;\ndef : Processor<\"arm1136jf-s\",      ARMV6Itineraries,   [ARMv6,\n                                                         FeatureVFP2,\n                                                         FeatureHasSlowFPVMLx]>;\n\ndef : Processor<\"cortex-m0\",        ARMV6Itineraries,   [ARMv6m,\n                                                         FeatureHasNoBranchPredictor]>;\ndef : Processor<\"cortex-m0plus\",    ARMV6Itineraries,   [ARMv6m,\n                                                         FeatureHasNoBranchPredictor]>;\ndef : Processor<\"cortex-m1\",        ARMV6Itineraries,   [ARMv6m,\n                                                         FeatureHasNoBranchPredictor]>;\ndef : Processor<\"sc000\",            ARMV6Itineraries,   [ARMv6m,\n                                                         FeatureHasNoBranchPredictor]>;\n\ndef : Processor<\"arm1176jz-s\",      ARMV6Itineraries,   [ARMv6kz]>;\ndef : Processor<\"arm1176jzf-s\",     ARMV6Itineraries,   [ARMv6kz,\n                                                         FeatureVFP2,\n                                                         FeatureHasSlowFPVMLx]>;\n\ndef : Processor<\"mpcorenovfp\",      ARMV6Itineraries,   [ARMv6k]>;\ndef : Processor<\"mpcore\",           ARMV6Itineraries,   [ARMv6k,\n                                                         FeatureVFP2,\n                                                         FeatureHasSlowFPVMLx]>;\n\ndef : Processor<\"arm1156t2-s\",      ARMV6Itineraries,   [ARMv6t2]>;\ndef : Processor<\"arm1156t2f-s\",     ARMV6Itineraries,   [ARMv6t2,\n                                                         FeatureVFP2,\n                                                         FeatureHasSlowFPVMLx]>;\n\ndef : ProcessorModel<\"cortex-a5\",   CortexA8Model,      [ARMv7a, ProcA5,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureTrustZone,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureMP,\n                                                         FeatureVFP4]>;\n\ndef : ProcessorModel<\"cortex-a7\",   CortexA8Model,      [ARMv7a, ProcA7,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureTrustZone,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHasVMLxHazards,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureMP,\n                                                         FeatureVFP4,\n                                                         FeatureVirtualization]>;\n\ndef : ProcessorModel<\"cortex-a8\",   CortexA8Model,      [ARMv7a, ProcA8,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureNonpipelinedVFP,\n                                                         FeatureTrustZone,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHasVMLxHazards,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureVMLxForwarding]>;\n\ndef : ProcessorModel<\"cortex-a9\",   CortexA9Model,      [ARMv7a, ProcA9,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureTrustZone,\n                                                         FeatureHasVMLxHazards,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureFP16,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureExpandMLx,\n                                                         FeaturePreferVMOVSR,\n                                                         FeatureMuxedUnits,\n                                                         FeatureNEONForFPMovs,\n                                                         FeatureCheckVLDnAlign,\n                                                         FeatureMP]>;\n\ndef : ProcessorModel<\"cortex-a12\",  CortexA9Model,      [ARMv7a, ProcA12,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureTrustZone,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureVFP4,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureVirtualization,\n                                                         FeatureMP]>;\n\ndef : ProcessorModel<\"cortex-a15\",  CortexA9Model,      [ARMv7a, ProcA15,\n                                                         FeatureDontWidenVMOVS,\n                                                         FeatureSplatVFPToNeon,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureMuxedUnits,\n                                                         FeatureTrustZone,\n                                                         FeatureVFP4,\n                                                         FeatureMP,\n                                                         FeatureCheckVLDnAlign,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureVirtualization]>;\n\ndef : ProcessorModel<\"cortex-a17\",  CortexA9Model,      [ARMv7a, ProcA17,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureTrustZone,\n                                                         FeatureMP,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureVFP4,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureVirtualization]>;\n\n// FIXME: krait has currently the same features as A9 plus VFP4 and  HWDiv\ndef : ProcessorModel<\"krait\",       CortexA9Model,      [ARMv7a, ProcKrait,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureMuxedUnits,\n                                                         FeatureCheckVLDnAlign,\n                                                         FeatureVMLxForwarding,\n                                                         FeatureFP16,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureVFP4,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM]>;\n\ndef : ProcessorModel<\"swift\",       SwiftModel,         [ARMv7a, ProcSwift,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureNEONForFP,\n                                                         FeatureVFP4,\n                                                         FeatureUseWideStrideVFP,\n                                                         FeatureMP,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureAvoidMOVsShOp,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureHasVMLxHazards,\n                                                         FeatureProfUnpredicate,\n                                                         FeaturePrefISHSTBarrier,\n                                                         FeatureSlowOddRegister,\n                                                         FeatureSlowLoadDSubreg,\n                                                         FeatureSlowVGETLNi32,\n                                                         FeatureSlowVDUP32,\n                                                         FeatureUseMISched,\n                                                         FeatureNoPostRASched]>;\n\ndef : ProcessorModel<\"cortex-r4\",   CortexA8Model,      [ARMv7r, ProcR4,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureAvoidPartialCPSR]>;\n\ndef : ProcessorModel<\"cortex-r4f\",  CortexA8Model,      [ARMv7r, ProcR4,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureVFP3_D16,\n                                                         FeatureAvoidPartialCPSR]>;\n\ndef : ProcessorModel<\"cortex-r5\",   CortexA8Model,      [ARMv7r, ProcR5,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureVFP3_D16,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHWDivARM,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureAvoidPartialCPSR]>;\n\ndef : ProcessorModel<\"cortex-r7\",   CortexA8Model,      [ARMv7r, ProcR7,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureVFP3_D16,\n                                                         FeatureFP16,\n                                                         FeatureMP,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHWDivARM,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureAvoidPartialCPSR]>;\n\ndef : ProcessorModel<\"cortex-r8\",   CortexA8Model,      [ARMv7r,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureVFP3_D16,\n                                                         FeatureFP16,\n                                                         FeatureMP,\n                                                         FeatureSlowFPBrcc,\n                                                         FeatureHWDivARM,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureAvoidPartialCPSR]>;\n\ndef : ProcessorModel<\"cortex-m3\",   CortexM4Model,      [ARMv7m,\n                                                         ProcM3,\n                                                         FeaturePrefLoopAlign32,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor]>;\n\ndef : ProcessorModel<\"sc300\",       CortexM4Model,      [ARMv7m,\n                                                         ProcM3,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor]>;\n\ndef : ProcessorModel<\"cortex-m4\", CortexM4Model,        [ARMv7em,\n                                                         FeatureVFP4_D16_SP,\n                                                         FeaturePrefLoopAlign32,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor]>;\n\ndef : ProcessorModel<\"cortex-m7\", CortexM7Model,        [ARMv7em,\n                                                         ProcM7,\n                                                         FeatureFPARMv8_D16,\n                                                         FeatureUseMISched]>;\n\ndef : ProcNoItin<\"cortex-m23\",                          [ARMv8mBaseline,\n                                                         FeatureNoMovt,\n                                                         FeatureHasNoBranchPredictor]>;\n\ndef : ProcessorModel<\"cortex-m33\", CortexM4Model,       [ARMv8mMainline,\n                                                         FeatureDSP,\n                                                         FeatureFPARMv8_D16_SP,\n                                                         FeaturePrefLoopAlign32,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor,\n                                                         FeatureFixCMSE_CVE_2021_35465]>;\n\ndef : ProcessorModel<\"cortex-m35p\", CortexM4Model,      [ARMv8mMainline,\n                                                         FeatureDSP,\n                                                         FeatureFPARMv8_D16_SP,\n                                                         FeaturePrefLoopAlign32,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor,\n                                                         FeatureFixCMSE_CVE_2021_35465]>;\n\ndef : ProcessorModel<\"cortex-m55\", CortexM4Model,      [ARMv81mMainline,\n                                                         FeatureDSP,\n                                                         FeatureFPARMv8_D16,\n                                                         FeatureUseMISched,\n                                                         FeatureHasNoBranchPredictor,\n                                                         FeaturePrefLoopAlign32,\n                                                         FeatureHasSlowFPVMLx,\n                                                         HasMVEFloatOps,\n                                                         FeatureFixCMSE_CVE_2021_35465]>;\n\ndef : ProcNoItin<\"cortex-a32\",                           [ARMv8a,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC]>;\n\ndef : ProcNoItin<\"cortex-a35\",                          [ARMv8a, ProcA35,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC]>;\n\ndef : ProcNoItin<\"cortex-a53\",                          [ARMv8a, ProcA53,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFPAO]>;\n\ndef : ProcNoItin<\"cortex-a55\",                          [ARMv82a, ProcA55,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureDotProd]>;\n\ndef : ProcessorModel<\"cortex-a57\",  CortexA57Model,     [ARMv8a, ProcA57,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFPAO,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureCheapPredicableCPSR]>;\n\ndef : ProcessorModel<\"cortex-a72\",  CortexA57Model,     [ARMv8a, ProcA72,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC]>;\n\ndef : ProcNoItin<\"cortex-a73\",                          [ARMv8a, ProcA73,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC]>;\n\ndef : ProcNoItin<\"cortex-a75\",                          [ARMv82a, ProcA75,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"cortex-a76\",                          [ARMv82a, ProcA76,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"cortex-a76ae\",                        [ARMv82a, ProcA76,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"cortex-a77\",                          [ARMv82a, ProcA77,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"cortex-a78\",                          [ARMv82a, ProcA78,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"cortex-a78c\",                         [ARMv82a, ProcA78C,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureDotProd,\n                                                         FeatureFullFP16]>;\n\ndef : ProcNoItin<\"cortex-a710\",                         [ARMv9a, ProcA710,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureFP16FML,\n                                                         FeatureBF16,\n                                                         FeatureMatMulInt8,\n                                                         FeatureSB]>;\n\ndef : ProcNoItin<\"cortex-x1\",                           [ARMv82a, ProcX1,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"neoverse-v1\",                         [ARMv84a,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureFullFP16,\n                                                         FeatureBF16,\n                                                         FeatureMatMulInt8]>;\n\ndef : ProcNoItin<\"neoverse-n1\",                         [ARMv82a,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"neoverse-n2\",                         [ARMv85a,\n                                                         FeatureBF16,\n                                                         FeatureMatMulInt8,\n                                                         FeaturePerfMon]>;\n\ndef : ProcessorModel<\"cyclone\",     SwiftModel,         [ARMv8a, ProcSwift,\n                                                         FeatureHasRetAddrStack,\n                                                         FeatureNEONForFP,\n                                                         FeatureVFP4,\n                                                         FeatureMP,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureAvoidPartialCPSR,\n                                                         FeatureAvoidMOVsShOp,\n                                                         FeatureHasSlowFPVMLx,\n                                                         FeatureHasSlowFPVFMx,\n                                                         FeatureCrypto,\n                                                         FeatureUseMISched,\n                                                         FeatureZCZeroing,\n                                                         FeatureNoPostRASched]>;\n\ndef : ProcNoItin<\"exynos-m3\",                           [ARMv8a, ProcExynos]>;\ndef : ProcNoItin<\"exynos-m4\",                           [ARMv82a, ProcExynos,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\ndef : ProcNoItin<\"exynos-m5\",                           [ARMv82a, ProcExynos,\n                                                         FeatureFullFP16,\n                                                         FeatureDotProd]>;\n\ndef : ProcNoItin<\"kryo\",                                [ARMv8a, ProcKryo,\n                                                         FeatureHWDivThumb,\n                                                         FeatureHWDivARM,\n                                                         FeatureCrypto,\n                                                         FeatureCRC]>;\n\ndef : ProcessorModel<\"cortex-r52\", CortexR52Model,      [ARMv8r, ProcR52,\n                                                         FeatureUseMISched,\n                                                         FeatureFPAO]>;\n\n//===----------------------------------------------------------------------===//\n// Declare the target which we are implementing\n//===----------------------------------------------------------------------===//\n\ndef ARMAsmWriter : AsmWriter {\n  string AsmWriterClassName  = \"InstPrinter\";\n  int PassSubtarget = 1;\n  int Variant = 0;\n  bit isMCAsmWriter = 1;\n}\n\ndef ARMAsmParser : AsmParser {\n  bit ReportMultipleNearMisses = 1;\n}\n\ndef ARMAsmParserVariant : AsmParserVariant {\n  int Variant = 0;\n  string Name = \"ARM\";\n  string BreakCharacters = \".\";\n}\n\ndef ARM : Target {\n  // Pull in Instruction Info.\n  let InstructionSet = ARMInstrInfo;\n  let AssemblyWriters = [ARMAsmWriter];\n  let AssemblyParsers = [ARMAsmParser];\n  let AssemblyParserVariants = [ARMAsmParserVariant];\n  let AllowRegisterRenaming = 1;\n}\n"
  },
  {
    "path": "tests/inputs/Test.daml",
    "content": "-- https://raw.githubusercontent.com/digital-asset/daml/refs/heads/main/sdk/test-common/src/main/daml/model/Test.daml\n-- (truncated)\n-- Copyright (c) 2025 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n-- SPDX-License-Identifier: Apache-2.0\n\n{-# LANGUAGE CPP #-}\n\n-- file that contains the declarations used in the sandbox tests\n\nmodule Test where\n\nimport Iou()\nimport IouTrade()\n\ntemplate Dummy\n  with\n    operator : Party\n  where\n    signatory operator\n\n    choice DummyChoice1 : ()\n      controller operator\n      do return ()\n\n    choice FailingChoice : ()\n      controller operator\n      do assert False\n\n    nonconsuming choice Clone: ContractId Dummy\n      controller operator\n      do create Dummy with operator\n\n    nonconsuming choice FailingClone : ()\n      controller operator\n      do clone <- exercise self Clone\n         exercise self FailingChoice\n\n    choice ConsumeIfTimeIsBetween : ()\n      with\n        begin : Time\n        end : Time\n      controller operator\n      do currentTime <- getTime\n         assert (begin <= currentTime)\n         assert (currentTime <= end)\n\n    choice WrapWithAddress : ContractId AddressWrapper\n      with address : Address\n      controller operator\n      do create AddressWrapper with operator; address\n\n    choice PublicChoice: ()\n      with\n        anyParty: Party\n      controller anyParty\n      do return ()\n\ndata Address = Address\n  { street: Text\n  , city: Text\n  , state: Text\n  , zip: Text\n  } deriving (Eq, Show)\n\n-- DEL-4615\ntemplate AddressWrapper\n  with\n    operator: Party\n    address: Address\n  where\n    signatory operator\n"
  },
  {
    "path": "tests/inputs/Tk",
    "content": "#!/usr/local/bin/wish -f\n# from http://www.roesler-ac.de/wolfram/hello.htm\n# Hello World in Tk\n\nlabel .l -text \"Hello World!\"\npack .l\n"
  },
  {
    "path": "tests/inputs/Trapezoid_Rule.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Basic Numerical Integration: the Trapezoid Rule\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"A simple illustration of the trapezoid rule for definite integration:\\n\",\n    \"\\n\",\n    \"$$\\n\",\n    \"\\\\int_{a}^{b} f(x)\\\\, dx \\\\approx \\\\frac{1}{2} \\\\sum_{k=1}^{N} \\\\left( x_{k} - x_{k-1} \\\\right) \\\\left( f(x_{k}) + f(x_{k-1}) \\\\right).\\n\",\n    \"$$\\n\",\n    \"<br>\\n\",\n    \"First, we define a simple function and sample it between 0 and 10 at 200 points\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%matplotlib inline\\n\",\n    \"import numpy as np\\n\",\n    \"import matplotlib.pyplot as plt\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"def f(x):\\n\",\n    \"    return (x-3)*(x-5)*(x-7)+85\\n\",\n    \"\\n\",\n    \"x = np.linspace(0, 10, 200)\\n\",\n    \"y = f(x)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Choose a region to integrate over and take only a few points in that region\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"a, b = 1, 8 # the left and right boundaries\\n\",\n    \"N = 5 # the number of points\\n\",\n    \"xint = np.linspace(a, b, N)\\n\",\n    \"yint = f(xint)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Plot both the function and the area below it in the trapezoid approximation\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"plt.plot(x, y, lw=2)\\n\",\n    \"plt.axis([0, 9, 0, 140])\\n\",\n    \"plt.fill_between(xint, 0, yint, facecolor='gray', alpha=0.4)\\n\",\n    \"plt.text(0.5 * (a + b), 30,r\\\"$\\\\int_a^b f(x)dx$\\\", horizontalalignment='center', fontsize=20);\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Compute the integral both at high accuracy and with the trapezoid approximation\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"The integral is: 565.2499999999999 +/- 6.275535646693696e-12\\n\",\n      \"The trapezoid approximation with 5 points is: 559.890625\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"from __future__ import print_function\\n\",\n    \"from scipy.integrate import quad\\n\",\n    \"integral, error = quad(f, a, b)\\n\",\n    \"integral_trapezoid = sum( (xint[1:] - xint[:-1]) * (yint[1:] + yint[:-1]) ) / 2\\n\",\n    \"print(\\\"The integral is:\\\", integral, \\\"+/-\\\", error)\\n\",\n    \"print(\\\"The trapezoid approximation with\\\", len(xint), \\\"points is:\\\", integral_trapezoid)\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.4.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 0\n}\n"
  },
  {
    "path": "tests/inputs/TypeScript.ts",
    "content": "//\n// Copyright (c) Microsoft Corporation.  All rights reserved.\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//   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\nmodule TypeScript {\n    class Base64Format {\n        static encodedValues = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n        static encode(inValue: number) {\n            if (inValue < 64) {\n                return Base64Format.encodedValues.charAt(inValue);\n            }\n            throw TypeError(inValue + \": not a 64 based value\");\n        }\n\n        static decodeChar(inChar: string) {\n            if (inChar.length === 1) {\n                return Base64Format.encodedValues.indexOf(inChar);\n            } else {\n                throw TypeError('\"' + inChar + '\" must have length 1');\n            }\n        }\n    }\n\n    export class Base64VLQFormat {\n        static encode(inValue: number) {\n            // Add a new least significant bit that has the sign of the value.\n            // if negative number the least significant bit that gets added to the number has value 1\n            // else least significant bit value that gets added is 0\n            // eg. -1 changes to binary : 01 [1] => 3\n            //     +1 changes to binary : 01 [0] => 2\n            if (inValue < 0) {\n                inValue = ((-inValue) << 1) + 1;\n            }\n            else {\n                inValue = inValue << 1;\n            }\n\n            // Encode 5 bits at a time starting from least significant bits\n            var encodedStr = \"\";\n            do {\n                var currentDigit = inValue & 31; // 11111\n                inValue = inValue >> 5;\n                if (inValue > 0) {\n                    // There are still more digits to decode, set the msb (6th bit)\n                    currentDigit = currentDigit | 32; \n                }\n                encodedStr = encodedStr + Base64Format.encode(currentDigit);\n            } while (inValue > 0);\n\n            return encodedStr;\n        }\n\n        static decode(inString: string) {\n            var result = 0;\n            var negative = false;\n\n            var shift = 0;\n            for (var i = 0; i < inString.length; i++) {\n                var byte = Base64Format.decodeChar(inString[i]);\n                if (i === 0) {\n                    // Sign bit appears in the LSBit of the first value\n                    if ((byte & 1) === 1) {\n                        negative = true;\n                    }\n                    result = (byte >> 1) & 15; // 1111x\n                } else {\n                    result = result | ((byte & 31) << shift); // 11111\n                }\n\n                shift += (i === 0) ? 4 : 5;\n\n                if ((byte & 32) === 32) {\n                    // Continue\n                } else {\n                    return { value: negative ? -(result) : result, rest: inString.substr(i + 1) };\n                }\n            }\n\n            throw new Error(getDiagnosticMessage(DiagnosticCode.Base64_value_0_finished_with_a_continuation_bit, [inString]));\n        }\n    }\n}\n\n"
  },
  {
    "path": "tests/inputs/TypeScript_2.ts",
    "content": "import { createServer } from 'http'                    // from @frankdugan3, an example of TypeScript code\n                                                      \nexport const server = createServer((req, res) => {     // that was misidentified as Qt Linguist in cloc\n  res.writeHead(200, { 'Content-type': 'text/plain' }) // versions before 1.78\n  res.write('Hello world!')\n  res.end()\n}).listen(8080)\n"
  },
  {
    "path": "tests/inputs/USS.uss",
    "content": "/* https://github.com/AlDanial/cloc/pull/919 */\n/* name selector (like ID selector in CSS) */\n#root {\n    /* \n    some style\n    this is an example of a multiline comment \n    */\n}\n\n/* class selector (like in CSS) */\n.hidden {\n    display: none;\n}\n"
  },
  {
    "path": "tests/inputs/UXML.uxml",
    "content": "<!-- https://github.com/AlDanial/cloc/pull/919 -->\n<ui:UXML xmlns:ui=\"UnityEngine.UIElements\" xmlns:uie=\"UnityEditor.UIElements\" editor-extension-mode=\"False\">\n    <!-- Importing styles from uss file -->\n    <Style src=\"project://database/Assets/UI/Resources/common.uss?fileID=7433441132597879392&amp;guid=c5fd8770b48bac1e48d6087c0a2e0230&amp;type=3#common\" />\n    <!-- Instantiating build-in control (Button) -->\n    <ui:Button text=\"Choose me\" name=\"choice\" />\n</ui:UXML>\n"
  },
  {
    "path": "tests/inputs/X++.xpo",
    "content": "Exportfile for AOT version 1.0 or later\nFormatversion: 1\n\n***Element: CLS\n\n; Microsoft Dynamics Class: HelloWorld nicht geladen\n; --------------------------------------------------------------------------------\n  CLSVERSION 1\n  \n  CLASS #HelloWorld\n    Id 42000\n    PROPERTIES\n      Name                #HelloWorld\n      Extends             #\n      RunOn               #Called from\n    ENDPROPERTIES\n    \n    METHODS\n      Version: 3\n      SOURCE #classDeclaration\n        #class HelloWorld\n        #{\n        #}\n      ENDSOURCE\n      SOURCE #hello\n        #/**\n        # * This is a javadoc like documentation comment.\n        # *\n        # * This entire comment counts as 6 lines,\n        # * because it has two lines in the long description.\n        # */\n        #public string hello()\n        #{\n        #    // This is comment line #7. The next line should be counted as an empty line.\n        #\n        #    return \"Hello World!\"; /* This comment is not counted, because it is not a line of its own.\n        #                              This counts as comment #8\n        #                              And this is comment #9 */\n        #\n        #    // Comment #10. Two more empty lines - one above this line, one below.\n        #\n        #}\n      ENDSOURCE\n  SOURCE #someJob\n    #/**\n    # * For exported job files, the indentation is only 4 whitespaces.\n    # *\n    # * I have to admit that I have never seen a source file mixing these two different\n    # * indentation styles. This is only for the test case.\n    # */\n    #public string someJob()\n    #{\n    #    return nothingIsDoneHere();\n    #}\n  ENDSOURCE      \n    ENDMETHODS\n  ENDCLASS\n\n***Element: END\n"
  },
  {
    "path": "tests/inputs/XML.xml",
    "content": "<!-- from http://www.roesler-ac.de/wolfram/hello.htm -->\r\n<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<?xml-stylesheet type=\"text/xsl\" href=\"HelloWorld.xsl\" ?>\r\n<!-- Hello World in XML -->\r\n<text><string>Hello, World</string></text>\r\n"
  },
  {
    "path": "tests/inputs/XSL-FO.xsl",
    "content": "<!-- from http://www.roesler-ac.de/wolfram/hello.htm -->\r\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<!-- Hello World in XSL-FO -->\r\n<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\r\n    <fo:layout-master-set>\r\n        <fo:simple-page-master master-name=\"LetterPage\" page-width=\"8.5in\" page-height=\"11in\">?\r\n            <fo:region-body region-name=\"PageBody\" margin=\"0.7in\"/>\r\n        </fo:simple-page-master>\r\n    </fo:layout-master-set>\r\n    <fo:page-sequence master-reference=\"LetterPage\">\r\n        <fo:flow flow-name=\"PageBody\">\r\n            <fo:block font-size=\"12pt\" font-family=\"courier\">Hello, World</fo:block>\r\n        </fo:flow>\r\n    </fo:page-sequence>\r\n</fo:root>\r\n"
  },
  {
    "path": "tests/inputs/XSLT.xslt",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<!-- Hello World in XSLT -->\r\n<!-- from http://www.roesler-ac.de/wolfram/hello.htm -->\r\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\r\n    <xsl:template match=\"/\">\r\n        <xsl:value-of select=\"text/string\" />\r\n    </xsl:template>\r\n</xsl:stylesheet>\r\n"
  },
  {
    "path": "tests/inputs/Xtend.xtend",
    "content": "/* https://raw.githubusercontent.com/tsaglam/JavaCodeEcorification/master/src/main/java/jce/generators/EFactoryImplementationGenerator.xtend\n   with some mods to include ««« inline comments\n   */\npackage jce.generators\n\nimport java.io.File\nimport java.util.List\nimport jce.properties.EcorificationProperties\nimport jce.util.PathHelper\nimport org.eclipse.core.resources.IProject\n\n/**\n * Generator class for the generation of Ecore factory implementation classes.\n * @author Timur Saglam\n */\nclass EFactoryImplementationGenerator extends ClassGenerator {\n\textension PathHelper nameUtil\n\n\t/**\n\t * Basic constructor, sets the properties.\n\t */\n\tnew(EcorificationProperties properties) {\n\t\tsuper(properties)\n\t\tnameUtil = new PathHelper('.')\n\t}\n\n\t/**\n\t * Creates a Ecore Factory in a package path with a specific name. \n\t */\n\tdef public void create(String path, List<String> packageTypes, IProject project) {\n\t\tval currentPackage = path.replace(File.separatorChar, '.') // path to package declaration\n\t\tval interfacePackage = currentPackage.cutLastSegment\n\t\tval packageName = interfacePackage.getLastSegment.toFirstUpper\n\t\tval content = createFactoryContent(currentPackage, packageName, interfacePackage, packageTypes)\n\t\tcreateClass(path, '''«packageName»FactoryImpl.java''', content, project)\n\t\tmonitor.beginTask(''' Created «packageName»FactoryImpl.java''', 0) // detailed logging\n\t}\n\n\t/**\n\t * Creates the content of an Ecore factory.\n\t */\n\tdef private String createFactoryContent(String currentPackage, String packageName, String interfacePackage, List<String> packageTypes) '''\n\t\tpackage «currentPackage»;\n\t\t\n\t\timport org.eclipse.emf.ecore.EClass;\n\t\timport org.eclipse.emf.ecore.EObject;\n\t\timport org.eclipse.emf.ecore.EPackage;\n\t\timport org.eclipse.emf.ecore.impl.EFactoryImpl;\n\t\timport org.eclipse.emf.ecore.plugin.EcorePlugin;\n\t\t\n\t\timport «interfacePackage».«packageName»Factory;\n\t\timport «interfacePackage».«packageName»Package;\n\t\t«FOR type : packageTypes»\n\t\t\timport «interfacePackage.cutFirstSegment».«type»;\n\t\t«ENDFOR»\n\t\t\n\t\t/**\n\t\t * An implementation of the model <b>Factory</b>.\n\t\t * @generated\n\t\t */\n\t\tpublic class «packageName»FactoryImpl extends EFactoryImpl implements «packageName»Factory {\n\t\t    /**\n\t\t     * Creates the default factory implementation.\n\t\t     * <!-- begin-user-doc -->\n\t\t     * <!-- end-user-doc -->\n\t\t     * @generated\n\t\t     */\n\t\t    public static «packageName»Factory init() {\n\t\t        try {\n\t\t            «packageName»Factory the«packageName»Factory = («packageName»Factory)EPackage.Registry.INSTANCE.getEFactory(«packageName»Package.eNS_URI);\n\t\t            if (the«packageName»Factory != null) {\n\t\t                return the«packageName»Factory;\n\t\t            }\n\t\t        }\n\t\t        catch (Exception exception) {\n\t\t            EcorePlugin.INSTANCE.log(exception);\n\t\t        }\n\t\t        return new «packageName»FactoryImpl();\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * Creates an instance of the factory.\n\t\t     * @generated\n\t\t     */\n\t\t    public «packageName»FactoryImpl() {\n\t\t        super();\n\t\t    }\n\t\t\n\t\t    /**\n\t\t     * @generated\n\t\t     */\n\t\t    @Override\n\t\t    public EObject create(EClass eClass) {\n\t\t        switch (eClass.getClassifierID()) {\n\t\t\t\t\t«FOR type : packageTypes»\n\t\t\t\t\t\tcase «packageName»Package.«constantName(type)»: return create«type»();\n\t\t\t\t\t«ENDFOR»\n\t\t\t\t\tdefault:\n\t\t\t\t\t    throw new IllegalArgumentException(\"The class '\" + eClass.getName() + \"' is not a valid classifier\");\n\t\t\t\t\t     }\n\t\t\t\t\t }\n\t\t\t\n\t\t\t«FOR type : packageTypes SEPARATOR blankLine»\n\t\t\t\t«createFactoryMethod(type)»\n\t\t\t«ENDFOR»\n\t\t\t\n\t\t\t/**\n\t\t\t * @generated\n\t\t\t */\n\t\t\tpublic «packageName»Package get«packageName»Package() {\n\t\t\treturn («packageName»Package)getEPackage();\n\t\t\t}\n\t\t\n\t\t    /**\n\t\t     * @deprecated\n\t\t     * @generated\n\t\t     */\n\t\t    @Deprecated\n\t\t    public static «packageName»Package getPackage() {\n\t\t        return «packageName»Package.eINSTANCE;\n\t\t    }\n\t\t    \n\t\t} //«packageName»FactoryImpl\n\t'''\n\n\t/**\n\t * Creates the content of an Ecore factory method.\n\t */\n\tdef private String createFactoryMethod(String className) '''\n\t\t/**\n\t\t * @generated\n\t\t */\n\t\tpublic «className» create«className»() {\n\t\t\treturn new «className»(); // origin code instance\n\t\t}\t\n\t'''\n\n\t/**\n\t * Makes a constant name out of a type name (MyType => MY_TYPE, ABCTest => ABC_TEST)\n\t */\n\tdef private String constantName(String typeName) {\n\t\tvar constantName = \"\" // empty result string\n\t\tvar wasLowerCase = true // last word was lower case\n\t\tfor (String word : typeName.split(\"(?=\\\\p{Upper})\")) { // iterate over every word\n\t\t\tif(containsLowerCase(word) || wasLowerCase) { // if has or comes after lower case letter.\n\t\t\t\tconstantName += '_' // add separator\n\t\t\t}\n\t\t\tconstantName += word.toUpperCase()\n\t\t\twasLowerCase = containsLowerCase(word)\n\t\t}\n\t\treturn constantName.substring(1)\n\t}\n\n\t/**\n\t * Checks whether a String contains lower case characters. \n\t */\n\tdef private boolean containsLowerCase(String string) {\n\t\treturn !string.equals(string.toUpperCase())\n\t}\n}\n"
  },
  {
    "path": "tests/inputs/ZosMsg.mc",
    "content": ";// ZosMsg.h - Messages\r\n;\r\n;#pragma once\r\n;\r\n\r\nMessageIdTypedef=DWORD\r\n\r\nSeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS\r\n               Informational=0x1:STATUS_SEVERITY_INFORMATIONAL\r\n               Warning=0x2:STATUS_SEVERITY_WARNING\r\n               Error=0x3:STATUS_SEVERITY_ERROR\r\n              )\r\n\r\nFacilityNames=(App=0x100:FACILITY_APPLICATION\r\n               Xml=0x00C:FACILITY_XML)\r\n\r\nLanguageNames=(English=0x409:MSG00409)\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_APPL_NOT_AVAILABLE\r\nLanguage=English\r\n%2 is not available on this system: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_ATL_INIT_FAILED\r\nLanguage=English\r\nATL initialization failed.\r\n.\r\n\r\nMessageId= Facility=App Severity=Success SymbolicName=MSG_AUDIT_LOCK_RESET\r\nLanguage=English\r\nAudit lock reset.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_BINARY_CRLF_NOT_SUPPORTED\r\nLanguage=English\r\nBinary CRLF format is not supported by this version of the server.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_BINARY_DATA_NOT_SUPPORTED\r\nLanguage=English\r\nBinary format is not supported by this version of the server.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_CHECKING_IN1\r\nLanguage=English\r\nChecking in component: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_CHECKING_IN2\r\nLanguage=English\r\nChecking in %1!d! component(s) of type %2.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_CHECKING_OUT1\r\nLanguage=English\r\nChecking out component: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_CHECKING_OUT2\r\nLanguage=English\r\nChecking out %1!d! component(s) of type %2.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_CODE_PAGE_INCORRECT\r\nLanguage=English\r\nCode page for %1 is incorrect.  Code page number on server connection properties must match the \"LCLCCSID=%2\" parameter specified on the mainframe started task.  To disable this check, uncheck the \"Validate code page\" check box in the logon dialog box.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_COMMAND_DISABLED\r\nLanguage=English\r\nCommand disabled: %1.\r\n.\r\n\r\nMessageId= Facility=App Severity=Warning SymbolicName=MSG_CONFIRM_CANCEL\r\nLanguage=English\r\nAre you sure you want to cancel the operation?\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_CREATE_EVENT_FAILED\r\nLanguage=English\r\nFailed to create start notification event: %1.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_CREATE_DIRECTORY_FAILED\r\nLanguage=English\r\nFailed to create directory \"%1\": %2.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_DBCS_UNSUPPORTED\r\nLanguage=English\r\nServer software version does not support DBCS code page.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_DISCONNECTUSER_INPROGRESS\r\nLanguage=English\r\nDetach user %1 connection from server %2 in progress.  Time remaing %3!d! minute(s).\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_DRIVER_ERROR\r\nLanguage=English\r\nError connecting to Serena Network file system driver: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_DRIVER_NOT_STARTED\r\nLanguage=English\r\nSerena Network file system driver not started.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_DRIVER_PAUSED\r\nLanguage=English\r\nSerena Network file system has been paused.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_DUMP_CREATED\r\nLanguage=English\r\nDump file created:%n%1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_DUMP_FAILED\r\nLanguage=English\r\nUnable to create dump.%n%1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_EMPTY_FILE\r\nLanguage=English\r\nFile is empty.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_FILE_NOT_FOUND\r\nLanguage=English\r\nFile not found: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_FUNCTION_NOT_COMPLETED\r\nLanguage=English\r\nServer failed to complete this function.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_INCORRECT_CHANGEMAN_PORT\r\nLanguage=English\r\nIncorrect %1 port specified: %2.  The ChangeMan port number must match the \"CMN=nnnn\" parameter specified on the mainframe started task.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_INCORRECT_SERVER_PORT\r\nLanguage=English\r\nIncorrect %1 port specified: %2.  This server port number must match the \"XCH=nnnn\" parameter specified on the mainframe started task.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_JCL_TEXT_INVALID\r\nLanguage=English\r\nJCL text is not valid.  JCL statements must begin with \"//\".\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_JOB_STATEMENT_MISSING\r\nLanguage=English\r\nJOB statement missing.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_MAX_CHARS\r\nLanguage=English\r\nMaximum number of characters that can be specified is %1.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_MAX_LINES\r\nLanguage=English\r\nMaximum number of lines that can be specified is %1.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_NETWORK_ALREADY_STARTED\r\nLanguage=English\r\nSerena Network already started.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_NOT_ALPHA_FIRST\r\nLanguage=English\r\nFirst character must be alphabetic.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_NOT_ALPHANUMERIC\r\nLanguage=English\r\nText must contain only alphanumeric characters.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_NOTIFY_MESSAGE1\r\nLanguage=English\r\n%1.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_NOTIFY_MESSAGE2\r\nLanguage=English\r\n%1: %2.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_NOTIFY_MESSAGE3\r\nLanguage=English\r\n%1(%2): %3.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_PACKAGE_NOT_PARTICIPATING\r\nLanguage=English\r\nPackage %1 not a participating package.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_PART_PACKAGE_ALREADY_BELONGS\r\nLanguage=English\r\nParticipating package %1 already belongs to package %2.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_PASSWORD_MISMATCH\r\nLanguage=English\r\nNew password and confirm password do not match.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_PASSWORD_TOO_SHORT\r\nLanguage=English\r\nNew password phrase must be longert than 8 characters.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_REG_VERSION_MISMATCH\r\nLanguage=English\r\nVersion mismatch with product registration.  Register ChangeMan ZDD again using ZosReg.dll.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_REQUIRED_FIELD\r\nLanguage=English\r\nRequired field is empty.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_SERVER_SHUTDOWN\r\nLanguage=English\r\nServer %1  shutdown in progress.  Immediate termination.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_SERVER_SHUTDOWN_INPROGRESS\r\nLanguage=English\r\nServer %1  shutdown in progress.  Time remaining %2!d! minute(s).\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_SERVER_VERSION_UNSUPPORTED\r\nLanguage=English\r\nServer software version is unsupported.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_STARTED\r\nLanguage=English\r\nSerena Network started.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_STARTING\r\nLanguage=English\r\nSerena Network starting.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_STOPPING\r\nLanguage=English\r\nSerena Network stopping.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_SYSTEM\r\nLanguage=English\r\n%%%1\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_TEMP_FOLDER\r\nLanguage=English\r\nSerena Network temporary folder: \"%1\".\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_TEXT\r\nLanguage=English\r\n%1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_UNSUCCESSFUL\r\nLanguage=English\r\nThe requested operation was unsuccessful.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_UPLOAD_TOO_LARGE\r\nLanguage=English\r\nFile \"%1\" size (%2) exceeds maximum upload size (%3).\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_UPLOAD_WAIT\r\nLanguage=English\r\nWaiting for server to process uploaded data.\r\nThis may take several minutes.\r\n.\r\n\r\nMessageId= Facility=App Severity=Informational SymbolicName=MSG_VALIDATE_VERSIONS_WAIT\r\nLanguage=English\r\nWaiting for server to validate rocess uploaded data.\r\nThis may take several minutes.\r\n.\r\n\r\nMessageId= Facility=App Severity=Warning SymbolicName=MSG_VERSION_SERVER\r\nLanguage=English\r\nServer version does not support this function.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_WAIT_FAILED\r\nLanguage=English\r\nWait failed: %1\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_WINSOCK_INIT_FAILED\r\nLanguage=English\r\nWinSock initialization failed (%1): %2\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ATTRIBUTE_REQUIRED\r\nLanguage=English\r\nRequired \"%2!hs!=\" attribute is missing in <%1!hs!> element.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ATTRIBUTE_NAME_UNRECOGNIZED\r\nLanguage=English\r\nUnrecognized \"%2!hs!=\" attribute in <%1!hs!> element.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ATTRIBUTE_VALUE_INVALID\r\nLanguage=English\r\nInvalid value \"%3\" specified for \"%2!hs!=\" attribute in <%1!hs!> element.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ATTRIBUTE_VALUE_INVALID2\r\nLanguage=English\r\nInvalid value \"%4\" specified for \"%3!hs!=\" attribute in <%1!hs! name=\"%2\"> element.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ELEMENT_NOT_FOUND\r\nLanguage=English\r\nElement <%1!hs!> not found.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_ELEMENT_NAME_UNRECOGNIZED\r\nLanguage=English\r\nUnrecognized element name specified: <%1!hs!>\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_LOCATION\r\nLanguage=English\r\n%1  (Line %2!d!, Position %3!d!)\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_XML_PARSER_NOT_INSTALLED\r\nLanguage=English\r\nXML parser is not installed. XML services will not work.\r\n.\r\n\r\nMessageId= Severity=Error SymbolicName=MSG_XML_WRITER_STATE_INCORRECT\r\nLanguage=English\r\nXML writer is in incorrect state for requested operation.\r\n.\r\n\r\nMessageId= Facility=App Severity=Error SymbolicName=MSG_ZDDOPTS_ERROR\r\nLanguage=English\r\nServer %1 has invalid XML data specified in ZDDOPTS member %2.\r\n.\r\n\r\n"
  },
  {
    "path": "tests/inputs/ZosNet.rc",
    "content": "// Microsoft Visual C++ generated resource script.\r\n//\r\n#include \"Resource.h\"\r\n\r\n#define APSTUDIO_READONLY_SYMBOLS\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 2 resource.\r\n//\r\n#ifndef APSTUDIO_INVOKED\r\n#include \"TargetVer.h\"\r\n#endif\r\n#include <winres.h>\r\n#include \"StdRes.h\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#undef APSTUDIO_READONLY_SYMBOLS\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n// English (United States) resources\r\n\r\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\nLANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US\r\n#pragma code_page(1252)\r\n\r\n#ifdef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// TEXTINCLUDE\r\n//\r\n\r\n1 TEXTINCLUDE\r\nBEGIN\r\n    \"Resource.h\\0\"\r\nEND\r\n\r\n2 TEXTINCLUDE\r\nBEGIN\r\n    \"#ifndef APSTUDIO_INVOKED\\r\\n\"\r\n    \"#include \"\"TargetVer.h\"\"\\r\\n\"\r\n    \"#endif\\r\\n\"\r\n    \"#include <winres.h>\\r\\n\"\r\n    \"#include \"\"StdRes.h\"\"\\r\\0\"\r\nEND\r\n\r\n3 TEXTINCLUDE\r\nBEGIN\r\n    \"#include \"\"Version.rc2\"\"\\r\\n\"\r\n    \"#include \"\"Res\\\\ZosMsg.rc\"\"\\r\\0\"\r\nEND\r\n\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// AVI\r\n//\r\n\r\nIDV_CONNECT             AVI                     \"Res\\\\Connect.avi\"\r\nIDV_COPY_DATASET        AVI                     \"Res\\\\CopyDataSet.avi\"\r\nIDV_DOWNLOAD            AVI                     \"Res\\\\Download.avi\"\r\nIDV_FIND_FILE           AVI                     \"Res\\\\FindFile.avi\"\r\nIDV_UPLOAD              AVI                     \"Res\\\\Upload.avi\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// REGISTRY\r\n//\r\n\r\nIDR_ZOSNET              REGISTRY                \"Res\\\\ZosNet.rgs\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Icon\r\n//\r\n\r\n// Icon with lowest ID value placed first to ensure application icon\r\n// remains consistent on all systems.\r\nIDI_ZOSNETWORK          ICON                    \"Res\\\\ZosNetwork.ico\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Dialog\r\n//\r\n\r\nIDD_CHANGE_PASSWORD1 DIALOGEX 0, 0, 153, 74\r\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nCAPTION \"Change Password\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    LTEXT           \"New password:\",IDC_STATIC,7,10,50,8\r\n    EDITTEXT        IDC_CHANGE_PASSWORD_NEW,85,7,60,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    LTEXT           \"Confirm new password:\",IDC_STATIC,7,32,76,8\r\n    EDITTEXT        IDC_CHANGE_PASSWORD_CONFIRM,85,29,60,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    DEFPUSHBUTTON   \"OK\",IDOK,37,53,50,14\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,96,53,50,14\r\nEND\r\n\r\nIDD_CHANGE_PASSWORD2 DIALOGEX 0, 0, 257, 74\r\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nCAPTION \"Change Password\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    LTEXT           \"New password:\",IDC_STATIC,7,10,50,8\r\n    EDITTEXT        IDC_CHANGE_PASSWORD_NEW,85,7,165,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    LTEXT           \"Confirm new password:\",IDC_STATIC,7,32,76,8\r\n    EDITTEXT        IDC_CHANGE_PASSWORD_CONFIRM,85,29,165,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    DEFPUSHBUTTON   \"OK\",IDOK,141,53,50,14\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,200,53,50,14\r\nEND\r\n\r\nIDD_CONNECTING DIALOGEX 0, 0, 176, 143\r\nSTYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nEXSTYLE WS_EX_TOPMOST\r\nCAPTION \"Connecting...\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    CONTROL         \"\",IDC_CONNECTING_ANIMATE,\"SysAnimate32\",ACS_CENTER | ACS_TRANSPARENT | ACS_AUTOPLAY,7,7,162,48\r\n    LTEXT           \"User:\",IDC_STATIC,7,60,18,8\r\n    LTEXT           \"userid\",IDC_CONNECTING_USERID,43,60,126,8\r\n    LTEXT           \"Server:\",IDC_STATIC,7,74,25,8\r\n    LTEXT           \"server\",IDC_CONNECTING_SERVER,43,74,126,8\r\n    LTEXT           \"Address:\",IDC_STATIC,7,88,30,8\r\n    LTEXT           \"ip.addr\",IDC_CONNECTING_IPADDR,43,88,126,8\r\n    LTEXT           \"Port:\",IDC_STATIC,7,102,17,8\r\n    LTEXT           \"port\",IDC_CONNECTING_PORT,43,102,126,8\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,62,122,50,14\r\nEND\r\n\r\nIDD_JOB_CARD DIALOGEX 0, 0, 353, 85\r\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nCAPTION \"Check In\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    DEFPUSHBUTTON   \"OK\",IDOK,235,64,50,14\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,297,64,50,14\r\n    LTEXT           \"&Job card:\",IDC_STATIC,7,4,103,8\r\n    EDITTEXT        IDC_JOB_CARD,7,16,339,42,ES_MULTILINE | ES_UPPERCASE | ES_AUTOHSCROLL | ES_WANTRETURN\r\nEND\r\n\r\nIDD_LOGON1 DIALOGEX 0, 0, 247, 119\r\nSTYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nEXSTYLE WS_EX_TOPMOST | WS_EX_APPWINDOW\r\nCAPTION \"Logon\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    LTEXT           \"User ID:\",IDC_STATIC,7,10,28,8\r\n    EDITTEXT        IDC_LOGON_USERID,42,7,72,14,ES_UPPERCASE | ES_AUTOHSCROLL\r\n    LTEXT           \"Password:\",IDC_LABEL0,7,32,34,8\r\n    EDITTEXT        IDC_LOGON_PASSWORD,42,29,72,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    LTEXT           \"Address:\",IDC_STATIC,7,54,30,8\r\n    EDITTEXT        IDC_LOGON_IPADDR,42,51,72,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP\r\n    LTEXT           \"Port:\",IDC_STATIC,7,77,17,8\r\n    EDITTEXT        IDC_LOGON_PORT,41,74,72,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP\r\n    CONTROL         \"Use Windows password\",IDC_LOGON_WINDOWS_PASSWORD,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,143,9,91,10\r\n    CONTROL         \"Change password\",IDC_LOGON_CHANGE_PASSWORD,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,143,31,73,10\r\n    CONTROL         \"Enable notify messages\",IDC_LOGON_NOTIFY,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,143,53,91,10\r\n    CONTROL         \"Validate code page \",IDC_LOGON_CHECK_CODE_PAGE,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,143,76,79,10\r\n    DEFPUSHBUTTON   \"OK\",IDOK,123,98,50,14\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,190,98,50,14\r\nEND\r\n\r\nIDD_LOGON2 DIALOGEX 0, 0, 297, 95\r\nSTYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nEXSTYLE WS_EX_TOPMOST | WS_EX_APPWINDOW\r\nCAPTION \"Logon\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    LTEXT           \"User ID:\",IDC_STATIC,7,10,28,8\r\n    EDITTEXT        IDC_LOGON_USERID,42,7,63,14,ES_UPPERCASE | ES_AUTOHSCROLL\r\n    LTEXT           \"Address:\",IDC_STATIC,117,10,30,8\r\n    EDITTEXT        IDC_LOGON_IPADDR,152,7,72,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP\r\n    LTEXT           \"Port:\",IDC_STATIC,235,10,17,8\r\n    EDITTEXT        IDC_LOGON_PORT,257,7,34,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP\r\n    LTEXT           \"Password:\",IDC_LABEL0,7,32,34,8\r\n    EDITTEXT        IDC_LOGON_PASSWORD,42,29,248,14,ES_PASSWORD | ES_AUTOHSCROLL\r\n    CONTROL         \"Use Windows password\",IDC_LOGON_WINDOWS_PASSWORD,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,7,56,91,10\r\n    CONTROL         \"Change password\",IDC_LOGON_CHANGE_PASSWORD,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,7,76,81,10\r\n    CONTROL         \"Enable notify messages\",IDC_LOGON_NOTIFY,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,117,56,91,10\r\n    CONTROL         \"Validate code page \",IDC_LOGON_CHECK_CODE_PAGE,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,117,76,79,10\r\n    DEFPUSHBUTTON   \"OK\",IDOK,240,54,50,14\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,240,74,50,14\r\nEND\r\n\r\nIDD_PROGRESS DIALOGEX 0, 0, 204, 113\r\nSTYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU\r\nEXSTYLE WS_EX_APPWINDOW\r\nCAPTION \"Progress...\"\r\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\r\nBEGIN\r\n    CONTROL         \"\",IDC_PROGRESS_ANIMATE,\"SysAnimate32\",ACS_CENTER | ACS_TRANSPARENT | ACS_AUTOPLAY,7,7,190,48,WS_EX_TRANSPARENT\r\n    LTEXT           \"text-0\",IDC_PROGRESS_TEXT0,7,57,190,8\r\n    LTEXT           \"text-1\",IDC_PROGRESS_TEXT1,7,69,190,16\r\n    PUSHBUTTON      \"Cancel\",IDCANCEL,76,92,50,14\r\nEND\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// DESIGNINFO\r\n//\r\n\r\n#ifdef APSTUDIO_INVOKED\r\nGUIDELINES DESIGNINFO\r\nBEGIN\r\n    IDD_CHANGE_PASSWORD1, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 146\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 67\r\n    END\r\n\r\n    IDD_CHANGE_PASSWORD2, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 250\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 67\r\n    END\r\n\r\n    IDD_CONNECTING, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 169\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 136\r\n    END\r\n\r\n    IDD_JOB_CARD, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 346\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 78\r\n    END\r\n\r\n    IDD_LOGON1, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 240\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 112\r\n    END\r\n\r\n    IDD_LOGON2, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 290\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 88\r\n    END\r\n\r\n    IDD_PROGRESS, DIALOG\r\n    BEGIN\r\n        LEFTMARGIN, 7\r\n        RIGHTMARGIN, 197\r\n        TOPMARGIN, 7\r\n        BOTTOMMARGIN, 106\r\n    END\r\nEND\r\n#endif    // APSTUDIO_INVOKED\r\n\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// String Table\r\n//\r\n\r\nSTRINGTABLE\r\nBEGIN\r\n    IDS_FOLDER_USER_DATASETS \"%s Prefix\"\r\n    IDS_FOLDER_USER_JOBS    \"%s Owner\"\r\n    IDS_NETWORK_NAME        \"Serena Network\"\r\n    IDS_SERVICE_NAME        \"ZosNet\"\r\n    IDS_SYSTEM              \"system\"\r\n    IDS_TEST                \"Test\"\r\n    IDS_TITLE_CHECKING_IN   \"Checking in...\"\r\n    IDS_TITLE_CHECKING_OUT  \"Checking out...\"\r\n    IDS_TITLE_COPYING_DATASET \"Copying data set...\"\r\n    IDS_TITLE_DOWNLOADING   \"Downloading...\"\r\n    IDS_TITLE_LOGON         \"Logon: %s\"\r\n    IDS_TITLE_SEARCHING     \"Searching...\"\r\n    IDS_TITLE_TRANSFERRING_FILES \"Transferring files...\"\r\n    IDS_TITLE_UPLOADING     \"Uploading...\"\r\n    IDS_TITLE_VALIDATING_VERIONS \"Validating versions...\"\r\nEND\r\n\r\n#endif    // English (United States) resources\r\n/////////////////////////////////////////////////////////////////////////////\r\n\r\n\r\n\r\n#ifndef APSTUDIO_INVOKED\r\n/////////////////////////////////////////////////////////////////////////////\r\n//\r\n// Generated from the TEXTINCLUDE 3 resource.\r\n//\r\n#include \"Version.rc2\"\r\n#include \"Res\\ZosMsg.rc\"\r\n\r\n/////////////////////////////////////////////////////////////////////////////\r\n#endif    // not APSTUDIO_INVOKED\r\n\r\n"
  },
  {
    "path": "tests/inputs/ZosNp.def",
    "content": "LIBRARY ZosNp\r\n; Bruce Engle\r\n\r\nEXPORTS\r\n    NPGetConnection             @12\r\n    NPGetCaps                   @13\r\n    NPGetUser                   @16\r\n    NPAddConnection             @17\r\n    NPCancelConnection          @18\r\n    NPOpenEnum                  @33\r\n    NPEnumResource              @34\r\n    NPCloseEnum                 @35\r\n    NPFormatNetworkName         @36\r\n    NPAddConnection3            @38\r\n    NPGetUniversalName          @40\r\n    NPGetResourceParent         @41\r\n    NPGetConnectionPerformance  @49\r\n    NPGetResourceInformation    @52\r\n    NPLogonNotify               @500\r\n    NPPasswordChangeNotify      @501\r\n"
  },
  {
    "path": "tests/inputs/aa/bb/cc/plasma.c",
    "content": "/*\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\n#include <jni.h>\n#include <time.h>\n#include <android/log.h>\n#include <android/bitmap.h>\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <math.h>\n\n#define  LOG_TAG    \"libplasma\"\n#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)\n#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)\n\n/* Set to 1 to enable debug log traces. */\n#define DEBUG 0\n\n/* Set to 1 to optimize memory stores when generating plasma. */\n#define OPTIMIZE_WRITES  1\n\n/* Return current time in milliseconds */\nstatic double now_ms(void)\n{\n    struct timeval tv;\n    gettimeofday(&tv, NULL);\n    return tv.tv_sec*1000. + tv.tv_usec/1000.;\n}\n\n/* We're going to perform computations for every pixel of the target\n * bitmap. floating-point operations are very slow on ARMv5, and not\n * too bad on ARMv7 with the exception of trigonometric functions.\n *\n * For better performance on all platforms, we're going to use fixed-point\n * arithmetic and all kinds of tricks\n */\n\ntypedef int32_t  Fixed;\n\n#define  FIXED_BITS           16\n#define  FIXED_ONE            (1 << FIXED_BITS)\n#define  FIXED_AVERAGE(x,y)   (((x) + (y)) >> 1)\n\n#define  FIXED_FROM_INT(x)    ((x) << FIXED_BITS)\n#define  FIXED_TO_INT(x)      ((x) >> FIXED_BITS)\n\n#define  FIXED_FROM_FLOAT(x)  ((Fixed)((x)*FIXED_ONE))\n#define  FIXED_TO_FLOAT(x)    ((x)/(1.*FIXED_ONE))\n\n#define  FIXED_MUL(x,y)       (((int64_t)(x) * (y)) >> FIXED_BITS)\n#define  FIXED_DIV(x,y)       (((int64_t)(x) * FIXED_ONE) / (y))\n\n#define  FIXED_DIV2(x)        ((x) >> 1)\n#define  FIXED_AVERAGE(x,y)   (((x) + (y)) >> 1)\n\n#define  FIXED_FRAC(x)        ((x) & ((1 << FIXED_BITS)-1))\n#define  FIXED_TRUNC(x)       ((x) & ~((1 << FIXED_BITS)-1))\n\n#define  FIXED_FROM_INT_FLOAT(x,f)   (Fixed)((x)*(FIXED_ONE*(f)))\n\ntypedef int32_t  Angle;\n\n#define  ANGLE_BITS              9\n\n#if ANGLE_BITS < 8\n#  error ANGLE_BITS must be at least 8\n#endif\n\n#define  ANGLE_2PI               (1 << ANGLE_BITS)\n#define  ANGLE_PI                (1 << (ANGLE_BITS-1))\n#define  ANGLE_PI2               (1 << (ANGLE_BITS-2))\n#define  ANGLE_PI4               (1 << (ANGLE_BITS-3))\n\n#define  ANGLE_FROM_FLOAT(x)   (Angle)((x)*ANGLE_PI/M_PI)\n#define  ANGLE_TO_FLOAT(x)     ((x)*M_PI/ANGLE_PI)\n\n#if ANGLE_BITS <= FIXED_BITS\n#  define  ANGLE_FROM_FIXED(x)     (Angle)((x) >> (FIXED_BITS - ANGLE_BITS))\n#  define  ANGLE_TO_FIXED(x)       (Fixed)((x) << (FIXED_BITS - ANGLE_BITS))\n#else\n#  define  ANGLE_FROM_FIXED(x)     (Angle)((x) << (ANGLE_BITS - FIXED_BITS))\n#  define  ANGLE_TO_FIXED(x)       (Fixed)((x) >> (ANGLE_BITS - FIXED_BITS))\n#endif\n\nstatic Fixed  angle_sin_tab[ANGLE_2PI+1];\n\nstatic void init_angles(void)\n{\n    int  nn;\n    for (nn = 0; nn < ANGLE_2PI+1; nn++) {\n        double  radians = nn*M_PI/ANGLE_PI;\n        angle_sin_tab[nn] = FIXED_FROM_FLOAT(sin(radians));\n    }\n}\n\nstatic __inline__ Fixed angle_sin( Angle  a )\n{\n    return angle_sin_tab[(uint32_t)a & (ANGLE_2PI-1)];\n}\n\nstatic __inline__ Fixed angle_cos( Angle  a )\n{\n    return angle_sin(a + ANGLE_PI2);\n}\n\nstatic __inline__ Fixed fixed_sin( Fixed  f )\n{\n    return angle_sin(ANGLE_FROM_FIXED(f));\n}\n\nstatic __inline__ Fixed  fixed_cos( Fixed  f )\n{\n    return angle_cos(ANGLE_FROM_FIXED(f));\n}\n\n/* Color palette used for rendering the plasma */\n#define  PALETTE_BITS   8\n#define  PALETTE_SIZE   (1 << PALETTE_BITS)\n\n#if PALETTE_BITS > FIXED_BITS\n#  error PALETTE_BITS must be smaller than FIXED_BITS \n#endif\n\nstatic uint16_t  palette[PALETTE_SIZE];\n\nstatic uint16_t  make565(int red, int green, int blue)\n{\n    return (uint16_t)( ((red   << 8) & 0xf800) |\n                       ((green << 2) & 0x03e0) |\n                       ((blue  >> 3) & 0x001f) );\n}\n\nstatic void init_palette(void)\n{\n    int  nn, mm = 0;\n    /* fun with colors */\n    for (nn = 0; nn < PALETTE_SIZE/4; nn++) {\n        int  jj = (nn-mm)*4*255/PALETTE_SIZE;\n        palette[nn] = make565(255, jj, 255-jj);\n    }\n\n    for ( mm = nn; nn < PALETTE_SIZE/2; nn++ ) {\n        int  jj = (nn-mm)*4*255/PALETTE_SIZE;\n        palette[nn] = make565(255-jj, 255, jj);\n    }\n\n    for ( mm = nn; nn < PALETTE_SIZE*3/4; nn++ ) {\n        int  jj = (nn-mm)*4*255/PALETTE_SIZE;\n        palette[nn] = make565(0, 255-jj, 255);\n    }\n\n    for ( mm = nn; nn < PALETTE_SIZE; nn++ ) {\n        int  jj = (nn-mm)*4*255/PALETTE_SIZE;\n        palette[nn] = make565(jj, 0, 255);\n    }\n}\n\nstatic __inline__ uint16_t  palette_from_fixed( Fixed  x )\n{\n    if (x < 0) x = -x;\n    if (x >= FIXED_ONE) x = FIXED_ONE-1;\n    int  idx = FIXED_FRAC(x) >> (FIXED_BITS - PALETTE_BITS);\n    return palette[idx & (PALETTE_SIZE-1)];\n}\n\n/* Angles expressed as fixed point radians */\n\nstatic void init_tables(void)\n{\n    init_palette();\n    init_angles();\n}\n\nstatic void fill_plasma( AndroidBitmapInfo*  info, void*  pixels, double  t )\n{\n    Fixed yt1 = FIXED_FROM_FLOAT(t/1230.);\n    Fixed yt2 = yt1;\n    Fixed xt10 = FIXED_FROM_FLOAT(t/3000.);\n    Fixed xt20 = xt10;\n\n#define  YT1_INCR   FIXED_FROM_FLOAT(1/100.)\n#define  YT2_INCR   FIXED_FROM_FLOAT(1/163.)\n\n    int  yy;\n    for (yy = 0; yy < info->height; yy++) {\n        uint16_t*  line = (uint16_t*)pixels;\n        Fixed      base = fixed_sin(yt1) + fixed_sin(yt2);\n        Fixed      xt1 = xt10;\n        Fixed      xt2 = xt20;\n\n        yt1 += YT1_INCR;\n        yt2 += YT2_INCR;\n\n#define  XT1_INCR  FIXED_FROM_FLOAT(1/173.)\n#define  XT2_INCR  FIXED_FROM_FLOAT(1/242.)\n\n#if OPTIMIZE_WRITES\n        /* optimize memory writes by generating one aligned 32-bit store\n         * for every pair of pixels.\n         */\n        uint16_t*  line_end = line + info->width;\n\n        if (line < line_end) {\n            if (((uint32_t)line & 3) != 0) {\n                Fixed ii = base + fixed_sin(xt1) + fixed_sin(xt2);\n\n                xt1 += XT1_INCR;\n                xt2 += XT2_INCR;\n\n                line[0] = palette_from_fixed(ii >> 2);\n                line++;\n            }\n\n            while (line + 2 <= line_end) {\n                Fixed i1 = base + fixed_sin(xt1) + fixed_sin(xt2);\n                xt1 += XT1_INCR;\n                xt2 += XT2_INCR;\n\n                Fixed i2 = base + fixed_sin(xt1) + fixed_sin(xt2);\n                xt1 += XT1_INCR;\n                xt2 += XT2_INCR;\n\n                uint32_t  pixel = ((uint32_t)palette_from_fixed(i1 >> 2) << 16) |\n                                   (uint32_t)palette_from_fixed(i2 >> 2);\n\n                ((uint32_t*)line)[0] = pixel;\n                line += 2;\n            }\n\n            if (line < line_end) {\n                Fixed ii = base + fixed_sin(xt1) + fixed_sin(xt2);\n                line[0] = palette_from_fixed(ii >> 2);\n                line++;\n            }\n        }\n#else /* !OPTIMIZE_WRITES */\n        int xx;\n        for (xx = 0; xx < info->width; xx++) {\n\n            Fixed ii = base + fixed_sin(xt1) + fixed_sin(xt2);\n\n            xt1 += XT1_INCR;\n            xt2 += XT2_INCR;\n\n            line[xx] = palette_from_fixed(ii / 4);\n        }\n#endif /* !OPTIMIZE_WRITES */\n\n        // go to next line\n        pixels = (char*)pixels + info->stride;\n    }\n}\n\n/* simple stats management */\ntypedef struct {\n    double  renderTime;\n    double  frameTime;\n} FrameStats;\n\n#define  MAX_FRAME_STATS  200\n#define  MAX_PERIOD_MS    1500\n\ntypedef struct {\n    double  firstTime;\n    double  lastTime;\n    double  frameTime;\n\n    int         firstFrame;\n    int         numFrames;\n    FrameStats  frames[ MAX_FRAME_STATS ];\n} Stats;\n\nstatic void\nstats_init( Stats*  s )\n{\n    s->lastTime = now_ms();\n    s->firstTime = 0.;\n    s->firstFrame = 0;\n    s->numFrames  = 0;\n}\n\nstatic void\nstats_startFrame( Stats*  s )\n{\n    s->frameTime = now_ms();\n}\n\nstatic void\nstats_endFrame( Stats*  s )\n{\n    double now = now_ms();\n    double renderTime = now - s->frameTime;\n    double frameTime  = now - s->lastTime;\n    int nn;\n\n    if (now - s->firstTime >= MAX_PERIOD_MS) {\n        if (s->numFrames > 0) {\n            double minRender, maxRender, avgRender;\n            double minFrame, maxFrame, avgFrame;\n            int count;\n\n            nn = s->firstFrame;\n            minRender = maxRender = avgRender = s->frames[nn].renderTime;\n            minFrame  = maxFrame  = avgFrame  = s->frames[nn].frameTime;\n            for (count = s->numFrames; count > 0; count-- ) {\n                nn += 1;\n                if (nn >= MAX_FRAME_STATS)\n                    nn -= MAX_FRAME_STATS;\n                double render = s->frames[nn].renderTime;\n                if (render < minRender) minRender = render;\n                if (render > maxRender) maxRender = render;\n                double frame = s->frames[nn].frameTime;\n                if (frame < minFrame) minFrame = frame;\n                if (frame > maxFrame) maxFrame = frame;\n                avgRender += render;\n                avgFrame  += frame;\n            }\n            avgRender /= s->numFrames;\n            avgFrame  /= s->numFrames;\n\n            LOGI(\"frame/s (avg,min,max) = (%.1f,%.1f,%.1f) \"\n                 \"render time ms (avg,min,max) = (%.1f,%.1f,%.1f)\\n\",\n                 1000./avgFrame, 1000./maxFrame, 1000./minFrame,\n                 avgRender, minRender, maxRender);\n        }\n        s->numFrames  = 0;\n        s->firstFrame = 0;\n        s->firstTime  = now;\n    }\n\n    nn = s->firstFrame + s->numFrames;\n    if (nn >= MAX_FRAME_STATS)\n        nn -= MAX_FRAME_STATS;\n\n    s->frames[nn].renderTime = renderTime;\n    s->frames[nn].frameTime  = frameTime;\n\n    if (s->numFrames < MAX_FRAME_STATS) {\n        s->numFrames += 1;\n    } else {\n        s->firstFrame += 1;\n        if (s->firstFrame >= MAX_FRAME_STATS)\n            s->firstFrame -= MAX_FRAME_STATS;\n    }\n\n    s->lastTime = now;\n}\n\nJNIEXPORT void JNICALL Java_com_example_plasma_PlasmaView_renderPlasma(JNIEnv * env, jobject  obj, jobject bitmap,  jlong  time_ms)\n{\n    AndroidBitmapInfo  info;\n    void*              pixels;\n    int                ret;\n    static Stats       stats;\n    static int         init;\n\n    if (!init) {\n        init_tables();\n        stats_init(&stats);\n        init = 1;\n    }\n\n    if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {\n        LOGE(\"AndroidBitmap_getInfo() failed ! error=%d\", ret);\n        return;\n    }\n\n    if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) {\n        LOGE(\"Bitmap format is not RGB_565 !\");\n        return;\n    }\n\n    if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {\n        LOGE(\"AndroidBitmap_lockPixels() failed ! error=%d\", ret);\n    }\n\n    stats_startFrame(&stats);\n\n    /* Now fill the values with a nice little plasma */\n    fill_plasma(&info, pixels, time_ms );\n\n    AndroidBitmap_unlockPixels(env, bitmap);\n\n    stats_endFrame(&stats);\n}\n"
  },
  {
    "path": "tests/inputs/acpclust.R",
    "content": "### Code by Eric Lecoutre, Universite catholique de Louvain, Belgium\n### Winner of the R Homepage graphics competition 2004\n# http://www.r-project.org/misc/acpclust.R\n\n### Created using R 1.8.1, still works in 2.9.2\n\nrequire(ade4)\n## require(mva)   # was merged into stats\nrequire(RColorBrewer)\nrequire(pixmap)\n\nltitle <- function(x,backcolor=\"#e8c9c1\",forecolor=\"darkred\",cex=2,ypos=0.4)\n{\t\n    plot(x=c(-1,1),y=c(0,1),xlim=c(0,1),ylim=c(0,1),type=\"n\",axes=FALSE)\n    polygon(x=c(-2,-2,2,2),y=c(-2,2,2,-2),col=backcolor,border=NA)\n    text(x=0,y=ypos,pos=4,cex=cex,labels=x,col=forecolor)\n}\n\nplotacpclust <- function(data,xax=1,yax=2,hcut,cor=TRUE,clustermethod=\"ave\",\n                         colbacktitle=\"#e8c9c1\",wcos=3,Rpowered=FALSE,...)\n{\n    ## data: data.frame to analyze\n    ## xax, yax: Factors to select for graphs\n    \n    ## Parameters for hclust\n    ##   hcut\n    ##   clustermethod\n    \n    require(ade4)\n    \n    pcr=princomp(data,cor=cor)\n    \n    datac=t((t(data)-pcr$center )/pcr$scale)\n    \n    hc=hclust(dist(data),method=clustermethod)\n    if (missing(hcut)) hcut=quantile(hc$height,c(0.97))\n    \n    def.par <- par(no.readonly = TRUE)\n    on.exit(par(def.par))\n    \n    mylayout=layout(matrix(c(1,2,3,4,5,1,2,3,4,6,7,7,7,8,9,7,7,7,10,11),ncol=4),widths=c(4/18,2/18,6/18,6/18),heights=c(lcm(1),3/6,1/6,lcm(1),1/3))\n    \n    par(mar = c(0.1, 0.1, 0.1, 0.1))\n    par(oma = rep(1,4))\n    ltitle(paste(\"PCA \",dim(unclass(pcr$loadings))[2], \"vars\"),cex=1.6,ypos=0.7)\n    text(x=0,y=0.2,pos=4,cex=1,labels=deparse(pcr$call),col=\"black\")\n    pcl=unclass(pcr$loadings)\n    pclperc=100*(pcr$sdev)/sum(pcr$sdev)\n    s.corcircle(pcl[,c(xax,yax)],1,2,sub=paste(\"(\",xax,\"-\",yax,\") \",\n                                     round(sum(pclperc[c(xax,yax)]),0),\"%\",sep=\"\"),\n                possub=\"bottomright\",csub=3,clabel=2)\n    wsel=c(xax,yax)\n    scatterutil.eigen(pcr$sdev,wsel=wsel,sub=\"\")\n    \n    dend=hc\n    dend$labels=rep(\"\",length(dend$labels))\n    dend=as.dendrogram(dend)\n\n    ngrp=length(cut(dend,hcut)$lower)\n    \n    ltitle(paste(\"Clustering \",ngrp, \"groups\"),cex=1.6,ypos=0.4)\n    \n    par(mar = c(3, 0.3, 1, 0.5))\n    \n    ## Dendrogram\n    attr(dend,\"edgetext\") = round(max(hc$height),1)\n    plot(dend, edgePar = list(lty=1, col=c(\"black\",\"darkgrey\")), edge.root=FALSE,horiz=TRUE,axes=TRUE)\n    \n    abline(v=hcut,col=\"red\")\n    text(x=hcut,y=length(hc$height),labels=as.character(round(hcut,1)),col=\"red\",pos=4)\n    \n    \n    colorsnames= brewer.pal(ngrp,\"Dark2\")\n    groupes=cutree(hc,h=hcut)\n    ttab=table(groupes)\n    \n    ## Groups\n    par(mar = c(0.3, 0.3, 1.6, 0.3))\n    mp=barplot(as.vector(rev(ttab)),horiz=TRUE,space=0,col=rev(colorsnames),\n               xlim=c(0,max(ttab)+10),axes=FALSE,main=\"Groups\",axisnames=FALSE)\n    text(rev(ttab),mp,as.character(rev(ttab)),col=rev(colorsnames),cex=1.2,pos=4)\n\n\n    \n    ## Main ACP scatterplot\n\n    par(mar = c(0.1,0.1, 0.1,0.1))\t\n    selscores=pcr$scores[,c(xax,yax)]\n    \n    zi=apply(datac,1,FUN=function(vec)return(sum(vec^2)))\n    cosinus= cbind(selscores[,1]^2 / zi,selscores[,2]^2 / zi)\n    cosinus= cbind(cosinus,apply(cosinus,1,sum))\n    ww= (cosinus[,wcos])*4 +0.5\n    \n    ## Outliers? Test with median+1.5*IQ\n    \n    ## Factor #1\n    out <- selscores[,1] < median(selscores[,1]) - 1.5 * diff(quantile(selscores[,1],c(0.25,0.75)))\n    out = out | selscores[,1] > median(selscores[,1]) + 1.5 * diff(quantile(selscores[,1],c(0.25,0.75)))\n    ## factor #2\t\t\n    out = out | selscores[,2] < median(selscores[,2]) - 1.5 * diff(quantile(selscores[,2],c(0.25,0.75)))\n    out = out | selscores[,2] > median(selscores[,2]) + 1.5 * diff(quantile(selscores[,2],c(0.25,0.75)))\n\n    plot(selscores,axes=FALSE,main=\"\",xlab=\"\",ylab=\"\",type=\"n\")\n    abline(h=0,col=\"black\")\n    abline(v=0,col=\"black\")\n    \n    \n    points(selscores[!out,1:2],col=(colorsnames[groupes])[!out],cex=ww,pch=16)\n    \n    \n    text(x=selscores[out,1],y=selscores[out,2],labels=dimnames(selscores)[[1]][out],\n         col=(colorsnames[groupes])[out], adj=1)\n    box()\n    \n    \n\n\n    ## Factor 1\n    par(mar = c(0.1, 0.1, 0.1, 0.1))\n    ltitle(paste(\"Factor \",xax, \" [\",round(pclperc[xax],0),\"%]\",sep=\"\" ),cex=1.6,ypos=0.4)\n    plotdens(pcr$scores[,c(xax)])\n    \n    ## Factor 2\n    par(mar = c(0.1, 0.1, 0.1, 0.1))\n    ltitle(paste(\"Factor \",yax,\" [\",round(pclperc[yax],0),\"%]\",sep=\"\"),cex=1.6,ypos=0.4)\n    plotdens(pcr$scores[,c(yax)])\n}\n\nconfshade2 <- function(y, xlo, xhi, col = 8.)\n{\n    n <- length(y)\n    for(i in 1.:(n - 1.)) {\n        polygon(c(xlo[i], xlo[i + 1.], xhi[i + 1.], xhi[i]),\n                c(y[i], y[i + 1.], y[i + 1.], y[i]), col = col, border = FALSE)\n    }\n}\n\nconfshade <- function(x, ylo, yhi, col = 8.)\n{\n    n <- length(x)\n    for(i in 1.:(n - 1.)) {\n        polygon(c(x[i], x[i + 1.], x[i + 1.], x[i]),\n                c(ylo[i], ylo[i + 1.], yhi[i + 1.], yhi[i]), col = col, border = FALSE)\n    }\n}\n\n\nplotdens <- function(X, npts = 200, range = 1.5, xlab = \"\", ylab = \"\", main = \"\", ...)\n{\n    dens <- density(X, n = npts)\n    qu <- quantile(X, c(0., 0.25, 0.5, 0.75, 1.))\n    x <- dens$x\n    y <- dens$y\n    fqux <- x[abs(x - qu[2.]) == min(abs(x - qu[2.]))]\n    fquy <- y[x == fqux]\n    fquX <- as.numeric(qu[2.])\n    tqux <- x[abs(x - qu[4.]) == min(abs(x - qu[4.]))]\n    tquy <- y[x == tqux]\n    tquX <- as.numeric(qu[4.])\n    medx <- x[abs(x - qu[3.]) == min(abs(x - qu[3.]))]\n    medy <- y[x == medx]\n    ## Prepare les donnees a dessiner\n    medX <- as.numeric(qu[3.])\n    dx <- dens$x\n    \n    dy <- dens$y\n    dx2 <- c(dx[dx <= fquX], fquX, dx[(dx > fquX) &\n                (dx <= medX)], medX, dx[(dx > medX) & (dx <= tquX)], tquX, dx[dx > tquX])\n    \n    dy2 <- \tc(dy[dx <= fquX], fquy, dy[(dx > fquX) & (dx <= medX)], medy,\n                  dy[(dx > medX) & (dx <= tquX)], tquy, dy[dx > tquX])\n    IQX <- dx2[(dx2 >= fquX) & (dx2 <= tquX)]\n    ##\n    ##\n    ## Initialise le graphique\n    ##\n\n    ## Dessine la densite\n    IQy <- dy2[(dx2 >= fquX) & (dx2 <= tquX)]\n    ## Trace densit sous IQ\n    plot(0., 0., xlim = c(min(dx2), max(dx2)), ylim = c(min(dy2), max(dy2)),\n         axes = F, xlab = xlab, ylab = ylab, main = main,type=\"n\", ...)\n    ## Ajoute mediane\n    confshade(IQX, rep(0., length(IQX)), IQy, col = \"#bdfcc9\")\n    bdw <- (tquX - fquX)/20.\n    x1 <- c(medX - bdw/2., medX - bdw/2.)\n    x2 <- c(medX + bdw/2., medX + bdw/2.)\n    y1 <- c(0., medy)\n    ## Ajoute lignes wiskers\n    polygon(c(x1, rev(x2)), c(y1, rev(y1)), col = 0.)\n    lines(x = c(fquX, fquX), y = c(0., fquy))\n    ## Ajoute wiskers\n    lines(x = c(tquX, tquX), y = c(0., tquy))\n    meany <- mean(dy2)\n    IQrange <- tquX - fquX\n    lines(x = c(medX - range * IQrange, fquX), y = c(meany, meany))\n    lines(x = c(tquX, medX + range * IQrange), y = c(meany, meany))\n    lines(x = c(medX - range * IQrange, medX - range * IQrange),\n          y = c(meany - (max(dy2) - min(dy2))/8., meany + (max(dy2) - min(dy2))/8.))\n\n    ## Ajoute outliers\n    \n    lines(x = c(medX + range * IQrange, medX + range * IQrange),\n          y = c(meany - (max(dy2) - min(dy2))/8., meany + (max(dy2) - min(dy2))/8.))\n    out <- c(X[X < medX - range * IQrange], X[X > medX + range * IQrange])\n\n    ## Ajoute les points...\n    ## Ajoute l'axe\n    points(out, rep(meany, length(out)), pch = 5., col = 2.)\n    ## Ajoute l'axe\n    points(dx2, dy2, pch = \".\", type = \"l\")\n    ##return(x = dessinx2, y = dessiny2)\n    axis(1., at = round(c(min(x), fquX, medX, tquX, max(x)), 2.), labels = F,\n         pos = 0.)\n    invisible(list(x = dx2, y = dy2))\n}\n\n\n\nBoxDens <- function(data, npts = 200., x = c(0., 100.), y = c(0., 50.), orientation = \"paysage\",\n                    add = TRUE, col = 11., border=FALSE,colline = 1., Fill = TRUE)\n{\n    dens <- density(data, n = npts)\n    dx <- dens$x\n    dy <- dens$y\n    if(add == FALSE)\n        plot(0., 0., axes = F, main = \"\", xlim = x, ylim = y, xlab = \"\",\n             ylab = \"\")\n    if(orientation == \"paysage\") {\n        dx2 <- (dx - min(dx))/(max(dx) - min(dx)) * (x[2.] - x[1.]) * 0.98 +\n            x[1.]\n        dy2 <- (dy - min(dy))/(max(dy) - min(dy)) * (y[2.] - y[1.]) * 0.98 +\n            y[1.]\n        seqbelow <- rep(y[1.], length(dx))\n        if(Fill == T)\n            confshade(dx2, seqbelow, dy2, col = col)\n        if (border==TRUE) points(dx2, dy2, type = \"l\", col = colline)\n    }\n    else {\n        dy2 <- (dx - min(dx))/(max(dx) - min(dx)) * (y[2.] - y[1.]) * 0.98 +\n            y[1.]\n        dx2 <- (dy - min(dy))/(max(dy) - min(dy)) * (x[2.] - x[1.]) * 0.98 +\n            x[1.]\n        seqleft <- rep(x[1.], length(dy))\n        if(Fill == T)\n            confshade2(dy2, seqleft, dx2, col = col)\n        if (border==TRUE) points(dx2, dy2, type = \"l\", col = colline)\n    }\n    polygon(x = c(x[1.], x[2.], x[2.], x[1.]),\n            y = c(y[2.], y[2.], y[1.], y[1.]), density = 0.)\n}\n\n\ndata(swiss)\n## png(file=\"swiss.png\", width=600,height=400)\nplotacpclust(swiss[,1:5], 1, 3, hcut=48)\n## dev.off()\n\n"
  },
  {
    "path": "tests/inputs/apertium-dan.dan.rlx",
    "content": "# based on\n# https://raw.githubusercontent.com/apertium/apertium-dan/master/apertium-dan.dan.rlx\n# -*- cg-pre-pipe: \"apertium -d . dan-morph|cg-conv -a 2>/dev/null\" -*-\n\nSOFT-DELIMITERS = \"<,>\" cm ;\nDELIMITERS = \"<.>\" \"<:>\" \"<!>\" \"<?>\" \"<|>\" \"<$.>\" \"<$:>\" \"<$!>\" \"<$?>\" \"<$|>\" ssingular ;\n\n#PARENTHESES = (\"<$(>\" \"$<)>\") (\"<$[>\" \"<$]>\") (\"<${>\" \"<$}>\") ;\n\nLIST GENDER = m f nt mf ut ;\nLIST NUMBER = sg pl sp ;\nLIST DEFNES = def ind ;\nLIST TEMPUS = inf pres pasv pret pp imp ;\n\n# For use with http://beta.visl.sdu.dk/cg3/single/#set-unification-set\n# as &&ADJ_N_AGR (also works for demonstratives):\nLIST AGR_MF = ut mf f m ;\nLIST AGR_SP = (sp un) ;\nSET AGR_MF_SG = (sg) + AGR_MF OR AGR_SP ;\nSET AGR_NT_SG = (sg) + (nt) OR AGR_SP ;\nSET AGR_PL = (pl) OR AGR_SP ;\nSET ADJ_N_AGR = AGR_MF_SG OR AGR_NT_SG OR AGR_PL ;\n# ADD:agrtest (@agrtest) &&ADJ_N_AGR IF (-1 &&ADJ_N_AGR);\n# sitt telefoner. sine telefoner. si telefoner. sin telefoner.\n# sitt telefon. sine telefon. si telefon. sin telefon.\n# sitt bidrag. sine bidrag. si bidrag. sin bidrag.\n# sitt hus. sine hus. si hus. sin hus.\n\nLIST ADJ_NUMGEN = pl (nt sg) (mf sg) ;\n\n\nLIST sg = sg ;\nLIST pl = pl ;\nLIST ut = ut ;\nLIST nt = nt ;\n\nLIST n = n ;\nLIST pr = pr ;\nLIST vblex = vblex ;\n\nLIST expl = expl ;\nLIST ord = ord ;\nLIST adj = adj ;\nLIST def = def ;\nLIST ind = ind ;\nLIST ref = ref ;\nLIST pers = pers ;\nLIST pres = pres ;\nLIST pret = pret ;\nLIST cm = cm ;\nLIST cnjadv = cnjadv ;\n\nLIST fv = pres pret ;\n\nSET pre-np-head = (*) - (gen) - (adj);\n\nLIST %al% = \"al\" ;\nLIST %al%-det = \"al\" det qnt ;\nLIST %aller% = (\"aller\"  adv) ;\nLIST %alt% = (\"al\"  det nt) ;\nLIST %andre% = \"andre\"  ;\nLIST %anden% = \"anden\"  ;\nLIST %andet% = \"andet\"  ;\nLIST %anden/samme%/quantifier-neuter = (\"anden\"  nt) (\"samme\" ) (det qnt) ;\nLIST %bodyparts%-plural = (\"arm\"  pl) (\"ben\"  pl) (\"krop\"  pl) (\"læg\"  pl) ;\nLIST %at% = \"at\"  ;\nLIST %særlig% = \"særlig\"  ;\nLIST %at/om% = \"om\"  \"at\"  ;\nLIST %om-at% = \"om at\"  ;\nLIST %af% = \"af\"  ;\nLIST %bare% = (\"bare\"  adv) ;\nLIST %begge/selve/alle% = \"selv\"  \"begge\"  (\"al\"  det pl) ;\nLIST %bla% = \"blandt andet\" \"bl.a.\" ;\nLIST %blik% = (\"blik\"  adv) ;\nLIST %både% = \"både\"  ;\nLIST %da% = \"da\"  ;\nLIST %den% = (\"den\"  det) ;\nLIST %den/denne% = (\"den\"  det) (\"denne\"  det) ;\nLIST %den/det/de% = \"det\"  \"den\"  \"de\" ;\nLIST %der% = \"der\"  ;\nLIST %det% = \"det\" (\"den\"  det nt) ;\nLIST %det%-pron = (\"det\"  prn) ;\nLIST %det/dette% = (\"den\"  det nt) (\"denne\"  det nt) ;\nLIST %disse% = (\"denne\" det dem un pl) ;\nLIST %eksempel% = \"eksempel\"  ;\nLIST %eksklusiv/e% = \"eksklusive\"  \"eksklusiv\"  ;\nLIST %eller% = \"eller\"  ;\nLIST %endnu% = \"endnu\"  ;\nLIST %end% = \"end\"  ;\nLIST %et% = (\"en\"  det nt sg) ;\nLIST %en% = (\"en\"  det ut sg) ;\nLIST %en/et% = (\"en\" det sg ut) (\"en\" det sg nt) ;\nLIST %fare%-past = (\"fare\"  vblex past) ;\nLIST %fast% = (\"fast\"  adj) ;\nLIST %flere% = (\"mange\" adj comp) ;\nLIST %for% = \"for\"  ;\nLIST %for/før/når% = \"når\"  \"før\"  \"for\"  ;\nLIST %frem/ind/op% = (\"frem\"  pr) (\"ind\"  pr) (\"op\"  pr) ;\nLIST %fuldstændig%  = (\"fuldstændig\") ;\nLIST %fuldt/mange% = \"mange\"  (\"fuld\"  adj nt ind sg) ; #\n"
  },
  {
    "path": "tests/inputs/args.janet",
    "content": "# https://github.com/MorganPeterson/args/blob/main/args.janet\n\n# https://github.com/AlDanial/cloc/issues/802\n(defn- to-byte\n  \"convert chars to byte and only return first result\"\n  [x]\n  (get (string/bytes x) 0))\n\n(defn- parse\n  \"parse command line arguments\"\n  [args]\n  (def f\n    (fiber/new \n      (fn []\n        (loop [x :in args]\n          (yield x)))))\n  (def dash (to-byte \"-\"))\n  (def spce (to-byte \" \"))\n\n  (var results @[])\n  (var kpwh false) # keep flag whole if no dash\n  \n  (while (fiber/can-resume? f)\n    (var args0 (resume f))\n\n    (cond\n      (= args0 dash) (set args0 (resume f))\n      (set kpwh true))\n    \n    (if (and (= args0 dash) (not (fiber/can-resume? f))) (break))\n    \n    (cond\n      (= args0 dash)\n      (do\n        (var a @[])\n        (loop [x :in f :until (or (= x spce) (not (fiber/can-resume? f)))]\n          (array/push a (string/from-bytes x)))\n        (array/push results (string/join a)))\n      (do\n        (var b @[])\n        (when (not (nil? args0))\n          (array/push b (string/from-bytes args0))\n          (loop [x :in f :until (or (= x spce) (not (fiber/can-resume? f)))]\n            (array/push b (string/from-bytes x)))\n          (cond\n            (true? kpwh) (array/push results (string/join b))\n            (do\n              (array/concat results b)\n              (set kpwh false)))))))\n  results)\n\n(defn flags\n  \"take in raw commandline string\"\n  [args]\n  (parse (string/join (tuple/slice args 1) \" \")))\n"
  },
  {
    "path": "tests/inputs/arvo.hoon",
    "content": ":< first 120 lines of https://raw.githubusercontent.com/urbit/arvo/master/sys/arvo.hoon\n::::::  ::::::::::::::::::::::::::::::::::::::::::::::::::::::\n::::::  ::::::    Postface                              ::::::\n::::::  ::::::::::::::::::::::::::::::::::::::::::::::::::::::\n=>  +7\n~>  %slog.[0 leaf+\"%arvo-assembly\"]\n::::::  ::::::::::::::::::::::::::::::::::::::::::::::::::::::\n::::::  ::::::    volume 3, Arvo models and skeleton    ::::::\n::::::  ::::::::::::::::::::::::::::::::::::::::::::::::::::::\n=>\n~%  %hex  +  ~\n|%\n++  arch  {fil/(unit @uvI) dir/(map @ta $~)}            ::  fundamental node\n++  arvo  (wind {p/term q/mill} mill)                   ::  arvo card\n++  beam  {{p/ship q/desk r/case} s/path}               ::  global name\n++  beak  {p/ship q/desk r/case}                        ::  garnish with beak\n++  bone  @ud                                           ::  opaque duct\n++  case                                                ::  version\n          $%  {$da p/@da}                               ::  date\n              {$tas p/@tas}                             ::  label\n              {$ud p/@ud}                               ::  sequence\n          ==                                            ::\n++  desk  @tas                                          ::  ship desk case spur\n++  cage  (cask vase)                                   ::  global metadata\n++  cask  |*(a/mold (pair mark a))                      ::  global data\n++  cuff                                                ::  permissions\n          $:  p/(unit (set monk))                       ::  can be read by\n              q/(set monk)                              ::  caused or created by\n          ==                                            ::\n++  curd  {p/@tas q/*}                                  ::  typeless card\n++  duct  (list wire)                                   ::  causal history\n++  hypo  |*(a/mold (pair type a))                      ::  type associated\n++  hobo  |*  a/mold                                    ::  kiss wrapper\n          $?  $%  {$soft p/*}                           ::\n              ==                                        ::\n              a                                         ::\n          ==                                            ::\n++  kirk  (unit (set monk))                             ::  audience\n++  lens                                                ::  observation core\n  $_  ^?                                                ::\n  |%  ++  u  *(unit (unit $~))                          ::  existence\n      ++  v  *(unit (unit cage))                        ::  full history\n      ++  w  *(unit (unit (unit cage)))                 ::  latest diff\n      ++  x  *(unit (unit cage))                        ::  data at path\n      ++  y  *(unit (unit arch))                        ::  directory\n      ++  z  *(unit (unit cage))                        ::  current subtree\n  --                                                    ::\n++  marc                                                ::  structured mark\n  $@  mark                                              ::  plain mark\n  $%  {$tabl p/(list (pair marc marc))}                 ::  map\n  ==                                                    ::\n++  mark  @tas                                          ::  content type\n++  mash  |=(* (mass +<))                               ::  producing mass\n++  mass  (pair cord (each noun (list mash)))           ::  memory usage  \n++  mill  (each vase milt)                              ::  vase+metavase\n++  milt  {p/* q/*}                                     ::  metavase\n++  monk  (each ship {p/@tas q/@ta})                    ::  general identity\n++  muse  {p/@tas q/duct r/arvo}                        ::  sourced move\n++  move  {p/duct q/arvo}                               ::  arvo move\n++  ovum  {p/wire q/curd}                               ::  typeless ovum\n++  pane  (list {p/@tas q/vase})                        ::  kernel modules\n++  pone  (list {p/@tas q/vise})                        ::  kernel modules old\n++  ship  @p                                            ::  network identity\n++  sink  (trel bone ship path)                         ::  subscription\n++  sley  $-  {* (unit (set monk)) term beam}           ::  namespace function\n          (unit (unit cage))                            ::\n++  slyd  $-  {* (unit (set monk)) term beam}           ::  super advanced\n          (unit (unit (cask)))                          ::\n++  slyt  $-({* *} (unit (unit)))                       ::  old namespace\n++  vile                                                ::  reflexive constants\n          $:  typ/type                                  ::  -:!>(*type)\n              duc/type                                  ::  -:!>(*duct)\n              pah/type                                  ::  -:!>(*path)\n              mev/type                                  ::  -:!>([%meta *vase])\n          ==                                            ::\n++  wind                                                ::  new kernel action\n          |*  {a/mold b/mold}                           ::  forward+reverse\n          $%  {$pass p/path q/a}                        ::  advance\n              {$slip p/a}                               ::  lateral\n              {$give p/b}                               ::  retreat\n          ==                                            ::\n++  wire  path                                          ::  event pretext\n++  sloy\n  !:\n  |=  sod/slyd\n  ^-  slyt\n  |=  {ref/* raw/*}\n  =+  pux=((soft path) raw)\n  ?~  pux  ~\n  ?.  ?=({@ @ @ @ *} u.pux)  ~\n  =+  :*  hyr=(slay i.u.pux)\n          fal=(slay i.t.u.pux)\n          dyc=(slay i.t.t.u.pux)\n          ved=(slay i.t.t.t.u.pux)\n          tyl=t.t.t.t.u.pux\n      ==\n  ?.  ?=({$~ $$ $tas @} hyr)  ~\n  ?.  ?=({$~ $$ $p @} fal)  ~\n  ?.  ?=({$~ $$ $tas @} dyc)  ~\n  ?.  ?=(^ ved)  ~\n  =+  ron=q.p.u.hyr\n  =+  bed=[[q.p.u.fal q.p.u.dyc (case p.u.ved)] (flop tyl)]\n  =+  bop=(sod ref ~ ron bed)\n  ?~  bop  ~\n  ?~  u.bop  [~ ~]\n  [~ ~ +.q.u.u.bop]\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n::                section 3bE, Arvo core                ::\n::\n++  vent                                                ::  vane core\n  |=  {lal/@tas vil/vile bud/vase sew/(pair worm vase)}\n  ~%  %vent  +>+  ~\n  |%\n  ++  ruck                                              ::  update vase\n    |=  {pax/path txt/@ta}\n    ^+  +>\n    =-  ?:(?=($| -.res) ((slog p.res) +>.$) p.res)\n    ^=  res  %-  mule  |.\n    =+  arg=[~2000.1.1 0 =>(~ |~(* ~))]\n    =+  rig=(slym q.sew arg)\n"
  },
  {
    "path": "tests/inputs/asciidoctor.adoc",
    "content": "// https://raw.githubusercontent.com/asciidoctor/asciidoctor/master/man/asciidoctor.adoc\n// Stripped down, added block comments for cloc\n= asciidoctor(1)\nDan Allen; Sarah White; Ryan Waldron\n:doctype: manpage\n:man manual: Asciidoctor Manual\n:man source: Asciidoctor 1.5.6.1\n:page-layout: base\n\n== NAME\n\nasciidoctor - converts AsciiDoc source files to HTML, DocBook and other formats\n\n== SYNOPSIS\n\n*asciidoctor* [_OPTION_]... _FILE_...\n\n== DESCRIPTION\n\nThe asciidoctor(1) command converts the AsciiDoc source file(s) _FILE_ to HTML5, DocBook 5, DocBook 4.5, man(ual) page and other custom output formats.\n\nIf _FILE_ is _-_ then the AsciiDoc source is read from standard input.\n\n== OPTIONS\n////\n=== Security Settings\n\n*-B, --base-dir*=_DIR_::\n  Base directory containing the document and resources.\n  Defaults to the directory containing the source file, or the working directory if the source is read from a stream.\n  When combined with the safe mode setting, can be used to chroot the execution of the program.\n\n*-S, --safe-mode*=_SAFE_MODE_::\n  Set safe mode level: _unsafe_, _safe_, _server_ or _secure_.\n  Disables potentially dangerous macros in source files, such as `include::[]`.\n  If not set, the safe mode level defaults to _unsafe_ when Asciidoctor is invoked using this script.\n\n*--safe*::\n  Set safe mode level to _safe_.\n  Enables include directives, but prevents access to ancestor paths of source file.\n  Provided for compatibility with the asciidoc command.\n  If not set, the safe mode level defaults to _unsafe_ when Asciidoctor is invoked using this script.\n\n=== Document Settings\n////\n\n*-a, --attribute*=_ATTRIBUTE_::\n  Define, override or delete a document attribute.\n  Command-line attributes take precedence over attributes defined in the source file unless the value ends with _@_.\n+\n_ATTRIBUTE_ is normally formatted as a key-value pair, in the form _NAME=VALUE_.\nAlternate acceptable forms are _NAME_ (where the _VALUE_ defaults to an empty string), _NAME!_ (unassigns the _NAME_ attribute) and _NAME=VALUE@_ (where _VALUE_ does not override value of _NAME_ attribute if it's already defined in the source document).\nValues containing spaces should be enclosed in quotes.\n+\nThis option may be specified more than once.\n\n////\n*-b, --backend*=_BACKEND_::\n  Backend output file format: _html5_, _docbook5_, _docbook45_ and _manpage_ are supported out of the box.\n  You can also use the backend alias names _html_ (aliased to _html5_) or _docbook_ (aliased to _docbook5_).\n  Other values can be passed, but if Asciidoctor cannot resolve the backend to a converter, it will fail.\n  Defaults to _html5_.\n////\n\n*-d, --doctype*=_DOCTYPE_::\n  Document type: _article_, _book_, _manpage_ or _inline_.\n  Sets the root element when using the _docbook_ backend and the style class on the HTML body element when using the _html_ backend.\n  The _book_ document type allows multiple level-0 section titles in a single document.\n  The _manpage_ document type enables parsing of metadata necessary to produce a man page.\n  The _inline_ document type allows the content of a single paragraph to be formatted and returned without wrapping it in a containing element.\n  Defaults to _article_.\n\n=== Rendering Control\n\n*-C, --compact*::\n  Compact the output by removing blank lines.\n  (No longer in use).\n// file truncated here\n"
  },
  {
    "path": "tests/inputs/assembly.cs",
    "content": "using System.Reflection;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyCompany(\"eventIS Interactive Solutions BV\")]\n[assembly: AssemblyProduct(\"Traxis\")]\n[assembly: AssemblyCopyright(\"Copyright <A9> 2006 - 2008 eventIS Interactive Solutions BV\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: AssemblyTrademark(\"\")]\n\n// Values in this file will be overwritten by the build process\n\n[assembly: AssemblyVersion(\"0.0.0.0\")]\n[assembly: AssemblyFileVersion(\"0.0.0.0\")]\n[assembly: AssemblyInformationalVersion(\"0.0.0.0\")]\n"
  },
  {
    "path": "tests/inputs/basic.luau",
    "content": " -- https://github.com/luau-lang/luau/blob/master/fuzz/basic.lua\nlocal function test(t)\n\tfor k,v in pairs(t) do\n\t\tprint(k,v)\n\tend\nend\n\ntest({a = 1})\n\n--[[\nmore comment\n]]\n"
  },
  {
    "path": "tests/inputs/basic.p4",
    "content": "// https://raw.githubusercontent.com/p4lang/tutorials/master/exercises/basic/basic.p4\n/* -*- P4_16 -*- */\n#include <core.p4>\n#include <v1model.p4>\n\nconst bit<16> TYPE_IPV4 = 0x800;\n\n/*************************************************************************\n*********************** H E A D E R S  ***********************************\n*************************************************************************/\n\ntypedef bit<9>  egressSpec_t;\ntypedef bit<48> macAddr_t;\ntypedef bit<32> ip4Addr_t;\n\nheader ethernet_t {\n    macAddr_t dstAddr;\n    macAddr_t srcAddr;\n    bit<16>   etherType;\n}\n\nheader ipv4_t {\n    bit<4>    version;\n    bit<4>    ihl;\n    bit<8>    diffserv;\n    bit<16>   totalLen;\n    bit<16>   identification;\n    bit<3>    flags;\n    bit<13>   fragOffset;\n    bit<8>    ttl;\n    bit<8>    protocol;\n    bit<16>   hdrChecksum;\n    ip4Addr_t srcAddr;\n    ip4Addr_t dstAddr;\n}\n\nstruct metadata {\n    /* empty */\n}\n\nstruct headers {\n    ethernet_t   ethernet;\n    ipv4_t       ipv4;\n}\n\n/*************************************************************************\n*********************** P A R S E R  ***********************************\n*************************************************************************/\n\nparser MyParser(packet_in packet,\n                out headers hdr,\n                inout metadata meta,\n                inout standard_metadata_t standard_metadata) {\n\n    state start {\n        /* TODO: add parser logic */\n        transition accept;\n    }\n}\n\n\n/*************************************************************************\n************   C H E C K S U M    V E R I F I C A T I O N   *************\n*************************************************************************/\n\ncontrol MyVerifyChecksum(inout headers hdr, inout metadata meta) {\n    apply {  }\n}\n\n\n/*************************************************************************\n**************  I N G R E S S   P R O C E S S I N G   *******************\n*************************************************************************/\n\ncontrol MyIngress(inout headers hdr,\n                  inout metadata meta,\n                  inout standard_metadata_t standard_metadata) {\n    action drop() {\n        mark_to_drop(standard_metadata);\n    }\n\n    action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {\n        /* TODO: fill out code in action body */\n    }\n\n    table ipv4_lpm {\n        key = {\n            hdr.ipv4.dstAddr: lpm;\n        }\n        actions = {\n            ipv4_forward;\n            drop;\n            NoAction;\n        }\n        size = 1024;\n        default_action = NoAction();\n    }\n\n    apply {\n        /* TODO: fix ingress control logic\n         *  - ipv4_lpm should be applied only when IPv4 header is valid\n         */\n        ipv4_lpm.apply();\n    }\n}\n\n/*************************************************************************\n****************  E G R E S S   P R O C E S S I N G   *******************\n*************************************************************************/\n\ncontrol MyEgress(inout headers hdr,\n                 inout metadata meta,\n                 inout standard_metadata_t standard_metadata) {\n    apply {  }\n}\n\n/*************************************************************************\n*************   C H E C K S U M    C O M P U T A T I O N   **************\n*************************************************************************/\n\ncontrol MyComputeChecksum(inout headers hdr, inout metadata meta) {\n     apply {\n        update_checksum(\n            hdr.ipv4.isValid(),\n            { hdr.ipv4.version,\n              hdr.ipv4.ihl,\n              hdr.ipv4.diffserv,\n              hdr.ipv4.totalLen,\n              hdr.ipv4.identification,\n              hdr.ipv4.flags,\n              hdr.ipv4.fragOffset,\n              hdr.ipv4.ttl,\n              hdr.ipv4.protocol,\n              hdr.ipv4.srcAddr,\n              hdr.ipv4.dstAddr },\n            hdr.ipv4.hdrChecksum,\n            HashAlgorithm.csum16);\n    }\n}\n\n\n/*************************************************************************\n***********************  D E P A R S E R  *******************************\n*************************************************************************/\n\ncontrol MyDeparser(packet_out packet, in headers hdr) {\n    apply {\n        /* TODO: add deparser logic */\n    }\n}\n\n/*************************************************************************\n***********************  S W I T C H  *******************************\n*************************************************************************/\n\nV1Switch(\nMyParser(),\nMyVerifyChecksum(),\nMyIngress(),\nMyEgress(),\nMyComputeChecksum(),\nMyDeparser()\n) main;\n"
  },
  {
    "path": "tests/inputs/bbf-device.yang",
    "content": "// fragment of\n// https://github.com/BroadbandForum/yang/raw/eaac2c3904365d3c7b17100c7d5120ed06a56b74/standard/common/bbf-device.yang\nmodule bbf-device {\n  yang-version 1.1;\n  namespace \"urn:bbf:yang:bbf-device\";\n  prefix bbf-dvc;\n\n  import ietf-yang-types {\n    prefix yang;\n  }\n  import ietf-inet-types {\n    prefix inet;\n  }\n  import bbf-yang-types {\n    prefix bbf-yang;\n  }\n  import bbf-device-types {\n    prefix bbf-dvct;\n  }\n  import bbf-node-types {\n    prefix bbf-nodet;\n  }\n\n  organization\n    \"Broadband Forum <https://www.broadband-forum.org>\n     Common YANG Work Area\";\n  contact\n    \"Comments or questions about this Broadband Forum YANG module\n     should be directed to <mailto:help@broadband-forum.org>.\n\n     Editor:      Nick Hancock, ADTRAN\n\n     Editor:      Ludwig Pauwels, Nokia\n\n     PS Leader:   Joey Boyd, ADTRAN\n\n     WA Director: Joey Boyd, ADTRAN\n\n     WA Director: Sven Ooghe, Nokia\";\n\n  description\n    \"This module contains a collection of YANG definitions for\n     supporting the Broadband Forum requirements on managing physical\n     devices.\";\n\n  revision 2022-03-01 {\n    description\n      \"Amendment 5.\n       * Approval Date:    2022-03-01.\n       * Publication Date: 2022-03-01.\";\n    reference\n      \"TR-383a5: Common YANG Modules\n                 <https://www.broadband-forum.org/technical/download/\n                          TR-383_Amendment-5.pdf>\";\n  }\n\n  // Features\n\n  feature reports-device-powering-state {\n    description\n      \"Indicates the support for reporting the device powering\n       state.\";\n  }\n\n  // Device Properties\n\n  grouping device-alias {\n    description\n      \"Alias information for the device.\";\n    leaf alias {\n      type bbf-yang:string-ascii64;\n      description\n        \"The alias that can be used to identify a device.\";\n    }\n  }\n\n  // Device hardware information\n\n\n  // Device Management Information\n\n  grouping device-management-info {\n    description\n      \"Data nodes relating to management plane information needed to\n       reach and communicate with the device.\";\n    leaf ip-address {\n      type inet:host;\n      description\n        \"The IP address or DNS domain name of the device.\";\n    }\n    leaf port {\n      type inet:port-number;\n      description\n        \"The port number used on the device for\n         management.\";\n    }\n    leaf admin-state {\n      type bbf-nodet:admin-state;\n      description\n        \"The administrative state of the device.\";\n    }\n  }\n\n}\n"
  },
  {
    "path": "tests/inputs/beluga.bel",
    "content": "%%% This aims at testing\n%%% cloc's configuration file\n%%% for beluga.\n\n% Refer to Beluga's reference guide for syntax\n% https://complogic.cs.mcgill.ca/beluga/userguide2/userguide.pdf\n\n % In-line comment (but after a space)\n\nnat : type. % in-line comment.\nz : nat.\nsucc : nat -> nat.\n\n%{\n    Multi-line\n    comment\n}%\n\n"
  },
  {
    "path": "tests/inputs/birds.pro",
    "content": "% https://raw.githubusercontent.com/Anniepoo/prolog-examples/master/birds.pl\n% renamed birds.pro to test pro disambiguation\n:- module(birds, [solve/0]).\n%\n% Start of an implementation of the code at\n% http://www.amzi.com/ExpertSystemsInProlog/\n%\n%\n:- dynamic\n\tknown/3,\n\tvoice/1,\n\tseason/1,\n\tcheek/1,\n\thead/1,\n\tflight/1,\n\tbill/1,\n\tlive/1,\n\tnostrils/1.\n\n:- discontiguous bird/1, wings/1.\n:- set_prolog_flag(unknown, error).\n\nbird(laysan_albatross):-\n  family(albatross),\n  color(white).\n\nbird(black_footed_albatross):-\n  family(albatross),\n  color(dark).\n\nbird(whistling_swan) :-\n  family(swan),\n  voice(muffled_musical_whistle).\n\nbird(trumpeter_swan) :-\n  family(swan),\n  voice(loud_trumpeting).\n\n\norder(tubenose) :-\nnostrils(external_tubular),\nlive(at_sea),\nbill(hooked).\n\norder(waterfowl) :-\nfeet(webbed),\nbill(flat).\n\nfamily(albatross) :-\norder(tubenose),\nsize(large),\nwings(long_narrow).\n\nfamily(swan) :-\norder(waterfowl),\nneck(long),\ncolor(white),\nflight(ponderous).\n\nbird(canada_goose):-\nfamily(goose),\nseason(winter),\ncountry(united_states),\nhead(black),\ncheek(white).\n\nbird(canada_goose):-\nfamily(goose),\nseason(summer),\ncountry(canada),\nhead(black),\ncheek(white).\n\ncountry(united_states):- region(mid_west).\n\ncountry(united_states):- region(south_west).\n\ncountry(united_states):- region(north_west).\n\ncountry(united_states):- region(mid_atlantic).\n\ncountry(canada):- province(ontario).\n\ncountry(canada):- province(quebec).\n\nregion(new_england):-\nstate(X),\nmember(X, [massachusetts, vermont]).\n\nregion(south_east):-\nstate(X),\nmember(X, [florida, mississippi]).\n\nstate(X) :- member(X, [florida, mississippi, massachusetts, vermont]).\n\nprovince(X) :- member(X, [ontario, quebec]).\n\nask(A, V):-\n  known(yes, A, V), % succeed if true\n  !. % stop looking\n\nask(A, V):-\n  known(_, A, V), % fail if false\n  !, fail.\n\n% known is barfing\nask(A, V):-\n  write(A:V), % ask user\n  write('? : '),\n  read(Y), % get the answer\n  asserta(known(Y, A, V)), % remember it\n  Y == yes. % succeed or fail\nask(A, V):-\n\t\\+ multivalued(A),\n\tknown(yes, A, V2),\n\tV \\== V2,\n\t!, fail.\n\neats(X):- ask(eats, X).\n\nfeet(X):- ask(feet, X).\n\nwings(X):- ask(wings, X).\n\nneck(X):- ask(neck, X).\n\ncolor(X):- ask(color, X).\n\nmultivalued(voice).\nmultivalued(feed).\n\nsize(X):- menuask(size, X, [large, plump, medium, small]).\n\nflight(X):- menuask(flight, X, [ponderous, agile, flap_glide]).\n\n\n\nmenuask(A, V, MenuList) :-\nwrite('What is the value for'), write(A), write('?'), nl,\nwrite(MenuList), nl,\nread(X),\ncheck_val(X, A, V, MenuList),\nasserta( known(yes, A, X) ),\nX == V.\n\ncheck_val(X, _A, _V, MenuList) :-\nmember(X, MenuList), !.\n\ncheck_val(X, A, V, MenuList) :-\nwrite(X), write(' is not a legal value, try again.'), nl,\nmenuask(A, V, MenuList).\n\ntop_goal(X) :- bird(X).\n\nsolve :-\nretractall(known/3),\ntop_goal(X),\nwrite('The answer is '), write(X), nl.\n\nsolve :-\nwrite('No answer found.'), nl.\n\n"
  },
  {
    "path": "tests/inputs/blur.glsl",
    "content": "// Adapted from:\n// http://callumhay.blogspot.com/2010/09/gaussian-blur-shader-glsl.html\n/* \n   https://github.com/genekogan/Processing-Shader-Examples\n   TextureShaders/data/blur.glsl\n */\n\n#ifdef GL_ES\nprecision mediump float;\nprecision mediump int;\n#endif\n\n#define PROCESSING_TEXTURE_SHADER\n\nvarying vec4 vertTexCoord;\nuniform sampler2D texture;\nuniform int blurSize;       \nuniform int horizontalPass; // 0 or 1 to indicate vertical or horizontal pass\nuniform float sigma;        // The sigma value for the gaussian function: higher value means more blur\n                            // A good value for 9x9 is around 3 to 5\n                            // A good value for 7x7 is around 2.5 to 4\n                            // A good value for 5x5 is around 2 to 3.5\n                            // ... play around with this based on what you need :)\n\n//const vec2 texOffset = vec2(1.0, 1.0);\nuniform vec2 texOffset;\nconst float PI = 3.14159265;\n\nvoid main() {  \n  vec2 p = vertTexCoord.st;\n  float numBlurPixelsPerSide = float(blurSize / 2); \n  \n  // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)\n  vec3 incrementalGaussian;\n  incrementalGaussian.x = 1.0 / (sqrt(2.0 * PI) * sigma);\n  incrementalGaussian.y = exp(-0.5 / (sigma * sigma));\n  incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;\n\n  vec4 avgValue = vec4(0.0, 0.0, 0.0, 0.0);\n  float coefficientSum = 0.0;\n\n  // Take the central sample first...\n  avgValue += texture2D(texture, p) * incrementalGaussian.x;\n  coefficientSum += incrementalGaussian.x;\n  incrementalGaussian.xy *= incrementalGaussian.yz;\n\n  // Go through the remaining 8 vertical samples (4 on each side of the center)\n  for (float i = 1.0; i <= numBlurPixelsPerSide; i++) { \n    avgValue += texture2D(texture, p - i * texOffset) * incrementalGaussian.x;         \n    avgValue += texture2D(texture, p + i * texOffset) * incrementalGaussian.x;         \n    coefficientSum += 2.0 * incrementalGaussian.x;\n    incrementalGaussian.xy *= incrementalGaussian.yz;\n  }\n\n  gl_FragColor = avgValue / coefficientSum;\n}\n"
  },
  {
    "path": "tests/inputs/body.gjs",
    "content": "{{!\n    https://github.com/miguelcobain/ember-yeti-table/raw/a6642a4f16b6786a0f72d1caaa3270d0cb194d05/ember-yeti-table/src/components/yeti-table/body.gjs\n}}\nimport { action } from '@ember/object';\n\nimport Component from '@glimmer/component';\n\n/**\n  Renders a `<tbody>` element and yields the row component, row data and index.\n  ```hbs\n  <table.body as |body person index|>\n    <body.row as |row|>\n      <row.cell>\n        {{person.firstName}} #{{index}}\n      </row.cell>\n      <row.cell>\n        {{person.lastName}}\n      </row.cell>\n      <row.cell>\n        {{person.points}}\n      </row.cell>\n    </body.row>\n  </table.body>\n  ```\n  It can also be used as a blockless component to let yeti table automatically\n  unroll thee rows for you, based on the `@prop` arguments you passed in to the\n  column definition components.\n  ```hbs\n  <table.body/>\n  ```\n  Remember that this component's block will be rendered once per each item in the `@data` array.\n\n  @class Body\n  @yield {object} body\n  @yield {Component} body.row - the row component\n  @yield {Object} rowData - one item in the data array\n  @yield {number} index\n*/\n\n// template imports\nimport { fn, get, hash } from '@ember/helper';\nimport TBodyRow from './tbody/row.gjs';\n\nexport default class Body extends Component {\n  <template>\n    <tbody class={{@theme.tbody}} ...attributes>\n      {{#if (has-block)}}\n\n        {{#each @data as |rowData index|}}\n          {{yield (hash row=(component TBodyRow theme=@theme onClick=@onRowClick columns=@columns)) rowData index}}\n        {{/each}}\n\n      {{else}}\n\n        {{#each @data as |rowData|}}\n          <TBodyRow\n            @theme={{@theme}}\n            @onClick={{if @onRowClick (fn this.handleRowClick rowData)}}\n            @columns={{@columns}}\n            as |row|\n          >\n\n            {{#each @columns as |column|}}\n              <row.cell @class={{column.columnClass}}>\n                {{#if column.prop}}\n                  {{get rowData column.prop}}\n                {{else}}\n                  {{rowData}}\n                {{/if}}\n              </row.cell>\n            {{/each}}\n          </TBodyRow>\n        {{/each}}\n      {{/if}}\n    </tbody>\n  </template>\n  /**\n   * Adds a click action to each row, called with the clicked row's data as an argument.\n   * Can be used with both the blockless and block invocations.\n   *\n   * @argument onRowClick\n   * @type Function\n   */\n\n  @action\n  handleRowClick(rowData) {\n    this.args.onRowClick?.(rowData);\n  }\n}\n"
  },
  {
    "path": "tests/inputs/bubs_tak_ard.prc",
    "content": "CREATE OR REPLACE TRIGGER bubs_tak_ard\r\n/* ***************************************************************************\r\n *\r\n * Trigger: bubs_tak_ard\r\n *\r\n * After row delete trigger to maintain history for the table bubs_taken.\r\n *\r\n * Generated by Invantive Producer.\r\n *\r\n * (C) Copyright 2004-2017 Invantive Software BV, the Netherlands. All rights reserved.\r\n *\r\n * ***************************************************************************/\r\nafter delete\r\non bubs_taken\r\nfor each row\r\ndeclare\r\n  l_effective date;\r\n  l_anti_date boolean;\r\n  l_dummy     pls_integer;\r\nbegin\r\n  if true /* History is enabled. */ \r\n  then\r\n    l_effective := itgen_history.get_effective_date('bubs_taken', 'D', l_anti_date);\r\n    if l_anti_date\r\n    then\r\n      --\r\n      -- Check that there are no more recent mutations.\r\n      --\r\n      begin\r\n        select 1\r\n        into   l_dummy\r\n        from   bubshtaken\r\n        where  h_datum_start  > l_effective\r\n        and    id =:old.id\r\n        ;\r\n        bubs_error_handler.handle_error\r\n        ( '{res:bubs_anti_date_not_possible_before_later_history'\r\n          || '?bubshtaken'\r\n          || '&' || to_char(:old.id)\r\n          || '}'\r\n        , p_are_code  => 'takitg025'\r\n        , p_top_error => null\r\n        );\r\n      exception\r\n        when no_data_found\r\n        then\r\n          null;\r\n        when too_many_rows\r\n        then\r\n          bubs_error_handler.handle_error\r\n          ( '{res:bubs_anti_date_not_possible_before_later_history'\r\n            || '?bubshtaken'\r\n            || '&' || to_char(:old.id)\r\n            || '}'\r\n          , p_are_code  => 'takitg026'\r\n          , p_top_error => null\r\n          );\r\n      end;\r\n    end if;\r\n    --\r\n    update bubshtaken\r\n    set    h_datum_einde = l_effective-1/86400\r\n    ,      h_actief_als_gevuld = null\r\n    where  /* Allow use of index. */ case when h_actief_als_gevuld is not null then id else null end = :old.id\r\n    and    h_datum_einde = to_date('99991231', 'YYYYMMDD')\r\n    and    h_actief_als_gevuld = 'J' /* For performance. */\r\n    ;\r\n    if sql%rowcount <> 1\r\n    then\r\n      bubs_error_handler.handle_error\r\n      ( '{res:bubs_could_not_finish_history'\r\n        || '?bubshtaken'\r\n        || '&' || to_char(:old.id)\r\n        || '&' || sql%rowcount\r\n        || '}'\r\n      , p_are_code  => 'takitg027'\r\n      , p_top_error => null\r\n      );\r\n    end if;\r\n  end if;\r\nend;\r\n/"
  },
  {
    "path": "tests/inputs/build.bzl",
    "content": "\"\"\"This example creates a rule with a declared output.\"\"\"\n\ndef _impl(ctx):\n  ctx.actions.write(\n      # Access the default outputs using ctx.outputs.<output name>.\n      output=ctx.outputs.my_output,\n      content=\"Hello World!\"\n  )\n  # The default outputs are added automatically to this target.\n\nrule_with_outputs = rule(\n    implementation=_impl,\n    outputs = {\n        # %{name} is substituted with the rule's name\n        \"my_output\": \"%{name}.txt\"\n    }\n)\n\n"
  },
  {
    "path": "tests/inputs/build.cake",
    "content": "var target = Argument(\"target\", \"Test\");\r\nvar configuration = Argument(\"configuration\", \"Release\");\r\n\r\n//////////////////////////////////////////////////////////////////////\r\n// TASKS\r\n//////////////////////////////////////////////////////////////////////\r\n\r\nTask(\"Clean\")\r\n    .WithCriteria(c => HasArgument(\"rebuild\"))\r\n    .Does(() =>\r\n{\r\n    CleanDirectory($\"./src/Example/bin/{configuration}\");\r\n});\r\n\r\nTask(\"Build\")\r\n    .IsDependentOn(\"Clean\")\r\n    .Does(() =>\r\n{\r\n    DotNetCoreBuild(\"./src/Example.sln\", new DotNetCoreBuildSettings\r\n    {\r\n        Configuration = configuration,\r\n    });\r\n});\r\n\r\nTask(\"Test\")\r\n    .IsDependentOn(\"Build\")\r\n    .Does(() =>\r\n{\r\n    DotNetCoreTest(\"./src/Example.sln\", new DotNetCoreTestSettings\r\n    {\r\n        Configuration = configuration,\r\n        NoBuild = true,\r\n    });\r\n});\r\n\r\n//////////////////////////////////////////////////////////////////////\r\n// EXECUTION\r\n//////////////////////////////////////////////////////////////////////\r\n\r\nRunTarget(target);"
  },
  {
    "path": "tests/inputs/cad.asy",
    "content": "// https://asymptote.sourceforge.io/gallery/CAD1.asy\nimport CAD;\n\nsCAD cad=sCAD.Create();\n\n/* Freehand line\nthis is a comment\n*/\ndraw(g=cad.MakeFreehand(pFrom=(3,-1)*cm,(6,-1)*cm),\n     p=cad.pFreehand);\n\n// Standard measurement lines\ndraw(g=box((0,0)*cm,(1,1)*cm),p=cad.pVisibleEdge);\ncad.MeasureParallel(L=\"$\\sqrt{2}$\",\n                    pFrom=(0,1)*cm,\n                    pTo=(1,0)*cm,\n                    dblDistance=-15mm);\n\n// Label inside,shifted to the right; arrows outside\ndraw(g=box((2,0)*cm,(3,1)*cm),p=cad.pVisibleEdge);\ncad.MeasureParallel(L=\"1\",\n                    pFrom=(2,1)*cm,\n                    pTo=(3,1)*cm,\n                    dblDistance=5mm,\n                    dblLeft=5mm,\n                    dblRelPosition=0.75);\n\n// Label and arrows outside\ndraw(g=box((5,0)*cm,(5.5,1)*cm),p=cad.pVisibleEdge);\ncad.MeasureParallel(L=\"0.5\",\n                    pFrom=(5,1)*cm,\n                    pTo=(5.5,1)*cm,\n                    dblDistance=5mm,\n                    dblLeft=10mm,\n                    dblRelPosition=-1);\n\n// Small bounds,asymmetric measurement line\ndraw(g=box((7,0)*cm,(7.5,1)*cm),p=cad.pVisibleEdge);\ncad.MeasureParallel(L=\"0.5\",\n                    pFrom=(7,1)*cm,\n                    pTo=(7.5,1)*cm,\n                    dblDistance=5mm,\n                    dblLeft=2*cad.GetMeasurementBoundSize(bSmallBound=true),\n                    dblRight=10mm,\n                    dblRelPosition=2,\n                    bSmallBound=true);\n"
  },
  {
    "path": "tests/inputs/cadence_test.cdc",
    "content": "/* https://cadence-lang.org/docs/testing-framework\n*/\n// A `setup` function that always runs before the rest of the test cases.\n// Can be used to initialize things that would be used across the test cases.\n// e.g: initialling a blockchain backend, initializing a contract, etc.\naccess(all)\nfun setup() {\n}\n\n// The `beforeEach` function runs before each test case. Can be used to perform\n// some state cleanup before each test case, among other things.\naccess(all)\nfun beforeEach() {\n}\n\n// The `afterEach` function runs after each test case.  Can be used to perform\n// some state cleanup after each test case, among other things.\naccess(all)\nfun afterEach() {\n}\n\n// Valid test functions start with the 'test' prefix.\naccess(all)\nfun testSomething() {\n}\n\naccess(all)\nfun testAnotherThing() {\n}\n\naccess(all)\nfun testMoreThings() {\n}\n\n// Test functions cannot have any arguments or return values.\naccess(all)\nfun testInvalidSignature(message: String): Bool {\n}\n\n// A `tearDown` function that always runs at the end of all test cases.\n// e.g: Can be used to stop the blockchain back-end used for tests, etc. or any cleanup.\naccess(all)\nfun tearDown() {\n}\n\n"
  },
  {
    "path": "tests/inputs/captcha.cs",
    "content": "\"http://smalltalk.gnu.org/blog/bonzinip/captcha-simplest-gst-external-module\"\nDLD addModule: 'GD'.\nFileStream fileIn: 'GST_DIR/share/smalltalk/GD/GD.st'.\n\n\"A useful method... (will be in 3.0.1)\"\nSequenceableCollection extend [\n    atRandom [\n        ^self at: (Random between: 1 and: self size)\n    ]\n]\n\n\"Make a four character captcha.\"\nfontPath := '/usr/share/fonts/bitstream-vera/Vera.ttf'.\nauthChars := '0123456789'.\nauthChars := authChars, 'abcdefghijklmnopqrstuvwxyz'.\nauthChars := authChars, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n\nauthString := String streamContents: [ :s |.\n   4 timesRepeat: [ s nextPut: authChars atRandom ]].\n\nGD\n    imageString: authString\n    font: fontPath\n    foreground: #[255 255 255]\n    background: #[0 0 0]\n    size: 40\n    to: 'captcha.png'.\n"
  },
  {
    "path": "tests/inputs/capture.ecr",
    "content": "<%# Embedded Crystal example %>\n<%#\nhttps://raw.githubusercontent.com/ysbaddaden/frost/master/test/views/capture.ecr\n\n%>\n<%= content_tag :h1, \"inlined content\" %>\n\n<%= content_tag :p do %>\n  inner content\n<% end %>\n\n<%= content_tag :div do %>\n  <%= tag :br %>\n<% end %>\n\n<%= content_tag :outer do %>\n  <%= content_tag :inner do %>\n    <%= content_tag :nested do %>\n      contents\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "tests/inputs/certificates.sls",
    "content": "# https://github.com/saltstack-formulas/nginx-formula/tree/master/nginx\n{% from 'nginx/map.jinja' import nginx with context %}\n\ninclude:\n  - nginx.service\n\n{% set certificates_path = salt['pillar.get']('nginx:certificates_path', '/etc/nginx/ssl') %}\n\n{%- for dh_param, value in salt['pillar.get']('nginx:dh_param', {}).items() %}\n{%- if value is string %}\ncreate_nginx_dhparam_{{ dh_param }}_key:\n  file.managed:\n    - name: {{ certificates_path }}/{{ dh_param }}\n    - contents_pillar: nginx:dh_param:{{ dh_param }}\n    - makedirs: True\n    - watch_in:\n      - service: nginx_service\n{%- else %}\ngenerate_nginx_dhparam_{{ dh_param }}_key:\n  pkg.installed:\n    - name: {{ nginx.lookup.openssl_package }}\n  file.directory:\n    - name: {{ certificates_path }}\n    - makedirs: True\n  cmd.run:\n    - name: openssl dhparam -out {{ dh_param }} {{ value.get('keysize', 2048) }}\n    - cwd: {{ certificates_path }}\n    - creates: {{ certificates_path }}/{{ dh_param }}\n    - watch_in:\n      - service: nginx_service\n{%- endif %}\n{%- endfor %}\n\n{%- for domain in salt['pillar.get']('nginx:certificates', {}).keys() %}\n\nnginx_{{ domain }}_ssl_certificate:\n  file.managed:\n    - name: {{ certificates_path }}/{{ domain }}.crt\n    - makedirs: True\n{% if salt['pillar.get'](\"nginx:certificates:{}:public_cert_pillar\".format(domain)) %}\n    - contents_pillar: {{salt['pillar.get']('nginx:certificates:{}:public_cert_pillar'.format(domain))}}\n{% else %}\n    - contents_pillar: nginx:certificates:{{ domain }}:public_cert\n{% endif %}\n    - watch_in:\n      - service: nginx_service\n\n{% if salt['pillar.get'](\"nginx:certificates:{}:private_key\".format(domain)) or salt['pillar.get'](\"nginx:certificates:{}:private_key_pillar\".format(domain))%}\nnginx_{{ domain }}_ssl_key:\n  file.managed:\n    - name: {{ certificates_path }}/{{ domain }}.key\n    - mode: 600\n    - makedirs: True\n{% if salt['pillar.get'](\"nginx:certificates:{}:private_key_pillar\".format(domain)) %}\n    - contents_pillar: {{salt['pillar.get']('nginx:certificates:{}:private_key_pillar'.format(domain))}}\n{% else %}\n    - contents_pillar: nginx:certificates:{{ domain }}:private_key\n{% endif %}\n    - watch_in:\n      - service: nginx_service\n{% endif %}\n{%- endfor %}\n"
  },
  {
    "path": "tests/inputs/ch10-REPL-oriented-repl-interactions.cj",
    "content": "; https://github.com/clojurebook/ClojureProgramming/blob/master/ch10-REPL-oriented-repl-interactions.clj\n; then renamed to ch10-REPL-oriented-repl-interactions.cj to test disambiguation with Cangjie\n\n;-----\n(ns com.clojurebook.fn-browser\n  (:import (javax.swing JList JFrame JScrollPane JButton)\n           java.util.Vector))\n\n(defonce fn-names (->> (ns-publics 'clojure.core)\n                    (map key)\n                    sort\n                    Vector.\n                    JList.))\n\n(defn show-info [] )\n\n(defonce window (doto (JFrame. \"\\\"Interactive Development!\\\"\") \n                  (.setSize (java.awt.Dimension. 400 300))\n                  (.add (JScrollPane. fn-names))\n                  (.add java.awt.BorderLayout/SOUTH\n                    (doto (JButton. \"Show Info\")\n                      (.addActionListener (reify java.awt.event.ActionListener\n                                            (actionPerformed [_ e] (show-info))))))\n                  (.setVisible true)))\n\n\n;-----\n(in-ns 'com.clojurebook.fn-browser)\n\n(import '(javax.swing JOptionPane JTextArea))\n\n(defn show-info\n  []\n  (when-let [selected-fn (.getSelectedValue fn-names)]\n    (JOptionPane/showMessageDialog\n      window\n      (-> (ns-resolve 'clojure.core selected-fn)\n        meta\n        :doc\n        (JTextArea. 10 40)\n        JScrollPane.)\n      (str \"Doc string for clojure.core/\" selected-fn)\n      JOptionPane/INFORMATION_MESSAGE)))\n\n\n;-----\n(split-with keyword? [:a :b :c 1 2 3])\n;= [(:a :b :c) (1 2 3)]\n(zipmap (first *1) (second *1))\n;= {:c 3, :b 2, :a 1}\n(apply zipmap (split-with keyword? [:a :b :c 1 2 3]))\n;= {:c 3, :b 2, :a 1}\n\n\n;-----\n(throw (Exception. \"foo\"))\n;= Exception foo  user/eval1 (NO_SOURCE_FILE:1)\n(pst)\n; Exception foo\n;   user/eval1 (NO_SOURCE_FILE:1)\n;   clojure.lang.Compiler.eval (Compiler.java:6465)\n; ...\n\n\n;-----\n(apropos #\"^ref\")\n;= (ref-max-history refer-clojure ref-set ref-history-count ref ref-min-history refer)\n\n\n;-----\n(source merge)\n; (defn merge\n;   \"Returns a map that consists of the rest of the maps conj-ed onto\n;   the first.  If a key occurs in more than one map, the mapping from\n;   the latter (left-to-right) will be the mapping in the result.\"\n;   {:added \"1.0\"\n;    :static true}\n;   [& maps]\n;   (when (some identity maps)\n;     (reduce1 #(conj (or %1 {}) %2) maps)))\n\n\n;-----\n(require 'clojure.string)\n;= nil\n(dir clojure.string)\n; blank?\n; capitalize\n; escape\n; join\n; lower-case\n; replace\n; replace-first\n; reverse\n; split\n; split-lines\n; trim\n; trim-newline\n; triml\n; trimr\n; upper-case\n\n\n;-----\n(ns clean-namespace)\n;= nil\n(ns-aliases *ns*)\n;= {}\n(require '[clojure.set :as set])\n;= nil\n(ns-aliases *ns*)\n;= {set #<Namespace clojure.set>}\n(ns-publics *ns*)\n;= {}\n(def x 0)\n;= #'clean-namespace/x\n(ns-publics *ns*)\n;= {x #'clean-namespace/x}\n\n\n;-----\n(ns-unalias *ns* 'set)\n;= nil\n(ns-aliases *ns*)\n;= {}\n(ns-unmap *ns* 'x)\n;= nil\n(ns-publics *ns*)\n;= {}\n\n\n;-----\n(in-ns 'user)\n;= #<Namespace user>\n(filter #(= 'clean-namespace (ns-name %)) (all-ns))\n;= (#<Namespace clean-namespace>)\n(remove-ns 'clean-namespace)\n;= #<Namespace clean-namespace>\n(filter #(= 'clean-namespace (ns-name %)) (all-ns))\n;= ()\n\n\n;-----\n(setq inferior-lisp-program \"lein repl\")\n\n\n;-----\nlein plugin install swank-clojure 1.3.4\n\n\n;-----\n[swank-clojure \"1.3.4\"]\n\n\n;-----\n(defn debug-me\n  [x y]\n  (let [z (merge x y)]\n    (swank.core/break)))\n\n\n;-----\n(let [log-capacity 5000\n      events (agent [])]\n  (defn log-event [e]\n    (send events #(if (== log-capacity (count %))   \n                    (-> % (conj e) (subvec 1))\n                    (conj % e)))\n    e)\n  (defn events [] @events))\n\n\n;-----\n(doseq [request (repeatedly 10000 (partial rand-nth [{:referrer \"twitter.com\"}\n                                                     {:referrer \"facebook.com\"}\n                                                     {:referrer \"twitter.com\"}\n                                                     {:referrer \"reddit.com\"}]))]\n  (log-event request))\n;= nil\n(count (events))\n;= 5000\n\n\n;-----\n(frequencies (events))\n;= {{:referrer \"twitter.com\"} 2502,\n    {:referrer \"facebook.com\"} 1280,\n    {:referrer \"reddit.com\"} 1218}\n\n\n;-----\n(defn a [b] (+ 5 b))\n;= #'user/a\n(def b (partial a 5))\n;= #'user/b\n(b)\n;= 10\n(defn a [b] (+ 10 b))\n;= #'user/a\n(b)\n;= 10\n\n\n;-----\n(def b (partial #'a 5))\n;= #'user/b\n(b)\n;= 15\n(defn a [b] (+ 5 b))\n;= #'user/a\n(b)\n;= 10\n\n\n"
  },
  {
    "path": "tests/inputs/chat.st",
    "content": "\"SimpleChat -- a SimpleTCP handler for a chat server\"\n\"http://sblinn.jottit.com/gnu_smalltalk_simplechat_tcp_server\"\n\nNamespace current addSubspace: #SimpleChat!\nNamespace current: SimpleChat!\n\nObject subclass: #Handler\n  instanceVariableNames: 'clients'\n  classVariableNames: ''\n  poolDictionaries: ''\n  category: ''!\n\n!Handler class methodsFor: 'instance creation'!\n\nnew\n  | chatHandler |\n  chatHandler := super new.\n  chatHandler init.\n  ^chatHandler\n!!\n\n!Handler methodsFor: 'initialization'!\n\ninit\n  clients := Dictionary new.\n  ^self\n!!\n\n!Handler methodsFor: 'handling'!\n\nhandle: aSocket\n  [self handleSocket: aSocket] fork\n!!\n\n!Handler methodsFor: 'internal handling'!\n\nhandleSocket: aSocket\n  | Name |\n  'Name: ' displayOn: aSocket.\n  aSocket flush.\n  Name := (aSocket nextLine).\n  (clients includesKey: Name) ifTrue: [\n    'Sorry, that name is in use.' displayOn: aSocket.\n    (Character nl asString) displayOn: aSocket.\n    self handle: aSocket\n  ] ifFalse: [\n    self handleMessage: ('New user: ', Name) from: '[System]'.\n    clients at: Name put: aSocket.\n    self handleClient: aSocket named: Name\n  ]\n!\n\nhandleClient: aSocket named: Name\n  [\n    | Message |\n    self sendPrompt: aSocket.\n    Message := (aSocket nextLine).\n    self handleMessage: Message from: Name.\n  ] repeat\n!\n\nhandleMessage: Message from: Name\n  clients associationsDo: [ :assoc |\n    (Name = (assoc key)) ifFalse: [\n      self sendMessage: ((Character nl asString), Name, ' sent: ', Message) to: (assoc value).\n      self sendPrompt: (assoc value)\n    ] ifTrue: [\n      self sendMessage: ('You sent: ', Message) to: (assoc value)\n    ]]\n!\n\nsendMessage: Message to: aSocket\n  Message displayOn: aSocket.\n  (Character nl asString) displayOn: aSocket\n!\n\nsendPrompt: aSocket\n    '> ' displayOn: aSocket.\n    aSocket flush\n!!\n\nNamespace current: SimpleChat superspace!\n"
  },
  {
    "path": "tests/inputs/child_template.jinja2",
    "content": "{#  https://jinja.palletsprojects.com/en/2.11.x/templates/#comments #}\nse.html\" %}\n{% block title %}Index{% endblock %}\n{% block head %}\n    {{ super() }}\n    <style type=\"text/css\">\n        .important { color: #336699; }\n  {#  </style>\n{% endblock %}\n{% block content %}\n    <h1>Index</h1>\n#}\n    <p class=\"important\">\n      Welcome to my awesome homepage.\n    </p>\n{% endblock %}\n"
  },
  {
    "path": "tests/inputs/child_template.njk",
    "content": "{#  https://jinja.palletsprojects.com/en/2.11.x/templates/#comments #}\nse.html\" %}\n{% block title %}Index{% endblock %}\n{% block head %}\n    {{ super() }}\n    <style type=\"text/css\">\n        .important { color: #336699; }\n  {#  </style>\n{% endblock %}\n{% block content %}\n    <h1>Index</h1>\n#}\n    <p class=\"important\">\n      Welcome to my awesome homepage.\n    </p>\n{% endblock %}\n"
  },
  {
    "path": "tests/inputs/clarityfiles.clar",
    "content": ";; Test fixture for Clarity language\n;; This file covers various comment and code patterns\n\n(define-constant TEST_CONSTANT u100)\n\n;; Full line comment before code\n(define-read-only (test-function (param uint))\n  (ok param)\n)\n\n;; Another comment\n(define-map test-map\n  uint\n  bool\n)\n\n(define-public (public-function)\n  ;; Inline comment in function\n  (begin\n    ;; Nested comment\n    (ok true)\n  )\n)\n\n;; Trailing comment on code line\n(define-data-var counter uint u0) ;; end of line comment\n\n;; Multiple blank lines above\n\n(define-constant ANOTHER_CONSTANT u200)\n\n"
  },
  {
    "path": "tests/inputs/class.imba",
    "content": "# https://github.com/imba/imba/raw/master/test/syntax/class.imba\nextern describe, test, ok, eq, it\n\nclass Organism\n\n\tvar lvar = 10\n\n\tdef self.type\n\t\t'organism'\n\n\tdef initialize\n\t\t@ivar = 1\n\t\n\tdef lineage\n\t\t'organism'\n\t\t\n\tdef name\n\t\t'organism'\n\n\tdef speak\n\t\t'ghaarg'\n\n\tdef alive\n\t\tyes\n\n\tdef lvar\n\t\tlvar\n\n\t# hmm, maybe we shouldnt allow this?\n\t#\tclass Other\n\t#\n\t#\t\tdef inner\n\t#\t\t\tyes\n\t\t\nclass Virus < Organism\n\n\tdef initialize\n\t\t@ivar = 2\n\n\tdef lineage\n\t\t\"{name}.{super.lineage}\"\n\n\tdef name\n\t\t'virus'\n\nclass Animal < Organism\n\n\t# def self.type\n\t#    \"animal.{super}\"\n\n\tdef lineage\n\t\t\"animal.{super.lineage}\"\n\nclass Cat < Animal\n\n\t# def self.type\n\t#    \"cat.{super}\"\n\n\tdef lineage\n\t\t\"cat.{super.lineage}\"\n\n\tdef speak\n\t\t'miau'\n\nclass Dog < Animal\n\n\t# def self.type\n\t#    \"dog.{super}\"\n\tdef lineage\n\t\t\"dog.{super.lineage}\"\n\t\t\n\tdef speak\n\t\t'woff'\n\t\t\n\nclass Human < Animal\n\n\tdef lineage\n\t\t\"human.{super.lineage}\"\n\n\tdef speak\n\t\t'hello'\n\nclass Zombie < Human\n\n\tdef lineage\n\t\t\"zombie.{super.lineage}\"\n\n\tdef alive\n\t\tno\n\n\ndescribe 'Syntax - Class' do\n\n\t# test 'nested classes work' do\n\t# \tok !!Organism.Other\n\n\ttest 'should' do\n\n\t\t# you can define variables local to classbody\n\t\tvar obj = Organism.new\n\t\teq obj.lvar, 10\n\n\tdescribe 'Methods' do\n\n\t\tit 'should define class methods' do\n\t\t\teq Organism.type, 'organism'\n\n\t\tit 'should inherit class methods' do\n\t\t\teq Virus:type, Organism:type\n\n\t\t# it 'should call super in class methods' do\n\t\t#   eq Dog.type, \"dog.animal.organism\"\n\t\t#   eq Cat.type, \"cat.animal.organism\"\n\n\tdescribe 'Instance' do\n\n\t\tit 'should call the parent constructor by default' do\n\t\t\tvar obj = Cat.new\n\t\t\teq obj.@ivar, 1\n\n\t\tit 'should define instance methods' do\n\t\t\tvar obj = Organism.new\n\t\t\tvar val = obj.alive\n\t\t\t# eq val, true\n\t\t\tok obj.alive\n\t\t\teq obj.speak, 'ghaarg'\n\n\t\tit 'should inherit instance methods' do\n\t\t\tvar obj = Virus.new\n\t\t\tok obj.alive\n\n\n\t\tit 'should override instance methods' do\n\t\t\teq Organism.new.name, 'organism'\n\t\t\teq Virus.new.name, 'virus'\n\n\t\tit 'should call super in instance methods' do\n\t\t\t# Should not refer to the prototype directly?\n\t\t\teq Virus.new.lineage, 'virus.organism'\n\t\t\teq Zombie.new.lineage, 'zombie.human.animal.organism'\n\n\ttest 'define methods outside scope' do\n\t\tclass Cls\n\t\t\tdef self.a do 1\n\t\t\tdef a do 2\n\n\t\tdef Cls.b\n\t\t\t1\n\n\t\textend class Cls\n\t\t\tdef b\n\t\t\t\t2\n\n\t\teq Cls.a, 1\n\t\teq Cls.b, 1\n\n\t\teq Cls.new.a, 2\n\t\teq Cls.new.b, 2\n\n\t\n\ttest 'Scoping' do\n\n\t\tvar variable = 1\n\n\t\tlocal class A\n\t\t\tvar variable = 2\n\n\t\t\tdef self.base\n\t\t\t\tvariable\n\n\t\t\tdef self.add add\n\t\t\t\tvariable += add\n\n\t\t\tdef initialize add\n\t\t\t\t@sum = variable + add\n\t\t\t\tself\n\n\t\t\tdef base\n\t\t\t\tvariable\n\n\t\t\tdef sum\n\t\t\t\t@sum\n\n\t\teq variable, 1\n\t\teq A.base, 2\n\t\teq A.new.base, 2\n\t\teq A.new(5).sum, 7\n\n\t\tA.add(2)\n\n\t\teq variable, 1\n    ###\t\teq A.base, 4 ###\n\n###\t\t\t\t\t\n\ttest 'issue #71' do\n\t\tvar res\n\t\tvar def ping cb\n\t\t\tres = cb()\n\n\t\tclass A\n\t\t\tping do self\n\n\t\teq res, A\n\n###\t\t\t\t\t\n\n\n\n"
  },
  {
    "path": "tests/inputs/cli-args.nf",
    "content": "#!/usr/bin/env nextflow\n// https://github.com/nextflow-io/nextflow/raw/refs/heads/master/tests/cli-args.nf\n/*\n * Copyright 2013-2024, Seqera Labs\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 \nprintln \"alpha: ${params.alpha}\"\nprintln \"beta : ${params.beta}\"\nprintln \"delta: ${params.delta}\"\nprintln \"gamma: ${params.gamma}\"\nprintln \"omega: ${params.omega}\"\nprintln \"args : ${args.join('_')}\"\n"
  },
  {
    "path": "tests/inputs/cloc-dev.code-workspace",
    "content": "{\n    // this is a comment\n\t\"folders\": [\n\t\t{\n\t\t\t\"path\": \".\"\n\t\t},\n\t\t{\n\t\t\t\"path\": \"tests\"\n\t\t},\n\t\t{\n\t\t\t\"path\": \"Unix\"\n\t\t}\n        /* \n           more\n                comments \n                         */\n\t],\n\t\"settings\": {}\n}\n"
  },
  {
    "path": "tests/inputs/cloc_counts.csv",
    "content": "files,language,blank,comment,code,\"github.com/AlDanial/cloc v 1.89  T=0.15 s (1625.6 files/s, 119625.7 lines/s)\"\n2,ANTLR Grammar,200,59,1012\n3,R,95,312,698\n1,C/C++ Header,191,780,617\n11,C++,132,183,603\n2,Forth,17,84,529\n4,TypeScript,53,39,416\n1,Logtalk,59,57,368\n7,C,110,72,354\n2,Windows Message File,89,9,348\n2,TeX,36,64,265\n1,Racket,32,159,247\n1,SVG,19,4,242\n1,Glade,0,22,232\n1,DIET,10,4,230\n1,Windows Resource File,42,45,218\n3,Assembly,40,140,204\n2,make,49,85,139\n1,Zig,2,10,128\n5,Bourne Shell,17,7,123\n2,Idris,38,90,117\n1,ECPP,26,34,116\n2,Prolog,43,8,114\n1,Ruby,11,30,111\n1,Hoon,0,10,110\n1,Imba,71,30,108\n1,Thrift,57,134,97\n1,Xtend,17,52,91\n1,Lean,36,20,90\n1,Odin,32,56,90\n2,Smalltalk,19,5,85\n1,Vuejs Component,10,2,85\n5,Java,13,28,81\n1,Scheme,10,18,78\n1,MXML,23,5,74\n2,Perl,44,72,73\n3,Visual Basic,48,57,72\n3,MATLAB,3,11,68\n1,Oracle PL/SQL,0,15,67\n1,Haml,5,16,66\n1,Swift,23,13,65\n1,Fish Shell,14,47,62\n1,RAML,5,3,62\n1,Verilog-SystemVerilog,4,20,62\n1,Clean,10,30,58\n1,Qt Linguist,0,4,57\n1,SaltStack,6,1,55\n1,Dockerfile,4,1,53\n1,Meson,13,9,48\n1,Fennel,6,3,44\n1,JCL,0,18,44\n1,HCL,14,36,43\n1,Nim,5,13,43\n1,Nix,15,15,43\n1,Sass,14,0,43\n3,Go,14,41,40\n1,Raku,19,12,39\n3,SQL,24,36,39\n1,Agda,10,3,38\n3,COBOL,5,8,35\n4,Haskell,23,26,35\n1,RobotFramework,9,5,35\n1,AsciiDoc,17,27,34\n1,EJS,0,11,34\n1,IPL,6,15,33\n1,PO File,9,18,33\n1,GLSL,10,14,32\n1,WebAssembly,8,20,32\n2,Mustache,5,7,31\n2,Specman e,4,12,31\n1,Squirrel,6,4,31\n7,Python,16,54,30\n1,ASP.NET,8,0,29\n1,Apex Class,3,6,28\n1,Cucumber,3,2,28\n1,Drools,7,16,28\n1,Freemarker Template,0,2,27\n1,Puppet,2,2,27\n1,Bazel,7,1,26\n2,PHP,11,13,26\n1,LFE,15,21,25\n1,Objective-C,11,11,25\n1,Scala,8,8,25\n1,Brainfuck,1,3,24\n6,Fortran 90,1,18,24\n1,Haxe,26,99,24\n1,Lisp,5,26,24\n3,C#,8,7,23\n1,Blade,10,5,22\n1,JSON,0,0,22\n1,JSON5,0,4,22\n2,Mathematica,24,17,22\n1,Stata,7,7,22\n1,TOML,8,4,22\n1,Jupyter Notebook,0,126,21\n1,Smarty,1,1,21\n1,YAML,0,1,20\n1,BrightScript,0,3,19\n1,Igor Pro,4,6,19\n1,PL/M,1,5,19\n1,Solidity,0,2,19\n1,TTCN,11,16,19\n2,XSLT,0,4,19\n4,Pascal,4,15,18\n1,Windows Module Definition,1,1,18\n1,Gradle,0,2,17\n1,Mojo,6,4,17\n2,Razor,6,7,17\n2,Logos,6,3,16\n1,Gencat NLS,1,4,15\n5,JavaScript,3,0,15\n1,Pig Latin,19,40,15\n1,SWIG,4,4,15\n1,TNSDL,5,3,15\n1,Embedded Crystal,4,4,14\n1,F#,3,6,14\n1,GraphQL,1,2,14\n2,IDL,25,7,14\n1,SugarSS,5,4,13\n1,Velocity Template Language,0,20,13\n1,Starlark,3,4,11\n1,Jinja Template,0,6,10\n1,Slim,0,3,10\n1,reStructuredText,6,4,10\n1,Kotlin,0,3,9\n1,Mako,3,8,9\n1,Svelte,2,2,9\n1,Vala,0,5,9\n3,XML,0,5,9\n1,F# Script,1,2,8\n1,FXML,2,3,8\n1,SparForte,6,8,8\n1,WXML,3,2,8\n1,Elixir,3,10,7\n2,Fortran 77,1,8,7\n1,INI,2,3,7\n3,Lua,9,33,7\n1,Chapel,7,35,6\n2,Julia,4,15,5\n1,PL/I,0,7,5\n1,APL,3,6,4\n1,Arduino Sketch,1,5,4\n1,ReasonML,2,8,4\n1,Rmd,10,19,4\n1,WXSS,0,0,4\n1,Groovy,0,3,3\n1,LLVM IR,2,6,3\n1,Literate Idris,2,2,3\n1,ProGuard,7,14,3\n1,Tcl/Tk,1,2,3\n1,dhall,6,17,3\n1,ColdFusion,1,2,2\n1,DOS Batch,1,2,2\n1,Focus,1,2,1\n1,MUMPS,0,2,1\n1,XQuery,0,1,1\n1,xBase,0,9,1\n243,SUM,2381,4182,11319\n"
  },
  {
    "path": "tests/inputs/clusterConf.ttcn",
    "content": "// http://www.wiley.com/legacy/wileychi/ttcn-3/supp/clusterConf.ttcn\n\n/* ------------------------------------------------------------\n *\n * $Id: clusterConf.ttcn,v 1.5 2005/02/10 07:33:55 deiss Exp $\n * \n * @author Thomas Deiss\n * @remark Copyright: Nokia, 2004, 2005\n * \n * @remark DISCLAIMER: This TTCN-3 code is experimental code.\n *       Its purpose is to highlight strengths and weaknesses of\n *       TTCN-3, but it is not intended to be directly added to \n *       real test suites. The reader is strongly advised to check the code\n *       whether it fits the readers purpose and adapt it accordingly.\n *\n * @desc This module contains type definitions for clusters of components.\n */\n\nmodule clusterConf {\n\n  group g_ports {\n\n    type port AnyPort mixed {\n      inout all\n      }\n    \n  } // endgroup g_ports\n\n  group g_components {\n    \n    type component Server {\n      port AnyPort pt_servers\n      }\n\n    type component Supervisor {\n      port AnyPort pt_servers;\n      port AnyPort pt_cluster\n      }\n    \n    type component Worker {\n      port AnyPort pt_servers\n      }\n    \n  } // endgroup g_components\n\n} //endmodule clusterConf\n"
  },
  {
    "path": "tests/inputs/comments.rhai",
    "content": "// https://github.com/rhaiscript/rhai/raw/refs/heads/main/scripts/comments.rhai\n\n// Note:  nested /* */ comments, as below, are not handled correctly by cloc\n\n// I am a single line comment!\n\n\nlet /* I am a spy in a variable declaration! */ x = 5;\n\n/* I am a simple\n   multi-line\n   comment */\n\n/* look /* at /* that, /* multi-line */ comments */ can be */ nested */\n\n/* surrounded by */ let this_is_not_a_comment = true // comments\n"
  },
  {
    "path": "tests/inputs/comments_in_str.svelte",
    "content": "<script lang=\"ts\">\n    const x = \"/*\";\n    const y = '/*';\n    const z = `/*`;\n    const re = /\\/*/;\n</script>\n\n<div>Hello</div>\n"
  },
  {
    "path": "tests/inputs/comp.ecpp",
    "content": "<html>\n<head>\n <style type=\"text/css\">\n   p.example { background-color: #fcc;\n               font-family: monospace;\n               white-space: pre;; }\n   p.result { background-color: #ccc; }\n </style>\n</head>\n<body>\n\n<h1>Calling subcomponents</h1>\n\n<p>\n<b>Ecpp</b>-pages can embed other pages. These embedded pages are called\nsubcomponents. They come in 2 variants: local and external. Local\nsubcomponents are defined inside another component with\n<b>&lt;%def&nbsp;<i>componentname</i>&gt;</b> and closed with\n<b>&lt;/def&gt;</b>. External subcomponents are normal components.\n</p>\n\n<p>\nA subcomponentcall starts with <b>&lt;&amp;</b> and ends with\n<b>&amp;&gt;</b>. Insert the componentname between these tags. If you omit the\nlibrary-part of the component, the current library is used. If the\ncomponentname is a single word, ecpp looks for a local component, which is\ncalled if found. Otherwise it is a external componentcall.\n</p>\n\n<p>\nYou can dynamically build componentnames, by putting a c++-expression inside\nbrackets. This expression is evaluated on runtime and the resulting component\nis called. The expression can be of type (or convertable to)\n<b>std::string</b>, <b>tnt::Compident</b> or <b>tnt::Subcompident</b>.\n</p>\n\n<p>\nAfter the componentname you can add named parameters. Put a name followed by\n'=' and a value. The value is either a constant string or a expression. A\nexpression must be bracketed. If you want to pass just the same parameters\nyour current component received, put the single word <b>qparam</b> into the\nlist (actually you can pass any <b>cxxtools::query_params</b>-variable).\n</p>\n\n<p>\nA special case are local components, which have c++-parameters. You can put a\nnormal parameterlist just like in c++-functions after the defition\n(<b>&lt;%def&gt;</b>-block) after the componentname. The can only be called locally.\n</p>\n\n<h2>Just a local componentcall</h2>\n\n<p class=\"example\">\n &lt;&amp; localcomp param1=\"value1\" &amp;&gt;\n</p>\n\n<p class=\"result\">\n <& localcomp param1=\"value1\" &>\n</p>\n\n\n<h2> Another local componentcall. We pass a c++-parameter. </h2>\n<p class=\"example\">\n &lt;&amp; localcomp_p(5) &amp;&gt;\n</p>\n<p class=\"result\">\n <& localcomp_p(5) >\n</p>\n\n\n<h2>A external componentcall (localcomp \"extcomp\" does not exist)</h2>\n\n<p class=\"example\">\n &lt;&amp; subcomp param1=\"value1\" &amp;&gt;\n</p>\n<p class=\"result\">\n <& subcomp param1=\"value1\" &>\n</p>\n\n<h2> a external componentcall </h2>\n\n<p class=\"example\">\n &lt;&amp; extcomp@extlib param1=\"value1\" &amp;&gt;\n</p>\n<p class=\"result\">\n <& extcomp@extlib param1=\"value1\" &>\n</p>\n\n<h2> a external subcomponentcall </h2>\n\n<p class=\"example\">\n &lt;&amp; extcomp.subcomp@extlib param1=\"value1\" &amp;&gt;\n</p>\n<p class=\"result\">\n <& extcomp.subcomp@extlib param1=\"value1\" &>\n</p>\n\n<h2> compose componentname by expression </h2>\n<{\n  // define some variables here\n  std::string compname = \"extcomp\";\n  std::string libname = \"extlib\";\n}>\n<p class=\"example\">\n &lt;&amp; (compname + '@' + libname) param1=\"value1\" &amp;&gt;\n</p>\n<p class=\"result\">\n <& (compname + '@' + libname) param1=\"value1\" &>\n</p>\n\n<h2> call component by componentidentifier </h2>\n<p class=\"example\">\n &lt;&amp; (tnt::Compident(compname, libname)) param1=\"value1\" &amp;&gt;\n</p>\n<p class=\"result\">\n <& (tnt::Compident(libname, compname)) param1=\"value1\" &>\n</p>\n\n<h2> pass a expression as parameter </h2>\n<p class=\"example\">\n &lt;&amp; localcomp param1=(1+5) qparam param2=\"uhu\"&amp;&gt;\n</p>\n<p class=\"result\">\n <& localcomp param1=(1+5) qparam param2=\"uhu\"&>\n</p>\n\n<h2> pass multiple values with the same name as parameter </h2>\n<p class=\"example\">\n &lt;&amp; localcomp param3=\"value1\" param3=\"value2\"\n              param4=\"17\" param4=(28) &amp;&gt;\n</p>\n <& localcomp param3=\"value1\" param3=\"value2\"\n              param4=\"17\" param4=(28) &>\n\n<%doc>\n<h2> call subcomponents in c++-blocks </h2>\n<p class=\"example\">\n  callComp(\"extcomp@extlib\", request, reply, qparam);\n</p>\n<p class=\"result\">\n<{\n  callComp(\"extcomp@extlib\", request, reply, qparam);\n}>\n</p>\n\n</body>\n</html>\n\n<%def localcomp>\n<%args>\nparam1;\nparam2;\nparam3[];\nint param4[];\n</%args>\n   This is a local subcomponent.\n   We got a parameter <i>param1</i> with the value <b><$param1$></b>.\n% if (!param2.empty()) {\n   We got <i>param2</i> also. Its value is <b><$param2$></b>.\n% }\n  We got <$ param3.size() $> times \"param3\" and <$ param4.size() $> times\n  \"param4\".\n  The values of param3 are:\n  <{ std::copy(param3.begin(), param3.end(),\n       std::ostream_iterator<param3_type::value_type>(reply.out(), \", \")); }>.\n  The values of param4 are:\n  <{ std::copy(param4.begin(), param4.end(),\n       std::ostream_iterator<param4_type::value_type>(reply.out(), \", \")); }>.\n</%def>\n</%doc>\n\n<%def localcomp_p(int i)>\nThis is a local subcomponent with parameter.\nWe got a c++-integer-parameter with the value <b><$i$></b>.\nThis component can only be called locally because of c++-parameters.\n</%def>\n"
  },
  {
    "path": "tests/inputs/complex_union.derw",
    "content": "-- https://github.com/eeue56/derw/blob/main/examples/complex_union.derw\ntype Animal =\n    Dog { name: string }\n    | Cat { lives: number }\n\nsayHiToPet: Animal -> string\nsayHiToPet pet =\n    case pet of\n        Dog { name } ->\n            `Good boy ${name}!`\n\t{-\n        Cat { lives } ->\n            \"You have \" + lives + \" lives remaining.\"\n\t-}\n\nmain: void\nmain =\n    Dog { name: \"roof\" }\n        |> sayHiToPet\n        |> console.log\n"
  },
  {
    "path": "tests/inputs/conditions.CBL",
    "content": "      $ SET SOURCEFORMAT\"FREE\"\r\nIDENTIFICATION DIVISION.\r\nPROGRAM-ID.  Conditions.\r\nAUTHOR.  Michael Coughlan.\r\n* An example program demonstrating the use of \r\n* condition names (level 88's).\r\n* The EVALUATE and PERFORM verbs are also used.\r\n\r\nDATA DIVISION.\r\nWORKING-STORAGE SECTION.\r\n01  Char               PIC X.\r\n    88 Vowel           VALUE \"a\", \"e\", \"i\", \"o\", \"u\".\r\n    88 Consonant       VALUE \"b\", \"c\", \"d\", \"f\", \"g\", \"h\"\r\n                             \"j\" THRU \"n\", \"p\" THRU \"t\", \"v\" THRU \"z\".\r\n    88 Digit           VALUE \"0\" THRU \"9\".\r\n    88 ValidCharacter  VALUE \"a\" THRU \"z\", \"0\" THRU \"9\".\r\n\r\nPROCEDURE DIVISION.\r\nBegin.\r\n    DISPLAY \"Enter lower case character or digit. No data ends.\".\r\n    ACCEPT Char.\r\n    PERFORM UNTIL NOT ValidCharacter\r\n        EVALUATE TRUE\r\n           WHEN Vowel DISPLAY \"The letter \" Char \" is a vowel.\"\r\n           WHEN Consonant DISPLAY \"The letter \" Char \" is a consonant.\"\r\n           WHEN Digit DISPLAY Char \" is a digit.\"\r\n           WHEN OTHER DISPLAY \"problems found\"\r\n        END-EVALUATE\r\n    END-PERFORM\r\n    STOP RUN.\r\n    \r\n"
  },
  {
    "path": "tests/inputs/config.junos",
    "content": "## Last commit: 2017-02-16 10:48:24 PST by root\n# based on https://github.com/Juniper/Intro-to-Using-Ansible-with-Junos-OS/raw/master/library/config.conf\nversion 14.2R6.5;\ngroups {\n    re0 {\n        system {\n            /* host-name be-mx480-1-re0; */\n        }\n        interfaces {\n            fxp0 {\n/*\n                unit 0 {\n                    family inet {\n                        filter {\n                            group 1; */\n                        }\n                        address **.***.*.**/22;\n                    }\n                }\n            }\n        }\n    }\n    re1 {\n        system {\n            host-name be-mx480-1-re1;\n        }\n        interfaces {\n            fxp0 {\n                unit 0 {\n                    family inet {\n                        filter {\n                            group 1;\n                        }\n                        address **.***.*.**/22;\n                    }\n                }\n            }\n        }\n    }\n    global {\n        system {\n            domain-name ********;\n            domain-search [ ******** ];\n            backup-router **.***.*.*** destination *.*.*.*;\n            time-zone America/Los_Angeles;\n            debugger-on-panic;\n            debugger-on-break;\n            dump-on-panic;\n            authentication-order [ radius password ];\n            root-authentication {\n                encrypted-password ******\n            }\n            name-server {\n                ***.***.*.**;\n                ***.***.**.***;\n                ***.**.**.***;\n                ***.**.**.***;\n            }\n            radius-server {\n                ***.***.**.***\n                ***.***.**.**\n            }\n            login {\n                class superuser-local {\n                    permissions all;\n                }\n                user labadmin {\n                    uid 2003;\n                    class superuser;\n                    shell csh;\n                    authentication {\n                        encrypted-password ****\n                    }\n                }\n            }\n            services {\n                finger;\n                ftp;\n                rlogin;\n                rsh;\n                ssh;\n                telnet;\n                xnm-clear-text;\n                netconf {\n                    ssh;\n                }\n            }\n            syslog {\n                user * {\n                    any emergency;\n                }\n                file messages {\n                    any warning;\n                    authorization info;\n                    archive world-readable;\n                }\n                file security {\n                    interactive-commands any;\n                    archive world-readable;\n                }\n            }\n            processes {\n                routing enable;\n                ntp enable;\n                management enable;\n                watchdog enable;\n                snmp enable;\n                inet-process enable;\n                mib-process enable;\n            }\n            ntp {\n                boot-server ***.**.**.*;\n                server ***.**.**.*;\n            }\n        }\n        snmp {\n            location \"Software lab\";\n            interface fxp0.0;\n            community public {\n                authorization read-only;\n            }\n            community private {\n                authorization read-write;\n            }\n        }\n        routing-options {\n            static {\n                route 10.***.*.*/16 {\n                    next-hop 10.***.*.***;\n                    retain;\n                    no-readvertise;\n                }\n            }\n        }\n    }\n}\napply-groups [ global re0 re1 ];\n"
  },
  {
    "path": "tests/inputs/cpp-example.inc",
    "content": "#\n# Copyright OpenEmbedded Contributors\n#\n# SPDX-License-Identifier: MIT\n#\n\nLICENSE = \"MIT\"\nLIC_FILES_CHKSUM = \"file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302\"\n\nDEPENDS += \"json-c\"\n\nPV = \"1.0\"\n\nSRC_URI = \"\\\n    file://cpp-example.cpp \\\n    file://cpp-example-lib.hpp \\\n    file://cpp-example-lib.cpp \\\n    file://test-cpp-example.cpp \\\n    file://run-ptest \\\n\"\n\nS = \"${WORKDIR}\"\n\ninherit ptest\n"
  },
  {
    "path": "tests/inputs/cross-platform.just",
    "content": "# https://github.com/casey/just/blob/master/examples/cross-platform.just\n# use with https://github.com/casey/just\n#\n# Example cross-platform Python project\n#\n\npython_dir := if os_family() == \"windows\" { \"./.venv/Scripts\" } else { \"./.venv/bin\" }\npython := python_dir + if os_family() == \"windows\" { \"/python.exe\" } else { \"/python3\" }\nsystem_python := if os_family() == \"windows\" { \"py.exe -3.9\" } else { \"python3.9\" }\n\n# Set up development environment\nbootstrap:\n    if test ! -e .venv; then {{ system_python }} -m venv .venv; fi\n    {{ python }} -m pip install --upgrade pip wheel pip-tools\n    {{ python_dir }}/pip-sync\n\n# Upgrade Python dependencies\nupgrade-deps: && bootstrap\n    {{ python_dir }}/pip-compile --upgrade\n\n# Sample project script 1\nscript1:\n    {{ python }} script1.py\n\n# Sample project script 2\nscript2 *ARGS:\n    {{ python }} script2.py {{ ARGS }}\n"
  },
  {
    "path": "tests/inputs/csharp-designer.designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace StyleCop.CSharp {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Strings {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Strings() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"StyleCop.CSharp.Strings\", typeof(Strings).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to StyleCop.\n        /// </summary>\n        internal static string Title {\n            get {\n                return ResourceManager.GetString(\"Title\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/cucumber.feature",
    "content": "# https://raw.githubusercontent.com/diaspora/diaspora/master/features/mobile/activity_stream.feature\n@javascript @mobile\nFeature: Viewing my activity on the steam mobile page\n  In order to navigate Diaspora*\n  As a mobile user\n  I want to view my activity stream\n\n  Background:\n    Given following users exist:\n      | username   |\n      | alice      |\n      | bob        |\n    And a user with username \"bob\" is connected with \"alice\"\n    And \"alice@alice.alice\" has a public post with text \"Hello! I am #newhere\"\n             # another comment\n  Scenario: Show my activity empty\n    When I sign in as \"bob@bob.bob\" on the mobile website\n    When I go to the activity stream page\n    Then I should see \"My activity\" within \"#main\"\n    And I should not see \"Hello! I am #newhere\"\n\n  Scenario: Show liked post on my activity\n    When I sign in as \"bob@bob.bob\" on the mobile website\n    When I click on selector \"a.like-action.inactive\"\n    And I go to the activity stream page\n    Then I should see \"My activity\" within \"#main\"\n    And I should see \"Hello! I am #newhere\" within \".ltr\"\n\n  Scenario: Show own post on my activity\n    When I sign in as \"alice@alice.alice\" on the mobile website\n    And I go to the activity stream page\n    Then I should see \"My activity\" within \"#main\"\n    And I should see \"Hello! I am #newhere\" within \".ltr\"\n"
  },
  {
    "path": "tests/inputs/custom.triple.extension.js",
    "content": "js 4\n"
  },
  {
    "path": "tests/inputs/darwin-configuration.nix",
    "content": "# https://raw.githubusercontent.com/input-output-hk/iohk-ops/develop/nix-darwin/darwin-configuration.nix\n{ config, pkgs, ... }:\n\nlet\n  opsLib = import <iohk-ops/lib.nix>;\n\nin {\n  imports = [ ];\n\n  # List packages installed in system profile. To search by name, run:\n  # $ nix-env -qaP | grep wget\n  environment.systemPackages = with pkgs; [\n    nix-repl\n    nix\n    tmux\n    ncdu\n    git\n  ] ++ (if pkgs.stdenv.isDarwin then [\n    darwin.cctools\n  ] else []);\n\n  # Create /etc/bashrc that loads the nix-darwin environment.\n  programs.bash.enable = true;\n  # programs.zsh.enable = true;\n  # programs.fish.enable = true;\n\n  # Used for backwards compatibility, please read the changelog before changing.\n  # $ darwin-rebuild changelog\n  system.stateVersion = 2;\n\n  # You should generally set this to the total number of logical cores in your system.\n  # $ sysctl -n hw.ncpu\n  nix.maxJobs = 4;\n  nix.buildCores = 0;\n  nix.useSandbox = false;  # this seems to break things when enabled\n  nix.extraOptions = ''\n    gc-keep-derivations = true\n    gc-keep-outputs = true\n  '';\n\n  nix.binaryCachePublicKeys = [ \"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=\" ];\n  nix.binaryCaches = [ \"https://hydra.iohk.io\" ];\n  nix.trustedUsers = [ \"@admin\" ];\n\n  nix.nixPath = [\n    \"nixpkgs=UNSET\"\n    \"darwin=UNSET\"\n    \"darwin-config=UNSET\"\n    \"iohk-ops=UNSET\"\n  ];\n\n  ########################################################################\n\n  # try to ensure 25G of free space\n  nix.gc.automatic = true;\n  nix.gc.options = \"--max-freed $((25 * 1024**3 - 1024 * $(df -P -k /nix/store | tail -n 1 | awk '{ print $4 }')))\";\n\n  ########################################################################\n\n  services.nix-daemon.enable = true;\n\n  # Recreate /run/current-system symlink after boot.\n  services.activate-system.enable = true;\n\n  system.activationScripts.postActivation.text = ''\n    printf \"disabling spotlight indexing... \"\n    mdutil -i off -d / &> /dev/null\n    mdutil -E / &> /dev/null\n    echo \"ok\"\n  '';\n\n  ########################################################################\n}\n"
  },
  {
    "path": "tests/inputs/dd/bb/cc/MoreTeapotsRenderer.cpp",
    "content": "/*\n * Copyright 2013 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\n//--------------------------------------------------------------------------------\n// MoreTeapotsRenderer.cpp\n// Render teapots\n//--------------------------------------------------------------------------------\n//--------------------------------------------------------------------------------\n// Include files\n//--------------------------------------------------------------------------------\n#include \"MoreTeapotsRenderer.h\"\n\n//--------------------------------------------------------------------------------\n// Teapot model data\n//--------------------------------------------------------------------------------\n#include \"teapot.inl\"\n\n//--------------------------------------------------------------------------------\n// Ctor\n//--------------------------------------------------------------------------------\nMoreTeapotsRenderer::MoreTeapotsRenderer() :\n                geometry_instancing_support_( false )\n{\n\n}\n\n//--------------------------------------------------------------------------------\n// Dtor\n//--------------------------------------------------------------------------------\nMoreTeapotsRenderer::~MoreTeapotsRenderer()\n{\n    Unload();\n}\n\n//--------------------------------------------------------------------------------\n// Init\n//--------------------------------------------------------------------------------\nvoid MoreTeapotsRenderer::Init( const int32_t numX,\n        const int32_t numY,\n        const int32_t numZ )\n{\n    if( ndk_helper::GLContext::GetInstance()->GetGLVersion() >= 3.0 )\n    {\n        geometry_instancing_support_ = true;\n    }\n    else if( ndk_helper::GLContext::GetInstance()->CheckExtension( \"GL_NV_draw_instanced\" )\n            && ndk_helper::GLContext::GetInstance()->CheckExtension(\n                    \"GL_NV_uniform_buffer_object\" ) )\n    {\n        LOGI( \"Supported via extension!\" );\n        //_bGeometryInstancingSupport = true;\n        //_bARBSupport = true; //Need to patch shaders\n        //Currently this has been disabled\n    }\n\n    //Settings\n    glFrontFace( GL_CCW );\n\n    //Create Index buffer\n    num_indices_ = sizeof(teapotIndices) / sizeof(teapotIndices[0]);\n    glGenBuffers( 1, &ibo_ );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );\n    glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(teapotIndices), teapotIndices, GL_STATIC_DRAW );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );\n\n    //Create VBO\n    num_vertices_ = sizeof(teapotPositions) / sizeof(teapotPositions[0]) / 3;\n    int32_t iStride = sizeof(TEAPOT_VERTEX);\n    int32_t iIndex = 0;\n    TEAPOT_VERTEX* p = new TEAPOT_VERTEX[num_vertices_];\n    for( int32_t i = 0; i < num_vertices_; ++i )\n    {\n        p[i].pos[0] = teapotPositions[iIndex];\n        p[i].pos[1] = teapotPositions[iIndex + 1];\n        p[i].pos[2] = teapotPositions[iIndex + 2];\n\n        p[i].normal[0] = teapotNormals[iIndex];\n        p[i].normal[1] = teapotNormals[iIndex + 1];\n        p[i].normal[2] = teapotNormals[iIndex + 2];\n        iIndex += 3;\n    }\n    glGenBuffers( 1, &vbo_ );\n    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );\n    glBufferData( GL_ARRAY_BUFFER, iStride * num_vertices_, p, GL_STATIC_DRAW );\n    glBindBuffer( GL_ARRAY_BUFFER, 0 );\n    delete[] p;\n\n    //Init Projection matrices\n    teapot_x_ = numX;\n    teapot_y_ = numY;\n    teapot_z_ = numZ;\n    vec_mat_models_.reserve( teapot_x_ * teapot_y_ * teapot_z_ );\n\n    UpdateViewport();\n\n    const float total_width = 500.f;\n    float gap_x = total_width / (teapot_x_ - 1);\n    float gap_y = total_width / (teapot_y_ - 1);\n    float gap_z = total_width / (teapot_z_ - 1);\n    float offset_x = -total_width / 2.f;\n    float offset_y = -total_width / 2.f;\n    float offset_z = -total_width / 2.f;\n\n    for( int32_t iX = 0; iX < teapot_x_; ++iX )\n        for( int32_t iY = 0; iY < teapot_y_; ++iY )\n            for( int32_t iZ = 0; iZ < teapot_z_; ++iZ )\n            {\n                vec_mat_models_.push_back(\n                        ndk_helper::Mat4::Translation( iX * gap_x + offset_x, iY * gap_y + offset_y,\n                                iZ * gap_z + offset_z ) );\n                vec_colors_.push_back(\n                        ndk_helper::Vec3( random() / float( RAND_MAX * 1.1 ),\n                                random() / float( RAND_MAX * 1.1 ),\n                                random() / float( RAND_MAX * 1.1 ) ) );\n\n                float fX = random() / float( RAND_MAX ) - 0.5f;\n                float fY = random() / float( RAND_MAX ) - 0.5f;\n                vec_rotations_.push_back( ndk_helper::Vec2( fX * 0.05f, fY * 0.05f ) );\n                vec_current_rotations_.push_back( ndk_helper::Vec2( fX * M_PI, fY * M_PI ) );\n            }\n\n    if( geometry_instancing_support_ )\n    {\n        //\n        //Create parameter dictionary for shader patch\n        std::map<std::string, std::string> param;\n        param[std::string( \"%NUM_TEAPOT%\" )] = ToString( teapot_x_ * teapot_y_ * teapot_z_ );\n        param[std::string( \"%LOCATION_VERTEX%\" )] = ToString( ATTRIB_VERTEX );\n        param[std::string( \"%LOCATION_NORMAL%\" )] = ToString( ATTRIB_NORMAL );\n        if( arb_support_ )\n            param[std::string( \"%ARB%\" )] = std::string( \"ARB\" );\n        else\n            param[std::string( \"%ARB%\" )] = std::string( \"\" );\n\n        //Load shader\n        bool b = LoadShadersES3( &shader_param_, \"Shaders/VS_ShaderPlainES3.vsh\",\n                \"Shaders/ShaderPlainES3.fsh\", param );\n        if( b )\n        {\n            //\n            //Create uniform buffer\n            //\n            GLuint bindingPoint = 1;\n            GLuint blockIndex;\n            blockIndex = glGetUniformBlockIndex( shader_param_.program_, \"ParamBlock\" );\n            glUniformBlockBinding( shader_param_.program_, blockIndex, bindingPoint );\n\n            //Retrieve array stride value\n            int32_t iNumIndices;\n            glGetActiveUniformBlockiv( shader_param_.program_, blockIndex,\n                    GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &iNumIndices );\n            GLint i[iNumIndices];\n            GLint stride[iNumIndices];\n            glGetActiveUniformBlockiv( shader_param_.program_, blockIndex,\n                    GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, i );\n            glGetActiveUniformsiv( shader_param_.program_, iNumIndices, (GLuint*) i,\n                    GL_UNIFORM_ARRAY_STRIDE, stride );\n\n            ubo_matrix_stride_ = stride[0] / sizeof(float);\n            ubo_vector_stride_ = stride[2] / sizeof(float);\n\n            glGenBuffers( 1, &ubo_ );\n            glBindBuffer( GL_UNIFORM_BUFFER, ubo_ );\n            glBindBufferBase( GL_UNIFORM_BUFFER, bindingPoint, ubo_ );\n\n            //Store color value which wouldn't be updated every frame\n            int32_t iSize = teapot_x_ * teapot_y_ * teapot_z_\n                    * (ubo_matrix_stride_ + ubo_matrix_stride_ + ubo_vector_stride_); //Mat4 + Mat4 + Vec3 + 1 stride\n            float* pBuffer = new float[iSize];\n            float* pColor = pBuffer + teapot_x_ * teapot_y_ * teapot_z_ * ubo_matrix_stride_ * 2;\n            for( int32_t i = 0; i < teapot_x_ * teapot_y_ * teapot_z_; ++i )\n            {\n                memcpy( pColor, &vec_colors_[i], 3 * sizeof(float) );\n                pColor += ubo_vector_stride_; //Assuming std140 layout which is 4 DWORD stride for vectors\n            }\n\n            glBufferData( GL_UNIFORM_BUFFER, iSize * sizeof(float), pBuffer, GL_DYNAMIC_DRAW );\n            delete[] pBuffer;\n        }\n        else\n        {\n            LOGI( \"Shader compilation failed!! Falls back to ES2.0 pass\" );\n            //This happens some devices.\n            geometry_instancing_support_ = false;\n            //Load shader for GLES2.0\n            LoadShaders( &shader_param_, \"Shaders/VS_ShaderPlain.vsh\", \"Shaders/ShaderPlain.fsh\" );\n        }\n    }\n    else\n    {\n        //Load shader for GLES2.0\n        LoadShaders( &shader_param_, \"Shaders/VS_ShaderPlain.vsh\", \"Shaders/ShaderPlain.fsh\" );\n    }\n}\n\nvoid MoreTeapotsRenderer::UpdateViewport()\n{\n    int32_t viewport[4];\n    glGetIntegerv( GL_VIEWPORT, viewport );\n    float fAspect = (float) viewport[2] / (float) viewport[3];\n\n    const float CAM_NEAR = 5.f;\n    const float CAM_FAR = 10000.f;\n    bool bRotate = false;\n    mat_projection_ = ndk_helper::Mat4::Perspective( fAspect, 1.f, CAM_NEAR, CAM_FAR );\n}\n\n//--------------------------------------------------------------------------------\n// Unload\n//--------------------------------------------------------------------------------\nvoid MoreTeapotsRenderer::Unload()\n{\n    if( vbo_ )\n    {\n        glDeleteBuffers( 1, &vbo_ );\n        vbo_ = 0;\n    }\n    if( ubo_ )\n    {\n        glDeleteBuffers( 1, &ubo_ );\n        ubo_ = 0;\n    }\n    if( ibo_ )\n    {\n        glDeleteBuffers( 1, &ibo_ );\n        ibo_ = 0;\n    }\n    if( shader_param_.program_ )\n    {\n        glDeleteProgram( shader_param_.program_ );\n        shader_param_.program_ = 0;\n    }\n}\n\n//--------------------------------------------------------------------------------\n// Update\n//--------------------------------------------------------------------------------\nvoid MoreTeapotsRenderer::Update( float fTime )\n{\n    const float CAM_X = 0.f;\n    const float CAM_Y = 0.f;\n    const float CAM_Z = 2000.f;\n\n    mat_view_ = ndk_helper::Mat4::LookAt( ndk_helper::Vec3( CAM_X, CAM_Y, CAM_Z ),\n            ndk_helper::Vec3( 0.f, 0.f, 0.f ), ndk_helper::Vec3( 0.f, 1.f, 0.f ) );\n\n    if( camera_ )\n    {\n        camera_->Update();\n        mat_view_ = camera_->GetTransformMatrix() * mat_view_ * camera_->GetRotationMatrix();\n    }\n}\n\n//--------------------------------------------------------------------------------\n// Render\n//--------------------------------------------------------------------------------\nvoid MoreTeapotsRenderer::Render()\n{\n    // Bind the VBO\n    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );\n\n    int32_t iStride = sizeof(TEAPOT_VERTEX);\n    // Pass the vertex data\n    glVertexAttribPointer( ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, iStride, BUFFER_OFFSET( 0 ) );\n    glEnableVertexAttribArray( ATTRIB_VERTEX );\n\n    glVertexAttribPointer( ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, iStride,\n            BUFFER_OFFSET( 3 * sizeof(GLfloat) ) );\n    glEnableVertexAttribArray( ATTRIB_NORMAL );\n\n    // Bind the IB\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );\n\n    glUseProgram( shader_param_.program_ );\n\n    TEAPOT_MATERIALS material = { { 1.0f, 1.0f, 1.0f, 10.f }, { 0.1f, 0.1f, 0.1f }, };\n\n    //Update uniforms\n    //\n    //using glUniform3fv here was troublesome..\n    //\n    glUniform4f( shader_param_.material_specular_, material.specular_color[0],\n            material.specular_color[1], material.specular_color[2], material.specular_color[3] );\n    glUniform3f( shader_param_.material_ambient_, material.ambient_color[0],\n            material.ambient_color[1], material.ambient_color[2] );\n\n    glUniform3f( shader_param_.light0_, 100.f, -200.f, -600.f );\n\n    if( geometry_instancing_support_ )\n    {\n        //\n        //Geometry instancing, new feature in GLES3.0\n        //\n\n        //Update UBO\n        glBindBuffer( GL_UNIFORM_BUFFER, ubo_ );\n        float* p = (float*) glMapBufferRange( GL_UNIFORM_BUFFER, 0,\n                teapot_x_ * teapot_y_ * teapot_z_ * (ubo_matrix_stride_ * 2) * sizeof(float),\n                GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT );\n        float* pMVPMat = p;\n        float* pMVMat = p + teapot_x_ * teapot_y_ * teapot_z_ * ubo_matrix_stride_;\n        for( int32_t i = 0; i < teapot_x_ * teapot_y_ * teapot_z_; ++i )\n        {\n            //Rotation\n            float fX, fY;\n            vec_current_rotations_[i] += vec_rotations_[i];\n            vec_current_rotations_[i].Value( fX, fY );\n            ndk_helper::Mat4 mat_rotation = ndk_helper::Mat4::RotationX( fX )\n                    * ndk_helper::Mat4::RotationY( fY );\n\n            // Feed Projection and Model View matrices to the shaders\n            ndk_helper::Mat4 mat_v = mat_view_ * vec_mat_models_[i] * mat_rotation;\n            ndk_helper::Mat4 mat_vp = mat_projection_ * mat_v;\n\n            memcpy( pMVPMat, mat_vp.Ptr(), sizeof(mat_v) );\n            pMVPMat += ubo_matrix_stride_;\n\n            memcpy( pMVMat, mat_v.Ptr(), sizeof(mat_v) );\n            pMVMat += ubo_matrix_stride_;\n        }\n        glUnmapBuffer( GL_UNIFORM_BUFFER );\n\n        //Instanced rendering\n        glDrawElementsInstanced( GL_TRIANGLES, num_indices_, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0),\n                teapot_x_ * teapot_y_ * teapot_z_ );\n\n    }\n    else\n    {\n        //Regular rendering pass\n        for( int32_t i = 0; i < teapot_x_ * teapot_y_ * teapot_z_; ++i )\n        {\n            //Set diffuse\n            float x, y, z;\n            vec_colors_[i].Value( x, y, z );\n            glUniform4f( shader_param_.material_diffuse_, x, y, z, 1.f );\n\n            //Rotation\n            vec_current_rotations_[i] += vec_rotations_[i];\n            vec_current_rotations_[i].Value( x, y );\n            ndk_helper::Mat4 mat_rotation = ndk_helper::Mat4::RotationX( x )\n                    * ndk_helper::Mat4::RotationY( y );\n\n            // Feed Projection and Model View matrices to the shaders\n            ndk_helper::Mat4 mat_v = mat_view_ * vec_mat_models_[i] * mat_rotation;\n            ndk_helper::Mat4 mat_vp = mat_projection_ * mat_v;\n            glUniformMatrix4fv( shader_param_.matrix_projection_, 1, GL_FALSE, mat_vp.Ptr() );\n            glUniformMatrix4fv( shader_param_.matrix_view_, 1, GL_FALSE, mat_v.Ptr() );\n\n            glDrawElements( GL_TRIANGLES, num_indices_, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0) );\n\n        }\n    }\n\n    glBindBuffer( GL_ARRAY_BUFFER, 0 );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );\n}\n\n//--------------------------------------------------------------------------------\n// LoadShaders\n//--------------------------------------------------------------------------------\nbool MoreTeapotsRenderer::LoadShaders( SHADER_PARAMS* params,\n        const char* strVsh,\n        const char* strFsh )\n{\n    //\n    //Shader load for GLES2\n    //In GLES2.0, shader attribute locations need to be explicitly specified before linking\n    //\n    GLuint program;\n    GLuint vertShader, fragShader;\n    char *vertShaderPathname, *fragShaderPathname;\n\n    // Create shader program\n    program = glCreateProgram();\n    LOGI( \"Created Shader %d\", program );\n\n    // Create and compile vertex shader\n    if( !ndk_helper::shader::CompileShader( &vertShader, GL_VERTEX_SHADER, strVsh ) )\n    {\n        LOGI( \"Failed to compile vertex shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Create and compile fragment shader\n    if( !ndk_helper::shader::CompileShader( &fragShader, GL_FRAGMENT_SHADER, strFsh ) )\n    {\n        LOGI( \"Failed to compile fragment shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Attach vertex shader to program\n    glAttachShader( program, vertShader );\n\n    // Attach fragment shader to program\n    glAttachShader( program, fragShader );\n\n    // Bind attribute locations\n    // this needs to be done prior to linking\n    glBindAttribLocation( program, ATTRIB_VERTEX, \"myVertex\" );\n    glBindAttribLocation( program, ATTRIB_NORMAL, \"myNormal\" );\n\n    // Link program\n    if( !ndk_helper::shader::LinkProgram( program ) )\n    {\n        LOGI( \"Failed to link program: %d\", program );\n\n        if( vertShader )\n        {\n            glDeleteShader( vertShader );\n            vertShader = 0;\n        }\n        if( fragShader )\n        {\n            glDeleteShader( fragShader );\n            fragShader = 0;\n        }\n        if( program )\n        {\n            glDeleteProgram( program );\n        }\n        return false;\n    }\n\n    // Get uniform locations\n    params->matrix_projection_ = glGetUniformLocation( program, \"uPMatrix\" );\n    params->matrix_view_ = glGetUniformLocation( program, \"uMVMatrix\" );\n\n    params->light0_ = glGetUniformLocation( program, \"vLight0\" );\n    params->material_diffuse_ = glGetUniformLocation( program, \"vMaterialDiffuse\" );\n    params->material_ambient_ = glGetUniformLocation( program, \"vMaterialAmbient\" );\n    params->material_specular_ = glGetUniformLocation( program, \"vMaterialSpecular\" );\n\n    // Release vertex and fragment shaders\n    if( vertShader )\n        glDeleteShader( vertShader );\n    if( fragShader )\n        glDeleteShader( fragShader );\n\n    params->program_ = program;\n    return true;\n}\n\nbool MoreTeapotsRenderer::LoadShadersES3( SHADER_PARAMS* params,\n        const char* strVsh,\n        const char* strFsh,\n        std::map<std::string, std::string>&shaderParams )\n{\n    //\n    //Shader load for GLES3\n    //In GLES3.0, shader attribute index can be described in a shader code directly with layout() attribute\n    //\n    GLuint program;\n    GLuint vertShader, fragShader;\n    char *vertShaderPathname, *fragShaderPathname;\n\n    // Create shader program\n    program = glCreateProgram();\n    LOGI( \"Created Shader %d\", program );\n\n    // Create and compile vertex shader\n    if( !ndk_helper::shader::CompileShader( &vertShader, GL_VERTEX_SHADER, strVsh, shaderParams ) )\n    {\n        LOGI( \"Failed to compile vertex shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Create and compile fragment shader\n    if( !ndk_helper::shader::CompileShader( &fragShader, GL_FRAGMENT_SHADER, strFsh,\n            shaderParams ) )\n    {\n        LOGI( \"Failed to compile fragment shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Attach vertex shader to program\n    glAttachShader( program, vertShader );\n\n    // Attach fragment shader to program\n    glAttachShader( program, fragShader );\n\n    // Link program\n    if( !ndk_helper::shader::LinkProgram( program ) )\n    {\n        LOGI( \"Failed to link program: %d\", program );\n\n        if( vertShader )\n        {\n            glDeleteShader( vertShader );\n            vertShader = 0;\n        }\n        if( fragShader )\n        {\n            glDeleteShader( fragShader );\n            fragShader = 0;\n        }\n        if( program )\n        {\n            glDeleteProgram( program );\n        }\n\n        return false;\n    }\n\n    // Get uniform locations\n    params->light0_ = glGetUniformLocation( program, \"vLight0\" );\n    params->material_ambient_ = glGetUniformLocation( program, \"vMaterialAmbient\" );\n    params->material_specular_ = glGetUniformLocation( program, \"vMaterialSpecular\" );\n\n    // Release vertex and fragment shaders\n    if( vertShader )\n        glDeleteShader( vertShader );\n    if( fragShader )\n        glDeleteShader( fragShader );\n\n    params->program_ = program;\n    return true;\n}\n\n//--------------------------------------------------------------------------------\n// Bind\n//--------------------------------------------------------------------------------\nbool MoreTeapotsRenderer::Bind( ndk_helper::TapCamera* camera )\n{\n    camera_ = camera;\n    return true;\n}\n\n//--------------------------------------------------------------------------------\n// Helper functions\n//--------------------------------------------------------------------------------\nstd::string MoreTeapotsRenderer::ToString( const int32_t i )\n{\n    char str[64];\n    snprintf( str, sizeof(str), \"%d\", i );\n    return std::string( str );\n}\n\n"
  },
  {
    "path": "tests/inputs/dd/bb/config.c",
    "content": "/* Generated automatically from /s/ndk-toolchain/src/python/Python-2.7.5/Modules/config.c.in by makesetup. */\n/* -*- C -*- ***********************************************\nCopyright (c) 2000, BeOpen.com.\nCopyright (c) 1995-2000, Corporation for National Research Initiatives.\nCopyright (c) 1990-1995, Stichting Mathematisch Centrum.\nAll rights reserved.\n\nSee the file \"Misc/COPYRIGHT\" for information on usage and\nredistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.\n******************************************************************/\n\n/* Module configuration */\n\n/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */\n\n/* This file contains the table of built-in modules.\n   See init_builtin() in import.c. */\n\n#include \"Python.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\nextern void initposix(void);\nextern void initthread(void);\nextern void initsignal(void);\nextern void initerrno(void);\nextern void init_sre(void);\nextern void init_codecs(void);\nextern void init_weakref(void);\nextern void initzipimport(void);\nextern void init_symtable(void);\nextern void initxxsubtype(void);\n\n/* -- ADDMODULE MARKER 1 -- */\n\nextern void PyMarshal_Init(void);\nextern void initimp(void);\nextern void initgc(void);\nextern void init_ast(void);\nextern void _PyWarnings_Init(void);\n\nstruct _inittab _PyImport_Inittab[] = {\n\n\t{\"posix\", initposix},\n\t{\"thread\", initthread},\n\t{\"signal\", initsignal},\n\t{\"errno\", initerrno},\n\t{\"_sre\", init_sre},\n\t{\"_codecs\", init_codecs},\n\t{\"_weakref\", init_weakref},\n\t{\"zipimport\", initzipimport},\n\t{\"_symtable\", init_symtable},\n\t{\"xxsubtype\", initxxsubtype},\n\n/* -- ADDMODULE MARKER 2 -- */\n\n    /* This module lives in marshal.c */\n    {\"marshal\", PyMarshal_Init},\n\n    /* This lives in import.c */\n    {\"imp\", initimp},\n\n    /* This lives in Python/Python-ast.c */\n    {\"_ast\", init_ast},\n\n    /* These entries are here for sys.builtin_module_names */\n    {\"__main__\", NULL},\n    {\"__builtin__\", NULL},\n    {\"sys\", NULL},\n    {\"exceptions\", NULL},\n\n    /* This lives in gcmodule.c */\n    {\"gc\", initgc},\n\n    /* This lives in _warnings.c */\n    {\"_warnings\", _PyWarnings_Init},\n\n    /* Sentinel */\n    {0, 0}\n};\n\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "tests/inputs/dd/bb/ee/TeapotRenderer.cpp",
    "content": "/*\n * Copyright 2013 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\n//--------------------------------------------------------------------------------\n// TeapotRenderer.cpp\n// Render a teapot\n//--------------------------------------------------------------------------------\n//--------------------------------------------------------------------------------\n// Include files\n//--------------------------------------------------------------------------------\n#include \"TeapotRenderer.h\"\n\n//--------------------------------------------------------------------------------\n// Teapot model data\n//--------------------------------------------------------------------------------\n#include \"teapot.inl\"\n\n//--------------------------------------------------------------------------------\n// Ctor\n//--------------------------------------------------------------------------------\nTeapotRenderer::TeapotRenderer()\n{\n\n}\n\n//--------------------------------------------------------------------------------\n// Dtor\n//--------------------------------------------------------------------------------\nTeapotRenderer::~TeapotRenderer()\n{\n    Unload();\n}\n\nvoid TeapotRenderer::Init()\n{\n    //Settings\n    glFrontFace( GL_CCW );\n\n    //Load shader\n    LoadShaders( &shader_param_, \"Shaders/VS_ShaderPlain.vsh\",\n            \"Shaders/ShaderPlain.fsh\" );\n\n    //Create Index buffer\n    num_indices_ = sizeof(teapotIndices) / sizeof(teapotIndices[0]);\n    glGenBuffers( 1, &ibo_ );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );\n    glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(teapotIndices), teapotIndices,\n            GL_STATIC_DRAW );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );\n\n    //Create VBO\n    num_vertices_ = sizeof(teapotPositions) / sizeof(teapotPositions[0]) / 3;\n    int32_t iStride = sizeof(TEAPOT_VERTEX);\n    int32_t iIndex = 0;\n    TEAPOT_VERTEX* p = new TEAPOT_VERTEX[num_vertices_];\n    for( int32_t i = 0; i < num_vertices_; ++i )\n    {\n        p[i].pos[0] = teapotPositions[iIndex];\n        p[i].pos[1] = teapotPositions[iIndex + 1];\n        p[i].pos[2] = teapotPositions[iIndex + 2];\n\n        p[i].normal[0] = teapotNormals[iIndex];\n        p[i].normal[1] = teapotNormals[iIndex + 1];\n        p[i].normal[2] = teapotNormals[iIndex + 2];\n        iIndex += 3;\n    }\n    glGenBuffers( 1, &vbo_ );\n    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );\n    glBufferData( GL_ARRAY_BUFFER, iStride * num_vertices_, p, GL_STATIC_DRAW );\n    glBindBuffer( GL_ARRAY_BUFFER, 0 );\n\n    delete[] p;\n\n    UpdateViewport();\n    mat_model_ = ndk_helper::Mat4::Translation( 0, 0, -15.f );\n\n    ndk_helper::Mat4 mat = ndk_helper::Mat4::RotationX( M_PI / 3 );\n    mat_model_ = mat * mat_model_;\n}\n\nvoid TeapotRenderer::UpdateViewport()\n{\n    //Init Projection matrices\n    int32_t viewport[4];\n    glGetIntegerv( GL_VIEWPORT, viewport );\n    float fAspect = (float) viewport[2] / (float) viewport[3];\n\n    const float CAM_NEAR = 5.f;\n    const float CAM_FAR = 10000.f;\n    bool bRotate = false;\n    mat_projection_ = ndk_helper::Mat4::Perspective( fAspect, 1.f, CAM_NEAR, CAM_FAR );\n}\n\nvoid TeapotRenderer::Unload()\n{\n    if( vbo_ )\n    {\n        glDeleteBuffers( 1, &vbo_ );\n        vbo_ = 0;\n    }\n\n    if( ibo_ )\n    {\n        glDeleteBuffers( 1, &ibo_ );\n        ibo_ = 0;\n    }\n\n    if( shader_param_.program_ )\n    {\n        glDeleteProgram( shader_param_.program_ );\n        shader_param_.program_ = 0;\n    }\n}\n\nvoid TeapotRenderer::Update( float fTime )\n{\n    const float CAM_X = 0.f;\n    const float CAM_Y = 0.f;\n    const float CAM_Z = 700.f;\n\n    mat_view_ = ndk_helper::Mat4::LookAt( ndk_helper::Vec3( CAM_X, CAM_Y, CAM_Z ),\n            ndk_helper::Vec3( 0.f, 0.f, 0.f ), ndk_helper::Vec3( 0.f, 1.f, 0.f ) );\n\n    if( camera_ )\n    {\n        camera_->Update();\n        mat_view_ = camera_->GetTransformMatrix() * mat_view_\n                * camera_->GetRotationMatrix() * mat_model_;\n    }\n    else\n    {\n        mat_view_ = mat_view_ * mat_model_;\n    }\n}\n\nvoid TeapotRenderer::Render()\n{\n    //\n    // Feed Projection and Model View matrices to the shaders\n    ndk_helper::Mat4 mat_vp = mat_projection_ * mat_view_;\n\n    // Bind the VBO\n    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );\n\n    int32_t iStride = sizeof(TEAPOT_VERTEX);\n    // Pass the vertex data\n    glVertexAttribPointer( ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, iStride,\n            BUFFER_OFFSET( 0 ) );\n    glEnableVertexAttribArray( ATTRIB_VERTEX );\n\n    glVertexAttribPointer( ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, iStride,\n            BUFFER_OFFSET( 3 * sizeof(GLfloat) ) );\n    glEnableVertexAttribArray( ATTRIB_NORMAL );\n\n    // Bind the IB\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo_ );\n\n    glUseProgram( shader_param_.program_ );\n\n    TEAPOT_MATERIALS material = { { 1.0f, 0.5f, 0.5f }, { 1.0f, 1.0f, 1.0f, 10.f }, {\n            0.1f, 0.1f, 0.1f }, };\n\n    //Update uniforms\n    glUniform4f( shader_param_.material_diffuse_, material.diffuse_color[0],\n            material.diffuse_color[1], material.diffuse_color[2], 1.f );\n\n    glUniform4f( shader_param_.material_specular_, material.specular_color[0],\n            material.specular_color[1], material.specular_color[2],\n            material.specular_color[3] );\n    //\n    //using glUniform3fv here was troublesome\n    //\n    glUniform3f( shader_param_.material_ambient_, material.ambient_color[0],\n            material.ambient_color[1], material.ambient_color[2] );\n\n    glUniformMatrix4fv( shader_param_.matrix_projection_, 1, GL_FALSE, mat_vp.Ptr() );\n    glUniformMatrix4fv( shader_param_.matrix_view_, 1, GL_FALSE, mat_view_.Ptr() );\n    glUniform3f( shader_param_.light0_, 100.f, -200.f, -600.f );\n\n    glDrawElements( GL_TRIANGLES, num_indices_, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0) );\n\n    glBindBuffer( GL_ARRAY_BUFFER, 0 );\n    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );\n}\n\nbool TeapotRenderer::LoadShaders( SHADER_PARAMS* params,\n        const char* strVsh,\n        const char* strFsh )\n{\n    GLuint program;\n    GLuint vert_shader, frag_shader;\n    char *vert_shader_pathname, *frag_shader_pathname;\n\n    // Create shader program\n    program = glCreateProgram();\n    LOGI( \"Created Shader %d\", program );\n\n    // Create and compile vertex shader\n    if( !ndk_helper::shader::CompileShader( &vert_shader, GL_VERTEX_SHADER, strVsh ) )\n    {\n        LOGI( \"Failed to compile vertex shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Create and compile fragment shader\n    if( !ndk_helper::shader::CompileShader( &frag_shader, GL_FRAGMENT_SHADER, strFsh ) )\n    {\n        LOGI( \"Failed to compile fragment shader\" );\n        glDeleteProgram( program );\n        return false;\n    }\n\n    // Attach vertex shader to program\n    glAttachShader( program, vert_shader );\n\n    // Attach fragment shader to program\n    glAttachShader( program, frag_shader );\n\n    // Bind attribute locations\n    // this needs to be done prior to linking\n    glBindAttribLocation( program, ATTRIB_VERTEX, \"myVertex\" );\n    glBindAttribLocation( program, ATTRIB_NORMAL, \"myNormal\" );\n    glBindAttribLocation( program, ATTRIB_UV, \"myUV\" );\n\n    // Link program\n    if( !ndk_helper::shader::LinkProgram( program ) )\n    {\n        LOGI( \"Failed to link program: %d\", program );\n\n        if( vert_shader )\n        {\n            glDeleteShader( vert_shader );\n            vert_shader = 0;\n        }\n        if( frag_shader )\n        {\n            glDeleteShader( frag_shader );\n            frag_shader = 0;\n        }\n        if( program )\n        {\n            glDeleteProgram( program );\n        }\n\n        return false;\n    }\n\n    // Get uniform locations\n    params->matrix_projection_ = glGetUniformLocation( program, \"uPMatrix\" );\n    params->matrix_view_ = glGetUniformLocation( program, \"uMVMatrix\" );\n\n    params->light0_ = glGetUniformLocation( program, \"vLight0\" );\n    params->material_diffuse_ = glGetUniformLocation( program, \"vMaterialDiffuse\" );\n    params->material_ambient_ = glGetUniformLocation( program, \"vMaterialAmbient\" );\n    params->material_specular_ = glGetUniformLocation( program, \"vMaterialSpecular\" );\n\n    // Release vertex and fragment shaders\n    if( vert_shader )\n        glDeleteShader( vert_shader );\n    if( frag_shader )\n        glDeleteShader( frag_shader );\n\n    params->program_ = program;\n    return true;\n}\n\nbool TeapotRenderer::Bind( ndk_helper::TapCamera* camera )\n{\n    camera_ = camera;\n    return true;\n}\n\n"
  },
  {
    "path": "tests/inputs/demo.odin",
    "content": "// portion of https://github.com/odin-lang/Odin/raw/master/examples/demo/demo.odin\npackage main\n\nimport \"core:fmt\"\nimport \"core:mem\"\nimport \"core:os\"\n\n\n/*\n\tThe Odin programming language is fast, concise, readable, pragmatic and open sourced.\n\tIt is designed with the intent of replacing C with the following goals:\n\t * simplicity\n\t * high performance\n\t * built for modern systems\n\t * joy of programming\n\n*/\n\nthe_basics :: proc() {\n\tfmt.println(\"\\n# the basics\");\n\n\t{ // The Basics\n\t\tfmt.println(\"Hellope\");\n\n\t\t// Lexical elements and literals\n\t\t// A comment\n\n\t\tmy_integer_variable: int; // A comment for documentaton\n\n\t\t// Multi-line comments begin with /* and end with */. Multi-line comments can\n\t\t// also be nested (unlike in C):\n\t\t/*\n\t\t\tYou can have any text or code here and\n\t\t\thave it be commented.\n\t\t*/\n\n\t\t// Note: `:=` is two tokens, `:` and `=`. The following are equivalent,\n\t\t/*\n\t\t\ti: int = 123;\n\t\t\ti:     = 123;\n\t\t\ti := 123;\n\t\t*/\n\n\t\t_ = my_integer_variable;\n\t\t_ = x;\n\t}\n}\n\ncontrol_flow :: proc() {\n\tfmt.println(\"\\n# control flow\");\n\t{ // Control flow\n\t\t// For loop\n\t\t// Odin has only one loop statement, the `for` loop\n\n\t\t// Basic for loop\n\t\tfor i := 0; i < 10; i += 1 {\n\t\t\tfmt.println(i);\n\t\t}\n\n\t\t// NOTE: Unlike other languages like C, there are no parentheses `( )` surrounding the three components.\n\t\t// Braces `{ }` or a `do` are always required>\n\t\tfor i := 0; i < 10; i += 1 { }\n\t\tfor i := 0; i < 10; i += 1 do fmt.print();\n\n\t\t// The initial and post statements are optional\n\t\ti := 0;\n\t\tfor ; i < 10; {\n\t\t\ti += 1;\n\t\t}\n\n\t\t// You can defer an entire block too:\n\t\t{\n\t\t\tbar :: proc() {}\n\n\t\t\tdefer {\n\t\t\t\tfmt.println(\"1\");\n\t\t\t\tfmt.println(\"2\");\n\t\t\t}\n\n\t\t\tcond := false;\n\t\t\tdefer if cond {\n\t\t\t\tbar();\n\t\t\t}\n\t\t}\n\n\t\t// Defer statements are executed in the reverse order that they were declared:\n\t\t{\n\t\t\tdefer fmt.println(\"1\");\n\t\t\tdefer fmt.println(\"2\");\n\t\t\tdefer fmt.println(\"3\");\n\t\t}\n\t\t// Will print 3, 2, and then 1.\n\n\t\tif false {\n\t\t\tf, err := os.open(\"my_file.txt\");\n\t\t\tif err != 0 {\n\t\t\t\t// handle error\n\t\t\t}\n\t\t\tdefer os.close(f);\n\t\t\t// rest of code\n\t\t}\n\t}\n\n\t{ // When statement\n\t\t/*\n\t\t\tThe when statement is almost identical to the if statement but with some differences:\n\n\t\t\t* Each condition must be a constant expression as a when\n\t\t\t  statement is evaluated at compile time.\n\t\t\t* The statements within a branch do not create a new scope\n\t\t\t* The compiler checks the semantics and code only for statements\n\t\t\t  that belong to the first condition that is true\n\t\t\t* An initial statement is not allowed in a when statement\n\t\t\t* when statements are allowed at file scope\n\t\t*/\n\n\t\t// Example\n\t\twhen ODIN_ARCH == \"386\" {\n\t\t\tfmt.println(\"32 bit\");\n\t\t} else when ODIN_ARCH == \"amd64\" {\n\t\t\tfmt.println(\"64 bit\");\n\t\t} else {\n\t\t\tfmt.println(\"Unsupported architecture\");\n\t\t}\n\t\t// The when statement is very useful for writing platform specific code.\n\t\t// This is akin to the #if construct in C’s preprocessor however, in Odin,\n\t\t// it is type checked.\n\t}\n\n\t{ // Branch statements\n\t\tcond, cond1, cond2 := false, false, false;\n\t\tone_step :: proc() { fmt.println(\"one_step\"); }\n\t\tbeyond :: proc() { fmt.println(\"beyond\"); }\n\n\t\t// Break statement\n\t\tfor cond {\n\t\t\tswitch {\n\t\t\tcase:\n\t\t\t\tif cond {\n\t\t\t\t\tbreak; // break out of the `switch` statement\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbreak; // break out of the `for` statement\n\t\t}\n\n\t\tloop: for cond1 {\n\t\t\tfor cond2 {\n\t\t\t\tbreak loop; // leaves both loops\n\t\t\t}\n\t\t}\n\n\t\t// Continue statement\n\t\tfor cond {\n\t\t\tif cond2 {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfmt.println(\"Hellope\");\n\t\t}\n\n\t\t// Fallthrough statement\n\n\t\t// Odin’s switch is like one in C or C++, except that Odin only runs the selected\n\t\t// case. This means that a break statement is not needed at the end of each case.\n\t\t// Another important difference is that the case values need not be integers nor\n\t\t// constants.\n\n\t\t// fallthrough can be used to explicitly fall through into the next case block:\n\n\t\tswitch i := 0; i {\n\t\tcase 0:\n\t\t\tone_step();\n\t\t\tfallthrough;\n\t\tcase 1:\n\t\t\tbeyond();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "tests/inputs/dev.exs",
    "content": "/*\n https://github.com/qhwa/bonfire/blob/master/config/dev.exs\n*/\nuse Mix.Config\n\nconfig :bonfire, Bonfire.EventStore,\n  serializer: Commanded.Serialization.JsonSerializer,\n  username: \"postgres\",\n  password: \"postgres\",\n  database: \"bonfire_eventstore_dev\",\n  hostname: \"localhost\",\n  pool_size: 10\n\n# Configure your database\nconfig :bonfire, Bonfire.Repo,\n  username: \"postgres\",\n  password: \"postgres\",\n  database: \"bonfire_dev\",\n  hostname: \"localhost\",\n  pool_size: 10\n\n# For development, we disable any cache and enable\n# debugging and code reloading.\n#\n# The watchers configuration can be used to run external\n# watchers to your application. For example, we use it\n# with webpack to recompile .js and .css sources.\nconfig :bonfire, BonfireWeb.Endpoint,\n  http: [port: 4000],\n  debug_errors: true,\n  code_reloader: true,\n  check_origin: false,\n  watchers: [\n    node: [\n      \"node_modules/webpack/bin/webpack.js\",\n      \"--mode\",\n      \"development\",\n      \"--watch-stdin\",\n      cd: Path.expand(\"../assets\", __DIR__)\n    ]\n  ]\n\n# ## SSL Support\n#\n# In order to use HTTPS in development, a self-signed\n# certificate can be generated by running the following\n# Mix task:\n#\n#     mix phx.gen.cert\n#\n# Note that this task requires Erlang/OTP 20 or later.\n# Run `mix help phx.gen.cert` for more information.\n#\n# The `http:` config above can be replaced with:\n#\n#     https: [\n#       port: 4001,\n#       cipher_suite: :strong,\n#       keyfile: \"priv/cert/selfsigned_key.pem\",\n#       certfile: \"priv/cert/selfsigned.pem\"\n#     ],\n#\n# If desired, both `http:` and `https:` keys can be\n# configured to run both http and https servers on\n# different ports.\n\n# Watch static and templates for browser reloading.\nconfig :bonfire, BonfireWeb.Endpoint,\n  live_reload: [\n    patterns: [\n      ~r\"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$\",\n      ~r\"priv/gettext/.*(po)$\",\n      ~r\"lib/bonfire_web/(live|views)/.*(ex)$\",\n      ~r\"lib/bonfire_web/templates/.*(eex)$\"\n    ]\n  ]\n\n# Do not include metadata nor timestamps in development logs\nconfig :logger, :console, format: \"[$level] $message\\n\"\n\n# Set a higher stacktrace during development. Avoid configuring such\n# in production as building large stacktraces may be expensive.\nconfig :phoenix, :stacktrace_depth, 20\n\n# Initialize plugs at runtime for faster development compilation\nconfig :phoenix, :plug_init_mode, :runtime\n"
  },
  {
    "path": "tests/inputs/diff/A/d1/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\n  print '(\"line 2\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/diff/A/d2/hello.java",
    "content": "/* hello.java */\nimport java.io.*;\nclass Hi {\n  static public void main( String args[] ) {\n    System.out.println( \"another line\" );\n    System.out.println( \"Hello World!\" );  /*\n                                              insert comment here\n                                            */\n  }\n  /* inline */\n}\n"
  },
  {
    "path": "tests/inputs/diff/A/d2/hi.py",
    "content": "#/usr/bin/env python\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\nprint(f'f-string')\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''\n"
  },
  {
    "path": "tests/inputs/diff/A/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/diff/B/d1/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\nc old style comment\n"
  },
  {
    "path": "tests/inputs/diff/B/d2/hi.py",
    "content": "#/usr/bin/env python\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\nprint(f'f-string')\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''\n"
  },
  {
    "path": "tests/inputs/diff/B/extra_file.pl",
    "content": "#!/usr/bin/perl\nprint \"extra\\n\";\n"
  },
  {
    "path": "tests/inputs/diff/B/hello.C",
    "content": "// hello.C -- stuff\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/dlist.lean",
    "content": "-- https://github.com/leanprover/lean/raw/master/library/data/dlist.lean\n/-\nCopyright (c) 2017 Microsoft Corporation. All rights reserved.\nReleased under Apache 2.0 license as described in the file LICENSE.\nAuthor: Leonardo de Moura\n-/\nuniverses u\n/--\nA difference list is a function that, given a list, returns the original\ncontents of the difference list prepended to the given list.\n\nThis structure supports `O(1)` `append` and `concat` operations on lists, making it\nuseful for append-heavy uses such as logging and pretty printing.\n-/\nstructure dlist (α : Type u) :=\n(apply     : list α → list α)\n(invariant : ∀ l, apply l = apply [] ++ l)\n\nnamespace dlist\nopen function\nvariables {α : Type u}\n\nlocal notation `♯`:max := by abstract {intros, rsimp}\n\n/-- Convert a list to a dlist -/\ndef of_list (l : list α) : dlist α :=\n⟨append l, ♯⟩\n\n/-- Convert a lazily-evaluated list to a dlist -/\ndef lazy_of_list (l : thunk (list α)) : dlist α :=\n⟨λ xs, l () ++ xs, ♯⟩\n\n/-- Convert a dlist to a list -/\ndef to_list : dlist α → list α\n| ⟨xs, _⟩ := xs []\n\n/--  Create a dlist containing no elements -/\ndef empty : dlist α :=\n⟨id, ♯⟩\n\nlocal notation a `::_`:max := list.cons a\n\n/-- Create dlist with a single element -/\ndef singleton (x : α) : dlist α :=\n⟨x::_, ♯⟩\n\nlocal attribute [simp] function.comp\n\n/-- `O(1)` Prepend a single element to a dlist -/\ndef cons (x : α) : dlist α →  dlist α\n| ⟨xs, h⟩ := ⟨x::_ ∘ xs, ♯⟩\n\n/-- `O(1)` Append a single element to a dlist -/\ndef concat (x : α) : dlist α → dlist α\n| ⟨xs, h⟩ := ⟨xs ∘ x::_, ♯⟩\n\n/-- `O(1)` Append dlists -/\nprotected def append : dlist α → dlist α → dlist α\n| ⟨xs, h₁⟩ ⟨ys, h₂⟩ := ⟨xs ∘ ys, ♯⟩\n\ninstance : has_append (dlist α) :=\n⟨dlist.append⟩\n\nlocal attribute [simp] of_list to_list empty singleton cons concat dlist.append\n\nlemma to_list_of_list (l : list α) : to_list (of_list l) = l :=\nby cases l; simp\n\nlemma of_list_to_list (l : dlist α) : of_list (to_list l) = l :=\nbegin\n   cases l with xs,\n   have h : append (xs []) = xs,\n   { intros, funext x, simp [l_invariant x] },\n   simp [h]\nend\n\nlemma to_list_empty : to_list (@empty α) = [] :=\nby simp\n\nlemma to_list_singleton (x : α) : to_list (singleton x) = [x] :=\nby simp\n\nlemma to_list_append (l₁ l₂ : dlist α) : to_list (l₁ ++ l₂) = to_list l₁ ++ to_list l₂ :=\nshow to_list (dlist.append l₁ l₂) = to_list l₁ ++ to_list l₂, from\nby cases l₁; cases l₂; simp; rsimp\n\nlemma to_list_cons (x : α) (l : dlist α) : to_list (cons x l) = x :: to_list l :=\nby cases l; rsimp\n\nlemma to_list_concat (x : α) (l : dlist α) : to_list (concat x l) = to_list l ++ [x] :=\nby cases l; simp; rsimp\n\nsection transfer\n\nprotected def rel_dlist_list (d : dlist α) (l : list α) : Prop :=\nto_list d = l\n\ninstance bi_total_rel_dlist_list : @relator.bi_total (dlist α) (list α) dlist.rel_dlist_list :=\n⟨assume d, ⟨to_list d, rfl⟩, assume l, ⟨of_list l, to_list_of_list l⟩⟩\n\nprotected lemma rel_eq :\n  (dlist.rel_dlist_list ⇒ dlist.rel_dlist_list ⇒ iff) (@eq (dlist α)) eq\n| l₁ ._ rfl l₂ ._ rfl := ⟨congr_arg to_list,\n  assume : to_list l₁ = to_list l₂,\n  have of_list (to_list l₁) = of_list (to_list l₂), from congr_arg of_list this,\n  by simp [of_list_to_list] at this; assumption⟩\n\nprotected lemma rel_empty : dlist.rel_dlist_list (@empty α) [] :=\nto_list_empty\n\nprotected lemma rel_singleton : (@eq α ⇒ dlist.rel_dlist_list) (λx, singleton x) (λx, [x])\n| ._ x rfl := to_list_singleton x\n\nprotected lemma rel_append :\n  (dlist.rel_dlist_list ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) (λ(x y : dlist α), x ++ y) (λx y, x ++ y)\n| l₁ ._ rfl l₂ ._ rfl := to_list_append l₁ l₂\n\nprotected lemma rel_cons :\n  (@eq α ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) cons (λx y, x :: y)\n| x ._ rfl l ._ rfl := to_list_cons x l\n\nprotected lemma rel_concat :\n  (@eq α ⇒ dlist.rel_dlist_list ⇒ dlist.rel_dlist_list) concat (λx y, y ++ [x])\n| x ._ rfl l ._ rfl := to_list_concat x l\n\nprotected meta def transfer : tactic unit := do\n  _root_.transfer.transfer [`relator.rel_forall_of_total, `dlist.rel_eq, `dlist.rel_empty,\n    `dlist.rel_singleton, `dlist.rel_append, `dlist.rel_cons, `dlist.rel_concat]\n\nexample : ∀(a b c : dlist α), a ++ (b ++ c) = (a ++ b) ++ c :=\nbegin\n  dlist.transfer,\n  intros,\n  simp\nend\n\nexample : ∀(a : α), singleton a ++ empty = singleton a :=\nbegin\n  dlist.transfer,\n  intros,\n  simp\nend\n\nend transfer\n\nend dlist\n"
  },
  {
    "path": "tests/inputs/door.tres",
    "content": "; https://github.com/godotengine/tps-demo/raw/master/door/model/door.tres\n[gd_resource type=\"SpatialMaterial\" load_steps=5 format=2]\n\n[ext_resource path=\"res://door/textures/door_orm.png\" type=\"Texture\" id=1]\n[ext_resource path=\"res://door/textures/door_emission.png\" type=\"Texture\" id=2]\n[ext_resource path=\"res://door/textures/door_normal.png\" type=\"Texture\" id=3]\n[ext_resource path=\"res://door/textures/door_albedo.png\" type=\"Texture\" id=4]\n\n[resource]\nresource_name = \"door\"\nalbedo_texture = ExtResource( 4 )\n ; metallic = 1.0\n ; metallic_texture = ExtResource( 1 )\n ; metallic_texture_channel = 2\n ; roughness_texture = ExtResource( 1 )\n ; roughness_texture_channel = 1\n ; emission_enabled = true\n ; emission = Color( 0, 0, 0, 1 )\nemission_energy = 3.0\nemission_operator = 0\nemission_on_uv2 = false\nemission_texture = ExtResource( 2 )\nnormal_enabled = true\nnormal_scale = 1.0\nnormal_texture = ExtResource( 3 )\nao_enabled = true\nao_light_affect = 0.0\nao_texture = ExtResource( 1 )\nao_on_uv2 = false\nao_texture_channel = 0\n"
  },
  {
    "path": "tests/inputs/dotNET_intermediate.il",
    "content": "// This is .NET Intermediate Language\n// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\n.assembly extern System.Console\n{\n  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )\n  .ver 4:0:0:0\n}\n.assembly extern mscorlib { }\n.assembly 'devdiv_815942_' {}\n.assembly extern xunit.core {}\n\n.class public Repro\n{\n    .method public static int32 Main() cil managed\n    {\n        .custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = (\n            01 00 00 00\n        )\n        // This testcase ensures that we correctly compare a double local\n        // against a float const by converting the float const to double\n        // instead of converting the local to float and losing precision\n  \n        .entrypoint\n        .locals init (float64 V_1)\n        ldc.i4.1\n        conv.i8\n        call       float64 [mscorlib]System.BitConverter::Int64BitsToDouble(int64)\n        conv.r8\n        stloc.0\n        ldloc.0\n        ldc.r4     0.0\n        bne.un.s   PASS\n        ldstr      \"FAIL!\"\n        call       void [System.Console]System.Console::WriteLine(string)\n        ldloc.0\n        call       void [System.Console]System.Console::WriteLine(float64)\n        ldc.i4.s   101\n        ret\nPASS:\n        ldstr      \"PASS!\"\n        call       void [System.Console]System.Console::WriteLine(string)\n        ldc.i4.s   100\n        ret\n    }\n}\n"
  },
  {
    "path": "tests/inputs/double_doors.dsc",
    "content": "doubledoors_world:\r\n    type: world\r\n    debug: false\r\n    events:\r\n        # Use monitor to allow the event to be cancelled by any other scripts or plugins\r\n        # But use 'on' to make the door move as immediately as possible\r\n        on player right clicks *_door bukkit_priority:monitor:\r\n        # Iron doors aren't opened on click\r\n        - if <context.location.material.name> == iron_door:\r\n            - stop\r\n        - define face <context.location.block_facing>\r\n        # A door faces outward, rotate the outward face opposite the direction of the hinge to get the other door\r\n        - if <context.location.material.hinge> == left:\r\n            # Note: pi/2 is radian equivalent of 90 degrees.\r\n            - define face <[face].rotate_around_y[-<util.pi.div[2]>]>\r\n        - else:\r\n            - define face <[face].rotate_around_y[<util.pi.div[2]>]>\r\n        - define door2 <context.location.add[<[face]>]>\r\n        # Check that the double door *exists*\r\n        - if <[door2].material.name> == <context.location.material.name>:\r\n            - switch <[door2]>"
  },
  {
    "path": "tests/inputs/drools.drl",
    "content": "// https://github.com/AlDanial/cloc/issues/172\n\n/*\n * Copyright 2010 Red Hat, Inc. and/or its affiliates.\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\npackage org.drools.examples.fibonacci\n\nimport org.drools.examples.fibonacci.FibonacciExample.Fibonacci;\n\ndialect \"mvel\"\n\nrule Recurse\n    salience 10\n    when\n        f : Fibonacci ( value == -1 )\n        not ( Fibonacci ( sequence == 1 ) )    \n    then\n        insert( new Fibonacci( f.sequence - 1 ) );\n        System.out.println( \"recurse for \" + f.sequence );\nend\n\nrule Bootstrap\n    when\n        f : Fibonacci( sequence == 1 || == 2, value == -1 ) // this is a multi-restriction || on a single field\n    then \n        modify ( f ){ value = 1 };\n        System.out.println( f.sequence + \" == \" + f.value );\nend\n\nrule Calculate\n    when\n        f1 : Fibonacci( s1 : sequence, value != -1 ) // here we bind sequence\n        f2 : Fibonacci( sequence == (s1 + 1 ), value != -1 ) // here we don't, just to demonstrate the different way bindings can be used\n        f3 : Fibonacci( s3 : sequence == (f2.sequence + 1 ), value == -1 )              \n    then    \n        modify ( f3 ) { value = f1.value + f2.value };\n        System.out.println( s3 + \" == \" + f3.value ); // see how you can access pattern and field  bindings\nend\n"
  },
  {
    "path": "tests/inputs/drupal.mxml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<mx:Application xmlns:mx=\"http://www.adobe.com/2006/mxml\" layout=\"absolute\" creationComplete=\"init()\">\n  <mx:Script>\n    import mx.controls.*;\n    import mx.rpc.events.*;\n    import mx.utils.ArrayUtil;\n\n    [Bindable]\n    public var recipes:Array;\n\n    public function init():void\n    {\n      getRecipes();\n    }\n    /*\n    this is a C Comment\n     */\n\n    public function onFault(event:FaultEvent):void\n    {\n      Alert.show(event.fault.faultString, \"Error\");\n    }\n\n    public function onViewsResult(event:ResultEvent):void\n    {\n      recipes = ArrayUtil.toArray(event.result);\n    }\n\n    public function getRecipes():void\n    {\n      views.getView(\"recipes_all\", ['nid','title','body','changed']);\n    }\n\n    public function saveRecipe():void\n    {\n      var edit:Object;\n      if (recipes_select.selectedItem) {\n        edit = recipes_select.selectedItem;\n      }\n      else {\n        edit = new Object;\n      }\n\n      edit.type = \"recipe\";\n\n      edit.title = dish.text;\n      edit.body = recipe.text;\n\n      if (edit.title == \"\" || edit.body == \"\") {\n        Alert.show(\"Enter some content\", \"Error\");\n      }\n\n      node.save(edit);\n      getRecipes();\n    }\n\n    public function onSaved(event:ResultEvent):void\n    {\n      Alert.show(\"Recipe was saved\", \"Saved\");\n    }\n\n    public function newRecipe():void\n    {\n      recipes_select.selectedItem = undefined;\n\n      dish.text = \"\";\n      recipe.text = \"\";\n    }\n  </mx:Script>\n\n  <mx:RemoteObject showBusyCursor=\"true\" destination=\"amfphp\" source=\"views\" id=\"views\">\n    <mx:method name=\"getView\" result=\"onViewsResult(event)\" fault=\"onFault(event)\" />\n  </mx:RemoteObject>\n\n  <mx:RemoteObject showBusyCursor=\"true\" destination=\"amfphp\" source=\"node\" id=\"node\">\n    <mx:method name=\"save\" result=\"onSaved(event)\" fault=\"onFault(event)\" />\n  </mx:RemoteObject>\n\n  <mx:Panel width=\"500\" height=\"400\" layout=\"absolute\" title=\"Recipes\" horizontalCenter=\"0\" verticalCenter=\"0\">\n    <mx:DataGrid x=\"10\" y=\"10\" width=\"460\" id=\"recipes_select\" dataProvider=\"{recipes}\" >\n      <mx:columns>\n        <mx:DataGridColumn headerText=\"NID\" dataField=\"nid\" width=\"40\"/>\n        <mx:DataGridColumn headerText=\"Dish\" dataField=\"title\"/>\n      </mx:columns>\n    </mx:DataGrid>\n\n    <mx:Label x=\"10\" y=\"160\" text=\"Dish\"/>\n\n    <mx:TextInput x=\"10\" y=\"186\" width=\"460\" id=\"dish\" text=\"{recipes_select.selectedItem.title}\"/>\n    <!-- an\n    html comment -->\n\n    <mx:Label x=\"10\" y=\"216\" text=\"Recipe\"/>\n\n    <mx:TextArea x=\"10\" y=\"242\" width=\"460\" height=\"75\" id=\"recipe\" text=\"{recipes_select.selectedItem.body}\"/>\n\n    <mx:Button x=\"416\" y=\"328\" label=\"Save\" click=\"saveRecipe()\"/>\n\n    <mx:Button x=\"420\" y=\"158\" label=\"New\" click=\"newRecipe()\"/>\n\n  </mx:Panel>\n</mx:Application>\n"
  },
  {
    "path": "tests/inputs/eddsa.circom",
    "content": "// https://raw.githubusercontent.com/iden3/circomlib/master/circuits/eddsa.circom\n/*\n    Copyright 2018 0KIMS association.\n\n    This file is part of circom (Zero Knowledge Circuit Compiler).\n\n    circom is a free software: you can redistribute it and/or modify it\n    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    circom is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n    License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with circom. If not, see <https://www.gnu.org/licenses/>.\n*/\npragma circom 2.0.0;\n\ninclude \"compconstant.circom\";\ninclude \"pointbits.circom\";\ninclude \"pedersen.circom\";\ninclude \"escalarmulany.circom\";\ninclude \"escalarmulfix.circom\";\n\ntemplate EdDSAVerifier(n) {\n    signal input msg[n];\n\n    signal input A[256];\n    signal input R8[256];\n    signal input S[256];\n\n    signal Ax;\n    signal Ay;\n\n    signal R8x;\n    signal R8y;\n\n    var i;\n\n// Ensure S<Subgroup Order\n\n    component  compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);\n\n    for (i=0; i<254; i++) {\n        S[i] ==> compConstant.in[i];\n    }\n    compConstant.out === 0;\n    S[254] === 0;\n    S[255] === 0;\n\n// Convert A to Field elements (And verify A)\n\n    component bits2pointA = Bits2Point_Strict();\n\n    for (i=0; i<256; i++) {\n        bits2pointA.in[i] <== A[i];\n    }\n    Ax <== bits2pointA.out[0];\n    Ay <== bits2pointA.out[1];\n\n// Convert R8 to Field elements (And verify R8)\n\n    component bits2pointR8 = Bits2Point_Strict();\n\n    for (i=0; i<256; i++) {\n        bits2pointR8.in[i] <== R8[i];\n    }\n    R8x <== bits2pointR8.out[0];\n    R8y <== bits2pointR8.out[1];\n\n// Calculate the h = H(R,A, msg)\n\n    component hash = Pedersen(512+n);\n\n    for (i=0; i<256; i++) {\n        hash.in[i] <== R8[i];\n        hash.in[256+i] <== A[i];\n    }\n    for (i=0; i<n; i++) {\n        hash.in[512+i] <== msg[i];\n    }\n\n    component point2bitsH = Point2Bits_Strict();\n    point2bitsH.in[0] <== hash.out[0];\n    point2bitsH.in[1] <== hash.out[1];\n\n// Calculate second part of the right side:  right2 = h*8*A\n\n    // Multiply by 8 by adding it 3 times.  This also ensure that the result is in\n    // the subgroup.\n    component dbl1 = BabyDbl();\n    dbl1.x <== Ax;\n    dbl1.y <== Ay;\n    component dbl2 = BabyDbl();\n    dbl2.x <== dbl1.xout;\n    dbl2.y <== dbl1.yout;\n    component dbl3 = BabyDbl();\n    dbl3.x <== dbl2.xout;\n    dbl3.y <== dbl2.yout;\n\n    // We check that A is not zero.\n    component isZero = IsZero();\n    isZero.in <== dbl3.x;\n    isZero.out === 0;\n\n    component mulAny = EscalarMulAny(256);\n    for (i=0; i<256; i++) {\n        mulAny.e[i] <== point2bitsH.out[i];\n    }\n    mulAny.p[0] <== dbl3.xout;\n    mulAny.p[1] <== dbl3.yout;\n\n\n// Compute the right side: right =  R8 + right2\n\n    component addRight = BabyAdd();\n    addRight.x1 <== R8x;\n    addRight.y1 <== R8y;\n    addRight.x2 <== mulAny.out[0];\n    addRight.y2 <== mulAny.out[1];\n\n// Calculate left side of equation left = S*B8\n\n    var BASE8[2] = [\n        5299619240641551281634865583518297030282874472190772894086521144482721001553,\n        16950150798460657717958625567821834550301663161624707787222815936182638968203\n    ];\n    component mulFix = EscalarMulFix(256, BASE8);\n    for (i=0; i<256; i++) {\n        mulFix.e[i] <== S[i];\n    }\n\n// Do the comparation left == right\n\n    mulFix.out[0] === addRight.xout;\n    mulFix.out[1] === addRight.yout;\n}\n"
  },
  {
    "path": "tests/inputs/elixir.ex",
    "content": "# This is a test for the Elixir SLOC counter.\n\ndefmodule Test do\n  @moduledoc \"\"\"\n  Test module\n  \"\"\"\n  @notdoc :foo\n\n  @doc ~S\"\"\"\n  Foo\n  \"\"\"\n  def foo do\n    @notdoc\n  end\n\n  @doc ~c'''\n  Bar\n  '''\n  def bar, do: :bar\nend\n"
  },
  {
    "path": "tests/inputs/en_AU.po",
    "content": "# portions of\n# https://raw.githubusercontent.com/xfce-mirror/xfce4-terminal/master/po/en_AU.po\n# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n#\n# Translators:\n# Michael Findlay <translate@cobber-linux.org>, 2013-2014\n# Michael Findlay <translate@cobber-linux.org>, 2016\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Xfce Apps\\n\"\n\"Report-Msgid-Bugs-To: \\n\"\n\"POT-Creation-Date: 2016-06-19 06:31+0200\\n\"\n\"PO-Revision-Date: 2016-06-21 08:54+0000\\n\"\n\"Last-Translator: Michael Findlay <translate@cobber-linux.org>\\n\"\n\"Language-Team: English (Australia) (http://www.transifex.com/xfce/xfce-apps/language/en_AU/)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Language: en_AU\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1);\\n\"\n\n#: ../colorschemes/black-on-white.theme.in.h:1\nmsgid \"Black on White\"\nmsgstr \"Black on White\"\n\n#: ../colorschemes/dark-pastels.theme.in.h:1\nmsgid \"Dark Pastels\"\nmsgstr \"Dark Pastels\"\n\n#: ../colorschemes/green-on-black.theme.in.h:1\nmsgid \"Green on Black\"\nmsgstr \"Green on Black\"\n\n#: ../terminal/main.c:147\n#, c-format\nmsgid \"See the %s man page for full explanation of the options above.\"\nmsgstr \"See the %s man page for full explanation of the options above.\"\n\n#: ../terminal/main.c:180 ../xfce4-terminal.desktop.in.h:1\nmsgid \"Xfce Terminal\"\nmsgstr \"Xfce Terminal\"\n\n#: ../terminal/main.c:196\nmsgid \"The Xfce development team. All rights reserved.\"\nmsgstr \"The Xfce development team. All rights reserved.\"\n\n#: ../terminal/main.c:197\nmsgid \"Written by Benedikt Meurer <benny@xfce.org>\"\nmsgstr \"Written by Benedikt Meurer <benny@xfce.org>\"\n\n#: ../terminal/main.c:198\nmsgid \"and Nick Schermer <nick@xfce.org>.\"\nmsgstr \"and Nick Schermer <nick@xfce.org>.\"\n\n#: ../terminal/main.c:199\n#, c-format\nmsgid \"Please report bugs to <%s>.\"\nmsgstr \"Please report bugs to <%s>.\"\n"
  },
  {
    "path": "tests/inputs/example_2d.gdshader",
    "content": "// https://github.com/AlDanial/cloc/issues/641\nshader_type canvas_item;\n\nuniform float blue = 1.0; // you can assign a default value to uniforms\n\nvoid vertex() {\n  // Animate Sprite moving in big circle around its location\n  VERTEX += vec2(cos(TIME)*100.0, sin(TIME)*100.0);\n}\n\nvoid fragment(){\n    // this shader will result in an more bluish sprite\n    COLOR = texture(TEXTURE, UV); //read from texture\n    COLOR.b = blue; //set blue channel to <blue>\n}\n"
  },
  {
    "path": "tests/inputs/fib.dfy",
    "content": "/*\nhttps://dafny.org/latest/OnlineTutorial/guide\n*/\nfunction fib(n: nat): nat\n{\n  if n == 0 then 0\n  else if n == 1 then 1\n  else fib(n - 1) + fib(n - 2)\n}\nmethod ComputeFib(n: nat) returns (b: nat)\n  ensures b == fib(n)  // Do not change this postcondition\n{\n  // Change the method body to instead use c as described.\n  // You will need to change both the initialization and the loop.\n  if n == 0 { return 0; }\n  var i: int := 1;\n  var a := 0;\n  b := 1;\n  while i < n\n    invariant 0 < i <= n\n    invariant a == fib(i - 1)\n    invariant b == fib(i)\n  {\n    a, b := b, a + b;\n    i := i + 1;\n  }\n}\n"
  },
  {
    "path": "tests/inputs/fib_class.pkl",
    "content": "/* \n\nhttps://raw.githubusercontent.com/apple/pkl/refs/heads/main/bench/src/jmh/resources/org/pkl/core/fib_class.pkl\n*/ \n\n//===----------------------------------------------------------------------===//\n// Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.\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//     https://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\nclass Fibonacci {\n  function fib(n) = if (n < 2) n else fib(n - 1) + fib(n - 2)\n}\nresult = new Fibonacci {}.fib(35)\n"
  },
  {
    "path": "tests/inputs/fibonacci.ncl",
    "content": "# https://raw.githubusercontent.com/tweag/nickel/master/examples/fibonacci/fibonacci.ncl\n# test = 'pass'\n\n# This is the naive, exponential version of fibonacci: don't call it on a big\n# value!\nlet rec fibonacci = fun n =>\n  if n == 0 then\n    0\n  else if n == 1 then\n    1\n  else\n    fibonacci (n - 1) + fibonacci (n - 2)\nin\nfibonacci 10\n"
  },
  {
    "path": "tests/inputs/find.plm",
    "content": "/*\n https://en.wikipedia.org/wiki/PL/M\n*/\n FIND: PROCEDURE(PA,PB) BYTE;\n    DECLARE (PA,PB) BYTE;\n    /* FIND THE STRING IN SCRATCH STARTING AT PA AND ENDING AT PB */\n    DECLARE J ADDRESS,\n        (K, MATCH) BYTE;\n    J = BACK ;\n    MATCH = FALSE;\n        DO WHILE NOT MATCH AND (MAXM > J);\n        LAST,J = J + 1; /* START SCAN AT J */\n        K = PA ; /* ATTEMPT STRING MATCH AT K */\n            DO WHILE SCRATCH(K) = MEMORY(LAST) AND\n                NOT (MATCH := K = PB);\n            /* MATCHED ONE MORE CHARACTER */\n            K = K + 1; LAST = LAST + 1;\n            END;\n        END;\n    IF MATCH THEN /* MOVE STORAGE */\n        DO; LAST = LAST - 1; CALL MOVER;\n        END;\n    RETURN MATCH;\n    END FIND;\n\n"
  },
  {
    "path": "tests/inputs/flatbuffers.fbs",
    "content": "\n/* Comment 1 */\ntable TestTable {\n\t// Comment 2\n  Item: int32;\n}"
  },
  {
    "path": "tests/inputs/fmt.ha",
    "content": "// License: MPL-2.0\n// (c) 2022 Alexey Yerin <yyp@disroot.org>\n// (c) 2021 Andri Yngvason <andri@yngvason.is>\n// (c) 2021-2022 Bor Grošelj Simić <bor.groseljsimic@telemach.net>\n// (c) 2021 Byron Torres <b@torresjrjr.com>\n// (c) 2021 Drew DeVault <sir@cmpwn.com>\n// (c) 2021 Ember Sawady <ecs@d2evs.net>\nuse ascii;\nuse bufio;\nuse encoding::utf8;\nuse io;\n// https://git.sr.ht/~sircmpwn/hare/tree/master/item/fmt/fmt.ha\nuse math;\nuse os;\nuse strconv;\nuse strings;\nuse types;\n\n// Tagged union of the [[formattable]] types and [[modifiers]]. Used for\n// functions which accept format strings.\nexport type field = (...formattable | *modifiers);\n\n// Tagged union of all types which are formattable.\nexport type formattable = (...types::numeric | uintptr | str | rune | bool |\n\tnullable *void | void);\n\n// Formats text for printing and writes it to [[os::stdout]].\nexport fn printf(fmt: str, args: field...) (io::error | size) =\n\tfprintf(os::stdout, fmt, args...);\n\n// Formats text for printing and writes it to [[os::stdout]], followed by a line\n// feed.\nexport fn printfln(fmt: str, args: field...) (io::error | size) =\n\tfprintfln(os::stdout, fmt, args...);\n"
  },
  {
    "path": "tests/inputs/foo_bar/bar/foo/momo/tbfm.sh",
    "content": "echo hello\n"
  },
  {
    "path": "tests/inputs/foo_bar/foo/bar/lala/tfbl.sh",
    "content": "echo hi\n"
  },
  {
    "path": "tests/inputs/fortran.inc",
    "content": "C https://en.wikibooks.org/wiki/Fortran/Fortran_examples\n! sum.f90\n! Performs summations using in a loop using EXIT statement\n! Saves input information and the summation in a data file\n\nprogram summation\n    implicit none\n    integer :: sum, a\n\n    print *, \"This program performs summations. Enter 0 to stop.\"\n    open (unit=10, file=\"SumData.DAT\")\n    sum = 0\n    do\n        print *, \"Add:\"\n        read *, a\n        if (a == 0) then\n            exit\n        else\n            sum = sum + a\n        end if\n        write (10,*) a\n    end do\n\n    print *, \"Summation =\", sum\n    write (10,*) \"Summation =\", sum\n    close(10)\nend\n\n"
  },
  {
    "path": "tests/inputs/fractal.um",
    "content": "/*\n https://github.com/vtereshkov/umka-lang/raw/master/examples/fractal/fractal.um\n*/\n// Fractal demo in Umka (adapted from a Wren version by Robert Nystrom)\n\nfn main() {\n    const (\n        yMin = -0.2\n        yMax =  0.1\n        xMin = -1.5\n        xMax = -1.1\n    )\n\n    for yPixel := 0; yPixel < 40; yPixel++ {\n      y0 := (yPixel / 40.0) * (yMax - yMin) + yMin\n      \n      for xPixel := 0; xPixel < 79; xPixel++ {\n        x0 := (xPixel / 78.0) * (xMax - xMin) + xMin\n        x, y := x0, y0\n        pixel := ' '       \n        \n        for iter := 0; iter < 80; iter++ {\n          x, y = x * x - y * y + x0, 2 * x * y + y0\n\n          // Stop if the point escaped\n          if x * x + y * y > 4 {\n            const pixels = \" .:;+=xX$&\"\n            pixel = pixels[iter / 8]\n            break\n          }\n        }\n\n        printf(\"%c\", pixel)\n      }\n\n      printf(\"\\n\")\n    }\n}\n"
  },
  {
    "path": "tests/inputs/fsharp.fs",
    "content": "(* http://en.wikipedia.org/wiki/F_Sharp_%28programming_language%29 \n *)\n/// A very naive prime number detector\nlet isPrime (n:int) =\n   let bound = int (sqrt (float n))\n   seq {2 .. bound} |> Seq.forall (fun x -> n % x <> 0)\n \n// We are using async workflows\nlet primeAsync n =\n    async { return (n, isPrime n) }\n \n/// Return primes between m and n using multiple threads\nlet primes m n =\n    seq {m .. n}\n        |> Seq.map primeAsync\n        |> Async.Parallel\n        |> Async.RunSynchronously\n        |> Array.filter snd\n        |> Array.map fst\n \n// Run a test\nprimes 1000000 1002000\n    |> Array.iter (printfn \"%d\")\n"
  },
  {
    "path": "tests/inputs/fsharp_script.fsx",
    "content": "// https://blogs.msdn.microsoft.com/chrsmith/2008/09/12/scripting-in-f/\n// Launches all .fs and .fsi files under the current folder in Notepad\nopen System\n\nallFilesUnder Environment.CurrentDirectory\n|> Seq.filter (function \n            | EndsWith \".fs\" _\n            | EndsWith \".fsi\" _\n                -> true\n            | _ -> false)\n|> Seq.iter (shellExecute \"Notepad.exe\")\n"
  },
  {
    "path": "tests/inputs/functional.cj",
    "content": "/*\nhttps://github.com/Zxilly/playground-cj/blob/master/src/examples/functional.cj\n*/\npackage playground\n\n// 用给定的分隔符拆分字符串，支持多分隔符\nimport std.collection.*\n\n// 常规实现\nfunc split_normal(text: String, sep: String): ArrayList<String> {\n    let indices = ArrayList<Int64>()\n    var last = true\n    for (i in 0..text.size) {\n        let current = sep.indexOf(text[i]).isSome()\n        if (last != current) {\n            indices.add(i)\n        }\n        last = current\n    }\n    if (!last) {\n        indices.add(text.size)\n    }\n\n    let result = ArrayList<String>()\n    for (i in 0..indices.size : 2) {\n        result.add(text[indices[i]..indices[i + 1]])\n    }\n    return result\n}\n\n// 函数式编程实现\nfunc split(text: String, sep: String): ArrayList<String> {\n    let indices = ArrayList<Int64>()\n    text |> enumerate |>\n        fold(false) {\n        state, e =>\n        let current = sep.indexOf(e[1]).isNone()\n        if (state != current) {\n            indices.add(e[0])\n        }\n        current\n    } |> {\n        valid: Bool => if (valid) {\n            indices.add(text.size)\n        }\n    }\n\n    let result = ArrayList<String>()\n    for (i in 0..indices.size : 2) {\n        result.add(text[indices[i]..indices[i + 1]])\n    }\n    return result\n}\n\nmain() {\n    let text = \"123, 456 7&89, , 96^3, 567\"\n    let separator = \"&^, \"\n    println(split_normal(text, separator))\n    println(split(text, separator))\n}\n"
  },
  {
    "path": "tests/inputs/futhark.fut",
    "content": "-- ISC License\n--\n-- Copyright (c) 2013-2018. DIKU, University of Copenhagen\n--\n-- Permission to use, copy, modify, and/or distribute this software for\n-- any purpose with or without fee is hereby granted, provided that the\n-- above copyright notice and this permission notice appear in all\n-- copies.\n--\n-- THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL\n-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED\n-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE\n-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\n-- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\n-- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER\n-- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\n-- PERFORMANCE OF THIS SOFTWARE.\n--\n-- | The default prelude that is implicitly available in all Futhark\n-- files.\n\nopen import \"soacs\"\nopen import \"array\"\nopen import \"math\"\nopen import \"functional\"\nopen import \"ad\"\n\n-- | Create single-precision float from integer.\ndef r32 (x: i32): f32 = f32.i32 x\n-- | Create integer from single-precision float.\ndef t32 (x: f32): i32 = i32.f32 x\n\n-- | Create double-precision float from integer.\ndef r64 (x: i32): f64 = f64.i32 x\n-- | Create integer from double-precision float.\ndef t64 (x: f64): i32 = i32.f64 x\n\n-- | Negate a boolean.  `not x` is the same as `!x`.  This function is\n-- mostly useful for passing to `map`.\ndef not (x: bool): bool = !x\n\n-- | Semantically just identity, but serves as an optimisation\n-- inhibitor.  The compiler will treat this function as a black box.\n-- You can use this to work around optimisation deficiencies (or\n-- bugs), although it should hopefully rarely be necessary.\n-- Deprecated: use `#[opaque]` attribute instead.\ndef opaque 't (x: t): t =\n  #[opaque] x\n\n-- | Semantically just identity, but at runtime, the argument value\n-- will be printed.  Deprecated: use `#[trace]` attribute instead.\ndef trace 't (x: t): t =\n  #[trace(trace)] x\n\n-- | Semantically just identity, but acts as a break point in\n-- `futhark repl`.  Deprecated: use `#[break]` attribute instead.\ndef break 't (x: t): t =\n  #[break] x\n"
  },
  {
    "path": "tests/inputs/generate.fnl",
    "content": "; https://github.com/bakpakin/Fennel/raw/master/generate.fnl\n\n;; A general-purpose function for generating random values.\n\n(var generate nil)\n\n(local random-char\n       (fn []\n         (if (> (math.random) 0.9)\n             (string.char (+ 48 (math.random 10)))\n             (> (math.random) 0.5)        ; an in-line comment\n             (string.char (+ 97 (math.random 26)))\n             (> (math.random) 0.5)\n             (string.char (+ 65 (math.random 26)))\n             (> (math.random) 0.5)\n             (string.char (+ 32 (math.random 11)))\n             (> (math.random) 0.5)\n             (string.char (+ 45 (math.random 2)))\n             :else\n             (string.char (+ 58 (math.random 5))))))\n\n(local generators {:number (fn [] ; weighted towards mid-range integers\n                             (if (> (math.random) 0.9)\n                                 (let [x (math.random 2147483647)]\n                                   (math.floor (- x (/ x 2))))\n                                 (> (math.random) 0.2)\n                                 (math.floor (math.random 2048))\n                                 :else (math.random)))\n                   :string (fn []\n                             (var s \"\")\n                             (for [_ 1 (math.random 16)]\n                               (set s (.. s (random-char))))\n                             s)\n                   :table (fn [table-chance]\n                            (let [t {}]\n                              (var k nil)\n                              (for [_ 1 (math.random 16)]\n                                ;; no nans plz\n                                (set k (generate 0.9))\n                                (while (~= k k) (set k (generate 0.9)))\n                                (tset t k (generate (* table-chance 1.5))))\n                              t))\n                   :boolean (fn [] (> (math.random) 0.5))})\n\n(set generate\n     (fn [table-chance]\n       (local table-chance (or table-chance 0.5))\n       (if (> (math.random) 0.5) (generators.number)\n           (> (math.random) 0.5) (generators.string)\n           (> (math.random) table-chance) (generators.table table-chance)\n           :else (generators.boolean))))\n\ngenerate\n"
  },
  {
    "path": "tests/inputs/git_helpers.fish",
    "content": "# https://raw.githubusercontent.com/Konstruktionist/fish/master/conf.d/git_helpers.fish\n# Building Gary Bernhardt's githelpers bash script in fish\n# ========================================================\n#\n# Log output:\n#\n# * 51c333e    (12 days)    <Gary Bernhardt>   add vim-eunuch\n#\n# Branch output:\n#\n# * release/v1.1    (13 days)    <Leyan Lo>   add pretty_git_branch\n#\n# The time massaging regexes start with ^[^<]* because that ensures that they\n# only operate before the first \"<\". That \"<\" will be the beginning of the\n# author name, ensuring that we don't destroy anything in the commit message\n# that looks like time.\n#\n# The log format uses ∬ characters between each field, and `column` is later\n# used to split on them. A ∬ in the commit subject or any other field will\n# break this. (GB used originally the } character, I think that may\n# occasionally show up in a commit message)\n# -----------------------------------------\n\nset -l ycolor (set_color bryellow)\nset -l ncolor (set_color normal)\nset -l gcolor (set_color brgreen)\nset -l bcolor (set_color blue)\nset -l rcolor (set_color brred)\n\nset -l log_hash \"$ycolor%h\"\nset -l log_relative_time \"$gcolor(%ar)\"\nset -l log_author \"$bcolor<%an>\"\nset -l log_refs \"$rcolor%d$ncolor\"\nset -l log_subject \"%s\"\n\n# Use a special character to separate our fields so strings with spaces in\n# them (like names & subjects) will not split on them.\n# Character used is ∬ = U+222C (DOUBLE INTEGRAL). I'm fairly sure nobody uses\n# that in commit messages.\n# DO NOT use it between log_refs and log_subject to prevent hideous whitespace\n# problems.\n\nset log_format \"$log_hash∬$log_relative_time∬$log_author∬$log_refs $log_subject\"\n\nset -l branch_prefix \"%(HEAD)\"\nset -l branch_ref \"$rcolor%(refname:short)\"\nset -l branch_hash \"$ycolor%(objectname:short)\"\nset -l branch_date \"$gcolor(%(committerdate:relative))\"\nset -l branch_author \"$bcolor<%(authorname)>$ncolor\"\nset -l branch_contents \"%(contents:subject)\"\n\nset branch_format \"$branch_prefix∬$branch_ref∬$branch_hash∬$branch_date∬$branch_author∬$branch_contents\"\n\n# Logs\nfunction gitl -d 'l = all commits, only current branch'\n  # 1st string replace: remove all ' ago' only in date column\n  # 2nd string replace: replace (2 years, 5 months) with (2 years)\n  # 3rd - 5th string replace: print Merge commit messages in cyan\n  # NOTE: to get the merge commit messages printed cyan we can not use the above\n  # declared variables rcolor & ncolor. If we do we get an error stating:\n  # 'Variables may not be used as commands' or 'string replace: Expected\n  # argument\"\n  git log --graph --pretty=\"tformat:$log_format\" $argv |\\\n    string replace -r '(^[^<]*)\\sago\\)' '$1)' |\\\n    string replace -r ',\\s\\d+?\\s\\w+\\s?' '' |\\\n    string replace -r 'Merge branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge pull request\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge remote-tracking branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    # TODO: Ideally these last 3 would be replaced by\n    #\n    #   string replace -r ([\\s]{3}Merge.*) (set_color cyan)'$1'(set_color normal)\n    #\n    # but somehow fish doesn't understand this and ignores it. There are no\n    # error messages, it just ignores the set_color commands & prints the\n    # commit message in normal color. It works in RegExR & online regex\n    # testers.\n    # Needs further investigation.\n    column -t -s '∬' |\\\n    less -FXRS\nend\n\nfunction gitla -d 'la = all commits, all reachable refs'\n  gitl --all\nend\n\nfunction gitr -d 'r = recent commits, only current branch'\n  gitl -30\nend\n\nfunction gitra -d 'ra = recent commits, all reachable refs'\n  gitr --all\nend\n\nfunction gith -d 'h = head'\n  gitl -1\nend\n\nfunction githp -d 'hp = head with patch'\n  gitl -1\n  git show -p --pretty=\"tformat:\"\nend\n\n# Branches\n#   This follows the same logic as in the Logs section\nfunction gitb -d 'b = all branches'\n  git branch -v --format=$branch_format $argv |\\\n    string replace -r '(^[^<]*)\\sago\\)' '$1)' |\\\n    string replace -r ',\\s\\d+?\\s\\w+\\s?' '' |\\\n    string replace -r 'Merge branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge pull request\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge remote-tracking branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    column -t -s '∬' | less -FXRS\nend\n\nfunction gitbs -d 'bs = all branches, sorted by last commit date'\n  git branch -v --format=$branch_format --sort=-committerdate $argv |\\\n    string replace -r '(^[^<]*)\\sago\\)' '$1)' |\\\n    string replace -r ',\\s\\d+?\\s\\w+\\s?' '' |\\\n    string replace -r 'Merge branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge pull request\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    string replace -r 'Merge remote-tracking branch\\s.*' (set_color cyan)'$0'(set_color normal) |\\\n    column -t -s '∬' | less -FXRS\nend\n"
  },
  {
    "path": "tests/inputs/github_user.aria",
    "content": "# https://egranata.github.io/aria/\n\n# github_user.aria\nimport Request from aria.network.request;\nimport JsonValue from aria.json.parser;\n\nval whoami = \"egranata\";\n\nfunc main() {\n    val request = Request.new(\"https://api.github.com/users/{0}\".format(whoami));\n    request.headers[\"User-Agent\"] = \"AriaLang/1.0\";\n    val response = request.get();\n\n    if response.status_code == 200 {\n        val user_data = JsonValue.parse(response.content).flatten();\n        println(\"User {1} has {0} public repositories.\".format(user_data[\"public_repos\"], whoami));\n    } else {\n        println(\"Failed to fetch user data. Status: {0}\".format(response.status_code));\n    }\n}\n"
  },
  {
    "path": "tests/inputs/glade-search-popover.ui",
    "content": "<!-- https://raw.githubusercontent.com/GNOME/gnome-terminal/master/src/search-popover.ui -->\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- Generated with glade 3.19.0 -->\n<interface>\n  <requires lib=\"gtk+\" version=\"3.16\"/>\n  <template class=\"TerminalSearchPopover\" parent=\"GtkWindow\">\n    <property name=\"can_focus\">False</property>\n    <property name=\"title\" translatable=\"yes\">Search</property>\n    <property name=\"resizable\">False</property>\n    <property name=\"skip_pager_hint\">True</property>\n    <child>\n      <object class=\"GtkBox\" id=\"box1\">\n        <property name=\"visible\">True</property>\n        <property name=\"can_focus\">False</property>\n        <property name=\"margin_left\">12</property>\n        <property name=\"margin_right\">12</property>\n        <property name=\"margin_top\">12</property>\n        <property name=\"margin_bottom\">12</property>\n        <property name=\"orientation\">vertical</property>\n        <child>\n          <object class=\"GtkBox\" id=\"box2\">\n            <property name=\"visible\">True</property>\n            <property name=\"can_focus\">False</property>\n            <property name=\"spacing\">18</property>\n            <child>\n              <object class=\"GtkBox\" id=\"box4\">\n                <property name=\"visible\">True</property>\n                <property name=\"can_focus\">False</property>\n                <child>\n                  <object class=\"GtkSearchEntry\" id=\"search_entry\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"activates_default\">True</property>\n                    <property name=\"width_chars\">30</property>\n                    <property name=\"primary_icon_name\">edit-find-symbolic</property>\n                    <property name=\"primary_icon_activatable\">False</property>\n                    <property name=\"primary_icon_sensitive\">False</property>\n                    <property name=\"placeholder_text\" translatable=\"yes\">Search</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">True</property>\n                    <property name=\"fill\">True</property>\n                    <property name=\"position\">0</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkButton\" id=\"search_prev_button\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"receives_default\">True</property>\n                    <property name=\"tooltip_text\" translatable=\"yes\">Search for previous occurrence</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <child>\n                      <object class=\"GtkImage\" id=\"image2\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">False</property>\n                        <property name=\"icon_name\">go-up-symbolic</property>\n                        <property name=\"use_fallback\">True</property>\n                      </object>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">True</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkButton\" id=\"search_next_button\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"can_default\">True</property>\n                    <property name=\"receives_default\">True</property>\n                    <property name=\"tooltip_text\" translatable=\"yes\">Search for next occurrence</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <child>\n                      <object class=\"GtkImage\" id=\"image3\">\n                        <property name=\"visible\">True</property>\n                        <property name=\"can_focus\">False</property>\n                        <property name=\"icon_name\">go-down-symbolic</property>\n                        <property name=\"use_fallback\">True</property>\n                      </object>\n                    </child>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">True</property>\n                    <property name=\"position\">2</property>\n                  </packing>\n                </child>\n                <style>\n                  <class name=\"linked\"/>\n                </style>\n              </object>\n              <packing>\n                <property name=\"expand\">True</property>\n                <property name=\"fill\">True</property>\n                <property name=\"position\">0</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkToggleButton\" id=\"reveal_button\">\n                <property name=\"can_focus\">True</property>\n                <property name=\"receives_default\">True</property>\n                <property name=\"tooltip_text\" translatable=\"yes\">Toggle search options</property>\n                <property name=\"focus_on_click\">False</property>\n                <property name=\"active\">True</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image1\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">False</property>\n                    <property name=\"icon_name\">view-context-menu-symbolic</property>\n                    <property name=\"use_fallback\">True</property>\n                  </object>\n                </child>\n                <accessibility>\n                  <relation type=\"controller-for\" target=\"revealer\"/>\n                </accessibility>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">True</property>\n                <property name=\"position\">1</property>\n              </packing>\n            </child>\n            <child>\n              <object class=\"GtkButton\" id=\"close_button\">\n                <property name=\"can_focus\">True</property>\n                <property name=\"receives_default\">True</property>\n                <property name=\"focus_on_click\">False</property>\n                <child>\n                  <object class=\"GtkImage\" id=\"image4\">\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">False</property>\n                    <property name=\"icon_name\">window-close-symbolic</property>\n                    <property name=\"use_fallback\">True</property>\n                  </object>\n                </child>\n              </object>\n              <packing>\n                <property name=\"expand\">False</property>\n                <property name=\"fill\">True</property>\n                <property name=\"position\">2</property>\n              </packing>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">True</property>\n            <property name=\"position\">0</property>\n          </packing>\n        </child>\n        <child>\n          <object class=\"GtkRevealer\" id=\"revealer\">\n            <property name=\"visible\">True</property>\n            <property name=\"can_focus\">False</property>\n            <property name=\"transition_type\">none</property>\n            <property name=\"reveal_child\">True</property>\n            <child>\n              <object class=\"GtkBox\" id=\"box3\">\n                <property name=\"visible\">True</property>\n                <property name=\"can_focus\">False</property>\n                <property name=\"margin_top\">18</property>\n                <property name=\"orientation\">vertical</property>\n                <property name=\"spacing\">6</property>\n                <child>\n                  <object class=\"GtkCheckButton\" id=\"match_case_checkbutton\">\n                    <property name=\"label\" translatable=\"yes\">_Match case</property>\n                    <property name=\"use_action_appearance\">False</property>\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"receives_default\">False</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"yalign\">0.5</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">0</property>\n                  </packing>\n                </child>\n<!--\n                <child>\n                  <object class=\"GtkCheckButton\" id=\"entire_word_checkbutton\">\n                    <property name=\"label\" translatable=\"yes\">Match _entire word only</property>\n                    <property name=\"use_action_appearance\">False</property>\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"receives_default\">False</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">1</property>\n                  </packing>\n                </child>\n-->\n                <child>\n                  <object class=\"GtkCheckButton\" id=\"regex_checkbutton\">\n                    <property name=\"label\" translatable=\"yes\">Match as _regular expression</property>\n                    <property name=\"use_action_appearance\">False</property>\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"receives_default\">False</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">2</property>\n                  </packing>\n                </child>\n                <child>\n                  <object class=\"GtkCheckButton\" id=\"wrap_around_checkbutton\">\n                    <property name=\"label\" translatable=\"yes\">_Wrap around</property>\n                    <property name=\"use_action_appearance\">False</property>\n                    <property name=\"visible\">True</property>\n                    <property name=\"can_focus\">True</property>\n                    <property name=\"receives_default\">False</property>\n                    <property name=\"use_underline\">True</property>\n                    <property name=\"focus_on_click\">False</property>\n                    <property name=\"xalign\">0</property>\n                    <property name=\"active\">True</property>\n                    <property name=\"draw_indicator\">True</property>\n                  </object>\n                  <packing>\n                    <property name=\"expand\">False</property>\n                    <property name=\"fill\">False</property>\n                    <property name=\"position\">3</property>\n                  </packing>\n                </child>\n              </object>\n            </child>\n          </object>\n          <packing>\n            <property name=\"expand\">False</property>\n            <property name=\"fill\">True</property>\n            <property name=\"position\">1</property>\n          </packing>\n        </child>\n      </object>\n    </child>\n  </template>\n</interface>\n"
  },
  {
    "path": "tests/inputs/glossary.json",
    "content": "{\n    \"glossary\": {\n        \"title\": \"example glossary\",\n        \"GlossDiv\": {\n            \"title\": \"S\",\n            \"GlossList\": {\n                \"GlossEntry\": {\n                    \"ID\": \"SGML\",\n                    \"SortAs\": \"SGML\",\n                    \"GlossTerm\": \"Standard Generalized Markup Language\",\n                    \"Acronym\": \"SGML\",\n                    \"Abbrev\": \"ISO 8879:1986\",\n                    \"GlossDef\": {\n                        \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n                        \"GlossSeeAlso\": [\"GML\", \"XML\"]\n                    },\n                    \"GlossSee\": \"markup\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/glossary.json5",
    "content": "// comments supported\n{\n    \"glossary\": {\n        \"title\": \"example glossary\",\n        \"GlossDiv\": {\n            \"title\": \"S\",\n            \"GlossList\": {\n                \"GlossEntry\": {\n                    \"ID\": \"SGML\",\n                    \"SortAs\": \"SGML\",\n                    \"GlossTerm\": \"Standard Generalized Markup Language\",\n                    \"Acronym\": \"SGML\",\n                    \"Abbrev\": \"ISO 8879:1986\",\n                    \"GlossDef\": {\n                        \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\n                        \"GlossSeeAlso\": [\"GML\", \"XML\"]\n                    },\n                    \"GlossSee\": \"markup\"\n                }\n            }\n            /*\n             *  more comments\n             */\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/gnureadline.vala",
    "content": "// https://wiki.gnome.org/Projects/Vala/InputSamples?highlight=%28%5CbVala%2FExamples%5Cb%29\nvoid main () {\n    while (true) {\n        var name = Readline.readline (\"Please enter your name: \");\n        if (name != null && name != \"\") {\n/*\n            stdout.printf (\"Hello, %s\\n\", name);\n            Readline.History.add (name);\n*/\n        } else {\n            break;\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/graphql.gql",
    "content": "# https://www.npmjs.com/package/graphql-example\nmutation { # create new user\n  createUser(name: \"\") {\n    id\n    name\n    errors {\n\n      path\n      errors {\n      \tvalidator\n      \tmessage\n      \tcode\n  # comment 2\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/greeter.tsx",
    "content": "/*\nhttps://raw.githubusercontent.com/Microsoft/TypeScriptSamples/master/greeter/greeter.ts\nrenamed to greeter.tsx to test .tsx association\n*/\nclass Greeter {\n    constructor(public greeting: string) { }\n    greet() {\n        return \"<h1>\" + this.greeting + \"</h1>\";\n    }\n};\n\nvar greeter = new Greeter(\"Hello, world!\");\n    \n// document.body.innerHTML = greeter.greet();\n"
  },
  {
    "path": "tests/inputs/groovy_triple.gvy",
    "content": "print(\n\"\"\" /*\n\"\"\")\nprint(\n\"\"\" */\n\"\"\")\n"
  },
  {
    "path": "tests/inputs/guard_talking.yarn",
    "content": "// https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/detour\ntitle: Guard\n---\nGuard: Have I told you my backstory?\n-> Yes.\n\tGuard: Oh. Well, then.\n-> No?\n\t<<detour Guard_Backstory>>\nGuard: Anyway, you can't come in.\n===\n\ntitle: Guard_Backstory\n---\nGuard: Do you want the detailed version or the short version?\n    -> Detailed.\n        <<detour Guard_Detailed_Backstory>>\n        Guard: I hope you enjoyed learning all that.. Anyway...\n    -> Short.\n        Guard: Right, well, I was a recruit, then I wasn't.\n===\n\ntitle: Guard_Detailed_Backstory\n---\nGuard: It all started when I was a mere recruit.\n// (five minutes of exposition omitted)\n// (other stuff happens)\nGuard: Want to hear more?\n    -> Yes.\n    -> No.\n        <<return>>\nGuard: (speaks more garbage)\n===\n"
  },
  {
    "path": "tests/inputs/guestbook.tpl",
    "content": "{* Smarty https://www.smarty.net/sampleapp4 *}\n\n<table border=\"0\" width=\"300\">\n  <tr>\n    <th colspan=\"2\" bgcolor=\"#d1d1d1\">\n      Guestbook Entries (<a href=\"{$SCRIPT_NAME}?action=add\">add</a>)</th>\n  </tr>\n  {foreach from=$data item=\"entry\"}\n    <tr bgcolor=\"{cycle values=\"#dedede,#eeeeee\" advance=false}\">\n      <td>{$entry.Name|escape}</td>        \n    <td align=\"right\">\n      {$entry.EntryDate|date_format:\"%e %b, %Y %H:%M:%S\"}</td>        \n    </tr>\n    <tr>\n      <td colspan=\"2\" bgcolor=\"{cycle values=\"#dedede,#eeeeee\"}\">\n        {$entry.Comment|escape}</td>\n    </tr>\n    {foreachelse}\n      <tr>\n        <td colspan=\"2\">No records</td>\n      </tr>\n  {/foreach}\n</table>\n"
  },
  {
    "path": "tests/inputs/hanoi.inc",
    "content": "// https://github.com/compuphase/pawn/tree/main/examples/hanoi.p\n\n/* The Towers of Hanoi, a game solved through recursion */\n\n@start()\n    {\n    print \"How many disks: \"\n    var disks = getvalue()\n    move 1, 3, 2, disks\n    }\n\nmove(from, to, spare, numdisks)\n    {\n    if (numdisks > 1)\n        move from, spare, to, numdisks-1\n    printf \"Move disk from pillar %d to pillar %d\\n\", from, to\n    if (numdisks > 1)\n        move spare, to, from, numdisks-1\n    }\n"
  },
  {
    "path": "tests/inputs/harbour_xbase.prg",
    "content": "// This is a comment\n/* This is a comment */\n/* This is\na comment */\n* This is a comment\n&& This is a comment\nNOTE This is a comment\nnote This is a comment\na = 1\nNOTE\n"
  },
  {
    "path": "tests/inputs/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/hello.bf",
    "content": "[ This program prints \"Hello World!\" and a newline to the screen, its\n  length is 106 active command characters. [It is not the shortest.]\n\n  This loop is a \"comment loop\", a simple way of adding a comment\n  to a BF program such that you don't have to worry about any command\n  characters. Any \".\", \",\", \"+\", \"-\", \"<\" and \">\" characters are simply\n  ignored, the \"[\" and \"]\" characters just have to be balanced. This\n  loop and the commands it contains are ignored because the current cell\n  defaults to a value of 0; the 0 value causes this loop to be skipped.\n]\n++++++++               Set Cell #0 to 8\n[\n    >++++               Add 4 to Cell #1; this will always set Cell #1 to 4\n    [                   as the cell will be cleared by the loop\n        >++             Add 2 to Cell #2\n        >+++            Add 3 to Cell #3\n        >+++            Add 3 to Cell #4\n        >+              Add 1 to Cell #5\n        <<<<-           Decrement the loop counter in Cell #1\n    ]                   Loop till Cell #1 is zero; number of iterations is 4\n    >+                  Add 1 to Cell #2\n    >+                  Add 1 to Cell #3\n    >-                  Subtract 1 from Cell #4\n    >>+                 Add 1 to Cell #6\n    [<]                 Move back to the first zero cell you find; this will\n                        be Cell #1 which was cleared by the previous loop\n    <-                  Decrement the loop Counter in Cell #0\n]                       Loop till Cell #0 is zero; number of iterations is 8\n"
  },
  {
    "path": "tests/inputs/hello.f",
    "content": "c     Hello World\n*     Hello World\n!     Hello World\n      program hello\n      implicit none\n      print '(\"Hello, World!\")'\n      end\n      ! a fancy comment\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/hello.java",
    "content": "/* hello.java */\nimport java.io.*;\nclass Hi {\n  static public void main( String args[] ) {\n    System.out.println( \"Hello World!\" );  /*\n                                              insert comment here\n                                            */\n  }\n}\n"
  },
  {
    "path": "tests/inputs/hello.kt",
    "content": "/* http://confluence.jetbrains.com/display/Kotlin/Hello%2C+world! \n*/\nfun main(args : Array<String>) { \n  val language = if (args.size == 0) \"EN\" else args[0] \n  println(when (language) { \n    \"EN\" -> \"Hello!\" \n    \"ES\" -> \"¡Hola!\" \n    // will this render?\n    \"RU\" -> \"Привет!\"  \n    else -> \"Sorry, I can't greet you in $language yet\" \n  }) \n}\n"
  },
  {
    "path": "tests/inputs/hello.lua",
    "content": "-- single line comment\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/hello.pas",
    "content": "{ Hello World in Pascal, for testing SLOCCount.\n  This is multi-line, testing curly braces. }\n(* This is another multi-line comment.\n   Here's another line. *)\nprogram Hello;\nbegin     (* Main *)\n   writeln ('Hello, world.')\nend.      (* Main *)\n\n"
  },
  {
    "path": "tests/inputs/hello.pl1",
    "content": "/*\n *   Compile:\n *               gcc hello.c -o hello\n *\n *   Run:\n *               hello\n */\nmain (int argc, char *argv[])\n{\n  printf(\"Hello.\\n\");\n~ printf(\"tilde line.\\n\");\n}\n"
  },
  {
    "path": "tests/inputs/hello.sp",
    "content": "#!/usr/local/bin/spar\n-- http://www.sparforte.com/sparforte21/examples/hello.html\n\n-- Hello world in a quick and scripty way\n? \"Hello world!\";\n\n-- Hello world in a do it again way\n?%;\n\n-- Hello world in a Bourne shell way\necho Hello world!;\n\n-- Hello world in an AdaScript parameter shell way\necho( \"Hello world!\" );\n\n-- Hello world in a ISO standard, scalable, structured way\nput_line( \"Hello world!\" );\n\n-- Hello world in a PostgreSQL database way\ndb.connect( \"ken\" );\nselect 'Hello world!';\ndb.disconnect;\n"
  },
  {
    "path": "tests/inputs/hello1.pas",
    "content": "{ Hello World in Pascal, for testing SLOCCount.\n  This is multi-line, testing curly braces. }\n(* This is another multi-line comment.\n   Here's another line. *)\n(* This is { another } test. **)\nprogram Hello;\nbegin     (* Main *)\n   writeln ('Hello, world.');\n   writeln ('It''s a test!');\n   writeln ('Show that newlines are detected')\nend.      (* Main *)\n\n"
  },
  {
    "path": "tests/inputs/hello_1.0.bb",
    "content": "# Hello world from meta-skeleton\nDESCRIPTION = \"Simple helloworld application\"\nSECTION = \"examples\"\nLICENSE = \"MIT\"\nLIC_FILES_CHKSUM = \"file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302\"\n\nSRC_URI = \"file://helloworld.c\"\n\nS = \"${WORKDIR}\"\n\ndo_compile() {\n\t${CC} ${LDFLAGS} helloworld.c -o helloworld\n}\n\ndo_install() {\n\tinstall -d ${D}${bindir}\n\tinstall -m 0755 helloworld ${D}${bindir}\n}\n"
  },
  {
    "path": "tests/inputs/hello_app.go",
    "content": "// https://raw.githubusercontent.com/golang/example/master/appengine-hello/app.go\n// Copyright 2015 Google Inc.\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// Package hello is a simple App Engine application that replies to requests\n// on /hello with a welcoming message.\npackage hello\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// init is run before the application starts serving.\nfunc init() {\n\t// Handle all requests with path /hello with the helloHandler function.\n\thttp.HandleFunc(\"/hello\", helloHandler)\n}\n\nfunc helloHandler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello from the Go app\")\n}\n\n"
  },
  {
    "path": "tests/inputs/hello_app.ʕ◔ϖ◔ʔ",
    "content": "// https://raw.githubusercontent.com/golang/example/master/appengine-hello/app.go\n// Copyright 2015 Google Inc.\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// Package hello is a simple App Engine application that replies to requests\n// on /hello with a welcoming message.\npackage hello\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// init is run before the application starts serving.\nfunc init() {\n\t// Handle all requests with path /hello with the helloHandler function.\n\thttp.HandleFunc(\"/hello\", helloHandler)\n}\n\nfunc helloHandler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello from the Go app\")\n}\n\n"
  },
  {
    "path": "tests/inputs/hello_app_autogen.go",
    "content": "// Code generated by manual copy DO NOT EDIT.\n// https://raw.githubusercontent.com/golang/example/master/appengine-hello/app.go\n// Copyright 2015 Google Inc.\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// Package hello is a simple App Engine application that replies to requests\n// on /hello with a welcoming message.\npackage hello\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// init is run before the application starts serving.\nfunc init() {\n\t// Handle all requests with path /hello with the helloHandler function.\n\thttp.HandleFunc(\"/hello\", helloHandler)\n}\n\nfunc helloHandler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello from the Go app\")\n}\n\n"
  },
  {
    "path": "tests/inputs/hello_app_autogen.ʕ◔ϖ◔ʔ",
    "content": "// Code generated by manual copy DO NOT EDIT.\n// https://raw.githubusercontent.com/golang/example/master/appengine-hello/app.go\n// Copyright 2015 Google Inc.\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// Package hello is a simple App Engine application that replies to requests\n// on /hello with a welcoming message.\npackage hello\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// init is run before the application starts serving.\nfunc init() {\n\t// Handle all requests with path /hello with the helloHandler function.\n\thttp.HandleFunc(\"/hello\", helloHandler)\n}\n\nfunc helloHandler(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintln(w, \"Hello from the Go app\")\n}\n\n"
  },
  {
    "path": "tests/inputs/helloworld.raml",
    "content": "# https://raw.githubusercontent.com/raml2html/raml2html/master/examples/helloworld.raml\n#\n#%RAML 1.0\ntitle: Hello world # required title\nversion: 1\nbaseUri: http://example.com/{version}\ndocumentation:\n  - title: Welcome\n    content: |\n      Welcome to the Example Documentation. The Example API allows you\n      to do stuff. See also [example.com](https://www.example.com).\n  - title: Chapter two\n    content: |\n      More content here. Including **bold** text!\n\n/helloworld: # optional resource\n  description: This is the top level description for /helloworld.\n\n  get: # HTTP method declaration\n    responses: # declare a response\n      200: # HTTP status code\n        body: # declare content of response\n          application/json: # media type\n            type: | # structural definition of a response (schema or type)\n              {\n                \"title\": \"Hello world Response\",\n                \"type\": \"object\",\n                \"properties\": {\n                  \"message\": {\n                    \"type\": \"string\"\n                  }\n                }\n              }\n            example: # example how a response looks like\n              {\n                \"message\": \"Hello world\"\n              }\n  /test:\n    displayName: TEST\n    get:\n      description: a sub resource\n\n  /{id}:\n    uriParameters:\n      id:\n        type: string\n        description: account identifier\n        minLength: 1\n        maxLength: 10\n\n    get:\n      headers:\n        Authorization:\n          type: string\n          description: Basic authentication header\n          example: |\n            Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n\n    put:\n      body:\n        application/x-www-form-urlencoded:\n          properties:\n            name:\n              description: name on account\n              type: string\n              examples:\n                example1: Naruto Uzumaki\n                example2: Kevin Renskers\n            gender:\n              enum: [\"male\", \"female\"]\n"
  },
  {
    "path": "tests/inputs/hi.mojo",
    "content": "#mojo\n# Works with Mojo.\n\n# pound comment\n\ndef main():\n    from time import now\n    print(\"Hello, the monotonic time is:\", now())  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''"
  },
  {
    "path": "tests/inputs/hi.py",
    "content": "#/usr/bin/env python\n# Works with both 2.x and 3.x versions of Python.\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''"
  },
  {
    "path": "tests/inputs/htlc.teal",
    "content": "// https://developer.algorand.org/docs/get-details/dapps/avm/teal/#looping-and-subroutines\n// Are used to comment in TEAL\n// htlc.teal\n// Push the CloseRemainderTo property of the current transaction onto the stack\ntxn CloseRemainderTo\n\n// Push addr2 onto the stack as the intended recipient\naddr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y\n\n// The == operator is used to verify that both of these are the same\n// This pops the two values off the stack and pushes the result 0 or 1\n==\n\n// Push the current transaction’s Receiver property onto the stack\n// In this example it should be addr2\ntxn Receiver\n\n// Push addr2 on the stack using the addr constant\naddr SOEI4UA72A7ZL5P25GNISSVWW724YABSGZ7GHW5ERV4QKK2XSXLXGXPG5Y\n\n// Use the == to verify that these are equal which pops off the top two values of the stack\n// and returns 0 or 1\n==\n\n// The stack should currently have two values from the two top conditions\n// These will be either 0s or 1s\n// Push the && operator which will AND the two previous conditions and return\n// either 0 or 1, which leaves one value on the stack either a 0 or a 1\n&&\n\n// Push the first argument to the transaction onto the stack\narg 0\n\n// The len operator pops the arg off the stack and \n// pushes the length of the argument onto the stack\nlen\n\n// Push a constant int of value 46 onto the stack\nint 46\n\n// The == operator verifies that the length of the argument\n// is equal to 46. This pops the two values and returns a 0 or 1\n// The stack now contains two values with a value of 0 or 1\n==\n\n// The && operator will AND the two values in the stack\n// which pops both values off the stack and returns a 0 or 1\n// The stack should now only have one value on the stack, 0 or 1\n&&\n\n// arg 0 is pushed back onto the stack\n// This represents the hashed passcode\narg 0\n\n// The sha256 operator pops the arg 0 off the stack\n// and pushes the hash value of the argument onto the stack\nsha256\n\n// The constant byte array of the base64 version of our secret is pushed onto the stack\nbyte base64 QzYhq9JlYbn2QdOMrhyxVlNtNjeyvyJc/I8d8VAGfGc=\n\n// The == operator pops the two values and pushes 0 or 1 onto the stack\n// If arg0 is equal to the secret this value will be 1 and if not it will be 0\n==\n\n// Two values are now on the stack. The && operator is used \n// to pop the last two values and push either 0 or 1\n// This will AND all previous conditions to this one.\n// The stack should only have a 0 or 1 value now\n&&\n"
  },
  {
    "path": "tests/inputs/html_heex_example.heex",
    "content": "<%= for entry <- entries do %>\n  <article class=\"dummy\">\n    <% # this is a nice comment about progress %>\n    <progress value={entry.progress} max=\"100\"> <%= entry.progress %>% </progress>\n<%!-- a\nmultiline\n       comment --%>\n  </article>\n<% end %>\n\n"
  },
  {
    "path": "tests/inputs/i18n_de.ts",
    "content": "<!-- http://code.qt.io/cgit/qt/qtbase.git/tree/examples/widgets/tools/i18n/translations/i18n_de.ts -->\n<!DOCTYPE TS><TS>\n<context>\n    <name>MainWindow</name>\n    <message>\n        <source>View</source>\n        <translation>Ansicht</translation>\n    </message>\n    <message>\n        <source>&amp;File</source>\n        <translation>&amp;Datei</translation>\n    </message> <!-- some comments -->\n    <message>\n        <source>E&amp;xit</source>\n        <translation>Be&amp;enden</translation>\n    </message>\n<!-- \n     some comments\n     -->\n    <message>\n        <source>First</source>\n        <translation>Erstens</translation>\n    </message>\n    <message>\n        <source>Third</source>\n        <translation>Drittens</translation>\n    </message>\n    <message>\n        <source>English</source>\n        <translation>Deutsch</translation>\n    </message>\n    <message>\n        <source>Language: %1</source>\n        <translation>Sprache: %1</translation>\n    </message>\n    <message>\n        <source>Oblique</source>\n        <translation>Schief</translation>\n    </message>\n    <message>\n        <source>Second</source>\n        <translation>Zweitens</translation>\n    </message>\n    <message>\n        <source>Isometric</source>\n        <translation>Isometrisch</translation>\n    </message>\n    <message>\n        <source>Perspective</source>\n        <translation>Perspektivisch</translation>\n    </message>\n    <message>\n        <source>Internationalization Example</source>\n        <translation>Internationalisierungsbeispiel</translation>\n    </message>\n    <message>\n        <source>LTR</source>\n        <translation>LTR</translation>\n    </message>\n</context>\n</TS>\n"
  },
  {
    "path": "tests/inputs/iclean.icl",
    "content": "// https://github.com/camilstaps/iClean/raw/master/iclean.icl\n/**\n * Interactive Clean\n *\n * Clean program to easily compile and run one-line Clean expressions\n *\n * The MIT License (MIT)\n * \n * Copyright (c) 2015 Camil Staps <info@camilstaps.nl>\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 */\nmodule iclean\n\nimport StdEnv\nimport ReadLine\n\n// SETTINGS\ntemp_path :== \"/tmp/\"\ntemp_module :== \"iclean\"\nreadline_history :== \".iclean_history\"\n// END SETTINGS\n\ntemp_file :== temp_path +++ temp_module +++ \".icl\"\n\nStart :: *World -> *World\nStart w\n# w = setReadLineName \"iClean\" w\n# w = usingHistory w\n# w = checkedWorldFunc readHistory \"Couldn't read history file\\n\" readline_history w\n# w = loop w\n# w = checkedWorldFunc writeHistory \"Couldn't write history file\\n\" readline_history w\n= w\nwhere\n    loop :: !*World -> *World\n    loop w\n    # (s,w) = readLine \"λ. \" False w\n    | isNothing s = print \"\\n\" w\n    # s = fromJust s\n    | s == \"\" = loop (print \"Use Ctrl-D to exit\\n\" w)\n    # w = addHistory s w\n    # w = writemodule s w\n    # (r,w) = compile temp_path temp_module w\n    | r <> 0 = loop w\n    # w = run (temp_path +++ temp_module) w\n    = loop w\n\ncheckedWorldFunc :: (a *World -> (Bool, *World)) !String !a !*World -> *World\ncheckedWorldFunc f err s w\n# (ok, w) = f s w\n| not ok = print err w\n| otherwise = w\n\nprint :: String *World -> *World\nprint s w\n# (io,w) = stdio w\n# io = fwrites s io\n# (ok,w) = fclose io w\n| not ok = abort \"Couldn't close stdio\\n\"\n| otherwise = w\n\nwritemodule :: String *World -> *World\nwritemodule s w\n# (ok,f,w) = fopen temp_file FWriteText w\n| not ok = abort (\"Couldn't open \" +++ temp_file +++ \" for writing.\\n\")\n# f = fwrites (\"module \" +++ temp_module +++ \"\\n\") f\n# f = fwrites \"import StdEnv\\n\" f\n# f = fwrites (\"Start = \" +++ s +++ \"\\n\") f\n# (ok,w) = fclose f w\n| not ok = abort (\"Couldn't close \" +++ temp_file +++ \"\\n\")\n| otherwise = w\n\ncompile :: !String !String !*World -> *(!Int,*World)\ncompile _ _ _ = code {\n    ccall compile \"SS:p:p\"\n}\n\nrun :: !String *World -> *World\nrun _ _ = code {\n    ccall run \"S:V:p\"\n}\n\n"
  },
  {
    "path": "tests/inputs/idris_block_comments.idr",
    "content": "--\n-- A module about shapes\n--\n\n||| a Shape\ndata Shape =\n  ||| Triangle with base and heigth\n  Triangle Double Double |\n  ||| Circle with radius\n  Circle Double\n\n||| computes the area of a shape\narea : Shape -> Double\narea (Triangle x y) = 0.5 * x * y\narea (Circle x) = pi * x * x\n                  -- pi is known by idris\n\n{-\ncommented out code\n-}\n"
  },
  {
    "path": "tests/inputs/igorpro.ipf",
    "content": "// Taken from https://github.com/t-b/igor-unit-testing-framework/blob/master/procedures/unit-testing-comparators.ipf\n// licensed under BSD\n\n/// @class NEQ_VAR_DOCU\n/// Tests two variables for inequality\n/// @param var1    first variable\n/// @param var2    second variable\nstatic Function NEQ_VAR_WRAPPER(var1, var2, flags)\n\tvariable var1, var2\n\tvariable flags\n\n\tincrAssert()\n\n\tif(shouldDoAbort())\n\t\treturn NaN\n\tendif\n\n\tif(EQUAL_VAR(var1, var2)) // do some stuff\n\t\tif(flags & OUTPUT_MESSAGE)\n\t\t\tprintFailInfo()\n\t\tendif\n\t\tif(flags & INCREASE_ERROR)\n\t\t\tincrError()\n\t\tendif\n\t\tif(flags & ABORT_FUNCTION)\n\t\t\tabortNow()\n\t\tendif\n\tendif\nEnd\n"
  },
  {
    "path": "tests/inputs/includes_demo.mustache",
    "content": "{{! https://github.com/mustache/mustache.github.com/archive/master.zip }}\n{% raw %}\n<h1>{{header}}</h1>\n{{#bug}}\n{{/bug}}\n\n{{#items}}\n  {{#first}}\n    <li><strong>{{name}}</strong></li>\n  {{/first}}\n  {{#link}}\n    <li><a href=\"{{url}}\">{{name}}</a></li>\n  {{/link}}\n{{/items}} {{!\nstuff\n  }}\n{{#empty}}\n  <p>The list is empty.</p>\n{{/empty}}\n{% endraw %}\n"
  },
  {
    "path": "tests/inputs/inner_ref.jsonnet",
    "content": "// https://jsonnet.org/learning/tutorial.html\n{\n  Martini: {\n    local drink = self,\n    ingredients: [\n      { kind: \"Farmer's Gin\", qty: 1 },\n      {\n        kind: 'Dry White Vermouth',\n        qty: drink.ingredients[0].qty,\n        /* note ability to add\n           trailing commas */\n      },\n    ],\n    garnish: 'Olive',\n    served: 'Straight Up',\n            # The `self` keyword refers to the current\n            # object, which is the Martini in this case.\n  },\n}\n"
  },
  {
    "path": "tests/inputs/input.gts",
    "content": "{{! partial of\n    https://raw.githubusercontent.com/josemarluedke/frontile/a9680f2681a8b1193feba0fdc27871566bcde120/packages/forms/src/components/input.gts\n}}\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { on } from '@ember/modifier';\nimport {\n  useStyles,\n  type InputSlots,\n  type InputVariants,\n  type SlotsToClasses\n} from '@frontile/theme';\nimport { FormControl, type FormControlSharedArgs } from './form-control';\nimport { triggerFormInputEvent } from '../utils';\nimport { ref } from '@frontile/utilities';\nimport { CloseButton } from '@frontile/buttons';\n\ninterface Args extends FormControlSharedArgs {\n  type?: string;\n  value?: string;\n  name?: string;\n  size?: InputVariants['size'];\n  classes?: SlotsToClasses<InputSlots>;\n\n  /**\n   * Whether to include a clear button\n   */\n  isClearable?: boolean;\n\n  /**\n   * Controls pointer-events property of startContent.\n   * If you want to pass the click event to the input, set it to `none`.\n   *\n   * @defaultValue 'auto'\n   */\n  startContentPointerEvents?: 'none' | 'auto';\n\n  /**\n   * Controls pointer-events property of endContent.\n   * If you want to pass the click event to the input, set it to `none`.\n   *\n   * @defaultValue 'auto'\n   */\n  endContentPointerEvents?: 'none' | 'auto';\n\n  /**\n   * Callback when oninput is triggered\n   */\n  onInput?: (value: string, event?: InputEvent) => void;\n\n  /**\n   * Callback when onchange is triggered\n   */\n  onChange?: (value: string, event?: InputEvent) => void;\n}\n\ninterface InputSignature {\n  Args: Args;\n  Blocks: {\n    startContent: [];\n    endContent: [];\n  };\n  Element: HTMLInputElement;\n}\n\nfunction or(arg1: unknown, arg2: unknown): boolean {\n  return !!(arg1 || arg2);\n}\n\nclass Input extends Component<InputSignature> {\n  @tracked uncontrolledValue: string = '';\n\n  inputRef = ref<HTMLInputElement>();\n\n    if (this.isControlled) {\n      this.args.onInput?.(value, event as InputEvent);\n    } else {\n      this.uncontrolledValue = value;\n    }\n  }\n\n  @action handleOnChange(event: Event): void {\n    const value = (event.target as HTMLInputElement).value;\n\n    if (this.isControlled) {\n      this.args.onChange?.(value, event as InputEvent);\n    } else {\n      this.uncontrolledValue = value;\n    }\n  }\n\n    this.inputRef.element?.focus();\n    triggerFormInputEvent(this.inputRef.element);\n  }\n\n  <template>\n    <FormControl\n      @size={{@size}}\n      @label={{@label}}\n      @isRequired={{@isRequired}}\n      @description={{@description}}\n      @errors={{@errors}}\n      @isInvalid={{@isInvalid}}\n      @class={{this.classes.base class=@classes.base}}\n      as |c|\n    >\n      <div class={{this.classes.innerContainer class=@classes.innerContainer}}>\n        {{#if (has-block \"startContent\")}}\n          <div\n            data-test-id=\"input-start-content\"\n            class={{this.classes.startContent\n              class=@classes.startContent\n              startContentPointerEvents=(if\n                @startContentPointerEvents @startContentPointerEvents \"auto\"\n              )\n            }}\n          >\n            {{yield to=\"startContent\"}}\n          </div>\n        {{/if}}\n        <input\n          {{this.inputRef.setup}}\n          {{on \"input\" this.handleOnInput}}\n          {{on \"change\" this.handleOnChange}}\n          id={{c.id}}\n          }}\n          data-component=\"input\"\n          aria-invalid={{if c.isInvalid \"true\"}}\n          aria-describedby={{c.describedBy @description c.isInvalid}}\n          ...attributes\n        />\n        {{#if (or (has-block \"endContent\") this.isClearable)}}\n          <div\n          >\n            {{yield to=\"endContent\"}}\n\n            {{#if this.isClearable}}\n              <CloseButton\n              />\n            {{/if}}\n          </div>\n        {{/if}}\n      </div>\n    </FormControl>\n  </template>\n}\n\nexport { Input, type InputSignature };\nexport default Input;\n"
  },
  {
    "path": "tests/inputs/insertJournalEntry.ipl",
    "content": "/*\nhttps://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/Tivoli+Netcool+Impact/page/Policy+Language+Code+Library\n */\n//--------------------------------------------------------------------\n//\n// insertJournalEntry- this IPL function will create a journal entry\n//                     of 'text' for event with serial# 'serial' in\n//                     data source 'datasource'.\n//\n//                     The OOB function for creating journal entries\n//                     does not support 2+ entries for same serial\n//                     in same second.\n//\n//--------------------------------------------------------------------\n\nFunction insertJournalEntry ( datasource, serial, text )\n{\n\n  UID = 16;  // user impact\n  Chrono = GetDate();\n  randNum = Random(100000);   // this is added to support 2+ entries made for same serial# in same second\n  KeyField = serial + \":\" + UID + \":\" + Chrono + \":\" + randNum;\n\n  // journal entry text (jet) array - 16 \"text fields\" each varchar(255)\n  jet = { \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" };\n\n  index = 0;\n  while( (Length(text)>0) and (index<Length(jet)) )\n  {\n    jet[index] = Substring(text, 0, 256);\n    if(Length(text)>255)\n    {\n      text = Substring(text, 256, Length(text));\n    }\n    else\n    {\n      text=\"\";\n    }\n    index = index + 1;\n  }\n\n  insertStmt = \"insert into alerts.journal ( KeyField,Serial,UID,Chrono,Text1,Text2,Text3,Text4,Text5,Text6,Text7,Text8,Text9,T\next10,Text11,Text12,Text13,Text14,Text15,Text16)\";\n  insertStmt = insertStmt + \" values ( '\" + KeyField + \"', \" + serial + \", \" + UID + \", \" + Chrono;\n  index=0;\n  while(index<Length(jet))\n  {\n    insertStmt = insertStmt + \",'\" + Replace(jet[index], \"'\", \"\\\"\") + \"'\";\n    index = index + 1;\n  }\n  insertStmt = insertStmt + \")\";\n\n  DirectSQL( datasource, insertStmt, False );\n}\n"
  },
  {
    "path": "tests/inputs/invoices.prql",
    "content": "# https://prql-lang.org/\nfrom invoices\nfilter invoice_date >= @1970-01-16\nderive {\n  transaction_fees = 0.8,\n  income = total - transaction_fees\n}\n\nfilter income > 1\n\ngroup customer_id (\n  aggregate {\n    average total,\n    sum_income = sum income,\n    ct = count total,\n  }\n)\n"
  },
  {
    "path": "tests/inputs/io.c3",
    "content": "// https://github.com/c3lang/c3c/blob/master/lib/std/io/io.c3  (partial saved here)\n// Copyright (c) 2021-2025 Christoffer Lerno. All rights reserved.\n// Use of this source code is governed by the MIT license\n// a copy of which can be found in the LICENSE_STDLIB file.\nmodule std::io;\nimport libc;\n\nenum Seek\n{\n\tSET,\n\tCURSOR,\n\tEND\n}\n\nfaultdef\n\tALREADY_EXISTS,\n\tBUSY,\n\tCANNOT_READ_DIR,\n\tDIR_NOT_EMPTY,\n\tPARENT_DIR_MISSING,\n\tEOF,\n\tFILE_CANNOT_DELETE,\n\tFILE_IS_DIR,\n\tFILE_IS_PIPE,\n\tFILE_NOT_DIR,\n\tFILE_NOT_FOUND,\n\tFILE_NOT_VALID,\n\tGENERAL_ERROR,\n\tILLEGAL_ARGUMENT,\n\tINCOMPLETE_WRITE,\n\tINTERRUPTED,\n\tINVALID_POSITION,\n\tINVALID_PUSHBACK,\n\tNAME_TOO_LONG,\n\tNOT_SEEKABLE,\n\tNO_PERMISSION,\n\tOUT_OF_SPACE,\n\tOVERFLOW,\n\tPATH_COULD_NOT_BE_FOUND,\n\tREAD_ONLY,\n\tSYMLINK_FAILED,\n\tTOO_MANY_DESCRIPTORS,\n\tUNEXPECTED_EOF,\n\tUNKNOWN_ERROR,\n\tUNSUPPORTED_OPERATION,\n\tWOULD_BLOCK;\n\n\n<*\n Read from a stream (default is stdin) to the next \"\\n\"\n or to the end of the stream, whatever comes first.\n \"\\r\" will be filtered from the String.\n\n @param [&inout] allocator : \"The allocator used to allocate the read string.\"\n @param stream : `The stream to read from.`\n @param limit : `Optionally limits the amount of bytes to read in a single line. Will NOT discard the remaining line data.`\n @require @is_not_instream_if_ptr(stream) : \"The value for 'stream' should have been passed as a pointer and not as a value, please add '&'.\"\n @require @is_instream(stream) : `Make sure that the stream is actually an InStream.`\n @param [inout] allocator : `the allocator to use.`\n @return `The string containing the data read.`\n*>\nmacro String? readline(Allocator allocator, stream = io::stdin(), usz limit = 0)\n{\n\treturn readline_impl{$typeof(stream)}(allocator, stream, limit);\n}\n\n<*\n Reads a string, see `readline`, except the it is allocated\n on the temporary allocator and does not need to be freed.\n\n @param stream : `The stream to read from.`\n @param limit : `Optionally limits the amount of bytes to read in a single line. Will NOT discard the remaining line data.`\n @require @is_not_instream_if_ptr(stream) : \"The value for 'stream' should have been passed as a pointer and not as a value, please add '&'.\"\n @require @is_instream(stream) : `The stream must implement InStream.`\n @return `The temporary string containing the data read.`\n*>\nmacro String? treadline(stream = io::stdin(), usz limit = 0)\n{\n\treturn readline(tmem, stream, limit) @inline;\n}\n\nfn String? readline_impl(Allocator allocator, Stream stream, usz limit) <Stream> @private\n{\n\tif (allocator == tmem)\n\t{\n\t\tDString str = dstring::temp_with_capacity(256);\n\t\treadline_to_stream(&str, stream, limit)!;\n\t\treturn str.str_view();\n\t}\n\t@pool()\n\t{\n\t\tDString str = dstring::temp_with_capacity(256);\n\t\treadline_to_stream(&str, stream, limit)!;\n\t\treturn str.copy_str(allocator);\n\t};\n}\n\n<*\n Reads a string, see `readline`, the data is passed to an outstream\n\n @param out_stream : `The stream to write to`\n @param in_stream : `The stream to read from.`\n @param limit : `Optionally limits the byte-length of the allocated output string.`\n @require @is_not_instream_if_ptr(in_stream) : \"The value for 'in_stream' should have been passed as a pointer and not as a value, please add '&'.\"\n @require @is_not_outstream_if_ptr(out_stream) : \"The value for 'out_stream' should have been passed as a pointer and not as a value, please add '&'.\"\n @require @is_instream(in_stream) : `The in_stream must implement InStream.`\n @require @is_outstream(out_stream) : `The out_stream must implement OutStream.`\n @return `The number of bytes written. When a 'limit' is provided and the return value is equal to it, there may be more to read on the current line.`\n*>\nmacro usz? readline_to_stream(out_stream, in_stream = io::stdin(), usz limit = 0)\n{\n\treturn readline_to_stream_impl{$typeof(in_stream), $typeof(out_stream)}(out_stream, in_stream, limit);\n}\n\nfn usz? readline_to_stream_impl(OStream out_stream, IStream in_stream, usz limit) <IStream, OStream> @private\n{\n\tbool $is_stream = IStream == InStream;\n\t$if $is_stream:\n\t\tvar func @safeinfer = &in_stream.read_byte;\n\t\tchar val = func((void*)in_stream)!;\n\t$else\n\t\tchar val = in_stream.read_byte()!;\n\t$endif\n\tbool $is_out_stream = OStream == OutStream;\n\t$if $is_out_stream:\n\t\tvar out_func @safeinfer = &out_stream.write_byte;\n\t$endif\n\n\tif (val == '\\n') return 0;\n\tusz len;\n\tif (val != '\\r')\n\t{\n\t\t$if $is_out_stream:\n\t\t\tout_func((void*)out_stream.ptr, val)!;\n\t\t$else\n\t\t\tout_stream.write_byte(val)!;\n\t\t$endif\n\t\tlen++;\n\t}\n\twhile (!limit || len < limit)\n\t{\n\t\t$if $is_stream:\n\t\t\tchar? c = func((void*)in_stream);\n\t\t$else\n\t\t\tchar? c = in_stream.read_byte();\n\t\t$endif\n\t\tif (catch err = c)\n\t\t{\n\t\t\tif (err == io::EOF) break;\n\t\t\treturn err~;\n\t\t}\n\t\tif (c == '\\r') continue;\n\t\tif (c == '\\n') break;\n\t\t$if $is_out_stream:\n\t\t\tout_func((void*)out_stream.ptr, c)!;\n\t\t$else\n\t\t\tout_stream.write_byte(c)!;\n\t\t$endif\n\t\tlen++;\n\t}\n\treturn len;\n}\n\n"
  },
  {
    "path": "tests/inputs/issue_875.bdy",
    "content": "/*\n * bubble sort\n */\nDECLARE\n  TYPE number_array IS VARRAY(100) OF NUMBER;\n  arr number_array := number_array(64, 34, 25, 12, 22, 11, 90);\n  n NUMBER := arr.COUNT;\n  i NUMBER := 0;\n  j NUMBER := 0;\n  temp NUMBER;\nBEGIN\n  FOR i IN 1 .. (n - 1) LOOP -- outer\n    FOR j IN 1 .. (n - i - 1) LOOP -- inner\n      IF arr(j) > arr(j + 1) THEN\n        temp := arr(j);\n        arr(j) := arr(j + 1);\n        arr(j + 1) := temp;\n      END IF;\n    END LOOP;\n  END LOOP;\n  -- print\n  FOR i IN 1 .. n LOOP\n    DBMS_OUTPUT.PUT_LINE(arr(i));\n  END LOOP;\nEND;\n/\n"
  },
  {
    "path": "tests/inputs/issue_876.vue",
    "content": "<template>\n    <div v-loading=\"loading\">\n        <div>aaa</div>\n    </div>\n</template>\n<script>\nimport(menCommonConstant } from '@/utils/menConstant'\n// test\nexport detault,\n    name: 'SpecProgramClientNotice',\n    components: {\n        vxeTable, //table\n        menClientInout\n    }\n</script>\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "tests/inputs/issues/114/bar/bee/inner_most.js",
    "content": "js 1\n"
  },
  {
    "path": "tests/inputs/issues/114/bar/under_Bar.js",
    "content": "js 2\n"
  },
  {
    "path": "tests/inputs/issues/114/foo/under_foo.js",
    "content": "js 3\n"
  },
  {
    "path": "tests/inputs/issues/131/README",
    "content": "This directory contains inputs for tests 21 through 24 in cloc/Unix/t/01_opts.t \nThe tests exercise cloc's ability to work with git submodules (specifically, \nto ignore code in these).  If you're working with a git repo clone you will \nneed to update the submodule via\n  git submodule init\n  git submodule update\nissued within your cloc working directory to get the tests to pass.\n"
  },
  {
    "path": "tests/inputs/issues/131/hi.py",
    "content": "#/usr/bin/env python\n# Works with both 2.x and 3.x versions of Python.\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n"
  },
  {
    "path": "tests/inputs/issues/132/.gitignore",
    "content": "ignore_git/*\n"
  },
  {
    "path": "tests/inputs/issues/132/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/132/README",
    "content": "Issue #132 (https://github.com/AlDanial/cloc/issues/132) needs\na non-git controlled subdirectory called 'ignore_git' created \nhere.  Copy into this new directory the file hi.py from the \ntest inputs directory.\n\n    # if cwd is cloc/tests/inputs/issues/132/ then:\n    mkdir ignore_git\n    cp ../../hi.py ignore_git/\n\n    # if cwd is cloc/ then:\n    mkdir tests/inputs/issues/132/ignore_git\n    cp    tests/inputs/hi.py tests/inputs/issues/132/ignore_git/\n\n    # if cwd is cloc/Unix then:\n    mkdir ../tests/inputs/issues/132/ignore_git\n    cp    ../tests/inputs/hi.py ../tests/inputs/issues/132/ignore_git/\n\nNote:  The actions above are done automatically when running \n'make test' in the cloc/Unix directory.\n    \n"
  },
  {
    "path": "tests/inputs/issues/132/ignore_dir/Fortran77.f",
    "content": "C from http://www.roesler-ac.de/wolfram/hello.htm\nC     Hello World in Fortran 77\n\n      PROGRAM HELLO\n      PRINT*, 'Hello World!'\n      END\n"
  },
  {
    "path": "tests/inputs/issues/166/X",
    "content": "Isabelle\n    filter remove_between_general (* *)\n    extension thy\n    3rd_gen_scale 3.00\n"
  },
  {
    "path": "tests/inputs/issues/166/fake.thy",
    "content": "This is (* not an\nIsabelle file\n*)\n\nInstead, just some text lines.\n"
  },
  {
    "path": "tests/inputs/issues/183/eval1957.SACunidir.fr",
    "content": " ( https://github.com/rsennrich/Bleualign/eval/eval1957.SACunidir.fr ) \nchronique himalayenne 1956 \navec notes complémentaires sur les années précédentes par g. o. dyhrenfurth \navec 3 illustrations \ndans la dernière époque sont les cotes de la grande himalaya-berge , ce qui a regrettables confusions . \ncomme est une pareille incertitude , même dans les plus célèbres , depuis 100 ans et mesurées expliquer ? \nce sont surtout les trois fehlerquellen aujourd' hui en être autrement qu' autrefois : \nla grandeur de la b ) jahres- et de la masse de l' himalaya et ;c ) les réductions au géoïde . \nil serait donc fait attendre que les depuis 1952 , qui étaient faites et neuberechnung très forte en face des écarts le vieux fournissent rouges , mais heureusement les plus tôt gemachten erreurs surtout kompensiert . \npour chomo-lungma ( mont everest ) d' assez six calculs aus den jahren 1849 et 1850 une valeur moyenne de 8839,8 m , six calculs de les années 1881-1902 lieferten un moyen de 8882,2 m. ce nombre a été encore trop bas que l' , et les ( 1513 ) sens pas montés jusqu' à plus de 8900 m hinaus . \nla nouvelle cote officielle publiée en 1955 ramène , de 8900 m. c' est donc le nombre , à la ronds . \npour le kangchenjunga , n' a connu que l' ancienne cote de 8579 m d' environ 60 ft . \n= 18,29 m augmenté doit être , la troisieme montagne de la terre , à environ 8597 m. est acheminés . \nla nouvelle cote officielle de ma connaissance n' est pas encore été publiée . \nquoi qu' il en soit , l' altitude de 8603 m qui figure sur la carte de marcel kurz , qui fut très bien . \nle lhotsé mesure toujours 8501 m , mais probablement demnächst , à environ 8510 m heraufgesetzt doivent être - conformément à ses voisins , l' everest et le makalu . \ncar la depuis un siècle , 8470 , maintenant , abandonnée . \nle nouveau chiffre officiel est 8481 m. \nle plus , c' est au cho oyu , pour le depuis quelque temps deux cotes - 2 les alpes - 1957 - die alpen 17 , 8153 m et 8189 m - dans « standen . \nune neuberechnung est probablement pas encore été terminés . \nle dhaulagiri , le mont blanc » de l' himalaya , le plus haut sommet de la terre , était coté jusqu' ici 8172 ou 8167 m . \nla nouvelle cote lui donne 8222 m. \nau-dessus de manaslu ( 8125 m ) , du nanga parbat ( 8125 m ) , l' annapurna i ( 8078 ou 8074 m ) , le shisha pangma ( 8013 m ) et les quatre « 8000 » pakistanais k2 ( 8611 m ) , le hidden peak ( 8068 m ) , le broad peak ( 8047 m ) et le gasherbrum ii ( 8035 m ) est pour rien de nouveau je garde pour ma part du passage . \nen tenant compte de tous les neuberechnung aujourd' hui physiques connu facteurs assez exige beaucoup de temps . \nles kaschmirfrage avec la frontière entre l' inde et le pakistan , dont encore . \nnous devons donc patienter encore , jusqu' à ce que les nouvelles altitudes pour tous les grands sommets de l' himalaya et du karakorum définitivement - c' est au moins pour quelques décennies - . \ndans notre revue des principales récentes expéditions le passé récent , nous commençons de nouveau avec ä l' himalaya : \n1. du kangchenjunga , les grimpeurs n' est pas beaucoup de nouveau à signaler au . \nla splendide ascension fut déjà dans notre « chronique himalayenne 1955 » traités ( voir les alpes 1956 , n° 4 ) . \nmais , du point de vue géologique , l' a méthodiquement par le dr toni hagen notre connaissance du kangchendzönga-massivs très nettement merveilleuse . \n« les alpes » 1956 , s.298-303 ( novembre ) bringen dans le texte , profils et un premier esquisses cartographiques ) . \n2. à la montagne de la terre , les arthaud ) . \nle livre de jean franco ( « makalu » , l' an dernier . \nb.arthaud ) , maintenant , même en allemand autant ( zürich : \norell füssli 1956 ) , après les amène gehaltvollen originalberichten et en face de notre annee « chronique himalayenne » en principe pas beaucoup de nouveau . \nmais les ascensions du makalu-gebietes par le dr toni hagen en hiver 1954/55 et en automne 1955 , dont les résultats de ce n' est que tout récemment fut quelque peu connue ( voir les alpes 1956 , p. 295-298 ) , étaient scientifiques de grösster bedeutung et lieferten bildlich aussi une splendide . \nla tectonique du peu à peu dévoilée et s' avère est aussi grandiose , comme on - nos anticipations le prévoyaient . \n3. , à l' est de la , le fleuve arun s' arim-fluss jusqu' à 1200 m , un des plus formidables qui , il y a sur la terre . \ndéjà en 1930 , j' en ai écrit : \n« de l' himalaya proprement dite , n' est pas malgré son altitude de partage des eaux ; \ncelle-ci est de plus au nord , , constituée par des chaînes . \ndes fleuves , comme par exemple le financé ( entre makalu- et kangchendzönga-gruppe ) ou la tista ( à l' est du kangchendzönga ) plus au sud jaillissent , sur le versant nord de l' himalaya et haben sich in terribles gorges vers le sud , par le gebirgswall durchgefressen . \npareille formidables par rückschreitende seulement à l' érosion , n' est pas possible . \napparemment filiusion ces cours d' eau issus déjà à l' océan indien , comme il n' a pas encore himmelstürmende great de l' himalaya , et ils tenaient avec la gebirgsaufwölbung pas . \nles hebung une zone situé au sud de la chaîne , donc peu à peu , ainsi que les rivières se dans la même rythme einschneiden et de leurs anciens cours dans la section essentiels . \nces fleuves sont plus vieux que l' himalaya . \n» le arun-tal est aussi et de pflanzengeographisch très intéressante . \nim auftrage du british museum j.d.a.stainton y a travaillé en été 1956 . \nil était accompagné du sherpa da temba ( himalayan club : \ndeux nr.212 ) . \n4. la grande expédition suisse de 1956 , de la ssaf soigneusement préparé et organisée , d' albert eggler mustergültig conduite et par les alpinistes bernois en vivent en parfaite harmonie camaraderie italienne - fut une des les entreprises dans l' histoire de l' himalaya . \nelle culmine dans la première ascension du lhotse ( 8501 m , resp. environ 8510 m ) , le 18 mai 1956 par ernst reiss et fritz luchsinger , la deuxième ascension du mount everest ( 8848 m ) , le 23 mai par jiirg marmet et ernst schmied et de la troisième ascension , le 24 mai par adolf reist et hansrudolf von gunten . \npour ne pas répéter ce qui est connu , il suffira ici , à quelques des principaux publications : \nréférences : \na ) les articles originaux dans « de la confédération » et « neue zürcher zeitung » de mai à octobre 1956 . \n- « les alpes 1956 , 132/133 , 147-151 , 175-177 et le fascicule de mars 1957 . \n- alberteggler : \nsommet par les nuages . \nberne : \nhallwag . \n- « berge der welt » , bd.xi ( 1956/57 ) , p. 161-177 . \noutre les succès bergsteigerischen réalisations , nous voulons l' exploration scientifique des everest-gebietes n' oublions pas : \n1952 augustin lombard , albert zimmermann , ;1952/53 1952 et 1953 l. g. c.pugh physiologisch , 1954 l'«aide heuberger géographique , 1954 et en 1955 pierre bordet et michel latreille , ainsi que les français - indépendant de tout -toni hagen , du point de vue géologique , 1955 , erwin schneider , but de 1956 , fritz müller et arthur durst glaziologisch et meteorologisch . \nles chomo-lungma-gruppe au bestbekannten devient peu à peu la région de l' himalaya . \n5. pour l' hiver 1956/57 est une expédition australienne , sous la conduite de peter c. bryne a annoncé , en solo khumbu ( wieder einmal ) sur la yeti-suche begeben will , c' est sur les « photographique schneemenschen»-jagd ( voir aussi 12 de cette chronique ) . \nn' est pas davantage encore connus . \n6. au-dessus de l' expédition féminine schottische , les au printemps 1955 au ne de kathmandu dans le jugal himal , qui était déjà dans l' intervention chronique ( voir les alpes 1956 , p. 81 ) peu . \nentre-temps , le livre a : \nmonica jackson et elizabeth stark , tents in the clouds ( london : \nil en 1956 ) , joliment illustré écrit allègrement et , quand nous nous aussi - h. w.tilman beistimmend - , nous aimerions rappeler que « human interest » , il ne devrait être et que les montagnes sont en général que les sur eux herumkriechenden hommes . \n7 sur le puissant manaslu ( 8125 m ) , les japonais 1952 une reconnaissance et de 1953 , une tentative sérieuse , bei dem sie jusqu' à 7750 m . \nen 1954 déjà , il n' y eut la marche d' approche par la vallée de la grande difficulté , avec de la population , qui se vers cette heureuse belästigung la gottheit au barrage . \nl' expédition dut faire demi-tour . \nen 1955 , le calme de la montagne , mais l' inévitable préparation diplomatique . \n1956 apporta la décision : \nsous la conduite du montagnard expérimenté qu' de yuko maki , le 1921 , avec les guides de grindelwald , fritz amatter , fritz steuri et samuel brawand , la première ascension par l' arête de la mittellegi de l' eiger avait réussi , cette fois-ci , a tenté une voie nouvelle . \njusqu' ici , on avait sur le versant se du massif gehalten : \nle village de sama ausgehend , par le manaslu-gletscher , naike-col ( 5600 m ) et le col nord ( 7100 m ) au un plateau glaciaire , un pas plus difficile , mais très long chemin , la neuf camp avait exige . \nmais , maintenant , se fit de la dernière montée par le sud , et l' on s' en tira avec six camps seulement . \nquatre membres de l' équipe des grimpeurs ont atteint le sommet -am 9.mai imanishi avec le sherpa gyalzen ( himalayan club : \ndeux jours ) et le 11 mai kato et higeta. par les quatre pointes , qui forment le sommet le plus élevé , est si étroit qu' un seul homme ; \nd' après les dernières mesures , le manaslu a exactement la même altitude que le nanga parbat ( 8125 m ) ; \ntous deux se trouvent à la 8 et 9 endroit de la rangliste . \nle récit de cette montagne ténacité la traduction exacte et les photos de leur expédition victorieuse de 1956 , on attend avec impatience . \n8. par les encore à gravir est reprise , le plus haut , le dhaulagiri ( d' après les nouveaux calculs 8222m ) , pour les depuis quatre ans gerungen devient dure ; \nen 1953 , et l' expédition de l' aacz , 1954 , la première expédition argentine , les jusqu' à 7950 m , et qu' il fit par un enfer pour le gipfelsieg gebracht fut , en 1955 , le schweizerisch-deutsche « vegetarische himalaya-expedition » et de 1956 , la seconde expédition argentine . \nde cette entreprise , dirigée par le colonel e.huerta , on n' a pas grand' deux , le 15 et 25 mai , échouèrent . \nsi les pressemeldungen des voix , fut une altitude d' environ 7200 m atteint . \npour 1957 , on dit qu' une expédition franco-suisse est en préparation , et si cette de la victoire , les argentins pourraient revenir en 1958 pour la troisième fois . \nle dhaulagiri est une montagne difficile et dangereux , lui aussi , l' heure de taille ... peut-être même bientôt . \ndu dhaulagiri himal , couronnée de six dépassant les 7000 m ( voir les alpes 1956 , p. 82 ) , rien de nouveau à signaler au . \ndans west-nepal depuis l' automne 1956 , le dr toni hagen . \n9. dans le garhwal , le trisul ( 7120 m ) , gravi deux fois , et cela par k.bunshah de bombay , avec deux sherpas et de deux allemands , f. et a. hieber . \nle trisul , la première fois déjà en 1907 par t. g. longstaff avec a. et h. bracherei et kharbir gravi , est un beau , mais unschwieriger montagne au sudouest de la nanda devi , est considéré comme « billiger sept mille » , et fut plusieurs fois déjà visité 10. dans la chronique himalayenne 1955 , déjà mentionné que peter aufscknaiter et george hampson une excursion dans les ronti-gruppe au sud de la rishi ganga-schlucht ( nanda devi-gebiet ) ont fait . \naprès coup est connu que dabei ( 1955 ) , la première ascension du ronti ) a réussi à 11 m.11. les expéditions féminines semblent venir à la mode . \nen mai et juin 1956 était l' expédition abinger » , sous la conduite de mrs.joyce dunsheath . \nc' étaient quatre membres du ladies alpine club , londres , les de manali , par le hampta-pass dans la vallée , est le bara shigri est leur camp de base , et , de là , de six sommets entre 5800 et de 6100 m erstiegen . \nils furent qui collaborent par le très ancien homme ang tsering uj ( « pansy » , h.c. n° 51 ) et trois autres sherpas . \n12. dans la vallée dont les eaux se déversent dans le même le dans le sud , au kulti-gletscherbecken , où , en 1955 , une expédition de la royal air force mountaineering association , dirigée par le capitaine a.j.m.smyth , travailla ( voir les alpes 1956 , s.85 haut ) . \nrécemment une très intéressante récit d' escadrille l. ( « alpine journal n° . \nalpine journal n° 293 , nov . \nen 1956 , p. 340-343 ) . \nje finis réparties - en traduction - quelques extraits : \n« ... nous rencontrâmes trois grands empreintes de pas sur l' arête , un peu au milieu du grand torrent glaciaire à notre droite . \nc' était indubitablement un animal aus dem glacées , vite , l' eau coulant sur l' îlot . \nnous voulions traverser volontiers la rivière , mais il était trop profonde et terriblement froid . \nc' est pourquoi nous nous vîmes maintenant bien pour , où la bête était hineingegangen dans l' eau . \nbientôt l' endroit était trouvée : \nune centaine de pas . \nde là , nous suivons la trace de toucher , donc sur le flanc ouest de la vallée et dans la direction , d' où la bête était venue . \nnous marchions parallèlement à l' itinéraire , sans elles , à environ croisent . \nl' animal était debout cheminant dans la fall-linie heruntergekommen ; \nen revanche , où il fut trop raide , il était sur son derrière heruntergerutscht . \naprès examen judicieuse , montre qu' il a cette descente suivants les mains avait utilisé , parfois au freiner , parfois pour nachzuhelfen . \nla distance entre de gauche et de droite handspuren était quelque trois pas . \naprès nous avoir la grande des traces premièrement aperçues , de la rivière jusqu' à un pont de neige , puis sur l' autre rive de nouveau revenir en arrière jusqu' à l' endroit où nous avions découvert d' abord les environs . \nc' est ici que l' eau environ 1 y2 m de profondeur , le courant avait le uferrand unterhöhlt - malgré tout , nous avons pu nous ne pûmes découvrir aucune empreinte de mains ou . \nquoi qu' il en soit créature qui avait passé là , extrêmement gross gewesen sein , car il était sortir de l' eau profonde simplement sur le bord de l' îlot . \ncomme ses camarades ladakhis , sur les précautions vers nos sherpas . \nmais cette attitude totalement . \n« zarur sahib , s' exclama , y eh bah nay hai » , cria-t-il . \n( ce n' est certainement pas un ours ) . \nla veille , il m' avait lors de mes caméras , 300 m en amont . \nnous pûmes constater que nos propres empreintes ne s' étaient élargies d' environ 3 sur leur . \nl' hypothèse que les prétendues empreintes par la fonte devait ) de bärenpfoten sont , dans le cas . \nen outre , nous avions de cette région , le bien jours à heures environ . \nnous savions que , depuis ce geschöpf , entre le 11 juin 1955 , de l' apres , et le 12 juin , tôt , la vallée de avait traversé . \nl' examen attentif des empreintes de pas sur le fil de l' île qu' elle ' de la rivière était durcie , quand la neige gelée , était donc dans la nuit ou très tôt le matin . \nsur des six voyages que j' ai faits souvent je ours noirs ou rouges et observé leurs traces , mais ici , dans ces empreintes de kulti étaient très différentes . \nchacun de large et les orteils , ( 203 mm . \nle certains avait une longueur de bien 30 cm et une largeur de 20 cm et était à certains endroits , environ 28 cm de profondeur , où j' ai même à peine 4 cm . \ndabei berceau je 89 kg , et je machte mes observations dans le soleil de midi . \ncette profondeur soit dans la neige dure , prouve que l' animal très lourd . \npendant des heures , nous suivons les traces , ce qui , à travers les se prolongeaient sur près d' un kilomètre et des torrents glaciaires , fut très difficile . \nelle avait ' d' au moins cinq de ces chenals , et sur le flanc est de la vallée rocheuse avant que ses traces aillent se perdre . \nil avait nulle part à quatre pattes . \nla distance de ses pas était presque le double des miens . \nfinalement nous abandonnâmes la chasse sur et retournèrent au camp de base . \nnos sherpas étaient très persuadés qu' il s' agissait d' un ,yéti ' . \nswami pranavananda a intéressantes récemment un article écrit ( ,the abominable snowman ' dans ,the alpine journal , n° 292 , mai 1956 , p. 110-117 ) , dans l' intention de montrer , le ,yeti-legende ' la force à faire . \nmalheureusement , il ne peut prétendre avoir jamais lui-même et il examine zu haben . \nil parle seulement de seconde main plusieurs tibétains ont confirme que des traces d' abord , puis , comme fährten d' un rouge ( nous installerions le dire : \nherausgestellt ours bruns ) . \nc' est , bien sûr , qu' un scheinargument . \nil est pourtant très bedeutsam : \nquand toujours d' une nouvelle espèce de conta - étaient toujours de nombreux sachverständige trop prêt , à une attester que si quelque chose ne pouvait exister . \nil y a cent ans , exactement franco-américain paul belloni du chaillu tira le premier gorille , le d' un blanc . \nplus de 2000 ans , l' europe avait tenu le gorille pour une pure légende , comme le serpent de mer ou les ,dragons ' du moyen âge . \nlorsque chaillu sa description de ce retour en europe , rires . \nil fallut encore si l' europe admette l' existence du gorille . \nil en fut de même plus tard , par exemple , avec le , du coelacanthus et l' okapi , la girafe des forêts primitives . \nles spécialistes de cet inconnu êtres vivants de l' existence de ces animaux . \nsceptiques demanderont pourquoi les rencontres avec le ,yéti ' ont été si rares , et il n' est que les indigènes , le visage . \non pourrait leur répondre par une contre-question : \ncomme beaucoup d' hommes , dans cette île la grande-bretagne ( ou en suisse ! ) ont déjà un dachs ( en liberté ) gesehen ? \ndans les vastes solitudes inexplorées de l' hima , les d' observer sans être . \nbien que la plupart des yeti-berichte par les indigènes , y est sans doute , que cette là de vie et de plus de possibilités , ont un yeti réprouvés , comme la main de européens , avec les buts record , le plus souvent en outre dans la saison chaude , si au-dessus de la limite des neiges , et , quand il y a beaucoup de ravitaillement . \nde ce côté , c' est très remarquable , que la limite des neiges , en 1955 , au loin , exceptionnellement ancestrale place . \nnous devons même notre d' origine le forschungsgebiet , la ligne de partage des eaux du shigri glacier , et nous nous abandonner avec le ( est ) kulti himal . \nwladimir tschernezky , le peut-être que la notion de ,yeti ' scientifiques , a été étudiée , verglich cette mystérieuse vivants avec le maintenant ausgestorbenen gigantopithecus . \nc' est peut-être un homme pense plutôt comme un ,yéti ' . \nles , qui les indigènes , surtout les sherpas , en face du yeti ressentons est due à ses instincts pillards et à son intelligence . \ntschernezky a confirmé , de même que nos kulti-spuren une très grande ressemblance avec les années précédentes , authentischen récits de photos et d' ascensions ... \n» le l.w.davies , le fliegeroffizier courageuses , le « juron s' échappait de la lächerlichkeit » n' a pas . \ndeux bonnes , très significatives . \npersonnellement , je suis après comme avant l' avis que , avec le cri « ours ! \n» et , avec quelques remarques ironiques le « schneemenschen-problem » ne sera pas résolue . \nvoir aussi ralph izzard : \nthe abominable snowman adventure , london : \n&amp; hodder and stoughton 1955 ) . \n13. l' année 1955 , est aussi les « ) , sous la hamish mcarthur dans . \ncomme le rapport ( « the alpine journal , n° 293 , p. 279-295 ) montre , ne fut pas seulement les grimpeurs , mais aussi un . \n... magnifiquement panoramas , jolie photos , une très granitiques kammverlauf-karte et une bibliographie de 55 numéros portent très nettement à la connaissance de ce jusqu' à un peu stiefmütterlich traitaient la région . \nl' altitude des montagnes se tiennent entre 5800 et 6300 m. ce sont donc pour himalaya-verhältnisse assez modeste des montagnes , pas überalpin , mais simplement alpin , mais paysage attrayant et , en partie , encore peu connu - un bon champ d' activité pour klein-expeditionen , les pas beaucoup de temps et d' argent . \n14. appliquer à la géologiques , particulièrement intéressante région voisine du spiti , les « par l' expédition de cambridge fossiles . \nau-dessus , le rapporte trevor braham ( « the alpine journal , n° 293 , . \n296-309 ) . \nle résultat de deux petits six mille de et de nombreuses traversées de cols . \n15 15. du karakorum le groupe du sasir kangri ( 7672 m ) , dans la grande boucle du fleuve shayok , constitue l' aile sud-est . \nce massif d' la première expédition du couple visser-hooft en 1922 . \naprès une longue pause - 1946 - , une expédition britannique conduite par j. o. m. roberts leur chance , mais si peu de succès , bien que tous les candidats au karakorum se désistèrent . \ncomme le sasir kangri se trouve dans la partie indienne du cachemire , il était pour le « himalayan mountaineering institute de darjiling un intérêt particulier . \nsous la conduite du montagnard expérimenté qu' n.d. major jayal aurait une nouvelle tentative fut faite en 1956 , mais cette fois , c' est en vain . \nles détails ne sont pas encore connu ; \nquoi qu' il en soit , mais fut annoncé que jayal aurait déclaré cette montagne . \nbien qu' encore pas un huit mille , c' est certainement un dur morceau . \n16. un des sommets les plus hardis du karakorum est la baltoro-gletschers située sur le versant nord de la tour de muztagh ( 7273 m ) . \npour la plupart , de la célèbre photo rapportée par vittorio sella en 1909 , il s' agissait cette presque als symbole , comme verkörperung du marche . \nmais j' ai déjà 1939 dans mon « baltoro ( bâle : \nbenno schwabe , basel ) sur s.66/67 écrit : \n« quand on la regarde du glacier supérieur de baltoro , il est presque , mesurés à une ascension auch nur songer . \nbei à la considérer de plus près , mais se montre , à mon avis , une chance : \nles parois , il est vrai , sans espoir . \nl' arête se , qui porte le ,blacktooth ' , n' est pas encourageante . \nmais le west- ou , plus exactement w.nw - est peut-être possible . \nle col au pied de l' arête w du chagaran-gletscher il faudrait chercher à atteindre . \n» exactement sur cette route , j' ai jadis , fut proposé de la tour de muztagh maintenant par une expédition britannique , sous la conduite de j.hartog submerge , et même de deux cordées les 6 et 7 juillet 1956 . \nles erfolgreichen bergsteiger étaient : \nhartog , j. brown et i. mcnaugh-davis . \ndu dernier camp ( 6400 m ) , ils ont atteint le sommet par l' arête ouest ; \nles deux cordées durent bivouaquer à la descente , ce qui valut à hartog de graves gelures . \n17. si incroyable que cela sonne , quelques jours plus tard , la tour de muztagh fut de nouveau gravi , et par le plus difficile encore l' arête sud-est par une expédition française . \nle chef en était guido magnone , dont le nom de avec la paroi ouest des drus , le cerro fitz roy , le makalu et de nombreux autres de la plus grande et plus difficiles ascensions verknüpft est . \nles autres participants étaient : \nandré contamine , paul keller , robert paragot et le médecin françois florence , comme officier de liaison pakistanais cwpt.ali .usman . \nle 31 mai , on était dans d' askole , le 2 juin , il aurait à bardumal ( « bagdomal » ) , presque une catastrophe , comme une puissante appels tout le camp de la terre , le 5 juin fut atteint à urdokas . \nc' est là que magnone apprit que l' expédition britannique , la meilleure équipe qu' on pût mettre sur nos jambes , se trouvait dans la tour de muztagh terminés , et déjà , avait une avance considérable . \ndepuis deux semaines , les anglais , les au-dessus de mustagh- et chagaran-gletscher étaient montés en tentative à l' arête ouest , et ils étaient déjà très haut sur la montagne . \npour les français une délicate situation : \nla voie des anglais suivre , n' entrait en ligne de compte . \non voulait , les en ces si loin en avant , dass sie que de toutes façons , sur le sommet . \nles français ne pas cher un autre but bergsteigerisches au glacier supérieur de baltoro ? \nmais on ne daraufwar préparé , et les porteurs avaient aussi , en revanche , pas assez de vivres . \nfinalement , on était oui , cette fois-ci dazu ausgezogen , techniquement difficile de problèmes . \nil fut donc décidé , les autres faces de la tour , aller s' il sur l' arête nord , ou peut-être , sur le versant sud , une voie possible . \nle mauvais temps et une grève des porteurs - combien d' expéditions ont eu de graves ennuis avec les baltis ! \n- retardèrent l' expédition de quelques jours . \nce n' est que le 12 juin , le camp de base fut installé à 4500 m environ , sur le moyen younghusband-gletscher ( aussi biange-gletscher genannt ) , où se trouve la branche orientale et le occidental réunissent , donc au pied de l' arête sud-est du « noires dent » ( 6719 m ) . \nnun commencèrent les reconnaissances : \nla première excursion les conduisit par la branche orientale au point le plus bas ( 5600 m environ ) , entre le mont steste et la tour de muztagh , donc au pied de sa prétendue » . \nquelle déception ! \nil n' y a pas d' arête , n' est qu' une au moins 1600 m de hauteur , effroyablement raide , balayée par les avalanches , la plus pure . \nretour donc au camp de base . \nle 17 juin , on réussit à travers les 900 m de la chute de seracs du glacier ouest , donc sur le versant sud du black tooth » , de trouver un passage , et fut commencé immédiatement , le câble de 300 m , dans la partie inférieure de la séraczone zu tendons et une il sur un nez rocheux au-dessus du glacier , que là ... il neigeait pendant dix jours . \nle seul ce qu' on put , était une visite à la « concurrence » sur l' autre versant de la montagne , pour la verstimmung par une large de prononciations se . \nanglais et français se séparèrent en bons camarades . \nenfin , le ciel s' éclaircit , avec toutes les forces , on fit à l' œuvre , aussi les hunza-träger taten leur splendide , et à la fin de juin le camp 1 ( 5100 m ) , le 2 juillet le camp 2 ( 5400 m ) . \nle camp 3 ( 6000 m ) dut sur l' éperon rocheux , la du black tooth » . \ncette distance entre le camp 2 et 3 était un böses morceau , à droite , malgré 400 m de cordes fixes , environ si difficile que la face nord des courtes , sur la rive gauche de la menace des . \nle allerschlimmste mais était la « grande pyramide au-dessus du camp 3 , un ressaut rocheux vertical , une épaisse couche de glace de 200 m auflag , et cette paroi a barré la voie d' accès au sommet dans toute sa largeur . \nil y avait là qu' une seule possibilité de durchkommens , tout à droite , et la descente est faite d' une terriblement raide hohlkehle . \nplusieurs jours de besogne acharnée et 300 m de cordes fixes . \nce n' est qu' au matin du 6 juillet , c' était si loin : \nils se dressaient , au-dessus de la paroi de glace , sur un petit glacier suspendu . \nle dr florence , le bergtüchtige médecin de l' expédition , et les deux meilleurs hunzas , aminula et gerikhan , les jusqu' ici des nôtres waren und wacker est hatten , demi-tour , et en arrière , ne restèrent que les quatre alpinistes de la cordée . \ndans brütender chaleur , ils battîmes avec neige farineuse où la neige profonde , de la place pour le camp 4 ( 6300 m ) . \nau-dessus d' eux se dressait la tour encore de 1000 mètres de haut , dans une raideur telle qu' elle fait hocher la tête . \nla seule voie , était l' arête sud-est . \nle 7 juillet , robert paragot tout à coup deux petits , qui se là-haut vers le ciel abzeichneten : \nles britanniques arrivaient au sommet . \nles français et ne se laissèrent pas décourager . \nen avant ! \nle fil de l' arête sud-est , est extrêmement difficile . \nles deux premières longueurs de corde au-dessus de la rimaye - le 7 juillet - hatten heures d' efforts , 250 mètres de dénivellation , requirent deux jours . \nsix heures de cramponnage à la limite de l' équilibre , des dalles verglacées surmontées à l' , ils purent enfin dans une brèche de l' arête . \nce fut certainement une des plus dures escalades qu' on ait faites jusqu' ici dans l' himalaya et à cette altitude . \na midi , le soleil disparaissait derrière nuages épais . \nsur l' arête , suivit une brèche profonde de l' autre , il fit aussi lentement , dass sie , à 16 heures , ce n' est que cent mètres dans le hori- zontale avaient pu , maintenant , il commence à neiger encore , donc ... retour au camp 4 ! \ntout ce qui leur encore de cordes , était resté , fut pour la descente dans la paroi . \ndeux jours , ils durent attendre maintenant dans la tente . \nle soir du 10 juillet , le ciel s' éclaircit , et le 11 juillet , le matin , ils commencèrent à l' attaque . \ngrâce aux cordes ging es jusqu' à la brèche de l' arête très flott , mais quand ils nouvelles traces , ils durent enfoncions jusqu' au milieu des cuisses un . \ndes tours sperrten verticale , le chemin . \nà gauche , des dalles , à droite , la neige et corniches au-dessus de la younghusband-gletscher . \na 16 heures , ils étaient au pied de la troisième et dernière grande tour , et derrière lui parut - il semble à portée de main , le sommet , mais , en vérité , ils n' avaient pas encore de la 6900-m-linie traversé . \nil était temps , une place de bivouac , deux étroites banquettes , où il . \nla vue du k2 par le broad peak , les gasherbrums et hidden peak , jusqu' à l' arrogant masherbrum , mais il fut , en passant nuit . \nle 12 juillet - c' est dans un ciel où rampent des , il faut se hâter . \nmais derrière le grand gendarme , la neige mou , aucun de toute la cordée a relais sûr , la trace devient un fossé profond , l' homme à la pointe se furette 30 , ou tout au plus de 40 mètres de montée , puis , sans dire un mot , et , à côté de nous , le lendemain pour faire place à . \nenfin , à 13 heures ... le sommet , si étroit qu' on peut à peine , et , après quelques instants croisements , la descente , car , depuis une demi-heure , il a déjà ! \nla descente est une course contre la nuit , mais en vain : \nquand ils sont dans la brèche , il est déjà complètement nuit . \nils se un rappel de 50 m pour atteindre les cordes fixes . \na tâtons , sous des rafales de neige épaisse , ils se travaux . \nils sont maintenant sous la rimaye , le dr florence . \nenfin , . . . \nle camp 4 ! \nlorsque , le 19 juillet sur les baltoro-gletscher , ils furent par le dr patey , le médecin de l' expédition anglaise , salue , le l' aide de son collègue français , à la manière de hartog demanda . \nles gelures aux pieds du chef de l' expédition britannique les anglais attendaient depuis quelques jours à urdokas . \nde cette magnifique emplacement , déjà pour autant de baltoro-unternehmungen a joué un grand rôle , maintenant assis , les membres des deux « konkurrenz»-expeditionen dans toute l' amitié à un festlichen repas et s' etaient du double succès obtenu sur l' un des plus beaux et des plus difficiles himalaya-berge . \nréférences : \nguido magnone : \nla tour de mustagh . \n« la montagne » , octobre 1956 , p. 261-270 . ) \n18. dans mon livre baltoro ( 1939 , j' avais une tentative du gasherbrum ii ( 8035 m ) chaudement recommandé . \ndans le « der dritte pol » ( 1952 ) : \n« le gasherbrum ii n' est pas facile , mais probablement possible et relativement sûr . \nje n' aurais sur l' expédition internationale de 1934 avait eu de bons porteurs d' altitude ; \npuis j' aurais sérieusement . \n» le prenait la österreichische himalaya-gesellschaft » à vienne à cœur et en 1956 , une baltoro-expedition avec ce but . \nl' équipe de six alpinistes et deux deux : \nfritz sepp larch , hans ratay ( photographe ) , richard reìnagl , heinrich roiss et hans willenpart .comme médecin le dr georg weiler , le dr erich traugott gattinger comme géologue . \nsur la base des expériences faites dans un camp d' entraînement , on choisit reform-ernährung , ce qui le poids des bagages . \nla prise dans le pakistan était très simples , mais malgré tous de solidarité des autorités , les autrichiens durent attendre neuf jours à rawalpindi , jusqu' à ce que le temps de leur vol avec le ge^ leurs bagages de skardu gestattete ; \ncar ce paysage unique vol juste au nanga parbat et par l' étroite industal est considéré comme l' une des plus dangereux luftrouten überhaupt et ne peut qu' à une proprete vue hasardeuse . \nc' est pourquoi skardu , la capitale du baltistan , ce n' est que le 27 avril . \nquain ali shah , les charges sur 27 kg . \nles tarifs des porteurs ont fortement augmenté aussi au pakistan . \ndans les régions habitées , reçoit un « 3 roupies ( 2 fr .70 ) par jour et de pourvoir lui-même à son entretien . \nau-dessus d' askole ( 3050 m ) , le salaire journalier monte à 4 roupies ( 3 fr .60 ) , et la nourriture des charges à l' expédition . \nde skardu à askolé les autrichiens utilisèrent 168 coulies et , de là , à cause des vivres 263 hommes . \na païju , la dernière oasis avant le baltoro-gletscher , les porteurs réussirent , les souliers que le règlement . \non avait 250 paires , mais malheureusement la voie normale , d. h. européenne forme . \nj' ai déjà souvent , signalons que pour les porteurs himalayens il faut principalement des pointures 42-44 ( que quelques numéros 41 et 45 ) , mais très larges ! \nle est malheureusement toujours , ce qui conduit de grands désagréments . \nle oberleder ( les steifkappe ) dut être aufgeschlitzt , afin que les pauvres types puissent y introduire leurs pieds ( non défigurés par des chaussures européennes , large de ! ) . \nbien sûr , il y eut de pieds blessés , et le médecin de l' expédition passait des heures à panser les écorchures blut- et les ampoules . \nà urdokas ( 4057 m ) , il y eut la grève habituelle , de l' baltoro-expedition n' a pas encore est resté , mais par le energische intervention de l' officier de liaison , bientôt de nouveau les choses en ordre . \ntoutefois 68 charges durent sous la garde du second assistant pakistanais , l' étudiant hayat ali shah , d' abord à urdokas . \nle gros de la troupe monta en trois étapes à la célèbre concordia-platz concorde , dans une tempête de neige . \nmaintenant , la plupart des « il ne tiennent plus , et la plupart abandonnèrent pour rentrer dans leur village . \n68 hommes , après de longues tractations prêts , les colis du dépôt d' urdokas à concordia . \nentre-temps , les autrichiens , pendelten avec onze balti-hochträgern ( « balti-tiger » ) à leurs charges plus à la place , où mes « i. h. e. » ( expedition internationale ä l' hi ) 1934 leur camp de base ( camp 4 ) avait eu , donc au pied du versant sud du gasherbrum vi ( 7190 m ) , à la talecke , où la « abruzzi glacier » au baltoro proprement dit . \npour les autrichiens , c' était un seul camp intermédiaire , parce qu' elle leur base oui à l' influence du « glacier sud » dans les « abruzzi-gletscher » , il fallut établissons , environ là où , en 1934 , le camp 5a ( 5250 m ) , la i.h.e , sur la moraine , avait posé . \nle 25 mai , les premiers grimpeurs et porteurs là un . \naprès une akklimatisierungsperiode seulement , un chemin à travers les très zerrissenen « gasherbrum-gletscher »zum pied sud du gasherbrum ii reconnue . \ndans la partie supérieure de la traction de deux gratrippen par le steilwandgürtel à la grande terrasse du gasherbrum ii . \nj' avais l' éperon se rocheuse , à droite , en recommandé , parce qu' il est tout à fait à l' abri des avalanches . \nles autrichiens cependant se décidèrent pour l' éperon sudouest probablement un peu plus facile , et à son pied , à environ 6000 m de leur camp i. , le 11 juin , les premières charges hingeschafft , le 13 , 15 et 17 juin était le pendelverkehr en pleine mue . \npuis , retint , avec de fortes chutes de neige , les alpinistes au camp de base . \nce n' est que le 30 juin , ils purent de nouveau au camp i et constatèrent , à leur extrême consternation que , entre-temps , une énorme avalanche presque tous les matériel déposé là . \nils avaient le place pour cru : \nebener glacier - et les pentes darüber étaient en terrasses . \nmais la grande himalaya-lawinen courir eben de vastes étendues même sur un terrain plat . \nil suffit de rappeler ici la catastrophe de 1937 au nanga parbat , les 16 morts . \ncette fois , il avait heureusement - car le camp n' était occupé -keine coûté tant de personnes , mais une grande partie des principaux d' équipement et de vivres , lag cinq à dix mètres de profondeur , sous une avalanche . \ndeux jours durant , tranchées et des puits ausgehoben , pour un peu moins par les unersetzlichen tentes , de cordes , de la « ferraille » , vivres , etc. montagnes , mais toutes les peines , c' est en vain . \nque faire ? \nsi l' on ne voulait pas s' avouer battu , on dut tout le programme et accepter les risques d' une campagne-éclair : \nratay et roiss , le 2 juillet la tranche entre le camp i ( 6000 m ) et le camp ii ( 6700 m ) , et beaucoup stufenarbeit praticable à était et de cordes fixes . \nle 3 juillet , larch et reìnagl vers le camp ii et le 4 juillet une trace de la haute montagne , jusqu' à une épaule , la place pour le camp iii ( 7150 m ) . \ncette ascension était pour les quatre porteurs d' altitude , les le 6 juillet supplémentaires furent ici , une rude travail , mais les balti-tiger se tenaient très courageuse et - transportées par leurs sahibs bien assuré - leurs lourdes charges jusqu' à l' épaule . \nmais ils étaient alors très abattus . \nla pente suivante , très raide et avait une édition de neige poudreuse . \nici aussi , pour utiliser les porteurs , si la pente dans vieltägiger soigneusement rangée de travail , et , en revanche , pas le temps . \nles grimpeurs durent donc ici , de leurs charges nous-mêmes porter , ce qui fut à l' origine , la suppression du camp iv à renoncer et d' un bivouac élevé à l' assaut de la voiture . \nle 6 juillet , tandis que reinagl assurait la descente des porteurs , morawec , chef de l' expédition , larch et willenpart avec de lourdes , entamaient la montée . \nla couche de neige sur la glace rendait tout assurage illusoire ; \nc' est pourquoi ils passèrent seilfrei , pour se gêner réciproquement . \na 20 h. 30 ils étaient à 7500 m environ , au pied de la pyramide sommitale et se installâmes sous un bloc de rocher pour la nuit . \nchacun se glissa dans son dralon-schlafsack facile ; \nils disposaient en outre d' un . \nce fut une nuit froide féroce , si bien qu' il trop léger de gelures , larch , sur les orteils , morawec au mains . \nenfin , il fut clair . \ndu lait chaud et un peu de weizenkeimbrot mussten que de vivres pour toute la journée . \nune traversée en écharpe sous la paroi sud-est du gasherbrum ii beaucoup de peine . \nce n' est que peu avant 9 heures quand ils atteignirent une petite brèche ( 7700 m environ . \nc' est la chaîne entre le baltoro et le shaksgam , et la ligne de partage des eaux entre l' indus et le tarim , l' océan indien et les de l' asie centrale . \nencore 335 m jusqu' au sommet . \ndans la paroi de glace très raide , la neige était par les rayons du soleil matinal , déjà ramolli la trace un terrible strapaze . \ntous les quelques pas , ils durent se reposer , et après l' air de lutte . \ninferieurs , ils luttaient s' , mètre par mètre . \nle dernier obstacle fut un ressaut rocheux et - le 7 juillet , à 13 h. 30 , ils foulèrent le sommet du gasherbrum ii ( 8035 m ) , un petit une , le de deux à peine mannshohen est couronné de pointes . \nils s' affalèrent épuisés dans la neige . \nce n' est qu' après un certain temps , ils furent en les rites obligés du culte des sommets : \npiolet avec le österreichischen et le pakistanais , des banderoles , la construction d' un steinmanns , ersteigungsdaten dans une cartouche de vides , muttergottes-medaillon , etc. c' était si chaud , qu' ils purent même l' anorak ôter et , une heure au sommet . \nle temps était radieux beau , la vue claire jusque dans le lointain . \nla descente s' est déroulée lisse , et bien qu' il se mit à neiger de nouveau le soir , ils étaient a 19.30 h. dans le camp iii ( 7150 m ) . \nle jour suivant , au camp ii , ils furent par le porteur salue avec enthousiasme et de la tempete . \nil est très réjouissant , dass es maintenant - sauf le fameux sherpas et de la partie raison bons hunzas - aussi sous les baltis , les hommes se développer authentique alpinistes et « krischauff à une promesse . \nle gasherbrum ii est le troisième huit mille , les autrichiens inscrivent à leur tableau : \nmassif du nanga parbat , cho oyu , gasherbrum . \ncette bewunderungswürdige succès console la österreichische himalaya-gesellschaft » à vienne on espère qu' un peu au-dessus d' une amère déception : \ndouze jours après l' escalade du gasherbrum n , donc le 19 juillet 1956 , trois membres de la « expédition autrichienne himalaya-karakorum 1956 » - hans ratay , heinrich roiss et le dr georg weiler - la deuxième ascension du sia-kangri-westgipfels ( ca.7315 m ) . \nla première ascension fut le 3 août 1934 quatre membres de la « internationale himalaya-expedition 1934 » ont réussi à - hans erti , albert höcht , mme hettie dyhrenfurth et g.o.dyhrenfurth . \nc' était la connaissances , en deux livres ( voir en bas ) et dans la littérature alpine , souvent besprochene course sur la un « record féminin d' altitude » . \nje nos nachfolgern - après 22 ans - volontiers leur succès nous féliciter cordialement , mais ... ils ont malheureusement cru , la première ascension d' un encore tout à fait inconnu et de 7729 m de la montagne , ils ont ce sommet « austria-peak » et dans la « österreichischen touristenzeitung » de janvier 1957 aussi toutes sortes d' erreurs , sinon publiées , dont sachliche rectification inévitable est : \n( 1 ) comme est la cote exactement les traînées qui troublaient échange de 7729 m ? \npar une ( d' ailleurs pas tout à fait korrekte ) umrechnung de 25 350 pieds . \nla cote , les depuis 1917 sur tous les karakorum-karten steht , mais est 24 350 ft . \n= 7422 m , et c' est justement la cote chiffre officiel du « queen mary peak » qui , depuis 1938 officiellement sia kangri . \n( 2 ) la cote 7422 m sur les trigonométriquement par le topographe c. grant peterkin ( expédition bullock-workman 1912 ) et se probablement sur le sommet principal du rapporte . \nles « expédition internationale de 1934 » a pour tous les quatre . \nle sommet ouest est bien 100 m plus bas que le sommet principal , soit 7315 m. c' est le point culminant , que les autrichiens ont atteint lors de leur deuxième ascension . \n( 3 ) une depuis des décennies , se bestiegener et de la « karakoram conference » officiellement sia kangri benannter montagne , naturellement , ne doit pas sans raison umgetauft soudain . \nle nom de « austria-peak » est donc de nouveau tout d' assu sec - même si staatspräsident iskander mirza , à raison de ces conditions tout irriger fêtait genehmigt a ( 4 ) la large selle entre le baltoro kangri ( auparavant « golden throne » , 7312 m ) et le sia kangri est le depuis une demi-heure de siècle bien conway saddle ( 6300 m ) , le de l' expédition composée italien ( duc de spoleto , le professeur desio ) 1929 visité à plusieurs reprises et ont été mesurés , c' est la « expédition internationale de 1934 » avait en conway-sattel même pendant leur oberes camp , et elle a oui , de là , tous les sommets du sia kangri et l' arête sud-est du baltoro kangri . \nc' est vraiment cela me rappelle quelque chose , si maintenant de 1956 , trois touristes qui , de tout le n' a aucune idée de descendre , comme première , ce col foulé zu haben . \nau surplus , naturellement , est le ! \nd' ailleurs , c' est le conway-sattel pas entre le baltoro et le siachen , mais entre le baltoro et kondus-gletscher . \nc' est le fleuve de glace , sur les on par le col . \nla siachen-gletscher est situé plus à l' est , comme il est . \nnouvelle est seulement que les autrichiens pas les de la « expédition internationale de 1934 » répété répétée et relativement sûre « mittelrippe » utilisée haben , mais probablement à gauche de notre route à travers la paroi abrupte et sur plusieurs de la haute montagne sommes montés , donc une nouvelle , dangereuse variante sur les sia-kangri-westgipfel ont fait . \nbei aller reconnaissance de cette performance reste complète de la valeur de l' ignorance de littérature correspondante . \nréférences : \ng.o.dyhrenfurth : \ndémon de l' himalaya » ( bâle : \nbenno schwabe , basel 1935 ) . \n- g.o.dyhrenfurth : \nbaltoro ( ibidem 1939 ) . \n- heinrich roiss : \n- première ascension des austria peak m ) 7729 m. oesterr. touristenzeitung , 70. année , folge 1 , vienne , dans jänner 1957 ) . \n19. le rakaposhi ( = « drachenschwanz » ) ( 7788 m ) , situé non loin de gilgit , le un aérodrome a de bonnes verkehrslage , c' est tout ce que la splendide montagne à la limite du hunzalandes déjà attaqué fut si souvent , qu' aucun autre 7000 m , mais toujours jusqu' en vain . \nen 1956 , une expédition anglo-américaine sous la conduite du capt . \nm.e.b.banks de nouveau , mais seulement jusqu' à environ 7000 m. le rakaposhi n' est pas facile , et le temps semble tout particulièrement mauvais . \n20. le mustagh ata ( = « père » ) ( 7433 m ) est une coupole en chinoise du pamir . \naprès les stériles tentatives de sven hedin - qui n' était - en 1894 , on hess de ces facile « 7000 » fut laissé longtemps en repos . \nce n' est qu' en 1947 , se tournèrent vers e.e.shipton et h. w.tilman sur la gipfel-kalotte , mais pas jusqu' au , encore très éloigné horizontalement -höchsten point . \nle , le 26 juillet 1956 par une grande expédition sino-soviétique sous la direction de m.beletski .cinq camps furent installés , le dernier à 7200 m. \n21. au nord du mustagh ata , aussi , le ostrande du pamir , se trouve le kongur debe ( 7681 m ) , de loin et large de la plus haute montagne qui , fortement massif aires de himalaya-charakter , se prolonge beaucoup plus difficile que son débonnaire voisin . \nle 19 août 1956 , il fut de six russes et deux chinois , les moyens techniques de l' alpinisme moderne - aussi à l' oxygène . \npas encore de récit circonstancié . \n22. nous les domaines de l' himalaya et du karakorum avons déjà quitté , de toute façon , nous jetons encore un coup d' oeil sur les plus hautes montagnes de l' urss : \npic de pics lénine ( autrefois pic kaufmann ) , 7134 m , première ascension en 1928 par e. schneider et k.wien ;souvent visités depuis par les alpinistes soviétiques . \nkhan tengri ( prince des esprits ) , 6995 m , d' après la , faites donc un sept mille , de plus en tien-schan ( montscélestes ) . \npremière ascension 1931 par m.t.pogre-bezki , f. sauberer et b.tjurin depuis , si en 1936 par le bâlois lorenz saladin . \npik stalin ( ancien garmo ) , 7495 m , dans l' alaï pamir . \npremière ascension en 1933 par e. m. abalakow . \nabalakow depuis visiteurs . \nsouvent visité depuis .pik korzhenewskaya , 7105 m , dans l' alaï pamir , à 15 km du pik stalin , a été gravi qu' en 1953 . \nle point culminant du tien-schan et apparemment la deuxième montagne de l' urss est pik pobjeda ( ) , 7439 m , découvert et mesuré en 1943 seulement . \ncette pour nous occidentaux quelque peu mystérieuse , est encore intacte ; \nles premières grand' n' ont jusqu' à une altitude de 7000 m. environ . \nréférences : ? \n, . \nbibliographie : \nmountaineeringintheü.s.s.r.«the alpine journal , n° 293 ( nov . \nen 1956 , p. 310-329 ) . \nconsidérons encore une fois la liste et l' état actuel des « 8000 » . \nont été gravis jusqu' à ce jour : \n1. 1950 : \nl' annapurna i , 8078 m. chef d' expédition m.herzog ;équipe du sommet m.herzog et l.lachenal . \n2. 1953 : \nmount everest , 8848 m , chef j. hunt ;équipe du sommet e. p. hillary et tensing norkay . \n3. nanga parbat , 8125 m. chef k.herrligkoffer ;h.buhl a atteint le sommet en solitaire . \n4. 1954 : \nk2 , 8611 m , chef a. desio ;équipe du sommet a.compagnoni et l.lacedelli . \n5. cho oyu , 8189 m ( ? ) , chef h.tichy , un sommet h.tichy , s.jöchler et pasang dawa lama . \n6. 1955 : \nmakalu , 8481 m. chef j. franco , cordées du sommet l.terray-j.couzy , j.franco- g. magnone-gyalzen norbu , j.bouvier-s.coupé-p.leroux-a . \nvialatte . \n7. kangchenjunga , environ 8597 m. chef ch . \nevans , g. band-j cordées du sommet . \nbrown , n. hardie-t . \nstreather . \n8. 1956 : \nle lhotse , environ 8510 m. chef a.eggler ;équipe du sommet e. reiss-f . \nluchsinger , ensuite le mont everest , j. marmet-e cordées du sommet . \nschmied , h.von gunten-a . \nreist . \n9. manaslu , 8125 m. chef y. maki , cordées du sommet imanishi-gyalzen , kato-higeta . \n10. gasherbrum ii , 8035 m. chef f.morawec ;équipe du sommet h. larch-f . \n« da waren's encore quatre » de huit mille encore vierges , c' est le dhaulagiri ( 8222 m ) , dans le népal , shisha pangma ou gosainthan ( 8013 m ) , dans le tibet , hidden peak ( 8068 m ) et broadpeak ( 8047 m ) dans le karakorum pakistanais ( baltoro-gebiet ) . \nshisha pangma se dresse derrière le « outre « rideau de fer » , et elle doit donc encore quelques temps de rester vierge , mais sur les trois autres a depuis longtemps déjà , un énorme assaut dans le domaine de la politique - c' est pour obtenir une autorisation pour 1957 , schlimmstenfalls pour 1958 . \n« je de cœur , que cette « marché des huit mille » baldigst terminée sein möge , damit nationale et persönlicher ambition abklingen peu à peu , pour le bien-être authentique bergsteigertums et calme de travail scientifique ! \n« un politique - vilaine chanson ! \n- fi donc ! \nune chanson politique ! \n» les nouvelles prescriptions du gouvernement népalais pour les expéditions étrangères - de kathmandou - scrupuleusement traduites , disent ceci : \n1. les expéditions ont un officier de liaison népalais , qui leur sera attribué par le gouvernement du népal . \n2. l' officier de l' expédition payera roupies ( = 180 francs suisses ) . \nen outre , il est assurera et avec nos sacs de couchage et de tous les autres tout l' équipe pendant la expeditionsdauer . \n3. l' expédition a tous les frais de voyage de l' officier de liaison , à partir de kathmandou et . \n4. l' expédition a leur activité exclusivement sur la montagne ou à la région , pour les ils l' autorisation par le gouvernement du népal . \n5. le gouvernement népalais peut en retirer , si elle se croit que le comportement ou de l' activité de l' expédition sont indésirables . \n6. a son retour , l' expédition le gouvernement du népal un rapport exact sur son activité . \n7. l' expédition a un plan précis , à unterbreiten qui , à l' intérieur de la voie du népal , doit être parcourue . \nces elle s' en tiendra strictement , lors de la marche d' approche et de tenir . \n8 expéditions d' emporter des appareils de transmission , armes , munitions , il est interdit , que le gouvernement du népal pour but une des . \n9. l' expédition doit , ce qui ne rien faire ou permettre aux sentiments religieux et les mœurs et usages des populations autochtones pourrait blesser . \n10. en cas d' accident , l' expédition au blessé ou de la famille du défunt une indemnité proportionnelle aux circonstances comme les conditions sont . \nles isotopes d' une lebensversicherung est en préparation . \nentre-temps , diene que norm que , pour un officier de 5000.- , pour un porteur roupies népalaises . \n11. tout ce qui , au cours de l' expédition fut recueilli , est le gouvernement du népal , doit avant que l' expédition soit autorisée à quitter le pays . \ncopies de toutes les photographies prises au cours de l' expédition doivent être soumises au gouvernement , avant que quelque chose ne soit . \n12. autorisation pour une expédition au gouvernement , une abgabe de 500 à 3000 roupies indiennes ( soit jusqu' à 2700 francs suisses ) . \n13 les nouvelles sur l' activité de l' expédition ( par exemple succès , échecs , accidents , etc. ) ne peuvent bénéficier du copyright . \nseuls sont libres les renseignements personnels . \ntout est le gouvernement du népal , doit quelque part , avant qu' il ne soit . \n14. toutes les demandes d' autorisation pour une expédition dans l' himalaya népalais sont , par le gouvernement du antragstellers confirmer et le gouvernement du népal . \nces nouvelles prescriptions sont déjà en vigueur . \nil fut même annoncé qu' une zone de 50 milles ( 76 km ) , le long de la frontière tibéto-népalaise , sur le versant népalais devait être fermée . \ncette « zone interdite » inclurait presque le népalaises et pratiquement chaque du népal ausgehende himalaya-expedition sinnlos machen . \ncette nouvelle alarmierende n' est pourtant pas encore confirmée et probablement pas très zutreffend , car le gouvernement du népal est à la « fremden-industrie » , ce qui nous intéresse et ne sait très exactement que chaque himalaya-expedition une masse de l' argent et sachwerte dans le pays . \ntoujours est-il que les nouvelles conditions , qui ont été attestées à plusieurs reprises , très dures . \nles articles 11 et 13 articles se révèle être un lourd sabot . \nle chef de l' expédition , peut-être pleinement responsables des milliers de vu de photographies ( schwarzweiss et en couleurs ) et de nombreux filmrollen ( illustration et de ton ) , de kathmandu , et plus par les autorités , zensurieren jusqu' à sa ausreise du népal gnädigst l' ? \nil n' est pas jedermanns sache , irréalisable en fait à signer . \n« corde trop tendue casse . \n» après la première ascension du dhaulagiri , du dernier achttausenders népalais , le karakorum fortement dans le dos , et le gouvernement de rotchinesischen - et aussi par des indiens sei - n' a pas si bien expédition dans les dernières années , de compréhension et de solidarité . \n"
  },
  {
    "path": "tests/inputs/issues/183/file.fth",
    "content": "\\ https://github.com/philburk/pforth/fth/file.fth\n\\ READ-LINE and WRITE-LINE\n\\\n\\ This code is part of pForth.\n\\\n\\ The pForth software code is dedicated to the public domain,\n\\ and any third party may reproduce, distribute and modify\n\\ the pForth software code or any derivative works thereof\n\\ without any compensation or license.  The pForth software\n\\ code is provided on an \"as is\" basis without any warranty\n\\ of any kind, including, without limitation, the implied\n\\ warranties of merchantability and fitness for a particular\n\\ purpose and their equivalents under the laws of any jurisdiction.\n\nprivate{\n\n10 constant \\N\n13 constant \\R\n\n\\ Unread one char from file FILEID.\n: UNREAD { fileid -- ior }\n    fileid file-position          ( ud ior )\n    ?dup\n    IF   nip nip \\ IO error\n    ELSE 1 s>d d- fileid reposition-file\n    THEN\n;\n\n\\ Read the next available char from file FILEID and if it is a \\n then\n\\ skip it; otherwise unread it.  IOR is non-zero if an error occured.\n\\ C-ADDR is a buffer that can hold at least one char.\n: SKIP-\\N { c-addr fileid -- ior }\n    c-addr 1 fileid read-file     ( u ior )\n    ?dup\n    IF \\ Read error?\n        nip\n    ELSE                          ( u )\n        0=\n        IF \\ End of file?\n            0\n        ELSE\n            c-addr c@ \\n =        ( is-it-a-\\n? )\n            IF   0\n            ELSE fileid unread\n            THEN\n        THEN\n    THEN\n;\n\n\\ This is just s\\\" \\n\" but s\\\" isn't yet available.\ncreate (LINE-TERMINATOR) \\n c,\n: LINE-TERMINATOR ( -- c-addr u ) (line-terminator) 1 ;\n\n\\ Standard throw code\n\\ See: http://lars.nocrew.org/forth2012/exception.html#table:throw\n-72 constant THROW_RENAME_FILE\n\n\\ Copy the string C-ADDR/U1 to C-ADDR2 and append a NUL.\n: PLACE-CSTR  ( c-addr1 u1 c-addr2 -- )\n    2dup 2>r          ( c-addr1 u1 c-addr2 )  ( r: u1 c-addr2 )\n    swap cmove        ( ) ( r: u1 c-addr2 )\n    0 2r> + c!        ( )\n;\n\n: MULTI-LINE-COMMENT ( \"comment<rparen>\" -- )\n    BEGIN\n        >in @ ')' parse         ( >in c-addr len )\n        nip + >in @ =           ( delimiter-not-found? )\n    WHILE                       ( )\n        refill 0= IF EXIT THEN  ( )\n    REPEAT\n;\n\n}private\n\n\\ This treats \\n, \\r\\n, and \\r as line terminator.  Reading is done\n\\ one char at a time with READ-FILE hence READ-FILE should probably do\n\\ some form of buffering for good efficiency.\n: READ-LINE ( c-addr u1 fileid -- u2 flag ior )\n    { a u f }\n    u 0 ?DO\n        a i chars + 1 f read-file                                  ( u ior' )\n        ?dup IF nip i false rot UNLOOP EXIT THEN \\ Read error?     ( u )\n        0= IF i i 0<> 0 UNLOOP EXIT THEN         \\ End of file?    ( )\n        a i chars + c@\n        CASE\n            \\n OF i true 0 UNLOOP EXIT ENDOF\n            \\r OF\n                \\ Detect \\r\\n\n                a i chars + f skip-\\n                              ( ior )\n                ?dup IF i false rot UNLOOP EXIT THEN \\ IO Error?   ( )\n                i true 0 UNLOOP EXIT\n\t    ENDOF\n        ENDCASE\n    LOOP\n    \\ Line doesn't fit in buffer\n    u true 0\n;\n\n: WRITE-LINE ( c-addr u fileid -- ior )\n    { f }\n    f write-file                  ( ior )\n    ?dup\n    IF \\ IO error\n    ELSE line-terminator f write-file\n    THEN\n;\n\n: RENAME-FILE ( c-addr1 u1 c-addr2 u2 -- ior )\n    { a1 u1 a2 u2 | new }\n    \\ Convert the file-names to C-strings by copying them after HERE.\n    a1 u1 here place-cstr\n    here u1 1+ chars + to new\n    a2 u2 new place-cstr\n    here new (rename-file) 0=\n    IF 0\n    ELSE throw_rename_file\n    THEN\n;\n\n\\ A limit used to perform a sanity check on the size argument for\n\\ RESIZE-FILE.\n2variable RESIZE-FILE-LIMIT\n10000000 0 resize-file-limit 2!  \\ 10MB is somewhat arbitrarily chosen\n\n: RESIZE-FILE ( ud fileid -- ior )\n    -rot 2dup resize-file-limit 2@ d>             ( fileid ud big? )\n    IF\n        .\" Argument (\" 0 d.r .\" ) is larger then RESIZE-FILE-LIMIT.\" cr\n        .\" (You can increase RESIZE-FILE-LIMIT with 2!)\" cr\n        abort\n    ELSE\n        rot (resize-file)\n    THEN\n;\n\n: (  ( \"comment<rparen>\"  -- )\n    source-id\n    CASE\n        -1 OF postpone ( ENDOF\n        0  OF postpone ( ENDOF\n        \\ for input from files\n        multi-line-comment\n    ENDCASE\n; immediate\n\n\\ We basically try to open the file in read-only mode.  That seems to\n\\ be the best that we can do with ANSI C.  If we ever want to do\n\\ something more sophisticated, like calling access(2), we must create\n\\ a proper primitive.  (OTOH, portable programs can't assume much\n\\ about FILE-STATUS and non-portable programs could create a custom\n\\ function for access(2).)\n: FILE-STATUS ( c-addr u -- 0 ior )\n    r/o bin open-file           ( fileid ior1 )\n    ?dup\n    IF   nip 0 swap             ( 0 ior1 )\n    ELSE close-file 0 swap      ( 0 ior2 )\n    THEN\n;\n\nprivatize\n"
  },
  {
    "path": "tests/inputs/issues/245/complex_regular_subexpression.scala",
    "content": "portion of finagle-base-http/src/test/scala/com/twitter/finagle/http/codec/HttpDtabTest.scala\nfrom finagle-finagle-17.11.0.tar.gz used to trigger \nComplex regular subexpression recursion limit (32766) exceeded\n\npackage com.twitter.finagle.http.codec\n\nimport com.google.common.io.BaseEncoding\nimport com.twitter.finagle.http.{Message, Method, Request, Version}\nimport com.twitter.finagle.{Dentry, Dtab, Failure, NameTree}\nimport java.nio.charset.Charset\nimport org.scalatest.FunSuite\nimport org.scalatest.junit.AssertionsForJUnit\n\nclass HttpDtabTest extends FunSuite with AssertionsForJUnit {\n  val okDests = Vector(\"/$/inet/10.0.0.1/9000\", \"/foo/bar\", \"/\")\n  val okPrefixes = Vector(\"/foo\", \"/\", \"/foo/*/bar\")\n  val okDentries = for {\n    prefix <- okPrefixes\n    dest <- okDests\n  } yield Dentry(Dentry.Prefix.read(prefix), NameTree.read(dest))\n\n  val Utf8 = Charset.forName(\"UTF-8\")\n  val Base64 = BaseEncoding.base64()\n  private def b64Encode(v: String): String =\n    Base64.encode(v.getBytes(Utf8))\n\n  val okDtabs =\n    Dtab.empty +: (okDentries.permutations map (ds => Dtab(ds))).toIndexedSeq\n\n  def newMsg(): Message = Request(Version.Http11, Method.Get, \"/\")\n\n//  test(\"write(dtab, msg); read(msg) == dtab\") {\n//    for (dtab <- okDtabs) {\n//      val m = newMsg()\n//      HttpDtab.write(dtab, m)\n//      val dtab1 = HttpDtab.read(m).get()\n//      assert(Equiv[Dtab].equiv(dtab, dtab1))\n//    }\n//  }\n\n}\n"
  },
  {
    "path": "tests/inputs/issues/280/L/hello_1.c",
    "content": "/* Hello World in C, Ansi-style */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n}\n"
  },
  {
    "path": "tests/inputs/issues/280/R/hello_2.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/286/project/ignore_subdir/test.py",
    "content": "print \"hello\"\n"
  },
  {
    "path": "tests/inputs/issues/286/project/read_subdir/hi.c",
    "content": "/*\n */\nint main() { int x = 1;\n    return 0; }\n"
  },
  {
    "path": "tests/inputs/issues/296/Lanczos.m",
    "content": "function [phiKM, AscendingLambda] = Lanczos(K, M, sigma, Jmax)\n[rows,cols] = size(K);                                                       \nif (rows ~= cols)                                                       \n  fprintf('Lanczos needs square matrices');                \nend                                                       \nZ       = K - sigma*M;                               % initialize some\nQ       = zeros(rows,Jmax+1);                        % variables\nT       = zeros(Jmax,Jmax);                          %\nrRand   = randn(rows,1);                             %\nrOld = rRand;\nbetaOld = sqrt(rOld'*M*rOld);                        %\nfor j = 1:Jmax,                                      %\n  Q(:,j+1) = rOld/betaOld;                           %\n  u = Z \\ (M*Q(:,j+1) - Z*Q(:,j)*betaOld);           % D.S.Scott's formulation\n  alpha = Q(:,j+1)'*M*u;                             % of the recurrence\n  r     = u - alpha*Q(:,j+1);                        %\n  for i=1:3,                                         %\n    sum = zeros(rows,1);                             % repeat a full orhto-\n    for k=2:j+1,                                     % gonalization three\n      sum = sum + (Q(:,k)'*M*r)*Q(:,k);              % times to ensure\n    end;                                             % high quality\n    r = r - sum;                                     % solutions\n  end;                                               %\n  beta = sqrt(r'*M*r);                               %\n  T(j,j)   = alpha;                                  %\n  if (j ~= Jmax)                                     % augment [T] with new\n    T(j+1,j) = beta;                                 % alpha_i, beta_i+1\n    T(j,j+1) = beta;                                 %\n  end;                                               %\n  Jactual = j;                                       %\n  if (abs(beta) < 1.0e-12)                           % singular beta; going\n    break                                            % any more will introduce\n  end                                                % spurious modes\n  betaOld = beta;                                    %\n  rOld    = r;                                       %\nend                                                  %\n[phiT,lambdaT] = eig(T(1:Jactual,1:Jactual));        % solve [T]{y} = L{y}\nlambdaKM   = zeros(Jactual,1);                       %\nfor j = 1:Jactual,                                   % invert and shift the\n  lambdaKM(j) = sigma + 1/lambdaT(j,j);              % eigenvalues to the\nend                                                  % user's domain\n[AscendingLambda, ordering] = sort(lambdaKM);        %\nphiKM      = zeros(rows,Jactual);                    % sort the eigenvalues\nUnOrdphiKM = zeros(rows,Jactual);                    % in ascending order\nUnOrdphiKM = Q(:,2:Jactual+1)*phiT;                  %\nfor j = 1:Jactual,                                   % resequence the e-vectors\n  phiKM(:,j) = UnOrdphiKM(:,ordering(j));            % to correspond to the\nend                                                  % e-values\n"
  },
  {
    "path": "tests/inputs/issues/296/Mathematica_1.m",
    "content": "(* http://spot.colorado.edu/~sitelic/samplecode/mathematica/imagesfile.html\n *)\n\nimage = Import[\"denise.png\",\"PNG\"]   (* or *)\n\nimage = Import[\"denise.gif\",\"GIF\"]\n\nA = image[[1,1]]/255.;\nListDensityPlot[A,Mesh->False, AspectRatio->Automatic]\n\n(*\n        -- or -- \n *)\n\nShow[Graphics[Raster[A]], AspectRatio->Automatic]\n\n\nblurA = ListConvolve[Table[1/25,{5},{5}],A];\n\nShow[Graphics[Raster[blurA]], AspectRatio->Automatic]\nB = Fourier[A];\n\n(*\n          delete\n    higher frequencies *)\n\nB[[Range[30,278],All]]=0;\n\nB[[All,Range[30,202]]]=0;\n\nShow[Graphics[Raster[ Re[InverseFourier[B]] ]], AspectRatio->Automatic]\n"
  },
  {
    "path": "tests/inputs/issues/296/Octave.m",
    "content": "% from http://www.roesler-ac.de/wolfram/hello.htm\r\n#Hello World in Octave (http://www.octave.org/)\r\nprintf(\"Hello World\\n\");\r\n"
  },
  {
    "path": "tests/inputs/issues/296/hello.lua",
    "content": "-- single line comment\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/issues/296/nested.lua",
    "content": "-- single line comment  issue #371\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n\n--[===[\nmulti \nline \ncomment\n--[==[\nstill comment\n--[=[\nstill comment\n--[[\nstill comment\n--]]\n--]=]\n--]==]\n--]===]\n"
  },
  {
    "path": "tests/inputs/issues/296/qsort_demo.m",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\n/*\n        Al Danial April 25 2000\n*/\n\n#define ELEMENTS 1000\n\nstatic int compar_string(const void *a, const void *b){\n        return (strcmp( (char *)a, (char *)b));\n}\n\nint comp(const void *a, const void *b ) {\n    return *(int *)a - * (int *)b;\n}\n\nmain(){\n\n        int x, i;\n        char *string;\n        struct sort_test_t {\n                int s;\n        } ;\n\n        struct sort_test_t sort_test[ELEMENTS];\n\n        /* inititalize the array */\n        for (i=0;i<ELEMENTS;i++) {\n                /* produce a random variable */\n                x=1+(100000.0*rand()/(RAND_MAX+1.0));\n                /* load the variable into the string as an array */\n                sort_test[i].s = (int) x;\n                /*\n                printf(\"unsorted %d %d\\n\", i, sort_test[i].s);\n                */\n        }\n\n        /* sort the array */\n        qsort(sort_test, ELEMENTS, sizeof(sort_test[0]), &comp);\n\n        /* output the sorted array */\n        for (i=0;i<ELEMENTS;i++) {\n                printf(\"sorted %d %d\\n\", i, sort_test[i].s);\n        }\n\n}\n"
  },
  {
    "path": "tests/inputs/issues/312/sam #ple.py",
    "content": "#!/usr/bin/env python\nprint('https://github.com/AlDanial/cloc/issues/312')\n"
  },
  {
    "path": "tests/inputs/issues/318/Rcs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.80\n  elapsed_seconds    : 0.00711297988891602\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 140.588053898237\n  lines_per_second   : 1124.7044311859\n  report_file        : results.yaml\n'RÃ©ponse.cs' :\n  blank: 2\n  comment: 1\n  code: 5\n  language: C#\nSUM: \n  blank: 2\n  comment: 1\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/inputs/issues/318/Réponse.cs",
    "content": "\n/* comment: This has 5 physical lines of code. */\n\nclass Test {\n  static void Main() {\n    System.Console.WriteLine(\"Hello, World (in C#)\");\n  }\n}\n"
  },
  {
    "path": "tests/inputs/issues/327/example.smarty2",
    "content": "anything\n"
  },
  {
    "path": "tests/inputs/issues/327/lang.config",
    "content": "Smarty\n    filter smarty_to_C\n    filter call_regexp_common C\n    extension smarty\n    extension smarty2\n    3rd_gen_scale 3.50\n"
  },
  {
    "path": "tests/inputs/issues/341/cItems.cls",
    "content": "VERSION 1.0 CLASS\r\nBEGIN\r\n  MultiUse = -1  'True\r\n  Persistable = 0  'NotPersistable\r\n  DataBindingBehavior = 0  'vbNone\r\n  DataSourceBehavior  = 0  'vbNone\r\n  MTSTransactionMode  = 0  'NotAnMTSObject\r\nEND\r\n\r\n'http://www.vbforums.com/showthread.php?374132-A-basic-example-of-Class-Modules\r\n'file = Class Sample (game).zip\r\n\r\nAttribute VB_Name = \"cItems\"\r\nAttribute VB_GlobalNameSpace = False\r\nAttribute VB_Creatable = True\r\nAttribute VB_PredeclaredId = False\r\nAttribute VB_Exposed = False\r\nAttribute VB_Ext_KEY = \"SavedWithClassBuilder6\" ,\"Yes\"\r\nAttribute VB_Ext_KEY = \"Collection\" ,\"cItem\"\r\nAttribute VB_Ext_KEY = \"Member0\" ,\"cItem\"\r\nAttribute VB_Ext_KEY = \"Top_Level\" ,\"Yes\"\r\nOption Explicit\r\n\r\n'local variable to hold collection\r\nPrivate mCol As Collection\r\n\r\nPublic Function Add( _\r\n        ItemType As eItemTypes, _\r\n        Value As Long, _\r\n        Rarity As Long, _\r\n        Optional ItemName As String, _\r\n        Optional sKey As String) As cItem\r\n    'create a new object\r\n    Dim objNewMember As cItem\r\n    Set objNewMember = New cItem\r\n\r\n\r\n    'set the properties passed into the method\r\n    objNewMember.Value = Value\r\n    objNewMember.Rarity = Rarity\r\n    If Len(sKey) = 0 Then\r\n        mCol.Add objNewMember\r\n    Else\r\n        mCol.Add objNewMember, sKey\r\n    End If\r\n\r\n\r\n    'return the object created\r\n    Set Add = objNewMember\r\n    Set objNewMember = Nothing\r\n\r\n\r\nEnd Function\r\n\r\nPublic Property Get Item(vntIndexKey As Variant) As cItem\r\nAttribute Item.VB_UserMemId = 0\r\n    'used when referencing an element in the collection\r\n    'vntIndexKey contains either the Index or Key to the collection,\r\n    'this is why it is declared as a Variant\r\n    'Syntax: Set foo = x.Item(xyz) or Set foo = x.Item(5)\r\n  Set Item = mCol(vntIndexKey)\r\nEnd Property\r\n\r\n\r\n\r\nPublic Property Get Count() As Long\r\n    'used when retrieving the number of elements in the\r\n    'collection. Syntax: Debug.Print x.Count\r\n    Count = mCol.Count\r\nEnd Property\r\n\r\n\r\nPublic Sub Remove(vntIndexKey As Variant)\r\n    'used when removing an element from the collection\r\n    'vntIndexKey contains either the Index or Key, which is why\r\n    'it is declared as a Variant\r\n    'Syntax: x.Remove(xyz)\r\n\r\n\r\n    mCol.Remove vntIndexKey\r\nEnd Sub\r\n\r\n\r\nPublic Property Get NewEnum() As IUnknown\r\nAttribute NewEnum.VB_UserMemId = -4\r\nAttribute NewEnum.VB_MemberFlags = \"40\"\r\n    'this property allows you to enumerate\r\n    'this collection with the For...Each syntax\r\n    Set NewEnum = mCol.[_NewEnum]\r\nEnd Property\r\n\r\n\r\nPrivate Sub Class_Initialize()\r\n    'creates the collection when this class is created\r\n    Set mCol = New Collection\r\nEnd Sub\r\n\r\n\r\nPrivate Sub Class_Terminate()\r\n    'destroys collection when this class is terminated\r\n    Set mCol = Nothing\r\nEnd Sub\r\n\r\n"
  },
  {
    "path": "tests/inputs/issues/341/thesis.cls",
    "content": "% https://oit.colorado.edu/software-hardware/tex-latex/thesis-class/documentation-sample-files\r\n%   (truncated)\r\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r\n%% thesis.cls - LaTeX2e class for CU Theses.\r\n%% To conform to the University of Colorado at Boulder\r\n%%\tGraduate School SPECIFICATIONS (April 2010) for\r\n%%\tPreparation of Master's Thesis and Doctoral Dissertations\r\n%% Version 1.00 written by John P. Weiss, 1997\r\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r\n%%\tversion 1.13, Hongcheng Ni, March 2014 -- made compatible with\r\n%%\t\thyperref.\r\n%%\tversion 1.12, Hongcheng Ni, March 2014 -- added title before\r\n%%\t\tthe advisor's name in the signature page.\r\n%%\tversion 1.11, Bruce Fast, April 2008 -- changed left margin\r\n%%\t\tfrom 1.75\" to 1\", and added \\IRBprotocol option\r\n%%\tversion 1.10, E. Joshua Rigler, January 2003 -- making it safe\r\n%%\t\tfor folks who inadvertently load setspace.sty, changed\r\n%%\t\t\\latex@xfloat to \\latexx@xfloat\r\n%%\tversion 1.09, BF, November 2000 -- conforms to revised specs\r\n%%\t\tno significant changes required\r\n%%\tversion 1.08, Steven V Penton, September 1999 -- added\r\n%%\t\t\\readerFive; moved list of tables in front of figures\r\n%%\tversion 1.07, BF, January 1999 -- fixed \\LoFisShort etc.\r\n%%\tversion 1.06, BF, November 1998 -- fixed level 4 headers;\r\n%%\t\tSubSubSections, inline4 & nonum4.  Eliminated\r\n%%\t\tunwanted space before chapter/section numbers.\r\n%%\tversion 1.05, BF, August 1998 -- Footnotes and floats\r\n%%\t\t(captions) now singlespaced, fixing an omission\r\n%%\t\tin v1.04.  Fixed value of \\belowcaptionskip,\r\n%%\t\tfor table captions.\r\n%%\tversion 1.04, BF, July 1998, Adjusted doublespacing\r\n%%\t\t(no longer uses setspace.sty) and margin values.\r\n%%\tversion 1.03, May 1998, Bruce Fast -- Added optional\r\n%%\t\t\\readerThree{}, \\readerFour{}; LoF/LoT debugging;\r\n%%\t\tdoublespaced abstract\r\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r\n\r\n\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\r\n\\ProvidesClass{thesis}[2014/03/27]\t% version 1.13\r\n\r\n\\typeout{}\r\n\\typeout{--------------------------------------------------------------}\r\n\\typeout{ +---+ Thesis Style (thesis.cls) version 1.13}\r\n\\typeout{ +---+ for University of Colorado Ph.D. theses/dissertations.}\r\n\\typeout{ * Conforms to the University of Colorado at Boulder Graduate}\r\n\\typeout{ * School \"SPECIFICATIONS for Preparation of Master's Thesis}\r\n\\typeout{ * and Doctoral Dissertations\" (rev. March 2014).}\r\n\\typeout{--------------------------------------------------------------}\r\n\\typeout{ URL: http://www.colorado.edu/oit/software-hardware/tex-latex}\r\n\\typeout{}\r\n\r\n% Certain options are not handled here but are passed on to report.cls\r\n% by \\PassOptionToClass.\r\n\r\n\\DeclareOption{fleqn}{ \\PassOptionsToClass{fleqn}{report} }\r\n\\DeclareOption{leqno}{ \\PassOptionsToClass{leqno}{report} }\r\n\\DeclareOption{openbib}{ \\PassOptionsToClass{openbib}{report} }\r\n\\DeclareOption{draft}{ \\PassOptionsToClass{draft}{report} }\r\n\\DeclareOption{final}{ \\PassOptionsToClass{final}{report} }\r\n\\DeclareOption{openright}{ \\PassOptionsToClass{openright}{report} }\r\n\\DeclareOption{openany}{ \\PassOptionsToClass{openany}{report} }\r\n\\DeclareOption{10pt}{ \\PassOptionsToClass{10pt}{report} }\r\n\\DeclareOption{11pt}{ \\PassOptionsToClass{11pt}{report} }\r\n\\DeclareOption{12pt}{ \\PassOptionsToClass{12pt}{report} }\r\n\r\n% Invalid options - normally used in report.cls and others, but not here:\r\n\r\n\\DeclareOption{titlepage}\r\n   {\\ClassWarning{thesis}{Title page always generated. Option ignored.}}\r\n\\DeclareOption{notitlepage}\r\n   {\\ClassWarning{thesis}{Option 'notitlepage' not available for thesis.}}\r\n\\DeclareOption{twoside}\r\n   {\\ClassWarning{thesis}{Option 'twoside' not available for thesis.}}\r\n\\DeclareOption{twocolumn}\r\n   {\\ClassWarning{thesis}{Option 'twocolumn' not available for thesis.}}\r\n\\DeclareOption{landscape}\r\n   {\\ClassWarning{thesis}{Option 'landscape' not available for thesis.}}\r\n\\DeclareOption{legalpaper}\r\n   {\\ClassWarning{thesis}{Option 'legalpaper' not available for thesis.}}\r\n\\DeclareOption{a4paper}\r\n   {\\ClassWarning{thesis}{Option 'a4paper' not available for this class.}}\r\n\\DeclareOption{a5paper}\r\n   {\\ClassWarning{thesis}{Option 'a5paper' not available for this class.}}\r\n\\DeclareOption{executivepaper}\r\n   {\\ClassWarning{thesis}{Option 'executivepaper' not available.}}\r\n\\DeclareOption{b5paper}\r\n   {\\ClassWarning{thesis}{Option 'b5paper' not available for this class.}}\r\n\\DeclareOption{letterpaper}\r\n   {\\ClassWarning{thesis}{Option 'letterpaper' superfluous. Ignored.}}\r\n\\DeclareOption{onecolumn}\r\n   {\\ClassWarning{thesis}{Option 'onecolumn' superfluous.  Ignored.}}\r\n\\DeclareOption{oneside}\r\n   {\\ClassWarning{thesis}{Option 'oneside' superfluous.  Ignored.}}\r\n\r\n%%%%%%%%%%% CUSTOM OPTIONS:\r\n% Options for no decimal numbering, or decimal number nested over 3 deep:\r\n\\newif\\if@AllHeadings\r\n\\newif\\if@NumberStdHeadings\r\n\\newif\\if@PerChptrNumbering\r\n\\newif\\if@emphisbold\r\n\\newif\\if@boldhead\r\n\\newif\\if@fixedHeadSz\r\n\\newif\\if@headSizeTwelvePt\r\n\\newif\\if@ChapterDefault\r\n\\newif\\if@SectionDefault\r\n\\newif\\if@SubSectionDefault\r\n\\newif\\if@OtherHeadingDefault\r\n\\newif\\if@centerChapter\r\n\\newif\\if@centerSection\r\n\\newif\\if@inlineSubSubSection\r\n\\newif\\if@numberSubSubSection\r\n\\newif\\if@chapterCaps\r\n\\@AllHeadingsfalse\r\n\\@NumberStdHeadingstrue\r\n\\@PerChptrNumberingtrue\r\n\\@emphisboldtrue\r\n\\@boldheadtrue\r\n\\@fixedHeadSzfalse\r\n\\@centerChaptertrue\r\n\\@centerSectionfalse\r\n\\@inlineSubSubSectionfalse\r\n\\@numberSubSubSectiontrue\r\n\\@chapterCapsfalse\r\n\\@headSizeTwelvePttrue\r\n\\DeclareOption{consecutivenumbering}{ \\@PerChptrNumberingfalse }\r\n\\DeclareOption{inlineh4}{ \\@inlineSubSubSectiontrue }\r\n\\DeclareOption{nonumh4}{ \\@numberSubSubSectionfalse }\r\n\\DeclareOption{centerh1}{ \\@centerSectiontrue }\r\n\\DeclareOption{chapleft}{ \\@centerSectiontrue }\r\n\\DeclareOption{chapup}{ \\@chapterCapstrue }\r\n\\DeclareOption{emph2underline}{ \\@emphisboldfalse }\r\n\\DeclareOption{plainhead}{ \\@boldheadfalse }\r\n\\DeclareOption{fixedheadsize}{ \\@fixedHeadSztrue }\r\n\\DeclareOption{varheadsize}{\\@headSizeTwelvePtfalse}% Hidden option.  Don't use.\r\n\\DeclareOption{numberchapteronly}{\r\n\t\\@PerChptrNumberingfalse\\@NumberStdHeadingsfalse\\@AllHeadingsfalse\r\n\t\\@centerChaptertrue\\@centerSectiontrue\r\n\t\\@inlineSubSubSectiontrue\\@numberSubSubSectionfalse }\r\n\\DeclareOption{allheadings}{\r\n\t\\@PerChptrNumberingtrue\\@NumberStdHeadingstrue\\@AllHeadingstrue\r\n\t\\@centerChaptertrue\\@centerSectionfalse\r\n\t\\@inlineSubSubSectionfalse\\@numberSubSubSectiontrue}\r\n\\DeclareOption{typewriterstyle}{ \\@emphisboldfalse\r\n\t\\@PerChptrNumberingfalse\\@NumberStdHeadingsfalse\\@AllHeadingsfalse\r\n\t\\@centerChaptertrue\\@centerSectiontrue\\@chapterCapstrue\r\n\t\\@inlineSubSubSectiontrue\\@numberSubSubSectionfalse\r\n\t\\@boldheadfalse\\@fixedHeadSztrue}\r\n\\DeclareOption{modernstyle}{ \\@emphisboldtrue\r\n\t\\@PerChptrNumberingtrue\\@NumberStdHeadingstrue\\@AllHeadingsfalse\r\n\t\\@centerChaptertrue\\@centerSectionfalse\\@chapterCapsfalse\r\n\t\\@inlineSubSubSectiontrue\\@numberSubSubSectionfalse\r\n\t\\@boldheadtrue\\@fixedHeadSzfalse}\r\n\\DeclareOption{defaultstyle}{ \\@emphisboldtrue\r\n\t\\@PerChptrNumberingtrue\\@NumberStdHeadingstrue\\@AllHeadingsfalse\r\n\t\\@centerChaptertrue\\@centerSectionfalse\\@chapterCapsfalse\r\n\t\\@inlineSubSubSectionfalse\\@numberSubSubSectiontrue\r\n\t\\@boldheadtrue\\@fixedHeadSzfalse}\r\n% lines deleted %\r\n\\endinput\r\n%%%%%%%%%%%%%%%% End of file ``thesis.cls''\r\n"
  },
  {
    "path": "tests/inputs/issues/350/fs.go",
    "content": "package fs\n\nfunc List() []string {\n\tafero.Glob(\"/*\")\n}\n\nfunc (fs aferoFs) AtomicCreateWith(fname string, data []byte) {\n\ttmpFile := Sprintf(\"%s.tmp\", fname)\n}\n\n// this is a comment\n// this is a \"comment\"\n// \"this is a comment\"\n\"// this is a comment\"\n\nfunc deleteTmpFiles(fs afero.Fs) {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfor _, n := range tmpFiles {\n\t\tfs.Remove()\n\t\tif err != nil {\n\t\t}\n\t}\n}\n// https://github.com/AlDanial/cloc/issues/350\n"
  },
  {
    "path": "tests/inputs/issues/365/RSpecTests.java",
    "content": "/*\n * https://raw.githubusercontent.com/elastic/logstash/master/x-pack/src/test/java/org/logstash/xpack/test/RSpecTests.java\n */\npackage org.logstash.xpack.test;\n\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Arrays;\nimport org.jruby.runtime.builtin.IRubyObject;\nimport org.junit.Assert;\nimport org.junit.Test;\nimport org.logstash.RubyUtil;\nimport org.logstash.Rubyfier;\n\npublic final class RSpecTests {\n    @Test\n    public void rspecTests() throws Exception {\n        RubyUtil.RUBY.getENV().put(\"IS_JUNIT_RUN\", \"true\");\n        RubyUtil.RUBY.getGlobalVariables().set(\n            \"$JUNIT_ARGV\", Rubyfier.deep(RubyUtil.RUBY, Arrays.asList(\n                \"-fd\", \"--pattern\", \"spec/**/*_spec.rb\"\n            ))\n        );\n        final Path rspec = Paths.get(\n            org.assertj.core.util.Files.currentFolder().getParent(), \"lib/bootstrap/rspec.rb\"\n        );\n        final IRubyObject result = RubyUtil.RUBY.executeScript(\n            new String(Files.readAllBytes(rspec), StandardCharsets.UTF_8),\n            rspec.toFile().getAbsolutePath()\n        );\n        if (!result.toJava(Long.class).equals(0L)) {\n            Assert.fail(\"RSpec test suit saw at least one failure.\");\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/issues/370/arduino_issue_370.ino",
    "content": "// file contains 0xA0 characters which defeats the counter unless stripped\r\n\r\n//Only do this if PC (Kenwood power setting) has changed:\r\n   // Extract power setting\r\n   if (new_PC==true){\r\n    String power_value=(store_PC.substring(2,5)); //extract the power value from the PC response string\r\n    KEN_pwr = power_value.toInt();         //then convert that extracted string to integer\r\n   // Serial.print(\"Integer power = \");\r\n   // Serial.println(KEN_pwr);\r\n   }\r\n"
  },
  {
    "path": "tests/inputs/issues/375/docstring.py",
    "content": "\"\"\"\nThis is a docstring.\n\"\"\"\n\ndef abc(d,\n        a11):\n    ''' this is a docstring '''\n    d = 2\n    a = \"\"\"\n    this is not\n    a docstring\n    \"\"\"\n    def xyz(d):\n        \"\"\"\n        this is a docstring\n        \"\"\"\n        x = 1\n        a = \"\"\" this is not a docstring\n        \"\"\"\n\nclass Abc():\n    ''' this is a docstring '''\n    d = 2\n    a = \"\"\"\n    this is not\n    a docstring\n    \"\"\"\n    def Xyz(d):\n        \"\"\"\n        this is a docstring\n        \"\"\"\n        x = 1\n        a = \"\"\"\n        this is not a docstring \"\"\"\n\n"
  },
  {
    "path": "tests/inputs/issues/378/git_script.sh",
    "content": "#!/bin/bash\nmkdir repo378\ncd    repo378\ngit init\nmkdir dir\necho \"unsigned int test=0;\" > dir/file1.c\nprintf \"unsigned int test2=0;\\n\" > dir/file2.c\necho \"unsigned int test3=0;\" > dir/file3.c\ngit add --all\ngit commit -m \"master commit1\"\ngit checkout -b branch1\ngit mv dir/file2.c .\nmkdir dir2\ngit mv dir/file3.c dir2/\ngit add --all\ngit commit -m \"branch1 commit1\"\ncloc --git --ignore-whitespace --diff --by-file \\\n    --report-file=/tmp/out1 --diff-alignment=/tmp/out2 \\\n    `git show-ref -s master | head -1` `git show-ref -s | head -1`\n"
  },
  {
    "path": "tests/inputs/issues/380/wrapper.pl",
    "content": "#!/usr/bin/perl -w\n\n=head1 NAME \n\nour_wrapper.pl - a wrapper calling provided algorithms\n\n=head1 SYNOPSIS\n\nour_wrapper.pl --program 'text' \n --inputfiles file1.xml,file2.xml\n --varfiles varInfo1.xml,varInfo2.xml\n --zfiles zfile1.xml,zfile2.xml\n --variables variable1,variable2\n --bbox west,south,east,north\n --starttime YYYY-MM-DDTHH:MI:SSZ\n --endtime YYYY-MM-DDTHH:MI:SSZ\n [--comparison comparison_type]\n [--dateline-method stitch]\n [--debug [0-3]]\n [--time-axis]\n [--output-type (filelist|ncfile)]\n [--units units1,units2,units-cfg.xml]\n \n=head1 DESCRIPTION\n\ntime_code.pl simplifies and regularizes the calling arguments for\n provided algorithims. \n=over\n\n=item --program\n\nFilename (no directory, ideally) of algorithm executable, plus any fixed\narguments as necessary. E.g., \"kmeans.pl -k 3\"\n\n=item --inputfiles\n\nComma separated list of input XML G6 Manifest files. \nThere is typically only file for most 1-variable-at-a-time services\n(like area averager), but it may be two files for some comparisons.\n\n=item --varfiles\n\nComma separated list of input XML files with informatino about the data fields.\nThere is typically only file for most 1-variable-at-a-time services\n(like area averager), but it may be two files for some comparisons.\n\n=item --variables\n\nComma separated list of variables\nThere is typically only one for most 1-variable-at-a-time services\n(like area averager), but it may be two for some comparisons.\n\n=item --bbox\n\nComma-separated west,south,east,north boundaries.\nTypically, the algorithm is expected to subset within these boundaries.\n\n=item --outfile\n\nOutput XML manifest file listing the file(s) created by the algorithm.\n\n=item --zfiles\n\nComma separated list of input XML zslice files, showing what z level the user\nhas selected.\n\n=item --starttime\n\nStart time in format YYYY-MM-DDTHH:MM:SSZ.\n\n=item --endtime\n\nEnd time in format YYYY-MM-DDTHH:MM:SSZ.\n\n=item --comparison\n\nWord or phrase describing the comparison type, \ne.g., \"minus\", \"divided by\", \"regressed against\"\n\n=item --debug\n\nDebug level, 0-3.\n\n=item --output-file-root\n\nRoot for the filename of the output data file.\n\n=item --session-dir\n\nSession directory. Default is '.'.\n\n=item --time-axis\n\nWhether the output data has a time axis. This is true for someting and time-axis.\nIf unset, assumes no time axis.\nThis is what controls whether Something::Visualizer::TimeTics is invoked.\n\n=item --output-type\n\nIf assigned the value 'filelist', the wrapper treats the output file argument as the \nname of the file that lists all the output files\n\n=item --units units1.xml,units2.xml,units-cfg.xml\n\nThis argument tells the wrapper and/or algorithm to do units conversion, taking\na comma-separated list of destination units: \nthe first one (or two for comparison) is the user\ninput, the last one is the units conversion configuration file.\n\n=cut\n\n# $Id: our_wrapper.pl,v 1.16 2015/04/16 22:15:42 cls Exp $\n# -@@@ GSdd4\n\nuse strict;\nuse Getopt::Long;\nuse Something::Algorithm::Wrapper;\n\nuse vars qw($program $comparison $bbox\n    $inputfiles $outfile $zfiles $varfiles $units\n    $variables $starttime $endtime\n    $mintimesteps $outputfileroot\n    $sessiondir\n    $comparison\n    $name\n    $debug\n    $dateline\n    $time_axis\n    $output_type\n    $shapefile\n    $group\n    $jobs\n);\n\nGetOptions(\n    \"program=s\"            => \\$program,\n    \"name=s\"               => \\$name,\n    \"starttime=s\"          => \\$starttime,\n    \"endtime=s\"            => \\$endtime,\n    \"bbox=s\"               => \\$bbox,\n    \"inputfiles=s\"         => \\$inputfiles,\n    \"outfile=s\"            => \\$outfile,\n    \"varfiles=s\"           => \\$varfiles,\n    \"zfiles=s\"             => \\$zfiles,\n    \"variables=s\"          => \\$variables,\n    \"minimum-time-steps=i\" => \\$mintimesteps,\n    \"output-file-root=s\"   => \\$outputfileroot,\n    \"session-dir=s\"        => \\$sessiondir,\n    \"comparison=s\"         => \\$comparison,\n    \"dateline=s\"           => \\$dateline,\n    \"debug=i\"              => \\$debug,\n    \"time-axis\"            => \\$time_axis,\n    \"output-type=s\"        => \\$output_type,\n    \"units=s\"              => \\$units,\n    \"group=s\"              => \\$group,\n    \"shapefile|S=s\"        => \\$shapefile,\n    \"jobs=i\"               => \\$jobs\n);\nmy %args = (\n    'program'          => $program,\n    'name'             => $name,\n    'time-axis'        => $time_axis,\n    'dateline'         => $dateline,\n    'starttime'        => $starttime,\n    'endtime'          => $endtime,\n    'bbox'             => $bbox,\n    'outfile'          => $outfile,\n    'output-file-root' => $outputfileroot,\n    'debug'            => $debug,\n    'varfiles'         => $varfiles,\n    'variables'        => $variables,\n    'inputfiles'       => $inputfiles,\n    'session-dir'      => $sessiondir,\n    'zfiles'           => $zfiles,\n    'output-type'      => $output_type,\n    'units'            => $units,\n    'group'            => $group,\n    'shapefile'        => $shapefile,\n    'jobs'             => $jobs\n);\n\nif ($comparison) {\n    $args{'comparison'}         = $comparison;\n    $args{'minimum-time-steps'} = $mintimesteps;\n}\nmy $outnc = Something::Algorithm::Wrapper::run(%args);\nexit( !( -s $outnc ) );\n"
  },
  {
    "path": "tests/inputs/issues/381/issue381.c",
    "content": "/* implement the main bcon interface */\r\n\r\n#define BCON_TRIGGER_PATH \"/bivio/bcon_triggers/bcon_trigger/\" \r\n#define BCON_TRIGGER_PATH_WITH_NAME \"/bivio/bcon_triggers/bcon_trigger[@name=\\\"\" \r\n#define BCON_TRIGGER_PATH_END_NAME \"\\\"]/\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_PRE_ASTRK \"\\\"]/pre_triggers/*\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_PRE_NO_ASTRK \"\\\"]/pre_triggers/\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_POST_ASTRK \"\\\"]/post_triggers/*\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_POST_NO_ASTRK \"\\\"]/post_triggers/\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_GET_ASTRK \"\\\"]/get_triggers/*\" \r\n#define BCON_TRIGGER_PATH_END_NAME_WITH_GET_NO_ASTRK \"\\\"]/get_triggers/\" \r\n#define BCON_TRIGGER_PATH_SET \"set[\"\r\n\r\n\r\ntypedef struct ErrorConstant ErrorConstant;\r\nstruct ErrorConstant\r\n{\r\n        int\t\tvalue;          /* value represented by the name */\r\n        const char\t*description;   /* human readable description */\r\n};\r\n"
  },
  {
    "path": "tests/inputs/issues/381/issue381.java",
    "content": "package com.triplemedia.sms.alphabets.cimd2;\r\n\r\n/**\r\n * Utility class for CIMD2 alphabet as defined in CIMD_Interface_Specification_SC70.pdf\r\n */\r\npublic class CIMD2Alphabet{\r\n\tpublic static final char CIMD2_SPECIAL_COMBINATION_CHARACTER = '_';\r\n\r\n    public static final String COMMERCIAL_AT = \"_Oa\";\r\n    public static final String SMALL_LETTER_y = \"y\";\r\n    public static final String SMALL_LETTER_z = \"z\";\r\n    \r\n    public static final String VERTICAL_BAR = \"_XX_!!\"; // |\r\n    public static final String CARET = \"_XX_gl\"; // ^\r\n    public static final String EURO = \"_XXe\"; // \r\n    public static final String OPENING_BRACE = \"_XX(\"; // {\r\n    public static final String CLOSING_BRACE = \"_XX)\"; // }\r\n    public static final String PAGE_BREAK = \"_XX\\f)\"; \r\n    public static final String OPENING_BRACKET = \"_XX<\"; // [\r\n    public static final String CLOSING_BRACKET = \"_XX>\"; // ]\r\n    public static final String TILDE = \"_XX=\"; // ~\r\n    public static final String BACKSLASH = \"_XX/\"; // \\\r\n    \r\n    public static final String VERTICAL_BAR_NO_ESC = \"_!!\"; // |\r\n    public static final String CARET_NO_ESC = \"_gl\"; // ^\r\n    public static final String EURO_NO_ESC = \"e\"; // \r\n    public static final String OPENING_BRACE_NO_ESC = \"(\"; // {\r\n    public static final String CLOSING_BRACE_NO_ESC = \")\"; // }\r\n    public static final String PAGE_BREAK_NO_ESC = \"\\f\"; \r\n    public static final String OPENING_BRACKET_NO_ESC = \"<\"; // [\r\n    public static final String CLOSING_BRACKET_NO_ESC = \">\"; // ]\r\n    public static final String TILDE_NO_ESC = \"=\"; // ~\r\n    public static final String BACKSLASH_NO_ESC = \"/\"; // \\\r\n\r\n}\r\n"
  },
  {
    "path": "tests/inputs/issues/386/make_386_repo.sh",
    "content": "#!/bin/sh\ngit init issue386\ncd issue386/\n\nCCODE=$(cat <<'EOC1'\n/*\n *   Compile:\n *               gcc hello.c -o hello\n *\n *   Run:\n *               hello\n */\nmain (int argc, char *argv[])\n{\n  printf(\"Hello.\\n\");\n}\nEOC1\n)\necho \"${CCODE}\" > hello1.c\n\nCCODE=$(cat <<'EOC2'\n//   Compile:\n//               gcc hello.c -o hello\n//               hello\nmain (int argc, char *argv[])\n{\n  printf(\"extra line.\\n\");\n  printf(\"Hello.\\n\");\n}\nEOC2\n)\necho \"${CCODE}\" > hello2.c\n\nPCODE=$(cat <<'EOP'\n#!/usr/bin/env python\nimport sys\nimport numpy as np\n# nothing useful\nprint(np.random.rand(3,4))\nEOP\n)\necho \"${PCODE}\" > stuff.py\n\ngit add hello1.c  hello2.c\ngit commit --allow-empty-message -m ''\ngit add stuff.py\ngit commit --allow-empty-message -m ''\ngit rm hello1.c\ngit commit --allow-empty-message -m ''\ngit rm stuff.py hello2.c\ngit commit --allow-empty-message -m ''\n\nHASH4=`git log --oneline -n 1 --skip 0 | perl -p -e 's/\\s+$/\\n/g'`\nHASH3=`git log --oneline -n 1 --skip 1 | perl -p -e 's/\\s+$/\\n/g'`\nHASH2=`git log --oneline -n 1 --skip 2 | perl -p -e 's/\\s+$/\\n/g'`\nHASH1=`git log --oneline -n 1 --skip 3 | perl -p -e 's/\\s+$/\\n/g'`\n\necho \"HASH4=$HASH4\"\necho \"HASH3=$HASH3\"\necho \"HASH2=$HASH2\"\necho \"HASH1=$HASH1\"\n\n# hello1.c hello2.c\ngit archive -o ${HASH1}.tar ${HASH1}\n\n# hello1.c hello2.c stuff.py\ngit archive -o ${HASH2}.tar ${HASH2}\n\n# hello2.c stuff.py\ngit archive -o ${HASH3}.tar ${HASH3}\n\n# empty\ngit archive -o ${HASH4}.tar ${HASH4}\n\ncloc --git --diff ${HASH1}     ${HASH2}\ncloc       --diff ${HASH1}.tar ${HASH2}.tar\necho '++++++++++++++++++++++++++++++++++++++++++'\ncloc --git --diff ${HASH2}     ${HASH3}\ncloc       --diff ${HASH2}.tar ${HASH3}.tar\necho '++++++++++++++++++++++++++++++++++++++++++'\ncloc --git --diff ${HASH3}     ${HASH4}\ncloc       --diff ${HASH3}.tar ${HASH4}.tar\necho '++++++++++++++++++++++++++++++++++++++++++'\ncloc --git --diff ${HASH4}     ${HASH1}\ncloc       --diff ${HASH4}.tar ${HASH1}.tar\necho '++++++++++++++++++++++++++++++++++++++++++'\ncloc --git --diff ${HASH1}     ${HASH4}\ncloc       --diff ${HASH1}.tar ${HASH4}.tar\n"
  },
  {
    "path": "tests/inputs/issues/405/globs.py",
    "content": "import glob\nimport numpy as np\n\ndef print_info(path)\n    '''\n    print stuff\n    '''\n    files = sorted(glob.glob('%s/*.*' % path))\n    for i, file in enumerate(files):\n        labels = np.loadtxt(file, dtype=np.float32).reshape(-1, 5)\n        x += np.bincount(labels[:, 0].astype('int32'), minlength=nc)\n        print(i, len(files))\n\n'''\nend stuff\n'''\n"
  },
  {
    "path": "tests/inputs/issues/407/count_dir/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/407/count_dir/Test/Java.java",
    "content": "// from http://www.roesler-ac.de/wolfram/hello.htm\n// Hello World in Java\n\n// 2016-12-02:  additional code by https://github.com/filippucher1\n// to test /* within quoted string github issue #140\n\n@Controller\n@RequestMapping( \"/path/*\" )\npublic class ControllerClass {\n/** \n* javadoc\n* style\n*/\n\n/* block comment 1 - on one line */\n\n/* \n  block comment 2\n*/\n\n/* \n* block comment 3\n*/\n\nimport java.io.*;\nclass HelloWorld {\n  static public void main( String args[] ) {\n    System.out.println( \"Hello World!\" );\n  }\n}\n"
  },
  {
    "path": "tests/inputs/issues/407/level2/Java.java",
    "content": "// from http://www.roesler-ac.de/wolfram/hello.htm\n// Hello World in Java\n\n// 2016-12-02:  additional code by https://github.com/filippucher1\n// to test /* within quoted string github issue #140\n\n@Controller\n@RequestMapping( \"/path/*\" )\npublic class ControllerClass {\n/** \n* javadoc\n* style\n*/\n\n/* block comment 1 - on one line */\n\n/* \n  block comment 2\n*/\n\n/* \n* block comment 3\n*/\n\nimport java.io.*;\nclass HelloWorld {\n  static public void main( String args[] ) {\n    System.out.println( \"Hello World!\" );\n  }\n}\n"
  },
  {
    "path": "tests/inputs/issues/407/level2/level/Test/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/407/level2/level/Test/level2/hi.py",
    "content": "#/usr/bin/env python\n# Works with both 2.x and 3.x versions of Python.\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''"
  },
  {
    "path": "tests/inputs/issues/407/linked_dir/hello.f",
    "content": "c     Hello World\n*     Hello World\n!     Hello World\n      program hello\n      implicit none\n      print '(\"Hello, World!\")'\n      end\n      ! a fancy comment\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/408/badly_named_ruby.pl",
    "content": "#!/usr/bin/env ruby\n\nrequire File.join(File.dirname(__FILE__), \"/some_code.rb\")\n"
  },
  {
    "path": "tests/inputs/issues/420/mixed_case_ext.Pl",
    "content": "# https://stackoverflow.com/questions/1721807/how-do-i-create-then-use-long-windows-paths-from-perl#1722223\r\nuse Win32::API;\r\n$cd = Win32::API->new('kernel32', 'CreateDirectoryW', 'PP', 'N');\r\n$dir = '\\\\\\\\?\\\\c:\\\\Users\\\\IEUser\\\\!long_dir';\r\n\r\n$res = 1;\r\n\r\nmy $i = 1;\r\ndo {\r\n    print 'path length: ' . length($dir) . \"\\n\";\r\n    $dirname = pack('S*', unpack('C*', \"$dir\\0\"));  #dirty way to produce UTF-16LE string\r\n\r\n    $res = $cd->Call($dirname, 0);\r\n    print \"$res\\n\";\r\n\r\n    $dir .= '\\\\' . sprintf \"D%09d\", $i;\r\n    ++$i;\r\n    $res = 0 if $i > 30;\r\n\r\n} while ( $res );\r\n"
  },
  {
    "path": "tests/inputs/issues/433/excl.txt",
    "content": "L/locale_facets.h\n"
  },
  {
    "path": "tests/inputs/issues/454/createServer.js",
    "content": "function createServer () {\n  server.use(bodyParser.text({ type: '*/*' }))\n\n  server.post('/:queueId', async function (request, response) {\n    response.status(200).end()\n  })\n\n  server.get('/:queueId', async function (request, response) {\n    const message = state\n    response.status(200).send(message).end()\n  })\n\n  return server\n}\n"
  },
  {
    "path": "tests/inputs/issues/455/list.txt",
    "content": "tests/inputs/diff/A/d1/hello.f90 | tests/inputs/diff/B/d1/hello.f90\ntests/inputs/diff/A/hello.C | tests/inputs/diff/B/hello.C\ntests/inputs/diff/A/d2/hi.py | tests/inputs/diff/B/d2/hi.py\n"
  },
  {
    "path": "tests/inputs/issues/455/list_align.txt",
    "content": "Files added: 1\n  + tests/inputs/diff/B/extra_file.pl ; Perl\n\nFiles removed: 1\n  - tests/inputs/diff/A/d2/hello.java ; Java\n\nFile pairs compared: 3\n  != tests/inputs/diff/A/d1/hello.f90 | tests/inputs/diff/B/d1/hello.f90 ; Fortran 90\n  != tests/inputs/diff/A/hello.C | tests/inputs/diff/B/hello.C ; C++\n  == tests/inputs/diff/A/d2/hi.py | tests/inputs/diff/B/d2/hi.py ; Python\n"
  },
  {
    "path": "tests/inputs/issues/456/XML_no_ext",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<!-- from http://www.roesler-ac.de/wolfram/hello.htm -->\r\n<?xml-stylesheet type=\"text/xsl\" href=\"HelloWorld.xsl\" ?>\r\n<!-- Hello World in XML -->\r\n<text><string>Hello, World</string></text>\r\n"
  },
  {
    "path": "tests/inputs/issues/456/XML_weird_ext.profile",
    "content": "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\r\n<?xml-stylesheet type=\"text/xsl\" href=\"HelloWorld.xsl\" ?>\r\n<text><string>hi world</string></text>\r\n<!-- slight mod -->\r\n"
  },
  {
    "path": "tests/inputs/issues/463/left.C",
    "content": "{     \n  }//\n  }\n}\n//\n"
  },
  {
    "path": "tests/inputs/issues/463/right.C",
    "content": "{     \n}\n"
  },
  {
    "path": "tests/inputs/issues/472/lua_def.txt",
    "content": "Lua\n    filter replace_regex X \n    filter remove_matches ^\\s*\\-\\-\n    extension lua\n    3rd_gen_scale 4.00\n"
  },
  {
    "path": "tests/inputs/issues/472/not_really.lua",
    "content": "-- single line comment\n\nX\n\nprint(\"hello, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/issues/476/A/bye.C",
    "content": "// bye.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"bye\" << std::endl;  // comment 1\n/*                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/476/A/bye.f90",
    "content": "! Bye World\nprogram bye\n  implicit none\n  print '(\"Bye, World!\")'\nend program bye\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/476/A/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n                                           /* 2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/476/A/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/476/B/bye.f90",
    "content": "! Hello World\nprogram bye\n  implicit none\n  print '(\"Hello, World!\")'\nend program bye\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/476/B/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/476/B/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/476/B/yo.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"yo\" << std::endl;  // comment 1\n}\n"
  },
  {
    "path": "tests/inputs/issues/482/A/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/482/A/hi.py",
    "content": "#/usr/bin/env python\n# Works with both 2.x and 3.x versions of Python.\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''"
  },
  {
    "path": "tests/inputs/issues/482/A/temp.c",
    "content": "\n\nmain() {\n int i;\n}\n"
  },
  {
    "path": "tests/inputs/issues/494/P_EDI_BookF8.sql",
    "content": "USE \r\nGO\r\n/****** Object:  StoredProcedure [dbo].[P_EDI_Book]    Script Date: 2020/05/22 11:41:27 ******/\r\nSET ANSI_NULLS ON\r\nGO\r\nSET QUOTED_IDENTIFIER ON\r\nGO\r\n\r\n\r\n--=================================================\r\n\r\n---------------------------------------------------\r\n--  \r\n---------------------------------------------------\r\n\r\n--  ＜下り＞\r\n--\r\n   ,@ext_day int = -5\t\t\t\t\t\t--2017-02-28 更新\r\n--   ,@ext_day int = -1\t\t\t\t\t\t--2016-08-17 更新\r\n   ,@ext_time datetime = '00:00:00'\r\n   \r\nAS\r\n--=================================================\r\n-- 開始\r\n--=================================================\r\nSP_MAIN:\r\n  SET NOCOUNT ON\r\n\r\n--=============================================\r\n-- なんとなく共通処理\r\n--=============================================\r\n\r\n  -- 必要なローカル変数定義\r\n  Declare @tran_ct int           -- トランザクションカウント\r\n \r\n  Declare @FETCH_STATUS int -- @@FETCH_STATUSワーク\r\n\r\n--=================================================\r\n-- パラメタチェック\r\n--=================================================\r\n\r\n  Declare @a_tax_rate_type char(1)  -- 税端数処理区分\r\n  -- ▼▼▼ 2013/11/21 add\r\n  Declare @a_tonets_v_up_flag char(1)\t-- トーハンTONET=V上り実装フラグ\r\n  Declare @a_tonets_v_dw_flag char(1)\t-- トーハンTONET=V下り実装フラグ\r\n  -- ▲▲▲ 2013/11/21 add\r\n\r\n--=================================================\r\n-- 共通処理\r\n--=================================================\r\n\r\n  -- 下り用処理カウンタ\r\n  Declare @count_all int  -- 処理対象\r\n \r\n\r\n  -- サーバ名・データベース名セット\r\n  Declare @server_name varchar(100)\r\n\r\n  End\r\n\r\n  -- ▼▼▼ 2013/11/21 add\r\n  -- 上り在庫変動処理（TONETS-V:T1）\r\n  If @edi_type = '56U' Begin\r\n\r\n  End\r\n  -- ▲▲▲ 2013/11/21 add\r\n  \r\n  -- 【上り未登録商品マスタ(エコール)】上り未登録商品マスタのクライアント処理\t-- 2014/01/20 add\r\n  If @edi_type = '60U' Begin\r\n\r\n  -- ▼▼▼ 2014/01/28 add\r\n  -- 【JEUGIA基幹連動】上り売上処理\r\n  If @edi_type = '62U' Begin\r\n\r\n  -- ▲▲▲ 2014/01/28 add\r\n\r\n  --\r\n\r\n--=================================================\r\n-- SP終了\r\n--=================================================\r\n\r\n\r\n"
  },
  {
    "path": "tests/inputs/issues/502/FileCounter20200715140433.txt",
    "content": "﻿Điếm LOC/P_EDI_Book.sql\r\n"
  },
  {
    "path": "tests/inputs/issues/502/Điếm LOC/P_EDI_Book.sql",
    "content": "USE \r\nGO\r\n/****** Object:  StoredProcedure [dbo].[P_EDI_Book]    Script Date: 2020/05/22 11:41:27 ******/\r\nSET ANSI_NULLS ON\r\nGO\r\nSET QUOTED_IDENTIFIER ON\r\nGO\r\n\r\n\r\n--=================================================\r\n\r\n---------------------------------------------------\r\n--  \r\n---------------------------------------------------\r\n\r\n--  ＜下り＞\r\n--\r\n   ,@ext_day int = -5\t\t\t\t\t\t--2017-02-28 更新\r\n--   ,@ext_day int = -1\t\t\t\t\t\t--2016-08-17 更新\r\n   ,@ext_time datetime = '00:00:00'\r\n   \r\nAS\r\n--=================================================\r\n-- 開始\r\n--=================================================\r\nSP_MAIN:\r\n  SET NOCOUNT ON\r\n\r\n--=============================================\r\n-- なんとなく共通処理\r\n--=============================================\r\n\r\n  -- 必要なローカル変数定義\r\n  Declare @tran_ct int           -- トランザクションカウント\r\n \r\n  Declare @FETCH_STATUS int -- @@FETCH_STATUSワーク\r\n\r\n--=================================================\r\n-- パラメタチェック\r\n--=================================================\r\n\r\n  Declare @a_tax_rate_type char(1)  -- 税端数処理区分\r\n  -- ▼▼▼ 2013/11/21 add\r\n  Declare @a_tonets_v_up_flag char(1)\t-- トーハンTONET=V上り実装フラグ\r\n  Declare @a_tonets_v_dw_flag char(1)\t-- トーハンTONET=V下り実装フラグ\r\n  -- ▲▲▲ 2013/11/21 add\r\n\r\n--=================================================\r\n-- 共通処理\r\n--=================================================\r\n\r\n  -- 下り用処理カウンタ\r\n  Declare @count_all int  -- 処理対象\r\n \r\n\r\n  -- サーバ名・データベース名セット\r\n  Declare @server_name varchar(100)\r\n\r\n  End\r\n\r\n  -- ▼▼▼ 2013/11/21 add\r\n  -- 上り在庫変動処理（TONETS-V:T1）\r\n  If @edi_type = '56U' Begin\r\n\r\n  End\r\n  -- ▲▲▲ 2013/11/21 add\r\n  \r\n  -- 【上り未登録商品マスタ(エコール)】上り未登録商品マスタのクライアント処理\t-- 2014/01/20 add\r\n  If @edi_type = '60U' Begin\r\n\r\n  -- ▼▼▼ 2014/01/28 add\r\n  -- 【JEUGIA基幹連動】上り売上処理\r\n  If @edi_type = '62U' Begin\r\n\r\n  -- ▲▲▲ 2014/01/28 add\r\n\r\n  --\r\n\r\n--=================================================\r\n-- SP終了\r\n--=================================================\r\n\r\n\r\n"
  },
  {
    "path": "tests/inputs/issues/513/L/empty.c",
    "content": ""
  },
  {
    "path": "tests/inputs/issues/513/diff_list.txt",
    "content": "Files added:  \n  + L/empty.c ; unused\n  + R/hello_2.c ; unused\n\nFiles removed:  \n  - L/hello_1.c ; unused\n\nFile pairs compared:  \n  == L/locale_facets.h | R/locale_facets.h ; unused\n"
  },
  {
    "path": "tests/inputs/issues/520/julia_docstr.jl",
    "content": "\"\"\"\n    id(x)\n\nThe identity function\n\"\"\"\nid(x) = x\n"
  },
  {
    "path": "tests/inputs/issues/521/Test 188/Test1.sql",
    "content": ",WORK_CONTENTS01\r\n\t\t\t,WORK_CONTENTS02\r\n\t\t\t,WORK_CONTENTS03\r\n\t\t\t,WORK_CONTENTS04\r\n\t\t\t,WORK_CONTENTS05\r\n\t\t\t,WORK_CONTENTS06\r\n\t\t\t,WORK_CONTENTS07\r\n\t\t\t,WORK_CONTENTS08\r\n\t\t\t,WORK_CONTENTS09\r\n\t\t\t,WORK_CONTENTS10"
  },
  {
    "path": "tests/inputs/issues/521/Test 188/UP0PB.sql",
    "content": ",WORK_CONTENTS01\r\n\t\t\t,WORK_CONTENTS02\r\n\t\t\t,WORK_CONTENTS03\r\n\t\t\t,WORK_CONTENTS04\r\n\t\t\t,WORK_CONTENTS05\r\n\t\t\t,WORK_CONTENTS06\r\n\t\t\t,WORK_CONTENTS07\r\n\t\t\t,WORK_CONTENTS08\r\n\t\t\t,WORK_CONTENTS09\r\n\t\t\t,WORK_CONTENTS10"
  },
  {
    "path": "tests/inputs/issues/521/Test188New/Test 188/Test1.sql",
    "content": ",WORK_CONTENTS01\r\n\t\t\t,WORK_CONTENTS02\r\n\t\t\t,WORK_CONTENTS03\r\n\t\t\t,WORK_CONTENTS04\r\n\t\t\t,WORK_CONTENTS05\r\n\t\t\t,WORK_CONTENTS06\r\n"
  },
  {
    "path": "tests/inputs/issues/521/Test188New/Test 188/UP0PB.sql",
    "content": ",WORK_CONTENTS01\r\n\t\t\t,WORK_CONTENTS02\r\n\t\t\t,WORK_CONTENTS03\r\n\t\t\t,WORK_CONTENTS04\r\n\t\t\t,WORK_CONTENTS05\r\n\t\t\t,WORK_CONTENTS06\r\n\t\t\t,WORK_CONTENTS07\r\n\t\t\t,WORK_CONTENTS08\r\n\t\t\t,WORK_CONTENTS09\r\n\t\t\t,WORK_CONTENTS10"
  },
  {
    "path": "tests/inputs/issues/528/Fortran77.f",
    "content": "C from http://www.roesler-ac.de/wolfram/hello.htm\nC     Hello World in Fortran 77\n\n      PROGRAM HELLO\n      PRINT*, 'Hello World!'\n      END\n"
  },
  {
    "path": "tests/inputs/issues/528/Lanczos.m",
    "content": "function [phiKM, AscendingLambda] = Lanczos(K, M, sigma, Jmax)\n[rows,cols] = size(K);                                                       \nif (rows ~= cols)                                                       \n  fprintf('Lanczos needs square matrices');                \nend                                                       \nZ       = K - sigma*M;                               % initialize some\nQ       = zeros(rows,Jmax+1);                        % variables\nT       = zeros(Jmax,Jmax);                          %\nrRand   = randn(rows,1);                             %\nrOld = rRand;\nbetaOld = sqrt(rOld'*M*rOld);                        %\nfor j = 1:Jmax,                                      %\n  Q(:,j+1) = rOld/betaOld;                           %\n  u = Z \\ (M*Q(:,j+1) - Z*Q(:,j)*betaOld);           % D.S.Scott's formulation\n  alpha = Q(:,j+1)'*M*u;                             % of the recurrence\n  r     = u - alpha*Q(:,j+1);                        %\n  for i=1:3,                                         %\n    sum = zeros(rows,1);                             % repeat a full orhto-\n    for k=2:j+1,                                     % gonalization three\n      sum = sum + (Q(:,k)'*M*r)*Q(:,k);              % times to ensure\n    end;                                             % high quality\n    r = r - sum;                                     % solutions\n  end;                                               %\n  beta = sqrt(r'*M*r);                               %\n  T(j,j)   = alpha;                                  %\n  if (j ~= Jmax)                                     % augment [T] with new\n    T(j+1,j) = beta;                                 % alpha_i, beta_i+1\n    T(j,j+1) = beta;                                 %\n  end;                                               %\n  Jactual = j;                                       %\n  if (abs(beta) < 1.0e-12)                           % singular beta; going\n    break                                            % any more will introduce\n  end                                                % spurious modes\n  betaOld = beta;                                    %\n  rOld    = r;                                       %\nend                                                  %\n[phiT,lambdaT] = eig(T(1:Jactual,1:Jactual));        % solve [T]{y} = L{y}\nlambdaKM   = zeros(Jactual,1);                       %\nfor j = 1:Jactual,                                   % invert and shift the\n  lambdaKM(j) = sigma + 1/lambdaT(j,j);              % eigenvalues to the\nend                                                  % user's domain\n[AscendingLambda, ordering] = sort(lambdaKM);        %\nphiKM      = zeros(rows,Jactual);                    % sort the eigenvalues\nUnOrdphiKM = zeros(rows,Jactual);                    % in ascending order\nUnOrdphiKM = Q(:,2:Jactual+1)*phiT;                  %\nfor j = 1:Jactual,                                   % resequence the e-vectors\n  phiKM(:,j) = UnOrdphiKM(:,ordering(j));            % to correspond to the\nend                                                  % e-values\n"
  },
  {
    "path": "tests/inputs/issues/528/Mathematica_1.m",
    "content": "(* http://spot.colorado.edu/~sitelic/samplecode/mathematica/imagesfile.html\n *)\n\nimage = Import[\"denise.png\",\"PNG\"]   (* or *)\n\nimage = Import[\"denise.gif\",\"GIF\"]\n\nA = image[[1,1]]/255.;\nListDensityPlot[A,Mesh->False, AspectRatio->Automatic]\n\n(*\n        -- or -- \n *)\n\nShow[Graphics[Raster[A]], AspectRatio->Automatic]\n\n\nblurA = ListConvolve[Table[1/25,{5},{5}],A];\n\nShow[Graphics[Raster[blurA]], AspectRatio->Automatic]\nB = Fourier[A];\n\n(*\n          delete\n    higher frequencies *)\n\nB[[Range[30,278],All]]=0;\n\nB[[All,Range[30,202]]]=0;\n\nShow[Graphics[Raster[ Re[InverseFourier[B]] ]], AspectRatio->Automatic]\n"
  },
  {
    "path": "tests/inputs/issues/528/Octave.m",
    "content": "% from http://www.roesler-ac.de/wolfram/hello.htm\r\n#Hello World in Octave (http://www.octave.org/)\r\nprintf(\"Hello World\\n\");\r\n"
  },
  {
    "path": "tests/inputs/issues/528/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/528/hello.f",
    "content": "c     Hello World\n*     Hello World\n!     Hello World\n      program hello\n      implicit none\n      print '(\"Hello, World!\")'\n      end\n      ! a fancy comment\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/528/matlab_line_colors.m",
    "content": "%{\nhttps://www.mathworks.com/matlabcentral/fileexchange/42673-beautiful-and-distinguishable-line-colors-colormap\n%}\n\n% LINE COLORS\nN=6;\nX = linspace(0,pi*3,1000);\nY = bsxfun(@(x,n)sin(x+2*n*pi/N), X.', 1:N);\nC = linspecer(N);\naxes('NextPlot','replacechildren', 'ColorOrder',C);\nplot(X,Y,'linewidth',5)\nylim([-1.1 1.1]);\n\n%{\n  SIMPLER LINE COLOR EXAMPLE\n%}\nN = 6; X = linspace(0,pi*3,1000);\nC = linspecer(N)\nhold off;\nfor ii=1:N\nY = sin(X+2*ii*pi/N);\nplot(X,Y,'color',C(ii,:),'linewidth',3);\nhold on;\nend\n\n%{\n  COLORMAP EXAMPLE\n%}\nA = rand(15);\nfigure; imagesc(A); % default colormap\nfigure; imagesc(A); colormap(linspecer); % linspecer colormap\n"
  },
  {
    "path": "tests/inputs/issues/528/qsort_demo.m",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\n/*\n        Al Danial April 25 2000\n*/\n\n#define ELEMENTS 1000\n\nstatic int compar_string(const void *a, const void *b){\n        return (strcmp( (char *)a, (char *)b));\n}\n\nint comp(const void *a, const void *b ) {\n    return *(int *)a - * (int *)b;\n}\n\nmain(){\n\n        int x, i;\n        char *string;\n        struct sort_test_t {\n                int s;\n        } ;\n\n        struct sort_test_t sort_test[ELEMENTS];\n\n        /* inititalize the array */\n        for (i=0;i<ELEMENTS;i++) {\n                /* produce a random variable */\n                x=1+(100000.0*rand()/(RAND_MAX+1.0));\n                /* load the variable into the string as an array */\n                sort_test[i].s = (int) x;\n                /*\n                printf(\"unsorted %d %d\\n\", i, sort_test[i].s);\n                */\n        }\n\n        /* sort the array */\n        qsort(sort_test, ELEMENTS, sizeof(sort_test[0]), &comp);\n\n        /* output the sorted array */\n        for (i=0;i<ELEMENTS;i++) {\n                printf(\"sorted %d %d\\n\", i, sort_test[i].s);\n        }\n\n}\n"
  },
  {
    "path": "tests/inputs/issues/530/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/537/my_define.txt",
    "content": "﻿VERTICA_SQL\r\n    filter call_regexp_common C\r\n    filter remove_matches ^\\s*--\r\n    filter remove_inline --.*$\r\n    extension VSQL\r\n    extension vsql\r\n    3rd_gen_scale 2.29\r\n"
  },
  {
    "path": "tests/inputs/issues/537/sourceCounter.vsql",
    "content": "USE \r\nGO\r\n/****** Object:  StoredProcedure [dbo].[P_EDI_Book]    Script Date: 2020/05/22 11:41:27 ******/\r\nSET ANSI_NULLS ON\r\nGO\r\nSET QUOTED_IDENTIFIER ON\r\nGO\r\n\r\n\r\n--  ＜下り＞\r\n--\r\n   ,@ext_day int = -5\t\t\t\t\t\t--2017-02-28 更新\r\n--   ,@ext_day int = -1\t\t\t\t\t\t--2016-08-17 更新\r\n   ,@ext_time datetime = '00:00:00'\r\n   \r\nAS\r\n--=================================================\r\n-- 開始\r\n--=================================================\r\nSP_MAIN:\r\n  SET NOCOUNT ON\r\n\r\n--=============================================\r\n-- なんとなく共通処理\r\n--=============================================\r\n\r\n  -- 必要なローカル変数定義\r\n  Declare @tran_ct int           -- トランザクションカウント\r\n \r\n  Declare @FETCH_STATUS int -- @@FETCH_STATUSワーク\r\n\r\n--=================================================\r\n-- パラメタチェック\r\n--=================================================\r\n\r\n "
  },
  {
    "path": "tests/inputs/issues/538/add.elm",
    "content": "{--}\nadd x y = x + y\n--}\n"
  },
  {
    "path": "tests/inputs/issues/539/nested_comments.elm",
    "content": "a = 1\n{- a multiline comment\n   {- can be nested -}\n-}\nb = 2\n"
  },
  {
    "path": "tests/inputs/issues/540/Hello.f",
    "content": "c     Hello World\n*     Hello World\n!     Hello World\n      program hello\n      implicit none\n      print '(\"Hello, World!\")'\n      end\n      ! a fancy comment\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/542/txt_lang_def.txtt",
    "content": "Text File\n    filter remove_matches .*\n    extension txtt\n    3rd_gen_scale 1.00\n"
  },
  {
    "path": "tests/inputs/issues/577/diff_list_file.txt",
    "content": "== tour.swift | tour2.swift ; junk\n"
  },
  {
    "path": "tests/inputs/issues/577/options.txt",
    "content": "--skip-uniqueness\n"
  },
  {
    "path": "tests/inputs/issues/577/tour.swift",
    "content": "// https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-XID_1\n\n//    let implicitInteger = 70\n//    let implicitDouble = 70.0\n//    let explicitDouble: Double = 70\n//\n//\n//\n//    let label = \"The width is \"\n//    let width = 94\n//    let widthLabel = label + String(width)\n\n\n\n    var shoppingList = [\"catfish\", \"water\", \"tulips\", \"blue paint\"]\n    shoppingList[1] = \"bottle of water\"\n    var occupations = [\n          // \"Malcolm\": \"Captain\",\n    \"Kaylee\": \"Mechanic\",\n    ]\n        /* occupations[\"Jayne\"] = \"Public Relations\" */\n\n\n\n    let individualScores = [75, 43, 103, 87, 12]\n    var teamScore = 0\n    for score in individualScores {\n    if score > 50 {\n    teamScore += 3\n    } else {\n    teamScore += 1\n    }\n    }\n    teamScore\n\n\n\n    var optionalString: String? = \"Hello\"\n    optionalString == nil\n    var optionalName: String? = \"John Appleseed\"\n    var greeting = \"Hello!\"\n    if let name = optionalName {\n    greeting = \"Hello, \\(name)\"\n    }\n\n\n\n    let vegetable = \"red pepper\"\n    switch vegetable {\n    case \"celery\":\n    let vegetableComment = \"Add some raisins and make ants on a log.\"\n    case \"cucumber\", \"watercress\":\n    let vegetableComment = \"That would make a good tea sandwich.\"\n    case let x where x.hasSuffix(\"pepper\"):\n    let vegetableComment = \"Is it a spicy \\(x)?\"\n    default:\n    let vegetableComment = \"Everything tastes good in soup.\"\n    }\n\n\n\n    let interestingNumbers = [\n    \"Prime\": [2, 3, 5, 7, 11, 13],\n    \"Fibonacci\": [1, 1, 2, 3, 5, 8],\n    \"Square\": [1, 4, 9, 16, 25],\n    ]\n    var largest = 0\n    for (kind, numbers) in interestingNumbers {\n    for number in numbers {\n    if number > largest {\n    largest = number\n    }\n    }\n    }\n    largest\n\n\n\n    func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {\n    for item in list {\n    if condition(item) {\n    return true\n    }\n    }\n    return false\n    }\n    func lessThanTen(number: Int) -> Bool {\n    return number < 10\n    }\n    var numbers = [20, 19, 7, 12]\n    hasAnyMatches(numbers, lessThanTen) /*\nFunctions are actually a special case of closures. You can write a closure without a name by surrounding code with braces ({}). Use in to separate the arguments and return type from the body. */\n\n    numbers.map({\n    (number: Int) -> Int in\n    let result = 3 * number\n    return result\n    })\n\n\n\n"
  },
  {
    "path": "tests/inputs/issues/577/tour2.swift",
    "content": "// https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-XID_1\n\n//    let implicitInteger = 70\n//    let implicitDouble = 70.0\n//    let explicitDouble: Double = 70\n//\n//\n//\n//    let label = \"The width is \"\n//    let width = 94\n//    let widthLabel = label + String(width)\n\n\n\n    var shoppingList = [\"catfish\", \"water\", \"tulips\", \"blue paint\"]\n    shoppingList[1] = \"bottle of water\"\n    var occupations = [\n          // \"Malcolm\": \"Captain\",\n    \"Kaylee\": \"Mechanic\",\n    ]\n        /* occupations[\"Jayne\"] = \"Public Relations\" */\n\n\n\n    let individualScores = [75, 43, 103, 87, 12]\n    var teamScore = 0\n    for score in individualScores {\n    if score > 50 {\n    teamScore += 3\n    } else {\n    teamScore += 1\n    }\n    }\n    teamScore\n\n\n\n    var optionalString: String? = \"Hello\"\n    optionalString == nil\n    var optionalName: String? = \"John Appleseed\"\n    var greeting = \"Hello!\"\n    if let name = optionalName {\n    greeting = \"Hello, \\(name)\"\n    }\n\n\n\n    let vegetable = \"red pepper\"\n    switch vegetable {\n    case \"celery\":\n    let vegetableComment = \"Add some raisins and make ants on a log.\"\n    case \"cucumber\", \"watercress\":\n    let vegetableComment = \"That would make a good tea sandwich.\"\n    case let x where x.hasSuffix(\"pepper\"):\n    let vegetableComment = \"Is it a spicy \\(x)?\"\n    default:\n    let vegetableComment = \"Everything tastes good in soup.\"\n    }\n\n\n\n    let interestingNumbers = [\n    \"Prime\": [2, 3, 5, 7, 11, 13],\n    \"Fibonacci\": [1, 1, 2, 3, 5, 8],\n    \"Square\": [1, 4, 9, 16, 25],\n    ]\n    var largest = 0\n    for (kind, numbers) in interestingNumbers {\n    for number in numbers {\n    if number > largest {\n    largest = number\n    }\n    }\n    }\n    largest\n\n\n\n    func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {\n    for item in list {\n    if condition(item) {\n    return true\n    }\n    }\n    return false\n    }\n    func lessThanTen(number: Int) -> Bool {\n    return number < 10\n    }\n    var numbers = [20, 19, 7, 12]\n    hasAnyMatches(numbers, lessThanTen) /*\nFunctions are actually a special case of closures. You can write a closure without a name by surrounding code with braces ({}). Use in to separate the arguments and return type from the body. */\n\n    numbers.map({\n    (number: Int) -> Int in\n    let result = 3 * number\n    return result\n    })\n\n\n\n"
  },
  {
    "path": "tests/inputs/issues/579/csharp-autogen.cs",
    "content": "//------------------------------------------------------------------------------\r\n// <auto-generated>\r\n// This code was generated by a tool.\r\n// Runtime Version:2.0.50727.42\r\n//\r\n// Changes to this file may cause incorrect behavior and will be lost if\r\n// the code is regenerated.\r\n// </auto-generated>\r\n//------------------------------------------------------------------------------\r\n\r\nnamespace FirstWeb\r\n{\r\n    public partial class _Default\r\n    {\r\n\r\n        /// <summary>\r\n        /// form1 control.\r\n        /// </summary>\r\n        /// <remarks>\r\n        /// Auto-generated field.\r\n        /// To modify move field declaration from designer file to code-behind file.\r\n        /// </remarks>\r\n        protected global::System.Web.UI.HtmlControls.HtmlForm form1;\r\n    }\r\n}"
  },
  {
    "path": "tests/inputs/issues/596/def.txt",
    "content": "Yarn\n    filter remove_matches ^\\s*#\n    filename yarn.lock\n    3rd_gen_scale 2.11\n"
  },
  {
    "path": "tests/inputs/issues/596/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/597/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/606/in/nomad_job.hcl",
    "content": "/*\n https://www.nomadproject.io/docs/job-specification/index.html\n */\n\n# This declares a job named \"docs\". There can be exactly one\n# job declaration per job file.\njob \"docs\" {\n  # Specify this job should run in the region named \"us\". Regions\n  # are defined by the Nomad servers' configuration.\n  region = \"us\"\n\n  # Spread the tasks in this job between us-west-1 and us-east-1.\n  datacenters = [\"us-west-1\", \"us-east-1\"]\n\n  # Run this job as a \"service\" type. Each job type has different\n  # properties. See the documentation below for more examples.\n  type = \"service\"\n\n  # Specify this job to have rolling updates, two-at-a-time, with\n  # 30 second intervals.\n  update {\n    stagger      = \"30s\"\n    max_parallel = 2\n  }\n\n  # A group defines a series of tasks that should be co-located\n  # on the same client (host). All tasks within a group will be\n  # placed on the same host.\n  group \"webs\" {\n    # Specify the number of these tasks we want.\n    count = 5\n\n    # Create an individual task (unit of work). This particular\n    # task utilizes a Docker container to front a web application.\n    task \"frontend\" {\n      # Specify the driver to be \"docker\". Nomad supports\n      # multiple drivers.\n      driver = \"docker\"\n\n      # Configuration is specific to each driver.\n      config {\n        image = \"hashicorp/web-frontend\"\n      }\n\n      # The service block tells Nomad how to register this service\n      # with Consul for service discovery and monitoring.\n      service {\n        # This tells Consul to monitor the service on the port\n        # labelled \"http\". Since Nomad allocates high dynamic port\n        # numbers, we use labels to refer to them.\n        port = \"http\"\n\n        check {\n          type     = \"http\"\n          path     = \"/health\"\n          interval = \"10s\"\n          timeout  = \"2s\"\n        }\n      }\n\n      # It is possible to set environment variables which will be\n      # available to the task when it runs.\n      env {\n        \"DB_HOST\" = \"db01.example.com\"\n        \"DB_USER\" = \"web\"\n        \"DB_PASS\" = \"loremipsum\"\n      }\n\n      # Specify the maximum resources required to run the task,\n      # include CPU, memory, and bandwidth.\n      resources {\n        cpu    = 500 # MHz\n        memory = 128 # MB\n\n        network {\n          mbits = 100\n\n          # This requests a dynamic port named \"http\". This will\n          # be something like \"46283\", but we refer to it via the\n          # label \"http\".\n          port \"http\" {}\n\n          # This requests a static port on 443 on the host. This\n          # will restrict this task to running once per host, since\n          # there is only one port 443 on each host.\n          port \"https\" {\n            static = 443\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/issues/611/cmakelists.txt",
    "content": "# portion of https://github.com/lammps/lammps/raw/master/cmake/CMakeLists.txt\n# renamed to lowercase to test Windows behavior\n########################################\n# CMake build system\n# This file is part of LAMMPS\n# Created by Christoph Junghans and Richard Berger\ncmake_minimum_required(VERSION 3.10)\n# set policy to silence warnings about ignoring <PackageName>_ROOT but use it\nif(POLICY CMP0074)\n  cmake_policy(SET CMP0074 NEW)\nendif()\n# set policy to silence warnings about missing executable permissions in\n# pythonx.y-config when cross-compiling. review occasionally if it may be set to NEW\nif(POLICY CMP0109)\n  cmake_policy(SET CMP0109 OLD)\nendif()\n########################################\n\nproject(lammps CXX)\nset(SOVERSION 0)\n\nget_filename_component(LAMMPS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/.. ABSOLUTE)\nget_filename_component(LAMMPS_LIB_BINARY_DIR ${CMAKE_BINARY_DIR}/lib ABSOLUTE)\n\nset(LAMMPS_SOURCE_DIR     ${LAMMPS_DIR}/src)\nset(LAMMPS_LIB_SOURCE_DIR ${LAMMPS_DIR}/lib)\nset(LAMMPS_DOC_DIR        ${LAMMPS_DIR}/doc)\nset(LAMMPS_TOOLS_DIR      ${LAMMPS_DIR}/tools)\nset(LAMMPS_PYTHON_DIR     ${LAMMPS_DIR}/python)\nset(LAMMPS_POTENTIALS_DIR ${LAMMPS_DIR}/potentials)\n\nset(LAMMPS_DOWNLOADS_URL \"https://download.lammps.org\" CACHE STRING \"Base URL for LAMMPS downloads\")\nset(LAMMPS_POTENTIALS_URL \"${LAMMPS_DOWNLOADS_URL}/potentials\")\nset(LAMMPS_THIRDPARTY_URL \"${LAMMPS_DOWNLOADS_URL}/thirdparty\")\nmark_as_advanced(LAMMPS_DOWNLOADS_URL)\n\nfind_package(Git)\n\n# by default, install into $HOME/.local (not /usr/local), so that no root access (and sudo!!) is needed\nif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)\n  if((CMAKE_SYSTEM_NAME STREQUAL \"Windows\") AND (NOT CMAKE_CROSSCOMPILING))\n    set(CMAKE_INSTALL_PREFIX \"$ENV{USERPROFILE}/LAMMPS\" CACHE PATH \"Default install path\" FORCE)\n  else()\n    set(CMAKE_INSTALL_PREFIX \"$ENV{HOME}/.local\" CACHE PATH \"Default install path\" FORCE)\n  endif()\nendif()\n\n# If enabled, no need to use LD_LIBRARY_PATH / DYLD_LIBRARY_PATH when installed\noption(LAMMPS_INSTALL_RPATH \"Set runtime path for shared libraries linked to LAMMPS binaries\" OFF)\nif(LAMMPS_INSTALL_RPATH)\n  set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR})\n  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)\nendif()\n\n# Cmake modules/macros are in a subdirectory to keep this file cleaner\nset(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Modules)\n\n# make sure LIBRARY_PATH is set if environment variable is set\nif(DEFINED ENV{LIBRARY_PATH})\n  list(APPEND CMAKE_LIBRARY_PATH \"$ENV{LIBRARY_PATH}\")\n  message(STATUS \"Appending $ENV{LIBRARY_PATH} to CMAKE_LIBRARY_PATH: ${CMAKE_LIBRARY_PATH}\")\nendif()\n\ninclude(LAMMPSUtils)\n\nget_lammps_version(${LAMMPS_SOURCE_DIR}/version.h PROJECT_VERSION)\n\ninclude(PreventInSourceBuilds)\n\nif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)\n  set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING \"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel.\" FORCE)\nendif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)\nstring(TOUPPER \"${CMAKE_BUILD_TYPE}\" BTYPE)\n\n# check for files auto-generated by make-based buildsystem\n# this is fast, so check for it all the time\ncheck_for_autogen_files(${LAMMPS_SOURCE_DIR})\n\n######################################################################\n# compiler tests\n# these need ot be done early (before further tests).\n#####################################################################\ninclude(CheckIncludeFileCXX)\n\n# set required compiler flags and compiler/CPU arch specific optimizations\nif((CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\") OR (CMAKE_CXX_COMPILER_ID STREQUAL \"IntelLLVM\"))\n  if(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n    if (CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\")\n      set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} /Qrestrict\")\n    endif()\n    if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4)\n      set(CMAKE_TUNE_DEFAULT \"/QxCOMMON-AVX512\")\n    else()\n      set(CMAKE_TUNE_DEFAULT \"/QxHost\")\n    endif()\n  else()\n    set(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -restrict\")\n    if(CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.3 OR CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL 17.4)\n      set(CMAKE_TUNE_DEFAULT \"-xCOMMON-AVX512\")\n    else()\n      set(CMAKE_TUNE_DEFAULT \"-xHost\")\n    endif()\n  endif()\nendif()\n\n# we require C++11 without extensions. Kokkos requires at least C++14 (currently)\nset(CMAKE_CXX_STANDARD 11)\nif(PKG_KOKKOS AND (CMAKE_CXX_STANDARD LESS 14))\n  set(CMAKE_CXX_STANDARD 14)\nendif()\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nset(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL \"Use compiler extensions\")\n# ugly hacks for MSVC which by default always reports an old C++ standard in the __cplusplus macro\n# and prints lots of pointless warnings about \"unsafe\" functions\nif(MSVC)\n  add_compile_options(/Zc:__cplusplus)\n  add_compile_options(/wd4244)\n  add_compile_options(/wd4267)\n  add_compile_definitions(_CRT_SECURE_NO_WARNINGS)\nendif()\n\n# export all symbols when building a .dll file on windows\nif((CMAKE_SYSTEM_NAME STREQUAL \"Windows\") AND BUILD_SHARED_LIBS)\n  set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)\nendif()\n\n########################################################################\n# User input options                                                   #\n########################################################################\nset(LAMMPS_MACHINE \"\" CACHE STRING \"Suffix to append to lmp binary (WON'T enable any features automatically\")\nmark_as_advanced(LAMMPS_MACHINE)\nif(LAMMPS_MACHINE)\n  set(LAMMPS_MACHINE \"_${LAMMPS_MACHINE}\")\nendif()\nset(LAMMPS_BINARY lmp${LAMMPS_MACHINE})\n\noption(BUILD_SHARED_LIBS \"Build shared library\" OFF)\nif(BUILD_SHARED_LIBS) # for all pkg libs, mpi_stubs and linalg\n  set(CMAKE_POSITION_INDEPENDENT_CODE ON)\nendif()\n\noption(BUILD_TOOLS \"Build and install LAMMPS tools (msi2lmp, binary2txt, chain)\" OFF)\noption(BUILD_LAMMPS_SHELL \"Build and install the LAMMPS shell\" OFF)\n\n# allow enabling clang-tidy for C++ files\nset(ENABLE_CLANG_TIDY OFF CACHE BOOL \"Include clang-tidy processing when compiling\")\nif(ENABLE_CLANG_TIDY)\n  set(CMAKE_CXX_CLANG_TIDY \"clang-tidy;-checks=*-header-filter=.*\" CACHE STRING \"\")\nendif()\n\ninclude(GNUInstallDirs)\nfile(GLOB ALL_SOURCES ${LAMMPS_SOURCE_DIR}/[^.]*.cpp)\nfile(GLOB MAIN_SOURCES ${LAMMPS_SOURCE_DIR}/main.cpp)\nlist(REMOVE_ITEM ALL_SOURCES ${MAIN_SOURCES})\nadd_library(lammps ${ALL_SOURCES})\n\n# tell CMake to export all symbols to a .dll on Windows with MinGW cross-compilers\nif(BUILD_SHARED_LIBS AND (CMAKE_SYSTEM_NAME STREQUAL \"Windows\") AND CMAKE_CROSSCOMPILING)\n  set_target_properties(lammps PROPERTIES LINK_FLAGS \"-Wl,--export-all-symbols\")\nendif()\n\nadd_executable(lmp ${MAIN_SOURCES})\ntarget_link_libraries(lmp PRIVATE lammps)\nset_target_properties(lmp PROPERTIES OUTPUT_NAME ${LAMMPS_BINARY})\ninstall(TARGETS lmp EXPORT LAMMPS_Targets DESTINATION ${CMAKE_INSTALL_BINDIR})\n\noption(CMAKE_VERBOSE_MAKEFILE \"Generate verbose Makefiles\" OFF)\n\nset(STANDARD_PACKAGES\n  ADIOS\n  ASPHERE\n  ATC\n  AWPMD\n  BOCS\n  BODY\n  BROWNIAN\n  CG-DNA\n  CG-SDK\n  CLASS2\n  COLLOID\n  COLVARS\n  COMPRESS\n  DIELECTRIC\n  DIFFRACTION\n  DIPOLE\n  DPD-BASIC\n  DPD-MESO\n  DPD-REACT\n  DPD-SMOOTH\n  DRUDE\n  EFF\n  EXTRA-COMPUTE\n  EXTRA-DUMP\n  EXTRA-FIX\n  EXTRA-MOLECULE\n  EXTRA-PAIR\n  FEP\n  GRANULAR\n  H5MD\n  INTERLAYER\n  KIM\n  KSPACE\n  LATBOLTZ\n  LATTE\n  MACHDYN\n  MANIFOLD\n  MANYBODY\n  MC\n  MDI\n  MEAM\n  MESONT\n  MESSAGE\n  MGPT\n  MISC\n  ML-HDNNP\n  ML-IAP\n  ML-PACE\n  ML-QUIP\n  ML-RANN\n  ML-SNAP\n  MOFFF\n  MOLECULE\n  MOLFILE\n  MPIIO\n  MSCG\n  NETCDF\n  ORIENT\n  PERI\n  PHONON\n  PLUGIN\n  PLUMED\n  POEMS\n  PTM\n  PYTHON\n  QEQ\n  QMMM\n  QTB\n  REACTION\n  REAXFF\n  REPLICA\n  RIGID\n  SCAFACOS\n  SHOCK\n  SMTBQ\n  SPH\n  SPIN\n  SRD\n  TALLY\n  UEF\n  VORONOI\n  VTK\n  YAFF)\n\nset(SUFFIX_PACKAGES CORESHELL GPU KOKKOS OPT INTEL OPENMP)\n\nforeach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES})\n  option(PKG_${PKG} \"Build ${PKG} Package\" OFF)\nendforeach()\n\n######################################################\n# packages with special compiler needs or external libs\n######################################################\ntarget_include_directories(lammps PUBLIC $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}>)\n\nif(PKG_ADIOS)\n  # The search for ADIOS2 must come before MPI because\n  # it includes its own MPI search with the latest FindMPI.cmake\n  # script that defines the MPI::MPI_C target\n  enable_language(C)\n  find_package(ADIOS2 REQUIRED)\n  target_link_libraries(lammps PRIVATE adios2::adios2)\nendif()\n\nif(NOT CMAKE_CROSSCOMPILING)\n  find_package(MPI QUIET)\n  option(BUILD_MPI \"Build MPI version\" ${MPI_FOUND})\nelse()\n  option(BUILD_MPI \"Build MPI version\" OFF)\nendif()\n\nif(BUILD_MPI)\n  # do not include the (obsolete) MPI C++ bindings which makes\n  # for leaner object files and avoids namespace conflicts\n  set(MPI_CXX_SKIP_MPICXX TRUE)\n  # We use a non-standard procedure to cross-compile with MPI on Windows\n  if((CMAKE_SYSTEM_NAME STREQUAL \"Windows\") AND CMAKE_CROSSCOMPILING)\n    include(MPI4WIN)\n    target_link_libraries(lammps PUBLIC MPI::MPI_CXX)\n  else()\n    find_package(MPI REQUIRED)\n    target_link_libraries(lammps PUBLIC MPI::MPI_CXX)\n    option(LAMMPS_LONGLONG_TO_LONG \"Workaround if your system or MPI version does not recognize 'long long' data types\" OFF)\n    if(LAMMPS_LONGLONG_TO_LONG)\n      target_compile_definitions(lammps PRIVATE -DLAMMPS_LONGLONG_TO_LONG)\n    endif()\n  endif()\nelse()\n  file(GLOB MPI_SOURCES ${LAMMPS_SOURCE_DIR}/STUBS/mpi.cpp)\n  add_library(mpi_stubs STATIC ${MPI_SOURCES})\n  set_target_properties(mpi_stubs PROPERTIES OUTPUT_NAME lammps_mpi_stubs${LAMMPS_MACHINE})\n  target_include_directories(mpi_stubs PUBLIC $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)\n  if(BUILD_SHARED_LIBS)\n    target_link_libraries(lammps PRIVATE mpi_stubs)\n    if(MSVC)\n      target_link_libraries(lmp PRIVATE mpi_stubs)\n      target_include_directories(lmp INTERFACE $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)\n      target_compile_definitions(lmp INTERFACE $<INSTALL_INTERFACE:LAMMPS_LIB_NO_MPI>)\n    endif(MSVC)\n    target_include_directories(lammps INTERFACE $<BUILD_INTERFACE:${LAMMPS_SOURCE_DIR}/STUBS>)\n    target_compile_definitions(lammps INTERFACE $<INSTALL_INTERFACE:LAMMPS_LIB_NO_MPI>)\n  else()\n    target_link_libraries(lammps PUBLIC mpi_stubs)\n  endif()\n  add_library(MPI::MPI_CXX ALIAS mpi_stubs)\nendif()\n\nset(LAMMPS_SIZES \"smallbig\" CACHE STRING \"LAMMPS integer sizes (smallsmall: all 32-bit, smallbig: 64-bit #atoms #timesteps, bigbig: also 64-bit imageint, 64-bit atom ids)\")\nset(LAMMPS_SIZES_VALUES smallbig bigbig smallsmall)\nset_property(CACHE LAMMPS_SIZES PROPERTY STRINGS ${LAMMPS_SIZES_VALUES})\nvalidate_option(LAMMPS_SIZES LAMMPS_SIZES_VALUES)\nstring(TOUPPER ${LAMMPS_SIZES} LAMMPS_SIZES)\ntarget_compile_definitions(lammps PUBLIC -DLAMMPS_${LAMMPS_SIZES})\n\n# posix_memalign is not available on Windows\nif(CMAKE_SYSTEM_NAME STREQUAL \"Windows\")\n  set(LAMMPS_MEMALIGN \"0\" CACHE STRING \"posix_memalign() is not available on Windows\" FORCE)\nelse()\n  set(LAMMPS_MEMALIGN \"64\" CACHE STRING \"enables the use of the posix_memalign() call instead of malloc() when large chunks or memory are allocated by LAMMPS. Set to 0 to disable\")\nendif()\nif(NOT ${LAMMPS_MEMALIGN} STREQUAL \"0\")\n  target_compile_definitions(lammps PRIVATE -DLAMMPS_MEMALIGN=${LAMMPS_MEMALIGN})\nendif()\n\noption(LAMMPS_EXCEPTIONS \"enable the use of C++ exceptions for error messages (useful for library interface)\" ${ENABLE_TESTING})\nif(LAMMPS_EXCEPTIONS)\n  target_compile_definitions(lammps PUBLIC -DLAMMPS_EXCEPTIONS)\nendif()\n"
  },
  {
    "path": "tests/inputs/issues/613/nav.scss",
    "content": "// https://blog.logrocket.com/the-definitive-guide-to-scss/\nnav {\n  background-color:#333;\n  padding:1em;\n  ul {\n    margin:0;\n    padding:0;\n    list-style:none;\n    li {\n      display:inline-block;\n    }\n  }\n}\n\nbutton {\n  background-color: #535353;\n  color: #000;\n  &:hover {\n    background-color: #000;\n/*\n    background-color: #050;\n*/\n    color: #fff;\n  }\n\n}\n"
  },
  {
    "path": "tests/inputs/issues/619/RA.s",
    "content": "; /****\nmov a, b\n; ****/\n"
  },
  {
    "path": "tests/inputs/issues/625/new/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/625/old/.gitignore",
    "content": "release_notes-?.??.txt\n"
  },
  {
    "path": "tests/inputs/issues/628/sample.graphql",
    "content": "# inline comment\n\n\"\"\"\nmulti line comment\n\"\"\"\n\nquery HeroNameAndFriends {\n  hero {\n    name\n    friends {\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/issues/644/UInt8.cs",
    "content": "﻿"
  },
  {
    "path": "tests/inputs/issues/657/C-Ansi.c",
    "content": "/* Hello World in C, Ansi-style */\n/* from http://www.roesler-ac.de/wolfram/hello.htm */\n\n#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\");\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "tests/inputs/issues/657/extra/Mathematica_1.m",
    "content": "(* http://spot.colorado.edu/~sitelic/samplecode/mathematica/imagesfile.html\n *)\n\nimage = Import[\"denise.png\",\"PNG\"]   (* or *)\n\nimage = Import[\"denise.gif\",\"GIF\"]\n\nA = image[[1,1]]/255.;\nListDensityPlot[A,Mesh->False, AspectRatio->Automatic]\n\n(*\n        -- or -- \n *)\n\nShow[Graphics[Raster[A]], AspectRatio->Automatic]\n\n\nblurA = ListConvolve[Table[1/25,{5},{5}],A];\n\nShow[Graphics[Raster[blurA]], AspectRatio->Automatic]\nB = Fourier[A];\n\n(*\n          delete\n    higher frequencies *)\n\nB[[Range[30,278],All]]=0;\n\nB[[All,Range[30,202]]]=0;\n\nShow[Graphics[Raster[ Re[InverseFourier[B]] ]], AspectRatio->Automatic]\n"
  },
  {
    "path": "tests/inputs/issues/657/hello.f",
    "content": "c     Hello World\n*     Hello World\n!     Hello World\n      program hello\n      implicit none\n      print '(\"Hello, World!\")'\n      end\n      ! a fancy comment\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/670/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/670/hi.py",
    "content": "#/usr/bin/env python\n# Works with both 2.x and 3.x versions of Python.\n\n# pound comment\n\nimport time\nprint('Hello.  The time is %f Unix epoch.' % (time.time()))  # inline comment\n\n\"\"\"\nDocstring,\n  also counted as comment.\n\"\"\"\n\n'''\nSingle\n  Quoted\n    Docstring'''"
  },
  {
    "path": "tests/inputs/issues/692/A.txt",
    "content": "../../diff/A\n../../diff/A/d2\n../../diff/A/d2/hi.py\n../../diff/A/d2/hello.java\n../../diff/A/d1\n../../diff/A/d1/hello.f90\n../../diff/A/hello.C\n"
  },
  {
    "path": "tests/inputs/issues/692/B.txt",
    "content": "# directory names are ignored\n../../diff/B/d2/hi.py\n../../diff/B/d1\n../../diff/B/d1/hello.f90\n../../diff/B/extra_file.pl\n../../diff/B/hello.C\n"
  },
  {
    "path": "tests/inputs/issues/701/demo.ml",
    "content": "let just_a_string = \"\n  (*\n\"\nlet x = 0\nlet also_a_string = \"\n  *)\n\"\nlet y = x\n"
  },
  {
    "path": "tests/inputs/issues/710/A/cal.data",
    "content": "   February 2023      \nSu Mo Tu We Th Fr Sa  \n          1  2  3  4  \n_\b _\b5  6  7  8  9 10 11  \n12 13 14 15 16 17 18  \n19 20 21 22 23 24 25  \n26 27 28              \n                      \n"
  },
  {
    "path": "tests/inputs/issues/710/A/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/710/B/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/710/test_files.list",
    "content": "Files removed: 1\n  - A/cal.data ; Text\n\nFile pairs compared: 1\n  == A/hello.C | B/hello.C ; C++\n"
  },
  {
    "path": "tests/inputs/issues/712/dir1/main.c",
    "content": "#include<stdio.h>\n\nint main(void){\n\tprintf(\"Hello world\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "tests/inputs/issues/712/dir1/sub_dir1/foo.txt",
    "content": "foo\n"
  },
  {
    "path": "tests/inputs/issues/712/dir2/foo.txt",
    "content": "foo\n"
  },
  {
    "path": "tests/inputs/issues/712/dir2/main.c",
    "content": "#include<stdio.h>\n\nint main(void){\n\tprintf(\"Hello world\\n\");\n\treturn 0;\n}\n"
  },
  {
    "path": "tests/inputs/issues/713/hello.C",
    "content": "// hello.C\n#include <iostream>\nint main ()\n{\n    std::cout << \"hello\" << std::endl;  // comment 1\n    std::cout << \"again\" << std::endl;  /* comment\n                                           2 */\n}\n"
  },
  {
    "path": "tests/inputs/issues/720/inputs.txt",
    "content": "These files are considered:\n    ../../Lanczos.m\n    ../../Mathematica_1.m\n    ../../matlab_line_colors.m\n    ../../Octave.m\n    ../../qsort_demo.m\n\nThese files are counted:\n    ../../Lanczos.m\n    ../../qsort_demo.m\n    ../../matlab_line_colors.m\n\n"
  },
  {
    "path": "tests/inputs/issues/722/Fortran77.f",
    "content": "C from http://www.roesler-ac.de/wolfram/hello.htm\nC     Hello World in Fortran 77\n\n      PROGRAM HELLO\n      PRINT*, 'Hello World!'\n      END\n"
  },
  {
    "path": "tests/inputs/issues/722/hello.f90",
    "content": "! Hello World\nprogram hello\n  implicit none\n  print '(\"Hello, World!\")'\nend program hello\n!hpf$ not a comment\n!omp$ not a comment either\n"
  },
  {
    "path": "tests/inputs/issues/722/hello.lua",
    "content": "-- single line comment\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/issues/735/excludes.txt",
    "content": "dd/bb/cc/MoreTeapotsRenderer.cpp\nignore_Fortran90.f90\n"
  },
  {
    "path": "tests/inputs/issues/753/Application_Data_Test.feature.cs",
    "content": "// ------------------------------------------------------------------------------\n//  <auto-generated>\n//      This code was generated by SpecFlow (https://www.specflow.org/).\n//      SpecFlow Version:3.9.0.0\n//      SpecFlow Generator Version:3.9.0.0\n// \n//      Changes to this file may cause incorrect behavior and will be lost if\n//      the code is regenerated.\n//  </auto-generated>\n// ------------------------------------------------------------------------------\n#region Designer generated code\n#pragma warning disable\nnamespace Foo_Bar.FeatureFiles\n{\n    using TechTalk.SpecFlow;\n    using System;\n    using System.Linq;\n    \n    \n    [System.CodeDom.Compiler.GeneratedCodeAttribute(\"TechTalk.SpecFlow\", \"3.9.0.0\")]\n    [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [NUnit.Framework.TestFixtureAttribute()]\n    [NUnit.Framework.DescriptionAttribute(\"Application Data_Test\")]\n    public partial class ApplicationData_Test\n    {\n        // ...\n    }\n}\n#pragma warning restore\n#endregion\n"
  },
  {
    "path": "tests/inputs/issues/753/assembly.cs",
    "content": "using System.Reflection;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyCompany(\"eventIS Interactive Solutions BV\")]\n[assembly: AssemblyProduct(\"Traxis\")]\n[assembly: AssemblyCopyright(\"Copyright <A9> 2006 - 2008 eventIS Interactive Solutions BV\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: AssemblyTrademark(\"\")]\n\n// Values in this file will be overwritten by the build process\n\n[assembly: AssemblyVersion(\"0.0.0.0\")]\n[assembly: AssemblyFileVersion(\"0.0.0.0\")]\n[assembly: AssemblyInformationalVersion(\"0.0.0.0\")]\n"
  },
  {
    "path": "tests/inputs/issues/753/csharp-designer.designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace StyleCop.CSharp {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"4.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Strings {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Strings() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"StyleCop.CSharp.Strings\", typeof(Strings).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to StyleCop.\n        /// </summary>\n        internal static string Title {\n            get {\n                return ResourceManager.GetString(\"Title\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/inputs/issues/781/fortran.inc",
    "content": "C https://en.wikibooks.org/wiki/Fortran/Fortran_examples\n! sum.f90\n! Performs summations using in a loop using EXIT statement\n! Saves input information and the summation in a data file\n\nprogram summation\n    implicit none\n    integer :: sum, a\n\n    print *, \"This program performs summations. Enter 0 to stop.\"\n    open (unit=10, file=\"SumData.DAT\")\n    sum = 0\n    do\n        print *, \"Add:\"\n        read *, a\n        if (a == 0) then\n            exit\n        else\n            sum = sum + a\n        end if\n        write (10,*) a\n    end do\n\n    print *, \"Summation =\", sum\n    write (10,*) \"Summation =\", sum\n    close(10)\nend\n\n"
  },
  {
    "path": "tests/inputs/issues/781/pascal.inc",
    "content": "(* https://en.wikibooks.org/wiki/Pascal_Programming/Examples *)\n{...........................................................................}\nProcedure PrinterTest;   { works in the text mode}\n\n  begin\n    rejestr.dx:=LPT1;  { Port Number to which the printer is attached ;  0 = LPT1 }\n    rejestr.ah:=2;     { Function Number ; printer port status }\n    Intr($17,rejestr); {BIOS Interrupt #17 : initializes the indicated printer port and returns its status }\n    if rejestr.ah=144  { 10010000B : (bit 7) =1  i (bit 4) =1  }\n       then writeLn('Printer on LPT1 is OK')\n       else writeLn('Printer on LPT1 is not OK');\n       WriteLst(Reset);\n  end; { Procedure PrinterTest }\n"
  },
  {
    "path": "tests/inputs/issues/781/test1.inc",
    "content": "<?php\n\n  /**\n  * Test file for php_count, part of SLOCCount.  This is a C-style comment.\n  * This file is different from .php.\n  */\n\n  // This is a C++-style comment.\n\n  # This is a shell-style comment.\n\n  # Here are 9 lines of code:\n\n  function get()\n  {\n    $total = 0;\n    $simplestring = 'hello';\n    $simplestring = '\\\\hello\\'';\n    $funkystring = \"hello\";\n    $funkystring = \"$hi\\\\\\\"\";\n    return 0;\n  }\n?>\n"
  },
  {
    "path": "tests/inputs/issues/784/.cloc-ignore",
    "content": "./src/net/companies/captcha.cs\n"
  },
  {
    "path": "tests/inputs/issues/784/src/net/companies/assembly.cs",
    "content": "using System.Reflection;\n\n// General Information about an assembly is controlled through the following\n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n\n[assembly: AssemblyCompany(\"eventIS Interactive Solutions BV\")]\n[assembly: AssemblyProduct(\"Traxis\")]\n[assembly: AssemblyCopyright(\"Copyright <A9> 2006 - 2008 eventIS Interactive Solutions BV\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: AssemblyTrademark(\"\")]\n\n// Values in this file will be overwritten by the build process\n\n[assembly: AssemblyVersion(\"0.0.0.0\")]\n[assembly: AssemblyFileVersion(\"0.0.0.0\")]\n[assembly: AssemblyInformationalVersion(\"0.0.0.0\")]\n"
  },
  {
    "path": "tests/inputs/issues/784/src/net/companies/captcha.cs",
    "content": "\"http://smalltalk.gnu.org/blog/bonzinip/captcha-simplest-gst-external-module\"\nDLD addModule: 'GD'.\nFileStream fileIn: 'GST_DIR/share/smalltalk/GD/GD.st'.\n\n\"A useful method... (will be in 3.0.1)\"\nSequenceableCollection extend [\n    atRandom [\n        ^self at: (Random between: 1 and: self size)\n    ]\n]\n\n\"Make a four character captcha.\"\nfontPath := '/usr/share/fonts/bitstream-vera/Vera.ttf'.\nauthChars := '0123456789'.\nauthChars := authChars, 'abcdefghijklmnopqrstuvwxyz'.\nauthChars := authChars, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.\n\nauthString := String streamContents: [ :s |.\n   4 timesRepeat: [ s nextPut: authChars atRandom ]].\n\nGD\n    imageString: authString\n    font: fontPath\n    foreground: #[255 255 255]\n    background: #[0 0 0]\n    size: 40\n    to: 'captcha.png'.\n"
  },
  {
    "path": "tests/inputs/issues/785/(dir)/test.svelte",
    "content": "<!--\n https://svelte.dev/examples#reactive-assignments -->\n<script>\n\tlet count = 0;\n\n\tfunction handleClick() {\n\t\tcount += 1;\n\t}\n</script>\n\n<button on:click={handleClick}>\n\tClicked {count} {count === 1 ? 'time' : 'times'}\n</button>\n"
  },
  {
    "path": "tests/inputs/issues/785/.cloc-ignore",
    "content": "./(dir)\n"
  },
  {
    "path": "tests/inputs/issues/785/ok/ok.sh",
    "content": "#!/bin/sh\necho \"ok\"\n"
  },
  {
    "path": "tests/inputs/issues/804/infoSQL.java",
    "content": "    public void infoSQL(String sql, String params, long count, long time) {\n        if (!isEnabled(TraceSystem.INFO)) {\n            return;\n        }\n        StringBuilder buff = new StringBuilder(sql.length() + params.length() + 20);\n        buff.append(lineSeparator).append(\"/*SQL\");\n        boolean space = false;\n        if (params.length() > 0) {\n            // This looks like a bug, but it is intentional:\n            // If there are no parameters, the SQL statement is\n            // the rest of the line. If there are parameters, they\n            // are appended at the end of the line. Knowing the size\n            // of the statement simplifies separating the SQL statement\n            // from the parameters (no need to parse).\n            space = true;\n            buff.append(\" l:\").append(sql.length());\n        }\n        if (count > 0) {\n            space = true;\n            buff.append(\" #:\").append(count);\n        }\n        if (time > 0) {\n            space = true;\n            buff.append(\" t:\").append(time);\n        }\n        if (!space) {\n            buff.append(' ');\n        }\n        buff.append(\"*/\");\n        StringUtils.javaEncode(sql, buff, false);\n        StringUtils.javaEncode(params, buff, false);\n        buff.append(';');\n        sql = buff.toString();\n        traceWriter.write(TraceSystem.INFO, module, sql, null);\n    }\n\n    /**\n     * Write Java source code with trace level DEBUG to the trace system.\n     *\n     * @param java the source code\n     */\n"
  },
  {
    "path": "tests/inputs/issues/805/text_block.java",
    "content": "// regular comment\npublic String getBlockOfHtml() {\nString request = \"\"\"\n            GET /*cho/foo HTT*/1.1\n            Host: local\n            Accept: */*\n            Co//ection: closed\n\n            \"\"\";\n\n    return \"\"\"\n            <html>\n              /* \n               * NOT comment\n               */\n                <body>\n                    <span>example text</span>\n                </body>\n            </html>\n            \"\"\";\n    }\n"
  },
  {
    "path": "tests/inputs/issues/806/huffman.java",
    "content": "public class Huffman\n{\n    static final int[][] CODES =\n        {\n            /*'\"' ( 34)  |11111110|01                         */        {0x3f9, 10},\n            /*''' ( 39)  |11111111|010                        */        {0x7fa, 11},\n        };\n    // Huffman decode tree stored in a flattened char array for good\n    // locality of reference.\n    // Build the Huffman lookup tree and LC TABLE\n}\n"
  },
  {
    "path": "tests/inputs/issues/811/inline_comment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<foo>\n    <bar/><!-- bar \n            is not \n            foo -->\n</foo>\n"
  },
  {
    "path": "tests/inputs/issues/816/star_slash_star.go",
    "content": "foo: = \"*/*\"\na: = 10\nb: = 20\nfoo: = \"*/*\"\n\n/*\n a comment\n */\n\nfoo: = `*/*`\na: = 10\nb: = 20\nfoo: = `*/*`\n"
  },
  {
    "path": "tests/inputs/issues/822/a/b/c.csv",
    "content": "aaa,bbb\nccc,ddd"
  },
  {
    "path": "tests/inputs/issues/822/a.csv",
    "content": "111,222"
  },
  {
    "path": "tests/inputs/issues/833/Developer/abc.txt",
    "content": "abc\n"
  },
  {
    "path": "tests/inputs/issues/833/Developer/clocTest/foo/bar/bar.swift",
    "content": "struct bar { }\n"
  },
  {
    "path": "tests/inputs/issues/833/Developer/clocTest/foo/foo.swift",
    "content": "struct foo {\n}\n"
  },
  {
    "path": "tests/inputs/issues/851/level_1/flatbuffers.fbs",
    "content": "\n/* Comment 1 */\ntable TestTable {\n\t// Comment 2\n  Item: int32;\n}"
  },
  {
    "path": "tests/inputs/issues/851/level_1/hello.lua",
    "content": "-- single line comment\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/issues/851/level_1/level_2/hello_2.lua",
    "content": "-- another instance\n-- single line comment\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello 2, world\")\nprint([[not a comment]])\n"
  },
  {
    "path": "tests/inputs/issues/862/Fortran77.f",
    "content": "C from http://www.roesler-ac.de/wolfram/hello.htm\nC     Hello World in Fortran 77\n\n      PROGRAM HELLO\n      PRINT*, 'Hello World!'\n      END\n"
  },
  {
    "path": "tests/inputs/issues/862/a.py",
    "content": "#!/usr/bin/env python\nimport numpy as np\n\nfrom pylab import gca\n\nlabels = [\"Baseline\", \"System\"]\ndata =   [3.75               , 4.75]\nerror =  [0.3497             , 0.3108]\n\nxlocations = na.array(range(len(data)))+0.5\nwidth = 0.6\n# bar chart with hollow bars:\nbar(xlocations, data, yerr=error, width=width, edgecolor='k', facecolor='none')\nyticks(range(0, 8))\nxticks(xlocations+ width/2, labels)\nxlim(0, xlocations[-1]+width*2)\ntitle(\"Average Ratings on the Training Set\")\ngca().get_xaxis().tick_bottom()\ngca().get_yaxis().tick_left()\n\nshow()\n"
  },
  {
    "path": "tests/inputs/issues/862/b.py",
    "content": "#!/usr/bin/env python\nimport numpy.numarray as na\n\nfrom pylab import *\n\nlabels = [\"Baseline\", \"System\"]\ndata =   [3.75               , 4.75]\nerror =  [0.3497             , 0.3108]\n\nxlocations = na.array(range(len(data)))+0.5\nwidth = 0.5\n# bar chart with hollow bars:\nbar(xlocations, data, yerr=error, width=width, edgecolor='k', facecolor='none')\nyticks(range(0, 8))\nxticks(xlocations+ width/2, labels)\nxlim(0, xlocations[-1]+width*2)\ntitle(\"Average Ratings on the Training Set\")\ngca().get_xaxis().tick_bottom()\ngca().get_yaxis().tick_left()\n\nshow()\n"
  },
  {
    "path": "tests/inputs/issues/862/hello.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n  puts(\"Hello World!\")\n  ;\n  return EXIT_SUCCESS\n  ;\n}\n"
  },
  {
    "path": "tests/inputs/issues/898/irregular'file.md",
    "content": "---\nid: 5dc174fcf86c76b9248c6eb3\ntitle: Step 2\nchallengeType: 0\ndashedName: step-2\ndemoType: onLoad                                                                                                                 ---\n\n# --description--\n\nIn this workshop, you will learn how to work with basic HTML elements like\nheadings, paragraphs.\n\n"
  },
  {
    "path": "tests/inputs/issues/898/regular.md",
    "content": "---\nid: 5dc174fcf86c76b9248c6eb2\ntitle: Step 1\nchallengeType: 0\ndashedName: step-1\ndemoType: onLoad                                                                                                                 ---\n\n# --description--\n\nIn this workshop, you will learn how to work with basic HTML elements like\nheadings, paragraphs, and lists by building a cat photo app.\n\n"
  },
  {
    "path": "tests/inputs/issues/906/current_version.py",
    "content": "\r\nimport sys\r\nimport os\r\nimport gitlab\r\nfrom sqlalchemy import text\r\nfrom sqlalchemy import create_engine, select, MetaData, Table, insert\r\nimport concurrent.futures\r\nfrom functools import partial\r\nfrom gitlab.exceptions import GitlabGetError\r\nimport concurrent.futures\r\nimport multiprocessing\r\nfrom datetime import datetime, timedelta\r\nimport logging\r\nimport time\r\nfrom sqlalchemy.ext.declarative import declarative_base\r\nfrom sqlalchemy.orm import sessionmaker\r\nimport json\r\n\r\nimport configparser\r\nconfig = configparser.ConfigParser()\r\n\r\n\r\ns_config = \"\"\"\r\n[GITLAB]\r\nxxxxx\r\nxxxxx\r\n\r\n[HGITLAB]\r\nxxxxx\r\nxxxxx\r\n\r\n[GITLAB2]\r\nxxxxx\r\nxxxxx\r\n\r\n[DATABASE]\r\nxxxxx\r\nxxxxx\r\n\"\"\"\r\n\r\nconfig.read_string(s_config)\r\n\r\n\r\n\r\ndef main():\r\n    \"\"\"main function that runs the analyze method based on schedule\r\n    # \"\"\"\r\n\r\n    engine = connectDB()\r\n\r\n    # or_code = sys.argv[1]\r\n    # Configure the logger\r\n    log_file_path = 'outputAllOrCode.log'\r\n    logger = logging.getLogger(__name__)\r\n    logger.setLevel(logging.INFO)\r\n    file_handler = logging.FileHandler(log_file_path)\r\n    file_handler.setLevel(logging.INFO)\r\n    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\r\n    file_handler.setFormatter(formatter)\r\n    logger.addHandler(file_handler)\r\n    print(\"Automatically Mapping Technology and extentions from Repos to DB table\")\r\n    logger.info(\"Automatically Mapping Technology and extentions from Repos to DB table\")\r\n\r\n    orcode_query = \"(select distinct(or_code)\\\r\n        from master_orcode mo left join tbl_project_orcode_mapping tpo on(tpo.orcode_id = mo.id) left join projects_master pm\\\r\n        on(pm.project_id = tpo.project_id) where mo.is_del != 1 and perspective in ('LINES_OF_CODE', 'COMBINATION') and \\\r\n        mo.or_code in (select or_code from master_isg_projects where status != 'Closed'))\"\r\n    orcodes = engine.execute(orcode_query)\r\n    orcode_list = [result[0] for result in orcodes]\r\n\r\n    for orcode in orcode_list:\r\n        print(f\"Now Running for orcode {orcode}\")\r\n        mapTechExtensions(engine,orcode,logger)\r\n\r\n    print(\"Script Executed now exiting code\")\r\n    logger.info(\"Script Executed now exiting code\")\r\n    exit(0)\r\n\r\n\r\ndef mapTechExtensions(engine,or_code,logger):\r\n\r\n\r\n    try:\r\n        project_query = text(\"select git_project_id, path, domain from projects_master where project_id in \\\r\n        (select project_id from tbl_project_orcode_mapping where orcode_id in\\\r\n        (select id from master_orcode where or_code in (:or_code)))\")\r\n        result = engine.execute(project_query, or_code=or_code)\r\n        rows = result.fetchall()\r\n\r\n        # Create a metadata object\r\n        metadata = MetaData(bind=engine)\r\n\r\n        # Define the tbl_orcode_extension_mapping table\r\n        tbl_orcode_extension_mapping = Table('tbl_orcode_extension_mapping', metadata, autoload=True)\r\n        master_technology_extension_mapping = Table('master_technology_extension_mapping', metadata, autoload=True)\r\n        tbl_extension_autosync_error_log = Table('tbl_extension_autosync_error_log', metadata, autoload=True)\r\n        current_date = datetime.now()\r\n        # Calculate the start date of the week (Monday)\r\n        start_of_week = current_date - timedelta(days=current_date.weekday())\r\n        # Set the activation_date variable\r\n        activation_date = start_of_week.date()\r\n        disabled_extension_query = text(\"SELECT extension FROM master_disabled_extensions WHERE is_del = 0\")\r\n        disabled_extensions = engine.execute(disabled_extension_query)\r\n        by_default_disabled_ext = [result[0] for result in disabled_extensions]\r\n        # by_default_disabled_ext=['.txt','.log','.png','.jpeg','.tmp','.bak','.swp','.dmp']\r\n        official_domain = ['https://gitlab.kpit.com', 'https://h-gitlab.kpit.com', 'https://gitlab2.kpit.com']\r\n\r\n        for row in rows:\r\n            if row:\r\n                git_project_id, path, domain = row[0], row[1], row[2]\r\n\r\n                if domain not in official_domain:\r\n                    continue\r\n                # Create a connection\r\n                conn = engine.connect()\r\n                try:\r\n                    gl = connectGit(domain)\r\n                    project = gl.projects.get(git_project_id)\r\n                except Exception as e:\r\n                    if(e.error_message=='404 Project Not Found'):\r\n                        # Insert error log into the tbl_extension_autosync_error_log table\r\n                        stmt = select([tbl_extension_autosync_error_log]).where(\r\n                            (tbl_extension_autosync_error_log.c.or_code == or_code) &\r\n                            (tbl_extension_autosync_error_log.c.git_project_id == git_project_id)\r\n                        )\r\n                        extensionResult = conn.execute(stmt)\r\n                        if not extensionResult.fetchone():\r\n                            stmt = insert(tbl_extension_autosync_error_log).values(\r\n                                git_project_id=git_project_id,\r\n                                or_code=or_code,\r\n                                path=path,\r\n                                domain=domain,\r\n                                description=e.error_message\r\n                            )\r\n                            conn.execute(stmt)\r\n                        extensionResult.close()\r\n                    logger.error(f\"{e}\")\r\n\r\n                # Set a timeout for list_file_extensions_all_branches\r\n                timeout = 300  # 10 minutes in seconds\r\n                # List project repository files\r\n                # all_branch_extensions  = list_file_extensions_all_branches(project)\r\n                try:\r\n                    # Use multiprocessing.Pool to run the function with a timeout\r\n                    with multiprocessing.Pool(processes=1) as pool:\r\n                        result = pool.apply_async(list_file_extensions_all_branches, (project,))\r\n                        all_branch_extensions = result.get(timeout=timeout)\r\n\r\n                    # Continue processing with 'all_branch_extensions' as needed\r\n                    print(all_branch_extensions)\r\n\r\n                except multiprocessing.TimeoutError:\r\n                    print(f\"Timeout occurred for project {git_project_id}. Continuing with the next project.\")\r\n                    logger.error(f\"Timeout occurred for project {git_project_id}. Continuing with the next project.\")\r\n                    # Insert error log into the tbl_extension_autosync_error_log table\r\n                    stmt = select([tbl_extension_autosync_error_log]).where(\r\n                        (tbl_extension_autosync_error_log.c.or_code == or_code) &\r\n                        (tbl_extension_autosync_error_log.c.git_project_id == git_project_id)\r\n                    )\r\n                    extensionResult = conn.execute(stmt)\r\n                    if not extensionResult.fetchone():\r\n                        stmt = insert(tbl_extension_autosync_error_log).values(\r\n                            git_project_id = git_project_id,\r\n                            or_code=or_code,\r\n                            path=path,\r\n                            domain=domain,\r\n                            description=\"Unable to fetch data from gitlab Timeout Error Occurred\"\r\n                        )\r\n                        conn.execute(stmt)\r\n                    extensionResult.close()\r\n                except Exception as e:\r\n                    print(f\"An error occurred for project {git_project_id}: {e}\")\r\n                    logger.error(f\"An error occurred for project {git_project_id}: {e}\")\r\n\r\n\r\n                # with open('D:/CTO Project(Insights)/automateTechnologyExtensionMapping/tecnology.txt', 'r') as file:\r\n                #     TechnologyData = json.load(file)\r\n\r\n                with open('/home/hrishikeshp/zdd/automateTechExtMapping/tecnology.txt', 'r') as file:\r\n                    TechnologyData = json.load(file)\r\n\r\n\r\n                # is_active = 1  # extension should be set as active\r\n                is_active = 0  # by default newly added extension should be set as disabled\r\n                # Insert data into the table\r\n                for extension in all_branch_extensions:\r\n                    name = \"Misc Technology\"  # Default name if extension is not found\r\n                    type = \"Misc Type\"\r\n                    for tech_info in TechnologyData:\r\n                        if extension in tech_info['extensions']:\r\n                            name = tech_info['name']\r\n                            type = tech_info['type']\r\n                            break\r\n\r\n                    # Check if the combination of or_code and extension already exists\r\n                    stmt = select([tbl_orcode_extension_mapping]).where(\r\n                        (tbl_orcode_extension_mapping.c.or_code == or_code) &\r\n                        (tbl_orcode_extension_mapping.c.extension == extension)\r\n                    )\r\n                    extensionResult = conn.execute(stmt)\r\n\r\n\r\n                    # Insert into the tbl_orcode_extension_mapping table only if the combination does not exist\r\n                    if not extensionResult.fetchone():\r\n                        # Insert into the tbl_orcode_extension_mapping table\r\n                        if extension in by_default_disabled_ext:\r\n                            stmt = insert(tbl_orcode_extension_mapping).values(\r\n                                or_code=or_code,\r\n                                technology_name=name,\r\n                                extension=extension,\r\n                                is_active=0,\r\n                                activation_date=activation_date,\r\n                                deactivation_date=activation_date\r\n                            )\r\n                            conn.execute(stmt)\r\n                        else:\r\n                            stmt = insert(tbl_orcode_extension_mapping).values(\r\n                                or_code=or_code,\r\n                                technology_name=name,\r\n                                extension=extension,\r\n                                is_active=is_active,\r\n                                activation_date=activation_date\r\n                            )\r\n                            conn.execute(stmt)\r\n\r\n                    extensionResult.close()\r\n\r\n                    # Check if the extension already exists in master extension table\r\n                    stmt2 = select([master_technology_extension_mapping]).where(\r\n                        (master_technology_extension_mapping.c.extension == extension)\r\n                    )\r\n                    masterTblExtensionResult = conn.execute(stmt2)\r\n\r\n                    # Insert into the tbl_orcode_extension_mapping table only if the combination does not exist\r\n                    if not masterTblExtensionResult.fetchone():\r\n                        # Insert into the tbl_orcode_extension_mapping table\r\n                        stmt2 = insert(master_technology_extension_mapping).values(\r\n                            technology_name=name,\r\n                            technology_type=type,\r\n                            extension=extension,\r\n                        )\r\n                        conn.execute(stmt2)\r\n\r\n                    masterTblExtensionResult.close()\r\n\r\n                # Close the database connection\r\n                conn.close()\r\n                # Print the file extensions\r\n                print(\"Done For \",path)\r\n                logger.info(f\"Done for {path}\")\r\n                gl = None\r\n                # for ext in all_branch_extensions:\r\n                    # print(ext)\r\n\r\n\r\n    except Exception as e:\r\n        print(e)\r\n        logger.error(f\"{e} error for or_code{or_code}\")\r\n\r\ndef list_file_extensions_all_branches(project):\r\n    # Get a list of all branch names in the repository\r\n    branches = project.branches.list(get_all=True)\r\n    branches2 = list(map(lambda branch: branch.name, branches))\r\n\r\n    max_threads = 10\r\n\r\n    # Create a partial function with 'project' as a fixed argument\r\n    # partial_func = partial(list_file_extensions_recursive, project=project)\r\n    partial_func = partial(wrapper_function, project=project)\r\n\r\n\r\n    try:\r\n        # Create a ThreadPoolExecutor with the specified number of threads\r\n        with concurrent.futures.ThreadPoolExecutor(max_threads) as executor:\r\n            # Map the process_branch function to the branch_names list, running them in parallel\r\n            # results = executor.map(partial_func, branches2)\r\n            results = executor.map(partial_func, branches2)\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) here\r\n        print(f\"GitLab server not responding. Error: {e}\")\r\n    except Exception as e:\r\n        # Handle other exceptions here\r\n        print(f\"An error occurred: {e}\")\r\n\r\n    all_branch_extension_list = []\r\n    for result in results:\r\n        all_branch_extension_list.extend(result)\r\n\r\n    # Remove duplicates and empty strings\r\n    unique_extensions = list(set(all_branch_extension_list))\r\n    if '' in unique_extensions:\r\n        unique_extensions.remove('')\r\n\r\n    return unique_extensions\r\n\r\ndef wrapper_function(branch_name, project):\r\n    try:\r\n        return list_file_extensions_recursive(project, branch_name)\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) specifically for this function\r\n        print(f\"GitLab server not responding for branch {branch_name}. Error: {e}\")\r\n        return set()  # Return an empty set or handle it as appropriate\r\n\r\ndef list_file_extensions_recursive(project,branch_name, path=\"\"):\r\n    # Initialize a set to store unique file extensions\r\n    file_extensions = set()\r\n\r\n    try:\r\n\r\n        # List project repository files and folders for the specified branch\r\n        items = project.repository_tree(path=path, ref=branch_name,get_all=True)\r\n\r\n        # Iterate through the files and folders\r\n        for item in items:\r\n            if item[\"type\"] == \"blob\":\r\n                file_name = item[\"name\"]\r\n                file_extension = os.path.splitext(file_name)[1]\r\n                file_extension = file_extension.lower()\r\n                file_extensions.add(file_extension)\r\n            elif item[\"type\"] == \"tree\":\r\n                # Recursively traverse into subfolders\r\n                subfolder_path = os.path.join(path, item[\"name\"]).replace(\"\\\\\", \"/\")\r\n                subfolder_extensions = list_file_extensions_recursive(project,branch_name,subfolder_path)\r\n                file_extensions.update(subfolder_extensions)\r\n\r\n        return file_extensions\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) specifically for this function\r\n        # print(f\"GitLab server not responding for branch {branch_name}. Error: {e}\")\r\n        raise  # Re-raise the exception to be caught in the wrapper_function\r\n    except Exception as e:\r\n        # Handle other exceptions here\r\n        # print(f\"An error occurred for branch {branch_name}: {e}\")\r\n        raise  # Re-raise the exception to be caught in the wrapper_function\r\n\r\ndef connectDB():\r\n    url = config.get('DATABASE', 'engine')\r\n    db = config.get('DATABASE', 'db')\r\n    try:\r\n        engine = create_engine(url + db)\r\n        return engine\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\n\r\ndef domain_selector(domain):\r\n    if 'https://gitlab2.kpit.com' == domain:\r\n        return 'GITLAB2'\r\n    if 'https://gitlab.kpit.com' == domain:\r\n        return 'GITLAB'\r\n    if 'https://h-gitlab.kpit.com' == domain:\r\n        return 'HGITLAB'\r\n\r\ndef connectGit(domain):\r\n    domain_name = domain_selector(domain)\r\n    # print (\"domain name\",domain_name)\r\n    token = config.get(domain_name, 'private_token')\r\n    url = config.get(domain_name, 'url')\r\n    # print (token,url)\r\n    try:\r\n        gl = gitlab.Gitlab(url, private_token=token)\r\n        return gl\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\ndef newConnectGitFn(domain):\r\n    domain_name = domain_selector(domain)\r\n    # print (\"domain name\",domain_name)\r\n    token = config.get(domain_name, 'private_token')\r\n    url = config.get(domain_name, 'url')\r\n    # print (token,url)\r\n    try:\r\n        gl = gitlab.Gitlab(url, private_token=token)\r\n        return gl\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\ndef create_table(conn, table_name):     \r\n    sql = f\"\"\" CREATE TABLE IF NOT EXISTS {table_name} (                                         \r\n    id integer PRIMARY KEY,                                        \r\n     code text NOT NULL                                     \r\n     ); \r\n     \"\"\"\r\n     try:         \r\n        c = conn.cursor()    \r\n        c.execute(sql)     \r\n     except Error as e:         \r\n        print(e)\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n"
  },
  {
    "path": "tests/inputs/issues/906/previous_version.py",
    "content": "\r\nimport sys\r\nimport os\r\nimport gitlab\r\nfrom sqlalchemy import text\r\nfrom sqlalchemy import create_engine, select, MetaData, Table, insert\r\nimport concurrent.futures\r\nfrom functools import partial\r\nfrom gitlab.exceptions import GitlabGetError\r\nimport concurrent.futures\r\nimport multiprocessing\r\nfrom datetime import datetime, timedelta\r\nimport logging\r\nimport time\r\nfrom sqlalchemy.ext.declarative import declarative_base\r\nfrom sqlalchemy.orm import sessionmaker\r\nimport json\r\n\r\nimport configparser\r\nconfig = configparser.ConfigParser()\r\n\r\n\r\ns_config = \"\"\"\r\n[GITLAB]\r\nxxxxx\r\nxxxxx\r\n\r\n[HGITLAB]\r\nxxxxx\r\nxxxxx\r\n\r\n[GITLAB2]\r\nxxxxx\r\nxxxxx\r\n\r\n[DATABASE]\r\nxxxxx\r\nxxxxx\r\n\"\"\"\r\n\r\nconfig.read_string(s_config)\r\n\r\n\r\n\r\ndef main():\r\n    \"\"\"main function that runs the analyze method based on schedule\r\n    # \"\"\"\r\n\r\n    engine = connectDB()\r\n\r\n    # or_code = sys.argv[1]\r\n    # Configure the logger\r\n    log_file_path = 'outputAllOrCode.log'\r\n    logger = logging.getLogger(__name__)\r\n    logger.setLevel(logging.INFO)\r\n    file_handler = logging.FileHandler(log_file_path)\r\n    file_handler.setLevel(logging.INFO)\r\n    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')\r\n    file_handler.setFormatter(formatter)\r\n    logger.addHandler(file_handler)\r\n    print(\"Automatically Mapping Technology and extentions from Repos to DB table\")\r\n    logger.info(\"Automatically Mapping Technology and extentions from Repos to DB table\")\r\n\r\n    orcode_query = \"(select distinct(or_code)\\\r\n        from master_orcode mo left join tbl_project_orcode_mapping tpo on(tpo.orcode_id = mo.id) left join projects_master pm\\\r\n        on(pm.project_id = tpo.project_id) where mo.is_del != 1 and perspective in ('LINES_OF_CODE', 'COMBINATION') and \\\r\n        mo.or_code in (select or_code from master_isg_projects where status != 'Closed'))\"\r\n    orcodes = engine.execute(orcode_query)\r\n    orcode_list = [result[0] for result in orcodes]\r\n\r\n    for orcode in orcode_list:\r\n        print(f\"Now Running for orcode {orcode}\")\r\n        mapTechExtensions(engine,orcode,logger)\r\n\r\n    print(\"Script Executed now exiting code\")\r\n    logger.info(\"Script Executed now exiting code\")\r\n    exit(0)\r\n\r\n\r\ndef mapTechExtensions(engine,or_code,logger):\r\n\r\n\r\n    try:\r\n        project_query = text(\"select git_project_id, path, domain from projects_master where project_id in \\\r\n        (select project_id from tbl_project_orcode_mapping where orcode_id in\\\r\n        (select id from master_orcode where or_code in (:or_code)))\")\r\n        result = engine.execute(project_query, or_code=or_code)\r\n        rows = result.fetchall()\r\n\r\n        # Create a metadata object\r\n        metadata = MetaData(bind=engine)\r\n\r\n        # Define the tbl_orcode_extension_mapping table\r\n        tbl_orcode_extension_mapping = Table('tbl_orcode_extension_mapping', metadata, autoload=True)\r\n        master_technology_extension_mapping = Table('master_technology_extension_mapping', metadata, autoload=True)\r\n        tbl_extension_autosync_error_log = Table('tbl_extension_autosync_error_log', metadata, autoload=True)\r\n        current_date = datetime.now()\r\n        # Calculate the start date of the week (Monday)\r\n        start_of_week = current_date - timedelta(days=current_date.weekday())\r\n        # Set the activation_date variable\r\n        activation_date = start_of_week.date()\r\n        disabled_extension_query = text(\"SELECT extension FROM master_disabled_extensions WHERE is_del = 0\")\r\n        disabled_extensions = engine.execute(disabled_extension_query)\r\n        by_default_disabled_ext = [result[0] for result in disabled_extensions]\r\n        # by_default_disabled_ext=['.txt','.log','.png','.jpeg','.tmp','.bak','.swp','.dmp']\r\n        official_domain = ['https://gitlab.kpit.com', 'https://h-gitlab.kpit.com', 'https://gitlab2.kpit.com']\r\n\r\n        for row in rows:\r\n            if row:\r\n                git_project_id, path, domain = row[0], row[1], row[2]\r\n\r\n                if domain not in official_domain:\r\n                    continue\r\n                # Create a connection\r\n                conn = engine.connect()\r\n                try:\r\n                    gl = connectGit(domain)\r\n                    project = gl.projects.get(git_project_id)\r\n                except Exception as e:\r\n                    if(e.error_message=='404 Project Not Found'):\r\n                        # Insert error log into the tbl_extension_autosync_error_log table\r\n                        stmt = select([tbl_extension_autosync_error_log]).where(\r\n                            (tbl_extension_autosync_error_log.c.or_code == or_code) &\r\n                            (tbl_extension_autosync_error_log.c.git_project_id == git_project_id)\r\n                        )\r\n                        extensionResult = conn.execute(stmt)\r\n                        if not extensionResult.fetchone():\r\n                            stmt = insert(tbl_extension_autosync_error_log).values(\r\n                                git_project_id=git_project_id,\r\n                                or_code=or_code,\r\n                                path=path,\r\n                                domain=domain,\r\n                                description=e.error_message\r\n                            )\r\n                            conn.execute(stmt)\r\n                        extensionResult.close()\r\n                    logger.error(f\"{e}\")\r\n\r\n                # Set a timeout for list_file_extensions_all_branches\r\n                timeout = 300  # 10 minutes in seconds\r\n                # List project repository files\r\n                # all_branch_extensions  = list_file_extensions_all_branches(project)\r\n                try:\r\n                    # Use multiprocessing.Pool to run the function with a timeout\r\n                    with multiprocessing.Pool(processes=1) as pool:\r\n                        result = pool.apply_async(list_file_extensions_all_branches, (project,))\r\n                        all_branch_extensions = result.get(timeout=timeout)\r\n\r\n                    # Continue processing with 'all_branch_extensions' as needed\r\n                    print(all_branch_extensions)\r\n\r\n                except multiprocessing.TimeoutError:\r\n                    print(f\"Timeout occurred for project {git_project_id}. Continuing with the next project.\")\r\n                    logger.error(f\"Timeout occurred for project {git_project_id}. Continuing with the next project.\")\r\n                    # Insert error log into the tbl_extension_autosync_error_log table\r\n                    stmt = select([tbl_extension_autosync_error_log]).where(\r\n                        (tbl_extension_autosync_error_log.c.or_code == or_code) &\r\n                        (tbl_extension_autosync_error_log.c.git_project_id == git_project_id)\r\n                    )\r\n                    extensionResult = conn.execute(stmt)\r\n                    if not extensionResult.fetchone():\r\n                        stmt = insert(tbl_extension_autosync_error_log).values(\r\n                            git_project_id = git_project_id,\r\n                            or_code=or_code,\r\n                            path=path,\r\n                            domain=domain,\r\n                            description=\"Unable to fetch data from gitlab Timeout Error Occurred\"\r\n                        )\r\n                        conn.execute(stmt)\r\n                    extensionResult.close()\r\n                except Exception as e:\r\n                    print(f\"An error occurred for project {git_project_id}: {e}\")\r\n                    logger.error(f\"An error occurred for project {git_project_id}: {e}\")\r\n\r\n\r\n                # with open('D:/CTO Project(Insights)/automateTechnologyExtensionMapping/tecnology.txt', 'r') as file:\r\n                #     TechnologyData = json.load(file)\r\n\r\n                with open('/home/hrishikeshp/zdd/automateTechExtMapping/tecnology.txt', 'r') as file:\r\n                    TechnologyData = json.load(file)\r\n\r\n\r\n                # is_active = 1  # extension should be set as active\r\n                is_active = 0  # by default newly added extension should be set as disabled\r\n                # Insert data into the table\r\n                for extension in all_branch_extensions:\r\n                    name = \"Misc Technology\"  # Default name if extension is not found\r\n                    type = \"Misc Type\"\r\n                    for tech_info in TechnologyData:\r\n                        if extension in tech_info['extensions']:\r\n                            name = tech_info['name']\r\n                            type = tech_info['type']\r\n                            break\r\n\r\n                    # Check if the combination of or_code and extension already exists\r\n                    stmt = select([tbl_orcode_extension_mapping]).where(\r\n                        (tbl_orcode_extension_mapping.c.or_code == or_code) &\r\n                        (tbl_orcode_extension_mapping.c.extension == extension)\r\n                    )\r\n                    extensionResult = conn.execute(stmt)\r\n\r\n\r\n                    # Insert into the tbl_orcode_extension_mapping table only if the combination does not exist\r\n                    if not extensionResult.fetchone():\r\n                        # Insert into the tbl_orcode_extension_mapping table\r\n                        if extension in by_default_disabled_ext:\r\n                            stmt = insert(tbl_orcode_extension_mapping).values(\r\n                                or_code=or_code,\r\n                                technology_name=name,\r\n                                extension=extension,\r\n                                is_active=0,\r\n                                activation_date=activation_date,\r\n                                deactivation_date=activation_date\r\n                            )\r\n                            conn.execute(stmt)\r\n                        else:\r\n                            stmt = insert(tbl_orcode_extension_mapping).values(\r\n                                or_code=or_code,\r\n                                technology_name=name,\r\n                                extension=extension,\r\n                                is_active=is_active,\r\n                                activation_date=activation_date\r\n                            )\r\n                            conn.execute(stmt)\r\n\r\n                    extensionResult.close()\r\n\r\n                    # Check if the extension already exists in master extension table\r\n                    stmt2 = select([master_technology_extension_mapping]).where(\r\n                        (master_technology_extension_mapping.c.extension == extension)\r\n                    )\r\n                    masterTblExtensionResult = conn.execute(stmt2)\r\n\r\n                    # Insert into the tbl_orcode_extension_mapping table only if the combination does not exist\r\n                    if not masterTblExtensionResult.fetchone():\r\n                        # Insert into the tbl_orcode_extension_mapping table\r\n                        stmt2 = insert(master_technology_extension_mapping).values(\r\n                            technology_name=name,\r\n                            technology_type=type,\r\n                            extension=extension,\r\n                        )\r\n                        conn.execute(stmt2)\r\n\r\n                    masterTblExtensionResult.close()\r\n\r\n                # Close the database connection\r\n                conn.close()\r\n                # Print the file extensions\r\n                print(\"Done For \",path)\r\n                logger.info(f\"Done for {path}\")\r\n                gl = None\r\n                # for ext in all_branch_extensions:\r\n                    # print(ext)\r\n\r\n\r\n    except Exception as e:\r\n        print(e)\r\n        logger.error(f\"{e} error for or_code{or_code}\")\r\n\r\ndef list_file_extensions_all_branches(project):\r\n    # Get a list of all branch names in the repository\r\n    branches = project.branches.list(get_all=True)\r\n    branches2 = list(map(lambda branch: branch.name, branches))\r\n\r\n    max_threads = 10\r\n\r\n    # Create a partial function with 'project' as a fixed argument\r\n    # partial_func = partial(list_file_extensions_recursive, project=project)\r\n    partial_func = partial(wrapper_function, project=project)\r\n\r\n\r\n    try:\r\n        # Create a ThreadPoolExecutor with the specified number of threads\r\n        with concurrent.futures.ThreadPoolExecutor(max_threads) as executor:\r\n            # Map the process_branch function to the branch_names list, running them in parallel\r\n            # results = executor.map(partial_func, branches2)\r\n            results = executor.map(partial_func, branches2)\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) here\r\n        print(f\"GitLab server not responding. Error: {e}\")\r\n    except Exception as e:\r\n        # Handle other exceptions here\r\n        print(f\"An error occurred: {e}\")\r\n\r\n    all_branch_extension_list = []\r\n    for result in results:\r\n        all_branch_extension_list.extend(result)\r\n\r\n    # Remove duplicates and empty strings\r\n    unique_extensions = list(set(all_branch_extension_list))\r\n    if '' in unique_extensions:\r\n        unique_extensions.remove('')\r\n\r\n    return unique_extensions\r\n\r\ndef wrapper_function(branch_name, project):\r\n    try:\r\n        return list_file_extensions_recursive(project, branch_name)\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) specifically for this function\r\n        print(f\"GitLab server not responding for branch {branch_name}. Error: {e}\")\r\n        return set()  # Return an empty set or handle it as appropriate\r\n\r\ndef list_file_extensions_recursive(project,branch_name, path=\"\"):\r\n    # Initialize a set to store unique file extensions\r\n    file_extensions = set()\r\n\r\n    try:\r\n\r\n        # List project repository files and folders for the specified branch\r\n        items = project.repository_tree(path=path, ref=branch_name,get_all=True)\r\n\r\n        # Iterate through the files and folders\r\n        for item in items:\r\n            if item[\"type\"] == \"blob\":\r\n                file_name = item[\"name\"]\r\n                file_extension = os.path.splitext(file_name)[1]\r\n                file_extension = file_extension.lower()\r\n                file_extensions.add(file_extension)\r\n            elif item[\"type\"] == \"tree\":\r\n                # Recursively traverse into subfolders\r\n                subfolder_path = os.path.join(path, item[\"name\"]).replace(\"\\\\\", \"/\")\r\n                subfolder_extensions = list_file_extensions_recursive(project,branch_name,subfolder_path)\r\n                file_extensions.update(subfolder_extensions)\r\n\r\n        return file_extensions\r\n    except GitlabGetError as e:\r\n        # Handle the GitLab Get Error (HTTP 503) specifically for this function\r\n        # print(f\"GitLab server not responding for branch {branch_name}. Error: {e}\")\r\n        raise  # Re-raise the exception to be caught in the wrapper_function\r\n    except Exception as e:\r\n        # Handle other exceptions here\r\n        # print(f\"An error occurred for branch {branch_name}: {e}\")\r\n        raise  # Re-raise the exception to be caught in the wrapper_function\r\n\r\ndef connectDB():\r\n    url = config.get('DATABASE', 'engine')\r\n    db = config.get('DATABASE', 'db')\r\n    try:\r\n        engine = create_engine(url + db)\r\n        return engine\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\n\r\ndef domain_selector(domain):\r\n    if 'https://gitlab2.kpit.com' == domain:\r\n        return 'GITLAB2'\r\n    if 'https://gitlab.kpit.com' == domain:\r\n        return 'GITLAB'\r\n    if 'https://h-gitlab.kpit.com' == domain:\r\n        return 'HGITLAB'\r\n\r\ndef connectGit(domain):\r\n    domain_name = domain_selector(domain)\r\n    # print (\"domain name\",domain_name)\r\n    token = config.get(domain_name, 'private_token')\r\n    url = config.get(domain_name, 'url')\r\n    # print (token,url)\r\n    try:\r\n        gl = gitlab.Gitlab(url, private_token=token)\r\n        return gl\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\ndef newConnectGitFn(domain):\r\n    domain_name = domain_selector(domain)\r\n    # print (\"domain name\",domain_name)\r\n    token = config.get(domain_name, 'private_token')\r\n    url = config.get(domain_name, 'url')\r\n    # print (token,url)\r\n    try:\r\n        gl = gitlab.Gitlab(url, private_token=token)\r\n        return gl\r\n    except Exception as ex:\r\n        # print(ex)\r\n        pass\r\n\r\nif __name__ == '__main__':\r\n    main()\r\n"
  },
  {
    "path": "tests/inputs/julia.jl",
    "content": "# https://learnxinyminutes.com/docs/julia/\n# Single line comments start with a hash (pound) symbol.\n#= Multiline comments can be written\n   by putting '#=' before the text  and '=#'\n   after the text. They can also be nested.\n=#\n\n####################################################\n## 1. Primitive Datatypes and Operators\n####################################################\n\n# Everything in Julia is an expression.\n\n# There are several basic types of numbers.\n3 # => 3 (Int64)\n3.2 # => 3.2 (Float64)\n2 + 1im # => 2 + 1im (Complex{Int64})\n2//3 # => 2//3 (Rational{Int64})\n"
  },
  {
    "path": "tests/inputs/just_stuff.haml",
    "content": "/ from test/templates\n/ in https://github.com/haml/haml/archive/master.zip\n!!! XML\n!!! XML ISO-8859-1\n!!! XML UtF-8 Foo bar\n!!!\n!!! 1.1\n!!! 1.1 Strict\n!!! Strict foo bar\n!!! FRAMESET\n%strong{:apos => \"Foo's bar!\"} Boo!\n== Embedded? false!\n== Embedded? #{true}!\n- embedded = true\n== Embedded? #{embedded}!\n== Embedded? #{\"twice! #{true}\"}!\n== Embedded? #{\"one\"} af\"t\"er #{\"another\"}!\n%p== Embedded? false!\n%p== Embedded? #{true}!\n- embedded = true\n%p== Embedded? #{embedded}!\n%p== Embedded? #{\"twice! #{true}\"}!\n%p== Embedded? #{\"one\"} af\"t\"er #{\"another\"}!\n= \"stuff followed by whitespace\"\n  \n- if true\n\n  %strong block with whitespace\n%p\n  \\Escape\n  \\- character\n  \\%p foo\n  \\yee\\ha\n/ Short comment\n/\n  This is a block comment\n  cool, huh?\n  %strong there can even be sub-tags!\n  = \"Or script!\"\n-# Haml comment\n-#\n  Nested Haml comment\n  - raise 'dead'\n%p{ :class => \"\" } class attribute should appear!\n%p{ :gorbachev => nil } this attribute shouldn't appear\n/[if lte IE6] conditional comment!\n/[if gte IE7]\n  %p Block conditional comment\n  %div\n    %h1 Cool, eh?\n/[if gte IE5.2]\n  Woah a period.\n= \"test\" |\n  \"test\" |\n-# Hard tabs shouldn't throw errors.\n\t\n- case :foo\n- when :bar\n  %br Blah\n- when :foo\n  %br\n- case :foo\n  - when :bar\n    %meta{ :foo => 'blah'}\n  - when :foo\n    %meta{ :foo => 'bar'}\n%img\n%hr\n%link\n%script Inline content\n%br\n  Nested content\n%p.foo{:class => true ? 'bar' : 'baz'}[@article] Blah\n%p.foo{:class => false ? 'bar' : ''}[@article] Blah\n%p.foo{:class => %w[bar baz]}[@article] Blah\n%p.qux{:class => 'quux'}[@article] Blump\n%p#foo{:id => %w[bar baz]}[@article] Whee\n== #{\"Woah inner quotes\"}\n%p.dynamic_quote{:quotes => \"single '\", :dyn => 1 + 2}\n%p.dynamic_self_closing{:dyn => 1 + 2}/\n%body\n  :plain\n    hello\n  %div\n\n    %img\n\n"
  },
  {
    "path": "tests/inputs/kvlang.kv",
    "content": "#:kivy 1.8.0\n#:import KivyLexer kivy.extras.highlight.KivyLexer\n#:import Factory kivy.factory.Factory\n# This is a Comment\n<ActionSpinnerOptions@SpinnerOption>\n    background_color: .4, .4, .4, 1\n\n<ActionSpinner@Spinner+ActionItem>\n    canvas.before:\n        Color:\n            rgba: 0.128, 0.128, 0.128, 1\n        Rectangle:\n            size: self.size\n            pos: self.pos\n    border: 27, 20, 12, 12\n    background_normal: 'atlas://data/images/defaulttheme/action_group'\n    option_cls: Factory.ActionSpinnerOptions\n\n<ActionDropdown>:\n    on_size: self.width = '220dp'\n\n<ShowcaseScreen>:\n    # This is a Comment\n    ScrollView:\n        do_scroll_x: False\n        do_scroll_y: False if root.fullscreen else (content.height > root.height - dp(16))\n        AnchorLayout:\n            size_hint_y: None\n            height: root.height if root.fullscreen else max(root.height, content.height)\n            GridLayout:\n                id: content\n                cols: 1\n                spacing: '8dp'\n                padding: '8dp'\n                size_hint: (1, 1) if root.fullscreen else (.8, None)\n                height: self.height if root.fullscreen else self.minimum_height\n\n\nBoxLayout:\n    orientation: 'vertical'\n\n    canvas.before:\n        Color:\n            rgb: .6, .6, .6\n        Rectangle:\n            size: self.size\n            source: 'data/background.png'\n\n    ActionBar:\n\n        ActionView:\n            id: av\n            ActionPrevious:\n                with_previous: (False if sm.current_screen.name == 'button' else True) if sm.current_screen else False\n                title: 'Showcase' + ('' if not app.current_title else ' - {}'.format(app.current_title))\n                on_release: app.go_hierarchy_previous()\n\n            ActionSpinner:\n                id: spnr\n                important: True\n                text: 'Jump to Screen'\n                values: app.screen_names\n                on_text:\n                    if sm.current != args[1]:\\\n                    idx = app.screen_names.index(args[1]);\\\n                    app.go_screen(idx)\n            ActionToggleButton:\n                text: 'Toggle sourcecode'\n                icon: 'data/icons/bug.png'\n                on_release: app.toggle_source_code()\n            ActionButton:\n                text: 'Previous screen'\n                icon: 'data/icons/chevron-left.png'\n                on_release: app.go_previous_screen()\n\n            ActionButton:\n                text: 'Next screen'\n                icon: 'data/icons/chevron-right.png'\n                on_release: app.go_next_screen()\n                important: True\n\n    ScrollView:\n        id: sv\n        size_hint_y: None\n        height: 0\n\n        CodeInput:\n            id: sourcecode\n            lexer: KivyLexer()\n            text: app.sourcecode\n            readonly: True\n            size_hint_y: None\n            font_size: '12sp'\n            height: self.minimum_height\n\n    ScreenManager:\n        id: sm\n        on_current_screen:\n            spnr.text = args[1].name\n            idx = app.screen_names.index(args[1].name)\n            if idx > -1: app.hierarchy.append(idx)\n"
  },
  {
    "path": "tests/inputs/layer.conf",
    "content": "# We have a conf and classes directory, add to BBPATH\nBBPATH .= \":${LAYERDIR}\"\n\n# We have recipes-* directories, add to BBFILES\nBBFILES += \"${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend\"\n\nBBFILE_COLLECTIONS += \"skeleton\"\nBBFILE_PATTERN_skeleton = \"^${LAYERDIR}/\"\nBBFILE_PRIORITY_skeleton = \"1\"\n\n# This should only be incremented on significant changes that will\n# cause compatibility issues with other layers\nLAYERVERSION_skeleton = \"1\"\n\nLAYERDEPENDS_skeleton = \"core\"\n\nLAYERSERIES_COMPAT_skeleton = \"scarthgap\"\n"
  },
  {
    "path": "tests/inputs/layout.dt",
    "content": "!!! 5\nhtml(lang='en-US')\n  - import std.datetime : Clock;\n  - auto year = Clock.currTime.year;\n  //\n    | Copyright (c) 1999-$#{year} by the D Language Foundation\n    | All Rights Reserved.\n    | https://dlang.org/foundation_overview.html\n  - import std.process : environment;\n  - import std.array : replace;\n  - static import std.string;\n  - string version_id = environment[\"GIT_TARGET\"];\n  - bool noExactSourceCodeLinks = environment[\"NO_EXACT_SOURCE_CODE_LINKS\"] == \"1\";\n  - bool haveVersion = version_id.startsWith(\"v\");\n  - string version_name = haveVersion ? version_id[1 .. $] : \"Prerelease\";\n  - string root_dir = info.linkTo(null) ~ (req is null ? \"../\" : \"\");\n  - string ddox_dir = haveVersion ? \"library/\" : \"library-prerelease/\";\n      \n  head\n    meta(charset='utf-8')\n    - string title;\n    meta(name='keywords', content='D programming language')\n    meta(name='description', content='D Programming Language')\n    block title\n    title #{title} - D Programming Language\n    link(rel='stylesheet', href='#{root_dir}css/codemirror.css')\n    link(rel='stylesheet', href='#{root_dir}css/style.css')\n    link(rel='stylesheet', href='#{root_dir}css/print.css', media='print')\n    link(rel='stylesheet', href='#{root_dir}css/ddox.css')\n    link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css')\n    link(rel='shortcut icon', href='#{root_dir}favicon.ico')\n    script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', type='text/javascript')\n    meta(name='viewport', content='width=device-width, initial-scale=1.0, minimum-scale=0.1, maximum-scale=10.0')\n\n  body.std(id='#{info.node.moduleName}')\n    script(type='text/javascript').\n      document.body.className += ' have-javascript';\n    #top\n      .helper\n        .helper.expand-container\n          a.logo(href='#{root_dir}')\n            img#logo(width='125', height='95', alt='D Logo', src='#{root_dir}images/dlogo.svg')\n          a.hamburger.expand-toggle(href=\"#{root_dir}menu.html\", title=\"Menu\")\n            span Menu\n          #cssmenu\n            ul\n              li\n                a(href=\"https://tour.dlang.org\")\n                  span Learn\n              li.expand-container\n                a.expand-toggle(href=\"#{root_dir}documentation.html\")\n                  span Documentation\n                ul\n                  li\n                    a(href=\"#{root_dir}spec/spec.html\") Language Reference\n                  li\n                    a(href=\"#{root_dir}phobos/index.html\") Library Reference\n                  li\n                    a(href=\"#{root_dir}dmd.html\") Command-line Reference\n                  li.menu-divider\n                    a(href=\"#{root_dir}comparison.html\") Feature Overview\n                  li\n                    a(href=\"#{root_dir}articles.html\") Articles\n              li\n                a(href=\"#{root_dir}download.html\")\n                  span Downloads\n              li\n                a(href=\"https://code.dlang.org\")\n                  span Packages\n              li.expand-container\n                a.expand-toggle(href=\"#{root_dir}community.html\")\n                  span Community\n                ul\n                  li\n                    a(href=\"https://dlang.org/blog\") Blog\n                  li\n                    a(href=\"#{root_dir}orgs-using-d.html\") Orgs using D\n                  li\n                    a(href=\"https://twitter.com/search?q=%23dlang\") Twitter\n                  li\n                    a(href=\"#{root_dir}calendar.html\") Calendar\n                  li.menu-divider\n                    a(href=\"https://forum.dlang.org\") Forums\n                  li\n                    a(href=\"irc://irc.freenode.net/d\") IRC\n                  li\n                    a(href=\"https://wiki.dlang.org\") Wiki\n                  li.menu-divider\n                    a(href=\"https://github.com/dlang\") GitHub\n                  li\n                    a(href=\"#{root_dir}bugstats.html\") Issues\n                  li\n                    a(href=\"https://wiki.dlang.org/Get_involved\") Get Involved\n                  li.menu-divider\n                    a(href=\"#{root_dir}foundation\") Foundation\n                  li\n                    a(href=\"#{root_dir}security.html\") Security Team\n                  li\n                    a(href=\"#{root_dir}foundation/donate.html\") Donate\n                  li\n                    a(href=\"#{root_dir}foundation/sponsors.html\") Sponsors\n              li.expand-container\n                a.expand-toggle(href=\"#{root_dir}resources.html\")\n                  span Resources\n                ul\n                  li\n                    a(href=\"https://wiki.dlang.org/Books\") Books\n                  li\n                    a(href=\"https://wiki.dlang.org/Tutorials\") Tutorials\n                  li.menu-divider\n                    a(href=\"https://wiki.dlang.org/Development_tools\") Tools\n                  li\n                    a(href=\"https://wiki.dlang.org/Editors\") Editors\n                  li\n                    a(href=\"https://wiki.dlang.org/IDEs\") IDEs\n                  li\n                    a(href=\"http://rainers.github.io/visuald/visuald/StartPage.html\") Visual D\n                  li.menu-divider\n                    a(href=\"#{root_dir}acknowledgements.html\") Acknowledgments\n                  li\n                    a(href=\"#{root_dir}dstyle.html\") D Style\n                  li\n                    a(href=\"#{root_dir}glossary.html\") Glossary\n                  li\n                    a(href=\"#{root_dir}sitemap.html\") Sitemap\n          .search-container.expand-container\n            a.expand-toggle(href=\"#{root_dir}search.html\", title=\"Search\")\n              span Search\n            #search-box\n              form(method='get', action='https://google.com/search', autocomplete='off')\n                input#domains(type='hidden', name='domains', value='dlang.org')\n                |             \n                input#sourceid(type='hidden', name='sourceid', value='google-search')\n                |             \n                span#search-query\n                  input#q(name='q', placeholder='Search')\n                  input#symbolSearch(style=\"display: none\", type=\"text\", name=\"symbolSearch\", placeholder=\"API Search\", onchange=\"performSymbolSearch(80);\", onkeypress=\"this.onchange();\", onpaste=\"this.onchange();\", oninput=\"this.onchange();\", autofocus)\n                span#search-dropdown\n                  .helper\n                    select#sitesearch(name='sitesearch', size='1')\n                      option(value='dlang.org') Entire D Site\n                      |                     \n                      option(selected='', value='dlang.org/spec') Language\n                      |                     \n                      option(selected='', value='dlang.org/library') Library\n                      |                     \n                      option(value='forum.dlang.org') Forums\n                span#search-submit\n                  button(type='submit')\n                    i.fa.fa-search\n                    span go\n              include ddox.inc.symbol-search.results\n\n    .container\n      .subnav-helper\n      .subnav\n        h2 API Documentation\n        p\n          span.smallprint\n            - if( haveVersion )\n              | version #{version_name}\n        p\n          a(href=\"#{root_dir}#{ddox_dir}index.html\") overview\n        ul\n          block navigation\n      #content.hyphenate\n        #tools\n          div\n            - import ddox.entities : Declaration;\n            - auto modname = info.node.moduleName;\n            - string project = \"dlang.org\";\n            - string path_prefix, line_suffix, filename;\n            - if( modname )\n              - if( modname.startsWith(\"core.\") || modname.startsWith(\"object\"))\n                - project = \"druntime\", path_prefix = \"src/\";\n              - else if( modname.startsWith(\"dmd.\") )\n                - project = \"dmd\", path_prefix = \"src/\";\n              - else\n                - project = \"phobos\", path_prefix = \"\";\n              - if (info.docGroups.length >= 1 && !noExactSourceCodeLinks)\n                - if (auto decl = cast(Declaration)info.docGroups[0].members[0]) line_suffix = \"#L\"~to!string(decl.line);\n              - if (info.node.module_.isPackageModule)\n                - filename = replace(modname, \".\", \"/\") ~ \"/package.d\";\n              - else\n                - filename = replace(modname, \".\", \"/\") ~ \".d\";\n\n            - if( modname )\n              .tip.smallprint\n                a(href='https://github.com/dlang/#{project}/blob/#{version_id}/#{path_prefix}#{filename}#{line_suffix}')\n                  | View source code\n                div\n                  | Display the source code in #{filename} from which this\n                  | page was generated on github.\n\n            .tip.smallprint\n              - auto pagename = modname ? path_prefix ~ replace(modname, \".\", \"/\") : \"index\";\n              a(href=\"https://issues.dlang.org/enter_bug.cgi?bug_file_loc=http%3A%2F%2Fdlang.org/#{ddox_dir}#{pagename}.html&bug_severity=enhancement&component=#{project}&op_sys=All&priority=P3&product=D&rep_platform=All&short_desc=%5B#{title}%5D&version=D2\") Report a bug\n              div\n                | If you spot a problem with this page, click here to create a\n                | Bugzilla issue.\n\n            - if( modname )\n              .tip.smallprint\n                a(href='https://github.com/dlang/#{project}/edit/master/#{path_prefix}#{filename}#{line_suffix}')\n                  | Improve this page\n                div\n                  | Quickly fork, edit online, and submit a pull request for this page.\n                  | Requires a signed-in GitHub account. This works well for small changes.\n                  | If you'd like to make larger changes you may want to consider using\n                  | local clone.\n\n        - auto hidx = std.string.lastIndexOf(title, ' ');\n        - auto node = info.docGroups.length ? info.docGroups[0].members[0] : null;\n        - if (title.endsWith(\" - multiple declarations\") && node)\n          h1 <code><a href=\"#{info.linkTo(info.mod)}\">#{info.mod.qualifiedName}</a>.#{title[0 .. $-24]}</code> #{title[$-24 ..$]}\n        - else if (hidx > 0 && !title.startsWith(\"Module \") && node)\n          h1 #{title[0 .. hidx]} <code><a href=\"#{info.linkTo(node.parent)}\">#{node.parent.qualifiedName}</a>.#{node.name}</code>\n        - else if (hidx > 0 && title.startsWith(\"Module \") && info.mod)\n          h1 Module <code>#{info.mod.qualifiedName}</code>\n        - else\n          h1= title\n        block body\n\n        |     \n        #quickindex.quickindex\n\n        #copyright.smallprint\n          | Copyright &copy; 1999-#{year} by the <a href=\"#{root_dir}foundation_overview.html\">D Language Foundation</a> | Page generated by <a href=\"https://github.com/rejectedsoftware/ddox\">ddox</a>.\n\n    script(type='text/javascript', src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js')\n    |     \n    script(type='text/javascript').\n      window.jQuery || document.write('\\x3Cscript src=\"#{root_dir}js/jquery-1.7.2.min.js\">\\x3C/script>')\n    |     \n    script(type='text/javascript', src='#{root_dir}js/codemirror-compressed.js')\n    |     \n    script(type='text/javascript', src='#{root_dir}js/run.js')\n    script(type='text/javascript', src='#{root_dir}js/run_examples.js')\n    script(type='text/javascript', src='#{root_dir}js/dlang.js')\n    script(type='text/javascript', src='#{root_dir}js/listanchors.js')\n    script(type=\"text/javascript\", src=\"#{root_dir}js/ddox.js\")\n    script(type='text/javascript').\n      jQuery(document).ready(listanchors);\n      setupDdox();\n"
  },
  {
    "path": "tests/inputs/linker.ld",
    "content": "/* Obtained from command `ld --verbose` */\n\n/* \nGNU ld (GNU Binutils for Ubuntu) 2.34\n  Supported emulations:\n   elf_x86_64\n   elf32_x86_64\n   elf_i386\n   elf_iamcu\n   elf_l1om\n   elf_k1om\n   i386pep\n   i386pe\nusing internal linker script:\n==================================================\n*/\n\n/* Script for -z combreloc -z separate-code */\n/* Copyright (C) 2014-2020 Free Software Foundation, Inc.\n   Copying and distribution of this script, with or without modification,\n   are permitted in any medium without royalty provided the copyright\n   notice and this notice are preserved.  */\nOUTPUT_FORMAT(\"elf64-x86-64\", \"elf64-x86-64\",\n              \"elf64-x86-64\")\nOUTPUT_ARCH(i386:x86-64)\nENTRY(_start)\nSEARCH_DIR(\"=/usr/local/lib/x86_64-linux-gnu\"); SEARCH_DIR(\"=/lib/x86_64-linux-gnu\"); SEARCH_DIR(\"=/usr/lib/x86_64-linux-gnu\"); SEARCH_DIR(\"=/usr/lib/x86_64-linux-gnu64\"); SEARCH_DIR(\"=/usr/local/lib64\"); SEARCH_DIR(\"=/lib64\"); SEARCH_DIR(\"=/usr/lib64\"); SEARCH_DIR(\"=/usr/local/lib\"); SEARCH_DIR(\"=/lib\"); SEARCH_DIR(\"=/usr/lib\"); SEARCH_DIR(\"=/usr/x86_64-linux-gnu/lib64\"); SEARCH_DIR(\"=/usr/x86_64-linux-gnu/lib\");\nSECTIONS\n{\n  PROVIDE (__executable_start = SEGMENT_START(\"text-segment\", 0x400000)); . = SEGMENT_START(\"text-segment\", 0x400000) + SIZEOF_HEADERS;\n  .interp         : { *(.interp) }\n  .note.gnu.build-id  : { *(.note.gnu.build-id) }\n  .hash           : { *(.hash) }\n  .gnu.hash       : { *(.gnu.hash) }\n  .dynsym         : { *(.dynsym) }\n  .dynstr         : { *(.dynstr) }\n  .gnu.version    : { *(.gnu.version) }\n  .gnu.version_d  : { *(.gnu.version_d) }\n  .gnu.version_r  : { *(.gnu.version_r) }\n  .rela.dyn       :\n    {\n      *(.rela.init)\n      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)\n      *(.rela.fini)\n      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)\n      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)\n      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)\n      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)\n      *(.rela.ctors)\n      *(.rela.dtors)\n      *(.rela.got)\n      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)\n      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)\n      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)\n      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)\n      *(.rela.ifunc)\n    }\n  .rela.plt       :\n    {\n      *(.rela.plt)\n      PROVIDE_HIDDEN (__rela_iplt_start = .);\n      *(.rela.iplt)\n      PROVIDE_HIDDEN (__rela_iplt_end = .);\n    }\n  . = ALIGN(CONSTANT (MAXPAGESIZE));\n  .init           :\n  {\n    KEEP (*(SORT_NONE(.init)))\n  }\n  .plt            : { *(.plt) *(.iplt) }\n.plt.got        : { *(.plt.got) }\n.plt.sec        : { *(.plt.sec) }\n  .text           :\n  {\n    *(.text.unlikely .text.*_unlikely .text.unlikely.*)\n    *(.text.exit .text.exit.*)\n    *(.text.startup .text.startup.*)\n    *(.text.hot .text.hot.*)\n    *(SORT(.text.sorted.*))\n    *(.text .stub .text.* .gnu.linkonce.t.*)\n    /* .gnu.warning sections are handled specially by elf.em.  */\n    *(.gnu.warning)\n  }\n  .fini           :\n  {\n    KEEP (*(SORT_NONE(.fini)))\n  }\n  PROVIDE (__etext = .);\n  PROVIDE (_etext = .);\n  PROVIDE (etext = .);\n  . = ALIGN(CONSTANT (MAXPAGESIZE));\n  /* Adjust the address for the rodata segment.  We want to adjust up to\n     the same address within the page on the next page up.  */\n  . = SEGMENT_START(\"rodata-segment\", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));\n  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }\n  .rodata1        : { *(.rodata1) }\n  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }\n  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }\n  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }\n  /* These sections are generated by the Sun/Oracle C++ compiler.  */\n  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }\n  /* Adjust the address for the data segment.  We want to adjust up to\n     the same address within the page on the next page up.  */\n  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));\n  /* Exception handling  */\n  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }\n  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }\n  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }\n  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }\n  /* Thread Local Storage sections  */\n  .tdata          :\n   {\n     PROVIDE_HIDDEN (__tdata_start = .);\n     *(.tdata .tdata.* .gnu.linkonce.td.*)\n   }\n  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }\n  .preinit_array    :\n  {\n    PROVIDE_HIDDEN (__preinit_array_start = .);\n    KEEP (*(.preinit_array))\n    PROVIDE_HIDDEN (__preinit_array_end = .);\n  }\n  .init_array    :\n  {\n    PROVIDE_HIDDEN (__init_array_start = .);\n    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))\n    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))\n    PROVIDE_HIDDEN (__init_array_end = .);\n  }\n  .fini_array    :\n  {\n    PROVIDE_HIDDEN (__fini_array_start = .);\n    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))\n    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))\n    PROVIDE_HIDDEN (__fini_array_end = .);\n  }\n  .ctors          :\n  {\n    /* gcc uses crtbegin.o to find the start of\n       the constructors, so we make sure it is\n       first.  Because this is a wildcard, it\n       doesn't matter if the user does not\n       actually link against crtbegin.o; the\n       linker won't look for a file to match a\n       wildcard.  The wildcard also means that it\n       doesn't matter which directory crtbegin.o\n       is in.  */\n    KEEP (*crtbegin.o(.ctors))\n    KEEP (*crtbegin?.o(.ctors))\n    /* We don't want to include the .ctor section from\n       the crtend.o file until after the sorted ctors.\n       The .ctor section from the crtend file contains the\n       end of ctors marker and it must be last */\n    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))\n    KEEP (*(SORT(.ctors.*)))\n    KEEP (*(.ctors))\n  }\n  .dtors          :\n  {\n    KEEP (*crtbegin.o(.dtors))\n    KEEP (*crtbegin?.o(.dtors))\n    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))\n    KEEP (*(SORT(.dtors.*)))\n    KEEP (*(.dtors))\n  }\n  .jcr            : { KEEP (*(.jcr)) }\n  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }\n  .dynamic        : { *(.dynamic) }\n  .got            : { *(.got) *(.igot) }\n  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);\n  .got.plt        : { *(.got.plt) *(.igot.plt) }\n  .data           :\n  {\n    *(.data .data.* .gnu.linkonce.d.*)\n    SORT(CONSTRUCTORS)\n  }\n  .data1          : { *(.data1) }\n  _edata = .; PROVIDE (edata = .);\n  . = .;\n  __bss_start = .;\n  .bss            :\n  {\n   *(.dynbss)\n   *(.bss .bss.* .gnu.linkonce.b.*)\n   *(COMMON)\n   /* Align here to ensure that the .bss section occupies space up to\n      _end.  Align after .bss to ensure correct alignment even if the\n      .bss section disappears because there are no input sections.\n      FIXME: Why do we need it? When there is no .bss section, we do not\n      pad the .data section.  */\n   . = ALIGN(. != 0 ? 64 / 8 : 1);\n  }\n  .lbss   :\n  {\n    *(.dynlbss)\n    *(.lbss .lbss.* .gnu.linkonce.lb.*)\n    *(LARGE_COMMON)\n  }\n  . = ALIGN(64 / 8);\n  . = SEGMENT_START(\"ldata-segment\", .);\n  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :\n  {\n    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)\n  }\n  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :\n  {\n    *(.ldata .ldata.* .gnu.linkonce.l.*)\n    . = ALIGN(. != 0 ? 64 / 8 : 1);\n  }\n  . = ALIGN(64 / 8);\n  _end = .; PROVIDE (end = .);\n  . = DATA_SEGMENT_END (.);\n  /* Stabs debugging sections.  */\n  .stab          0 : { *(.stab) }\n  .stabstr       0 : { *(.stabstr) }\n  .stab.excl     0 : { *(.stab.excl) }\n  .stab.exclstr  0 : { *(.stab.exclstr) }\n  .stab.index    0 : { *(.stab.index) }\n  .stab.indexstr 0 : { *(.stab.indexstr) }\n  .comment       0 : { *(.comment) }\n  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }\n  /* DWARF debug sections.\n     Symbols in the DWARF debugging sections are relative to the beginning\n     of the section so we begin them at 0.  */\n  /* DWARF 1 */\n  .debug          0 : { *(.debug) }\n  .line           0 : { *(.line) }\n  /* GNU DWARF 1 extensions */\n  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n  .debug_sfnames  0 : { *(.debug_sfnames) }\n  /* DWARF 1.1 and DWARF 2 */\n  .debug_aranges  0 : { *(.debug_aranges) }\n  .debug_pubnames 0 : { *(.debug_pubnames) }\n  /* DWARF 2 */\n  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\n  .debug_abbrev   0 : { *(.debug_abbrev) }\n  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }\n  .debug_frame    0 : { *(.debug_frame) }\n  .debug_str      0 : { *(.debug_str) }\n  .debug_loc      0 : { *(.debug_loc) }\n  .debug_macinfo  0 : { *(.debug_macinfo) }\n  /* SGI/MIPS DWARF 2 extensions */\n  .debug_weaknames 0 : { *(.debug_weaknames) }\n  .debug_funcnames 0 : { *(.debug_funcnames) }\n  .debug_typenames 0 : { *(.debug_typenames) }\n  .debug_varnames  0 : { *(.debug_varnames) }\n  /* DWARF 3 */\n  .debug_pubtypes 0 : { *(.debug_pubtypes) }\n  .debug_ranges   0 : { *(.debug_ranges) }\n  /* DWARF Extension.  */\n  .debug_macro    0 : { *(.debug_macro) }\n  .debug_addr     0 : { *(.debug_addr) }\n  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }\n  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }\n}\n\n/*\n==================================================\n*/\n"
  },
  {
    "path": "tests/inputs/locale_facets.h",
    "content": "// Locale support -*- C++ -*-\n// gcc-3.4.6/libstdc++-v3/include/bits/locale_facets.h\n\n// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005\n// Free Software Foundation, Inc.\n//\n// This file is part of the GNU ISO C++ Library.  This library is free\n// software; you can redistribute it and/or modify it under the\n// terms of the GNU General Public License as published by the\n// Free Software Foundation; either version 2, or (at your option)\n// 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\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 library; see the file COPYING.  If not, write to the Free\n// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,\n// USA.\n\n// As a special exception, you may use this file as part of a free software\n// library without restriction.  Specifically, if other files instantiate\n// templates or use macros or inline functions from this file, or you compile\n// this file and link it with other files to produce an executable, this\n// file does not by itself cause the resulting executable to be covered by\n// 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// ISO C++ 14882: 22.1  Locales\n//\n\n/** @file locale_facets.h\n *  This is an internal header file, included by other library headers.\n *  You should not attempt to use it directly.\n */\n\n#ifndef _LOCALE_FACETS_H\n#define _LOCALE_FACETS_H 1\n\n#pragma GCC system_header\n\n#include <ctime>\t// For struct tm\n#include <cwctype>\t// For wctype_t\n#include <iosfwd>\n#include <bits/ios_base.h>  // For ios_base, ios_base::iostate\n#include <streambuf>\n\nnamespace std\n{\n  // NB: Don't instantiate required wchar_t facets if no wchar_t support.\n#ifdef _GLIBCXX_USE_WCHAR_T\n# define  _GLIBCXX_NUM_FACETS 28\n#else\n# define  _GLIBCXX_NUM_FACETS 14\n#endif\n\n  // Convert string to numeric value of type _Tv and store results.\n  // NB: This is specialized for all required types, there is no\n  // generic definition.\n  template<typename _Tv>\n    void\n    __convert_to_v(const char* __in, _Tv& __out, ios_base::iostate& __err,\n\t\t   const __c_locale& __cloc);\n\n  // Explicit specializations for required types.\n  template<>\n    void\n    __convert_to_v(const char*, float&, ios_base::iostate&,\n\t\t   const __c_locale&);\n\n  template<>\n    void\n    __convert_to_v(const char*, double&, ios_base::iostate&,\n\t\t   const __c_locale&);\n\n  template<>\n    void\n    __convert_to_v(const char*, long double&, ios_base::iostate&,\n\t\t   const __c_locale&);\n\n  // NB: __pad is a struct, rather than a function, so it can be\n  // partially-specialized.\n  template<typename _CharT, typename _Traits>\n    struct __pad\n    {\n      static void\n      _S_pad(ios_base& __io, _CharT __fill, _CharT* __news,\n\t     const _CharT* __olds, const streamsize __newlen,\n\t     const streamsize __oldlen, const bool __num);\n    };\n\n  // Used by both numeric and monetary facets.\n  // Inserts \"group separator\" characters into an array of characters.\n  // It's recursive, one iteration per group.  It moves the characters\n  // in the buffer this way: \"xxxx12345\" -> \"12,345xxx\".  Call this\n  // only with __glen != 0.\n  template<typename _CharT>\n    _CharT*\n    __add_grouping(_CharT* __s, _CharT __sep,\n\t\t   const char* __gbeg, size_t __gsize,\n\t\t   const _CharT* __first, const _CharT* __last);\n\n  // This template permits specializing facet output code for\n  // ostreambuf_iterator.  For ostreambuf_iterator, sputn is\n  // significantly more efficient than incrementing iterators.\n  template<typename _CharT>\n    inline\n    ostreambuf_iterator<_CharT>\n    __write(ostreambuf_iterator<_CharT> __s, const _CharT* __ws, int __len)\n    {\n      __s._M_put(__ws, __len);\n      return __s;\n    }\n\n  // This is the unspecialized form of the template.\n  template<typename _CharT, typename _OutIter>\n    inline\n    _OutIter\n    __write(_OutIter __s, const _CharT* __ws, int __len)\n    {\n      for (int __j = 0; __j < __len; __j++, ++__s)\n\t*__s = __ws[__j];\n      return __s;\n    }\n\n\n  // 22.2.1.1  Template class ctype\n  // Include host and configuration specific ctype enums for ctype_base.\n  #include <bits/ctype_base.h>\n\n  // Common base for ctype<_CharT>.\n  /**\n   *  @brief  Common base for ctype facet\n   *\n   *  This template class provides implementations of the public functions\n   *  that forward to the protected virtual functions.\n   *\n   *  This template also provides abtract stubs for the protected virtual\n   *  functions.\n  */\n  template<typename _CharT>\n    class __ctype_abstract_base : public locale::facet, public ctype_base\n    ;\n\n  // NB: Generic, mostly useless implementation.\n  /**\n   *  @brief  Template ctype facet\n   *\n   *  This template class defines classification and conversion functions for\n   *  character sets.  It wraps <cctype> functionality.  Ctype gets used by\n   *  streams for many I/O operations.\n   *\n   *  This template provides the protected virtual functions the developer\n   *  will have to replace in a derived class or specialization to make a\n   *  working facet.  The public functions that access them are defined in\n   *  __ctype_abstract_base, to allow for implementation flexibility.  See\n   *  ctype<wchar_t> for an example.  The functions are documented in\n   *  __ctype_abstract_base.\n   *\n   *  Note: implementations are provided for all the protected virtual\n   *  functions, but will likely not be useful.\n  */\n  template<typename _CharT>\n    class ctype : public __ctype_abstract_base<_CharT>\n    ;\n\n  template<typename _CharT>\n    locale::id ctype<_CharT>::id;\n\n  // 22.2.1.3  ctype<char> specialization.\n  /**\n   *  @brief  The ctype<char> specialization.\n   *\n   *  This class defines classification and conversion functions for\n   *  the char type.  It gets used by char streams for many I/O\n   *  operations.  The char specialization provides a number of\n   *  optimizations as well.\n  */\n  template<>\n    class ctype<char> : public locale::facet, public ctype_base\n    ;\n\n  template<>\n    const ctype<char>&\n    use_facet<ctype<char> >(const locale& __loc);\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  // 22.2.1.3  ctype<wchar_t> specialization\n  /**\n   *  @brief  The ctype<wchar_t> specialization.\n   *\n   *  This class defines classification and conversion functions for the\n   *  wchar_t type.  It gets used by wchar_t streams for many I/O operations.\n   *  The wchar_t specialization provides a number of optimizations as well.\n   *\n   *  ctype<wchar_t> inherits its public methods from\n   *  __ctype_abstract_base<wchar_t>.\n  */\n  template<>\n    class ctype<wchar_t> : public __ctype_abstract_base<wchar_t>\n    ;\n\n  template<>\n    const ctype<wchar_t>&\n    use_facet<ctype<wchar_t> >(const locale& __loc);\n#endif //_GLIBCXX_USE_WCHAR_T\n\n  // Include host and configuration specific ctype inlines.\n  #include <bits/ctype_inline.h>\n\n  // 22.2.1.2  Template class ctype_byname\n  template<typename _CharT>\n    class ctype_byname : public ctype<_CharT>\n    ;\n\n  // 22.2.1.4  Class ctype_byname specializations.\n  template<>\n    ctype_byname<char>::ctype_byname(const char*, size_t refs);\n\n  template<>\n    ctype_byname<wchar_t>::ctype_byname(const char*, size_t refs);\n\n  // 22.2.1.5  Template class codecvt\n  #include <bits/codecvt.h>\n\n  // 22.2.2  The numeric category.\n  class __num_base\n  ;\n\n  template<typename _CharT>\n    struct __numpunct_cache : public locale::facet\n    ;\n\n  template<typename _CharT>\n    __numpunct_cache<_CharT>::~__numpunct_cache()\n\n  /**\n   *  @brief  Numpunct facet.\n   *\n   *  This facet stores several pieces of information related to printing and\n   *  scanning numbers, such as the decimal point character.  It takes a\n   *  template parameter specifying the char type.  The numpunct facet is\n   *  used by streams for many I/O operations involving numbers.\n   *\n   *  The numpunct template uses protected virtual functions to provide the\n   *  actual results.  The public accessors forward the call to the virtual\n   *  functions.  These virtual functions are hooks for developers to\n   *  implement the behavior they require from a numpunct facet.\n  */\n  template<typename _CharT>\n    class numpunct : public locale::facet\n    ;\n\n  template<typename _CharT>\n    locale::id numpunct<_CharT>::id;\n\n  template<>\n    numpunct<char>::~numpunct();\n\n  template<>\n    void\n    numpunct<char>::_M_initialize_numpunct(__c_locale __cloc);\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    numpunct<wchar_t>::~numpunct();\n\n  template<>\n    void\n    numpunct<wchar_t>::_M_initialize_numpunct(__c_locale __cloc);\n#endif\n\n  template<typename _CharT>\n    class numpunct_byname : public numpunct<_CharT>\n    ;\n\n  /**\n   *  @brief  Facet for parsing number strings.\n   *\n   *  This facet encapsulates the code to parse and return a number\n   *  from a string.  It is used by the istream numeric extraction\n   *  operators.\n   *\n   *  The num_get template uses protected virtual functions to provide the\n   *  actual results.  The public accessors forward the call to the virtual\n   *  functions.  These virtual functions are hooks for developers to\n   *  implement the behavior they require from the num_get facet.\n  */\n  template<typename _CharT, typename _InIter>\n    class num_get : public locale::facet\n    ;\n\n  template<typename _CharT, typename _InIter>\n    locale::id num_get<_CharT, _InIter>::id;\n\n\n  /**\n   *  @brief  Facet for converting numbers to strings.\n   *\n   *  This facet encapsulates the code to convert a number to a string.  It is\n   *  used by the ostream numeric insertion operators.\n   *\n   *  The num_put template uses protected virtual functions to provide the\n   *  actual results.  The public accessors forward the call to the virtual\n   *  functions.  These virtual functions are hooks for developers to\n   *  implement the behavior they require from the num_put facet.\n  */\n  template<typename _CharT, typename _OutIter>\n    class num_put : public locale::facet\n    ;\n\n  template <typename _CharT, typename _OutIter>\n    locale::id num_put<_CharT, _OutIter>::id;\n\n\n  /**\n   *  @brief  Facet for localized string comparison.\n   *\n   *  This facet encapsulates the code to compare strings in a localized\n   *  manner.\n   *\n   *  The collate template uses protected virtual functions to provide\n   *  the actual results.  The public accessors forward the call to\n   *  the virtual functions.  These virtual functions are hooks for\n   *  developers to implement the behavior they require from the\n   *  collate facet.\n  */\n  template<typename _CharT>\n    class collate : public locale::facet\n    ;\n\n  template<typename _CharT>\n    locale::id collate<_CharT>::id;\n\n  // Specializations.\n  template<>\n    int\n    collate<char>::_M_compare(const char*, const char*) const;\n\n  template<>\n    size_t\n    collate<char>::_M_transform(char*, const char*, size_t) const;\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    int\n    collate<wchar_t>::_M_compare(const wchar_t*, const wchar_t*) const;\n\n  template<>\n    size_t\n    collate<wchar_t>::_M_transform(wchar_t*, const wchar_t*, size_t) const;\n#endif\n\n  template<typename _CharT>\n    class collate_byname : public collate<_CharT>\n    ;\n\n\n  /**\n   *  @brief  Time format ordering data.\n   *\n   *  This class provides an enum representing different orderings of day,\n   *  month, and year.\n  */\n  class time_base\n  ;\n\n  template<typename _CharT>\n    struct __timepunct_cache : public locale::facet\n    ;\n\n  template<typename _CharT>\n    __timepunct_cache<_CharT>::~__timepunct_cache()\n\n  // Specializations.\n  template<>\n    const char*\n    __timepunct_cache<char>::_S_timezones[14];\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    const wchar_t*\n    __timepunct_cache<wchar_t>::_S_timezones[14];\n#endif\n\n  // Generic.\n  template<typename _CharT>\n    const _CharT* __timepunct_cache<_CharT>::_S_timezones[14];\n\n  template<typename _CharT>\n    class __timepunct : public locale::facet\n    ;\n\n  template<typename _CharT>\n    locale::id __timepunct<_CharT>::id;\n\n  // Specializations.\n  template<>\n    void\n    __timepunct<char>::_M_initialize_timepunct(__c_locale __cloc);\n\n  template<>\n    void\n    __timepunct<char>::_M_put(char*, size_t, const char*, const tm*) const;\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    void\n    __timepunct<wchar_t>::_M_initialize_timepunct(__c_locale __cloc);\n\n  template<>\n    void\n    __timepunct<wchar_t>::_M_put(wchar_t*, size_t, const wchar_t*,\n\t\t\t\t const tm*) const;\n#endif\n\n  // Include host and configuration specific timepunct functions.\n  #include <bits/time_members.h>\n\n  /**\n   *  @brief  Facet for parsing dates and times.\n   *\n   *  This facet encapsulates the code to parse and return a date or\n   *  time from a string.  It is used by the istream numeric\n   *  extraction operators.\n   *\n   *  The time_get template uses protected virtual functions to provide the\n   *  actual results.  The public accessors forward the call to the virtual\n   *  functions.  These virtual functions are hooks for developers to\n   *  implement the behavior they require from the time_get facet.\n  */\n  template<typename _CharT, typename _InIter>\n    class time_get : public locale::facet, public time_base\n    ;\n\n  template<typename _CharT, typename _InIter>\n    locale::id time_get<_CharT, _InIter>::id;\n\n  template<typename _CharT, typename _InIter>\n    class time_get_byname : public time_get<_CharT, _InIter>\n    {\n    public:\n      // Types:\n      typedef _CharT\t\t\tchar_type;\n      typedef _InIter\t\t\titer_type;\n\n      explicit\n      time_get_byname(const char*, size_t __refs = 0)\n      : time_get<_CharT, _InIter>(__refs) { }\n\n    protected:\n      virtual\n      ~time_get_byname() { }\n    };\n\n  /**\n   *  @brief  Facet for outputting dates and times.\n   *\n   *  This facet encapsulates the code to format and output dates and times\n   *  according to formats used by strftime().\n   *\n   *  The time_put template uses protected virtual functions to provide the\n   *  actual results.  The public accessors forward the call to the virtual\n   *  functions.  These virtual functions are hooks for developers to\n   *  implement the behavior they require from the time_put facet.\n  */\n  template<typename _CharT, typename _OutIter>\n    class time_put : public locale::facet\n    ;\n\n  template<typename _CharT, typename _OutIter>\n    locale::id time_put<_CharT, _OutIter>::id;\n\n  template<typename _CharT, typename _OutIter>\n    class time_put_byname : public time_put<_CharT, _OutIter>\n    ;\n\n\n  /**\n   *  @brief  Money format ordering data.\n   *\n   *  This class contains an ordered array of 4 fields to represent the\n   *  pattern for formatting a money amount.  Each field may contain one entry\n   *  from the part enum.  symbol, sign, and value must be present and the\n   *  remaining field must contain either none or space.  @see\n   *  moneypunct::pos_format() and moneypunct::neg_format() for details of how\n   *  these fields are interpreted.\n  */\n  class money_base\n  ;\n\n  template<typename _CharT, bool _Intl>\n    struct __moneypunct_cache : public locale::facet\n    {\n      const char*\t\t\t_M_grouping;\n      size_t                            _M_grouping_size;\n      bool\t\t\t\t_M_use_grouping;\n      _CharT\t\t\t\t_M_decimal_point;\n      _CharT\t\t\t\t_M_thousands_sep;\n      const _CharT*\t\t\t_M_curr_symbol;\n      size_t                            _M_curr_symbol_size;\n      const _CharT*\t\t\t_M_positive_sign;\n      size_t                            _M_positive_sign_size;\n      const _CharT*\t\t\t_M_negative_sign;\n      size_t                            _M_negative_sign_size;\n      int\t\t\t\t_M_frac_digits;\n      money_base::pattern\t\t_M_pos_format;\n      money_base::pattern\t        _M_neg_format;\n\n      // A list of valid numeric literals for input and output: in the standard\n      // \"C\" locale, this is \"-0123456789\". This array contains the chars after\n      // having been passed through the current locale's ctype<_CharT>.widen().\n      _CharT\t\t\t\t_M_atoms[money_base::_S_end];\n\n      bool\t\t\t\t_M_allocated;\n\n      __moneypunct_cache(size_t __refs = 0) : facet(__refs),\n      _M_grouping(NULL), _M_grouping_size(0), _M_use_grouping(false),\n      _M_decimal_point(_CharT()), _M_thousands_sep(_CharT()),\n      _M_curr_symbol(NULL), _M_curr_symbol_size(0),\n      _M_positive_sign(NULL), _M_positive_sign_size(0),\n      _M_negative_sign(NULL), _M_negative_sign_size(0),\n      _M_frac_digits(0),\n      _M_pos_format(money_base::pattern()),\n      _M_neg_format(money_base::pattern()), _M_allocated(false)\n      { }\n\n      ~__moneypunct_cache();\n\n      void\n      _M_cache(const locale& __loc);\n\n    private:\n      __moneypunct_cache&\n      operator=(const __moneypunct_cache&);\n      \n      explicit\n      __moneypunct_cache(const __moneypunct_cache&);\n    };\n\n  template<typename _CharT, bool _Intl>\n    __moneypunct_cache<_CharT, _Intl>::~__moneypunct_cache()\n    {\n      if (_M_allocated)\n\t{\n\t  delete [] _M_grouping;\n\t  delete [] _M_curr_symbol;\n\t  delete [] _M_positive_sign;\n\t  delete [] _M_negative_sign;\n\t}\n    }\n\n  /**\n   *  @brief  Facet for formatting data for money amounts.\n   *\n   *  This facet encapsulates the punctuation, grouping and other formatting\n   *  features of money amount string representations.\n  */\n  template<typename _CharT, bool _Intl>\n    class moneypunct : public locale::facet, public money_base\n    {\n    public:\n      // Types:\n      //@{\n      /// Public typedefs\n      typedef _CharT\t\t\tchar_type;\n      typedef basic_string<_CharT>\tstring_type;\n      //@}\n      typedef __moneypunct_cache<_CharT, _Intl>     __cache_type;\n\n    private:\n      __cache_type*\t\t\t_M_data;\n\n    public:\n      /// This value is provided by the standard, but no reason for its\n      /// existence.\n      static const bool\t\t\tintl = _Intl;\n      /// Numpunct facet id.\n      static locale::id\t\t\tid;\n\n      /**\n       *  @brief  Constructor performs initialization.\n       *\n       *  This is the constructor provided by the standard.\n       *\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      moneypunct(size_t __refs = 0) : facet(__refs), _M_data(NULL)\n      { _M_initialize_moneypunct(); }\n\n      /**\n       *  @brief  Constructor performs initialization.\n       *\n       *  This is an internal constructor.\n       *\n       *  @param cache  Cache for optimization.\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      moneypunct(__cache_type* __cache, size_t __refs = 0)\n      : facet(__refs), _M_data(__cache)\n      { _M_initialize_moneypunct(); }\n\n      /**\n       *  @brief  Internal constructor. Not for general use.\n       *\n       *  This is a constructor for use by the library itself to set up new\n       *  locales.\n       *\n       *  @param cloc  The \"C\" locale.\n       *  @param s  The name of a locale.\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      moneypunct(__c_locale __cloc, const char* __s, size_t __refs = 0)\n      : facet(__refs), _M_data(NULL)\n      { _M_initialize_moneypunct(__cloc, __s); }\n\n      /**\n       *  @brief  Return decimal point character.\n       *\n       *  This function returns a char_type to use as a decimal point.  It\n       *  does so by returning returning\n       *  moneypunct<char_type>::do_decimal_point().\n       *\n       *  @return  @a char_type representing a decimal point.\n      */\n      char_type\n      decimal_point() const\n      { return this->do_decimal_point(); }\n\n      /**\n       *  @brief  Return thousands separator character.\n       *\n       *  This function returns a char_type to use as a thousands\n       *  separator.  It does so by returning returning\n       *  moneypunct<char_type>::do_thousands_sep().\n       *\n       *  @return  char_type representing a thousands separator.\n      */\n      char_type\n      thousands_sep() const\n      { return this->do_thousands_sep(); }\n\n      /**\n       *  @brief  Return grouping specification.\n       *\n       *  This function returns a string representing groupings for the\n       *  integer part of an amount.  Groupings indicate where thousands\n       *  separators should be inserted.\n       *\n       *  Each char in the return string is interpret as an integer rather\n       *  than a character.  These numbers represent the number of digits in a\n       *  group.  The first char in the string represents the number of digits\n       *  in the least significant group.  If a char is negative, it indicates\n       *  an unlimited number of digits for the group.  If more chars from the\n       *  string are required to group a number, the last char is used\n       *  repeatedly.\n       *\n       *  For example, if the grouping() returns \"\\003\\002\" and is applied to\n       *  the number 123456789, this corresponds to 12,34,56,789.  Note that\n       *  if the string was \"32\", this would put more than 50 digits into the\n       *  least significant group if the character set is ASCII.\n       *\n       *  The string is returned by calling\n       *  moneypunct<char_type>::do_grouping().\n       *\n       *  @return  string representing grouping specification.\n      */\n      string\n      grouping() const\n      { return this->do_grouping(); }\n\n      /**\n       *  @brief  Return currency symbol string.\n       *\n       *  This function returns a string_type to use as a currency symbol.  It\n       *  does so by returning returning\n       *  moneypunct<char_type>::do_curr_symbol().\n       *\n       *  @return  @a string_type representing a currency symbol.\n      */\n      string_type\n      curr_symbol() const\n      { return this->do_curr_symbol(); }\n\n      /**\n       *  @brief  Return positive sign string.\n       *\n       *  This function returns a string_type to use as a sign for positive\n       *  amounts.  It does so by returning returning\n       *  moneypunct<char_type>::do_positive_sign().\n       *\n       *  If the return value contains more than one character, the first\n       *  character appears in the position indicated by pos_format() and the\n       *  remainder appear at the end of the formatted string.\n       *\n       *  @return  @a string_type representing a positive sign.\n      */\n      string_type\n      positive_sign() const\n      { return this->do_positive_sign(); }\n\n      /**\n       *  @brief  Return negative sign string.\n       *\n       *  This function returns a string_type to use as a sign for negative\n       *  amounts.  It does so by returning returning\n       *  moneypunct<char_type>::do_negative_sign().\n       *\n       *  If the return value contains more than one character, the first\n       *  character appears in the position indicated by neg_format() and the\n       *  remainder appear at the end of the formatted string.\n       *\n       *  @return  @a string_type representing a negative sign.\n      */\n      string_type\n      negative_sign() const\n      { return this->do_negative_sign(); }\n\n      /**\n       *  @brief  Return number of digits in fraction.\n       *\n       *  This function returns the exact number of digits that make up the\n       *  fractional part of a money amount.  It does so by returning\n       *  returning moneypunct<char_type>::do_frac_digits().\n       *\n       *  The fractional part of a money amount is optional.  But if it is\n       *  present, there must be frac_digits() digits.\n       *\n       *  @return  Number of digits in amount fraction.\n      */\n      int\n      frac_digits() const\n      { return this->do_frac_digits(); }\n\n      //@{\n      /**\n       *  @brief  Return pattern for money values.\n       *\n       *  This function returns a pattern describing the formatting of a\n       *  positive or negative valued money amount.  It does so by returning\n       *  returning moneypunct<char_type>::do_pos_format() or\n       *  moneypunct<char_type>::do_neg_format().\n       *\n       *  The pattern has 4 fields describing the ordering of symbol, sign,\n       *  value, and none or space.  There must be one of each in the pattern.\n       *  The none and space enums may not appear in the first field and space\n       *  may not appear in the final field.\n       *\n       *  The parts of a money string must appear in the order indicated by\n       *  the fields of the pattern.  The symbol field indicates that the\n       *  value of curr_symbol() may be present.  The sign field indicates\n       *  that the value of positive_sign() or negative_sign() must be\n       *  present.  The value field indicates that the absolute value of the\n       *  money amount is present.  none indicates 0 or more whitespace\n       *  characters, except at the end, where it permits no whitespace.\n       *  space indicates that 1 or more whitespace characters must be\n       *  present.\n       *\n       *  For example, for the US locale and pos_format() pattern\n       *  {symbol,sign,value,none}, curr_symbol() == '$' positive_sign() ==\n       *  '+', and value 10.01, and options set to force the symbol, the\n       *  corresponding string is \"$+10.01\".\n       *\n       *  @return  Pattern for money values.\n      */\n      pattern\n      pos_format() const\n      { return this->do_pos_format(); }\n\n      pattern\n      neg_format() const\n      { return this->do_neg_format(); }\n      //@}\n\n    protected:\n      /// Destructor.\n      virtual\n      ~moneypunct();\n\n      /**\n       *  @brief  Return decimal point character.\n       *\n       *  Returns a char_type to use as a decimal point.  This function is a\n       *  hook for derived classes to change the value returned.\n       *\n       *  @return  @a char_type representing a decimal point.\n      */\n      virtual char_type\n      do_decimal_point() const\n      { return _M_data->_M_decimal_point; }\n\n      /**\n       *  @brief  Return thousands separator character.\n       *\n       *  Returns a char_type to use as a thousands separator.  This function\n       *  is a hook for derived classes to change the value returned.\n       *\n       *  @return  @a char_type representing a thousands separator.\n      */\n      virtual char_type\n      do_thousands_sep() const\n      { return _M_data->_M_thousands_sep; }\n\n      /**\n       *  @brief  Return grouping specification.\n       *\n       *  Returns a string representing groupings for the integer part of a\n       *  number.  This function is a hook for derived classes to change the\n       *  value returned.  @see grouping() for details.\n       *\n       *  @return  String representing grouping specification.\n      */\n      virtual string\n      do_grouping() const\n      { return _M_data->_M_grouping; }\n\n      /**\n       *  @brief  Return currency symbol string.\n       *\n       *  This function returns a string_type to use as a currency symbol.\n       *  This function is a hook for derived classes to change the value\n       *  returned.  @see curr_symbol() for details.\n       *\n       *  @return  @a string_type representing a currency symbol.\n      */\n      virtual string_type\n      do_curr_symbol()   const\n      { return _M_data->_M_curr_symbol; }\n\n      /**\n       *  @brief  Return positive sign string.\n       *\n       *  This function returns a string_type to use as a sign for positive\n       *  amounts.  This function is a hook for derived classes to change the\n       *  value returned.  @see positive_sign() for details.\n       *\n       *  @return  @a string_type representing a positive sign.\n      */\n      virtual string_type\n      do_positive_sign() const\n      { return _M_data->_M_positive_sign; }\n\n      /**\n       *  @brief  Return negative sign string.\n       *\n       *  This function returns a string_type to use as a sign for negative\n       *  amounts.  This function is a hook for derived classes to change the\n       *  value returned.  @see negative_sign() for details.\n       *\n       *  @return  @a string_type representing a negative sign.\n      */\n      virtual string_type\n      do_negative_sign() const\n      { return _M_data->_M_negative_sign; }\n\n      /**\n       *  @brief  Return number of digits in fraction.\n       *\n       *  This function returns the exact number of digits that make up the\n       *  fractional part of a money amount.  This function is a hook for\n       *  derived classes to change the value returned.  @see frac_digits()\n       *  for details.\n       *\n       *  @return  Number of digits in amount fraction.\n      */\n      virtual int\n      do_frac_digits() const\n      { return _M_data->_M_frac_digits; }\n\n      /**\n       *  @brief  Return pattern for money values.\n       *\n       *  This function returns a pattern describing the formatting of a\n       *  positive valued money amount.  This function is a hook for derived\n       *  classes to change the value returned.  @see pos_format() for\n       *  details.\n       *\n       *  @return  Pattern for money values.\n      */\n      virtual pattern\n      do_pos_format() const\n      { return _M_data->_M_pos_format; }\n\n      /**\n       *  @brief  Return pattern for money values.\n       *\n       *  This function returns a pattern describing the formatting of a\n       *  negative valued money amount.  This function is a hook for derived\n       *  classes to change the value returned.  @see neg_format() for\n       *  details.\n       *\n       *  @return  Pattern for money values.\n      */\n      virtual pattern\n      do_neg_format() const\n      { return _M_data->_M_neg_format; }\n\n      // For use at construction time only.\n       void\n       _M_initialize_moneypunct(__c_locale __cloc = NULL,\n\t\t\t\tconst char* __name = NULL);\n    };\n\n  template<typename _CharT, bool _Intl>\n    locale::id moneypunct<_CharT, _Intl>::id;\n\n  template<typename _CharT, bool _Intl>\n    const bool moneypunct<_CharT, _Intl>::intl;\n\n  template<>\n    moneypunct<char, true>::~moneypunct();\n\n  template<>\n    moneypunct<char, false>::~moneypunct();\n\n  template<>\n    void\n    moneypunct<char, true>::_M_initialize_moneypunct(__c_locale, const char*);\n\n  template<>\n    void\n    moneypunct<char, false>::_M_initialize_moneypunct(__c_locale, const char*);\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    moneypunct<wchar_t, true>::~moneypunct();\n\n  template<>\n    moneypunct<wchar_t, false>::~moneypunct();\n\n  template<>\n    void\n    moneypunct<wchar_t, true>::_M_initialize_moneypunct(__c_locale,\n\t\t\t\t\t\t\tconst char*);\n\n  template<>\n    void\n    moneypunct<wchar_t, false>::_M_initialize_moneypunct(__c_locale,\n\t\t\t\t\t\t\t const char*);\n#endif\n\n  template<typename _CharT, bool _Intl>\n    class moneypunct_byname : public moneypunct<_CharT, _Intl>\n    {\n    public:\n      typedef _CharT\t\t\tchar_type;\n      typedef basic_string<_CharT>\tstring_type;\n\n      static const bool intl = _Intl;\n\n      explicit\n      moneypunct_byname(const char* __s, size_t __refs = 0)\n      : moneypunct<_CharT, _Intl>(__refs)\n      {\n\tif (std::strcmp(__s, \"C\") != 0 && std::strcmp(__s, \"POSIX\") != 0)\n\t  {\n\t    __c_locale __tmp;\n\t    this->_S_create_c_locale(__tmp, __s);\n\t    this->_M_initialize_moneypunct(__tmp);\n\t    this->_S_destroy_c_locale(__tmp);\n\t  }\n      }\n\n    protected:\n      virtual\n      ~moneypunct_byname() { }\n    };\n\n  template<typename _CharT, bool _Intl>\n    const bool moneypunct_byname<_CharT, _Intl>::intl;\n\n  /**\n   *  @brief  Facet for parsing monetary amounts.\n   *\n   *  This facet encapsulates the code to parse and return a monetary\n   *  amount from a string.\n   *\n   *  The money_get template uses protected virtual functions to\n   *  provide the actual results.  The public accessors forward the\n   *  call to the virtual functions.  These virtual functions are\n   *  hooks for developers to implement the behavior they require from\n   *  the money_get facet.\n  */\n  template<typename _CharT, typename _InIter>\n    class money_get : public locale::facet\n    {\n    public:\n      // Types:\n      //@{\n      /// Public typedefs\n      typedef _CharT\t\t\tchar_type;\n      typedef _InIter\t\t\titer_type;\n      typedef basic_string<_CharT>\tstring_type;\n      //@}\n\n      /// Numpunct facet id.\n      static locale::id\t\t\tid;\n\n      /**\n       *  @brief  Constructor performs initialization.\n       *\n       *  This is the constructor provided by the standard.\n       *\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      money_get(size_t __refs = 0) : facet(__refs) { }\n\n      /**\n       *  @brief  Read and parse a monetary value.\n       *\n       *  This function reads characters from @a s, interprets them as a\n       *  monetary value according to moneypunct and ctype facets retrieved\n       *  from io.getloc(), and returns the result in @a units as an integral\n       *  value moneypunct::frac_digits() * the actual amount.  For example,\n       *  the string $10.01 in a US locale would store 1001 in @a units.\n       *\n       *  Any characters not part of a valid money amount are not consumed.\n       *\n       *  If a money value cannot be parsed from the input stream, sets\n       *  err=(err|io.failbit).  If the stream is consumed before finishing\n       *  parsing,  sets err=(err|io.failbit|io.eofbit).  @a units is\n       *  unchanged if parsing fails.\n       *\n       *  This function works by returning the result of do_get().\n       *\n       *  @param  s  Start of characters to parse.\n       *  @param  end  End of characters to parse.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  err  Error field to set if parsing fails.\n       *  @param  units  Place to store result of parsing.\n       *  @return  Iterator referencing first character beyond valid money\n       *\t   amount.\n       */\n      iter_type\n      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,\n\t  ios_base::iostate& __err, long double& __units) const\n      { return this->do_get(__s, __end, __intl, __io, __err, __units); }\n\n      /**\n       *  @brief  Read and parse a monetary value.\n       *\n       *  This function reads characters from @a s, interprets them as a\n       *  monetary value according to moneypunct and ctype facets retrieved\n       *  from io.getloc(), and returns the result in @a digits.  For example,\n       *  the string $10.01 in a US locale would store \"1001\" in @a digits.\n       *\n       *  Any characters not part of a valid money amount are not consumed.\n       *\n       *  If a money value cannot be parsed from the input stream, sets\n       *  err=(err|io.failbit).  If the stream is consumed before finishing\n       *  parsing,  sets err=(err|io.failbit|io.eofbit).\n       *\n       *  This function works by returning the result of do_get().\n       *\n       *  @param  s  Start of characters to parse.\n       *  @param  end  End of characters to parse.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  err  Error field to set if parsing fails.\n       *  @param  digits  Place to store result of parsing.\n       *  @return  Iterator referencing first character beyond valid money\n       *\t   amount.\n       */\n      iter_type\n      get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,\n\t  ios_base::iostate& __err, string_type& __digits) const\n      { return this->do_get(__s, __end, __intl, __io, __err, __digits); }\n\n    protected:\n      /// Destructor.\n      virtual\n      ~money_get() { }\n\n      /**\n       *  @brief  Read and parse a monetary value.\n       *\n       *  This function reads and parses characters representing a monetary\n       *  value.  This function is a hook for derived classes to change the\n       *  value returned.  @see get() for details.\n       */\n      virtual iter_type\n      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,\n\t     ios_base::iostate& __err, long double& __units) const;\n\n      /**\n       *  @brief  Read and parse a monetary value.\n       *\n       *  This function reads and parses characters representing a monetary\n       *  value.  This function is a hook for derived classes to change the\n       *  value returned.  @see get() for details.\n       */\n      virtual iter_type\n      do_get(iter_type __s, iter_type __end, bool __intl, ios_base& __io,\n\t     ios_base::iostate& __err, string_type& __digits) const;\n\n      template<bool _Intl>\n        iter_type\n        _M_extract(iter_type __s, iter_type __end, ios_base& __io,\n\t\t   ios_base::iostate& __err, string& __digits) const;     \n    };\n\n  template<typename _CharT, typename _InIter>\n    locale::id money_get<_CharT, _InIter>::id;\n\n  /**\n   *  @brief  Facet for outputting monetary amounts.\n   *\n   *  This facet encapsulates the code to format and output a monetary\n   *  amount.\n   *\n   *  The money_put template uses protected virtual functions to\n   *  provide the actual results.  The public accessors forward the\n   *  call to the virtual functions.  These virtual functions are\n   *  hooks for developers to implement the behavior they require from\n   *  the money_put facet.\n  */\n  template<typename _CharT, typename _OutIter>\n    class money_put : public locale::facet\n    {\n    public:\n      //@{\n      /// Public typedefs\n      typedef _CharT\t\t\tchar_type;\n      typedef _OutIter\t\t\titer_type;\n      typedef basic_string<_CharT>\tstring_type;\n      //@}\n\n      /// Numpunct facet id.\n      static locale::id\t\t\tid;\n\n      /**\n       *  @brief  Constructor performs initialization.\n       *\n       *  This is the constructor provided by the standard.\n       *\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      money_put(size_t __refs = 0) : facet(__refs) { }\n\n      /**\n       *  @brief  Format and output a monetary value.\n       *\n       *  This function formats @a units as a monetary value according to\n       *  moneypunct and ctype facets retrieved from io.getloc(), and writes\n       *  the resulting characters to @a s.  For example, the value 1001 in a\n       *  US locale would write \"$10.01\" to @a s.\n       *\n       *  This function works by returning the result of do_put().\n       *\n       *  @param  s  The stream to write to.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  fill  char_type to use for padding.\n       *  @param  units  Place to store result of parsing.\n       *  @return  Iterator after writing.\n       */\n      iter_type\n      put(iter_type __s, bool __intl, ios_base& __io,\n\t  char_type __fill, long double __units) const\n      { return this->do_put(__s, __intl, __io, __fill, __units); }\n\n      /**\n       *  @brief  Format and output a monetary value.\n       *\n       *  This function formats @a digits as a monetary value according to\n       *  moneypunct and ctype facets retrieved from io.getloc(), and writes\n       *  the resulting characters to @a s.  For example, the string \"1001\" in\n       *  a US locale would write \"$10.01\" to @a s.\n       *\n       *  This function works by returning the result of do_put().\n       *\n       *  @param  s  The stream to write to.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  fill  char_type to use for padding.\n       *  @param  units  Place to store result of parsing.\n       *  @return  Iterator after writing.\n       */\n      iter_type\n      put(iter_type __s, bool __intl, ios_base& __io,\n\t  char_type __fill, const string_type& __digits) const\n      { return this->do_put(__s, __intl, __io, __fill, __digits); }\n\n    protected:\n      /// Destructor.\n      virtual\n      ~money_put() { }\n\n      /**\n       *  @brief  Format and output a monetary value.\n       *\n       *  This function formats @a units as a monetary value according to\n       *  moneypunct and ctype facets retrieved from io.getloc(), and writes\n       *  the resulting characters to @a s.  For example, the value 1001 in a\n       *  US locale would write \"$10.01\" to @a s.\n       *\n       *  This function is a hook for derived classes to change the value\n       *  returned.  @see put().\n       *\n       *  @param  s  The stream to write to.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  fill  char_type to use for padding.\n       *  @param  units  Place to store result of parsing.\n       *  @return  Iterator after writing.\n       */\n      virtual iter_type\n      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,\n\t     long double __units) const;\n\n      /**\n       *  @brief  Format and output a monetary value.\n       *\n       *  This function formats @a digits as a monetary value according to\n       *  moneypunct and ctype facets retrieved from io.getloc(), and writes\n       *  the resulting characters to @a s.  For example, the string \"1001\" in\n       *  a US locale would write \"$10.01\" to @a s.\n       *\n       *  This function is a hook for derived classes to change the value\n       *  returned.  @see put().\n       *\n       *  @param  s  The stream to write to.\n       *  @param  intl  Parameter to use_facet<moneypunct<CharT,intl> >.\n       *  @param  io  Source of facets and io state.\n       *  @param  fill  char_type to use for padding.\n       *  @param  units  Place to store result of parsing.\n       *  @return  Iterator after writing.\n       */\n      virtual iter_type\n      do_put(iter_type __s, bool __intl, ios_base& __io, char_type __fill,\n\t     const string_type& __digits) const;\n\n      template<bool _Intl>\n        iter_type\n        _M_insert(iter_type __s, ios_base& __io, char_type __fill,\n\t\t  const string_type& __digits) const;\n    };\n\n  template<typename _CharT, typename _OutIter>\n    locale::id money_put<_CharT, _OutIter>::id;\n\n  /**\n   *  @brief  Messages facet base class providing catalog typedef.\n   */\n  struct messages_base\n  {\n    typedef int catalog;\n  };\n\n  /**\n   *  @brief  Facet for handling message catalogs\n   *\n   *  This facet encapsulates the code to retrieve messages from\n   *  message catalogs.  The only thing defined by the standard for this facet\n   *  is the interface.  All underlying functionality is\n   *  implementation-defined.\n   *\n   *  This library currently implements 3 versions of the message facet.  The\n   *  first version (gnu) is a wrapper around gettext, provided by libintl.\n   *  The second version (ieee) is a wrapper around catgets.  The final\n   *  version (default) does no actual translation.  These implementations are\n   *  only provided for char and wchar_t instantiations.\n   *\n   *  The messages template uses protected virtual functions to\n   *  provide the actual results.  The public accessors forward the\n   *  call to the virtual functions.  These virtual functions are\n   *  hooks for developers to implement the behavior they require from\n   *  the messages facet.\n  */\n  template<typename _CharT>\n    class messages : public locale::facet, public messages_base\n    {\n    public:\n      // Types:\n      //@{\n      /// Public typedefs\n      typedef _CharT\t\t\tchar_type;\n      typedef basic_string<_CharT>\tstring_type;\n      //@}\n\n    protected:\n      // Underlying \"C\" library locale information saved from\n      // initialization, needed by messages_byname as well.\n      __c_locale\t\t\t_M_c_locale_messages;\n      const char*\t\t\t_M_name_messages;\n\n    public:\n      /// Numpunct facet id.\n      static locale::id\t\t\tid;\n\n      /**\n       *  @brief  Constructor performs initialization.\n       *\n       *  This is the constructor provided by the standard.\n       *\n       *  @param refs  Passed to the base facet class.\n      */\n      explicit\n      messages(size_t __refs = 0);\n\n      // Non-standard.\n      /**\n       *  @brief  Internal constructor.  Not for general use.\n       *\n       *  This is a constructor for use by the library itself to set up new\n       *  locales.\n       *\n       *  @param  cloc  The \"C\" locale.\n       *  @param  s  The name of a locale.\n       *  @param  refs  Refcount to pass to the base class.\n       */\n      explicit\n      messages(__c_locale __cloc, const char* __s, size_t __refs = 0);\n\n      /*\n       *  @brief  Open a message catalog.\n       *\n       *  This function opens and returns a handle to a message catalog by\n       *  returning do_open(s, loc).\n       *\n       *  @param  s  The catalog to open.\n       *  @param  loc  Locale to use for character set conversions.\n       *  @return  Handle to the catalog or value < 0 if open fails.\n      */\n      catalog\n      open(const basic_string<char>& __s, const locale& __loc) const\n      { return this->do_open(__s, __loc); }\n\n      // Non-standard and unorthodox, yet effective.\n      /*\n       *  @brief  Open a message catalog.\n       *\n       *  This non-standard function opens and returns a handle to a message\n       *  catalog by returning do_open(s, loc).  The third argument provides a\n       *  message catalog root directory for gnu gettext and is ignored\n       *  otherwise.\n       *\n       *  @param  s  The catalog to open.\n       *  @param  loc  Locale to use for character set conversions.\n       *  @param  dir  Message catalog root directory.\n       *  @return  Handle to the catalog or value < 0 if open fails.\n      */\n      catalog\n      open(const basic_string<char>&, const locale&, const char*) const;\n\n      /*\n       *  @brief  Look up a string in a message catalog.\n       *\n       *  This function retrieves and returns a message from a catalog by\n       *  returning do_get(c, set, msgid, s).\n       *\n       *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).\n       *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).\n       *\n       *  @param  c  The catalog to access.\n       *  @param  set  Implementation-defined.\n       *  @param  msgid  Implementation-defined.\n       *  @param  s  Default return value if retrieval fails.\n       *  @return  Retrieved message or @a s if get fails.\n      */\n      string_type\n      get(catalog __c, int __set, int __msgid, const string_type& __s) const\n      { return this->do_get(__c, __set, __msgid, __s); }\n\n      /*\n       *  @brief  Close a message catalog.\n       *\n       *  Closes catalog @a c by calling do_close(c).\n       *\n       *  @param  c  The catalog to close.\n      */\n      void\n      close(catalog __c) const\n      { return this->do_close(__c); }\n\n    protected:\n      /// Destructor.\n      virtual\n      ~messages();\n\n      /*\n       *  @brief  Open a message catalog.\n       *\n       *  This function opens and returns a handle to a message catalog in an\n       *  implementation-defined manner.  This function is a hook for derived\n       *  classes to change the value returned.\n       *\n       *  @param  s  The catalog to open.\n       *  @param  loc  Locale to use for character set conversions.\n       *  @return  Handle to the opened catalog, value < 0 if open failed.\n      */\n      virtual catalog\n      do_open(const basic_string<char>&, const locale&) const;\n\n      /*\n       *  @brief  Look up a string in a message catalog.\n       *\n       *  This function retrieves and returns a message from a catalog in an\n       *  implementation-defined manner.  This function is a hook for derived\n       *  classes to change the value returned.\n       *\n       *  For gnu, @a set and @a msgid are ignored.  Returns gettext(s).\n       *  For default, returns s. For ieee, returns catgets(c,set,msgid,s).\n       *\n       *  @param  c  The catalog to access.\n       *  @param  set  Implementation-defined.\n       *  @param  msgid  Implementation-defined.\n       *  @param  s  Default return value if retrieval fails.\n       *  @return  Retrieved message or @a s if get fails.\n      */\n      virtual string_type\n      do_get(catalog, int, int, const string_type& __dfault) const;\n\n      /*\n       *  @brief  Close a message catalog.\n       *\n       *  @param  c  The catalog to close.\n      */\n      virtual void\n      do_close(catalog) const;\n\n      // Returns a locale and codeset-converted string, given a char* message.\n      char*\n      _M_convert_to_char(const string_type& __msg) const\n      {\n\t// XXX\n\treturn reinterpret_cast<char*>(const_cast<_CharT*>(__msg.c_str()));\n      }\n\n      // Returns a locale and codeset-converted string, given a char* message.\n      string_type\n      _M_convert_from_char(char*) const\n      {\n#if 0\n\t// Length of message string without terminating null.\n\tsize_t __len = char_traits<char>::length(__msg) - 1;\n\n\t// \"everybody can easily convert the string using\n\t// mbsrtowcs/wcsrtombs or with iconv()\"\n\n\t// Convert char* to _CharT in locale used to open catalog.\n\t// XXX need additional template parameter on messages class for this..\n\t// typedef typename codecvt<char, _CharT, _StateT> __codecvt_type;\n\ttypedef typename codecvt<char, _CharT, mbstate_t> __codecvt_type;\n\n\t__codecvt_type::state_type __state;\n\t// XXX may need to initialize state.\n\t//initialize_state(__state._M_init());\n\n\tchar* __from_next;\n\t// XXX what size for this string?\n\t_CharT* __to = static_cast<_CharT*>(__builtin_alloca(__len + 1));\n\tconst __codecvt_type& __cvt = use_facet<__codecvt_type>(_M_locale_conv);\n\t__cvt.out(__state, __msg, __msg + __len, __from_next,\n\t\t  __to, __to + __len + 1, __to_next);\n\treturn string_type(__to);\n#endif\n#if 0\n\ttypedef ctype<_CharT> __ctype_type;\n\t// const __ctype_type& __cvt = use_facet<__ctype_type>(_M_locale_msg);\n\tconst __ctype_type& __cvt = use_facet<__ctype_type>(locale());\n\t// XXX Again, proper length of converted string an issue here.\n\t// For now, assume the converted length is not larger.\n\t_CharT* __dest = static_cast<_CharT*>(__builtin_alloca(__len + 1));\n\t__cvt.widen(__msg, __msg + __len, __dest);\n\treturn basic_string<_CharT>(__dest);\n#endif\n\treturn string_type();\n      }\n     };\n\n  template<typename _CharT>\n    locale::id messages<_CharT>::id;\n\n  // Specializations for required instantiations.\n  template<>\n    string\n    messages<char>::do_get(catalog, int, int, const string&) const;\n\n#ifdef _GLIBCXX_USE_WCHAR_T\n  template<>\n    wstring\n    messages<wchar_t>::do_get(catalog, int, int, const wstring&) const;\n#endif\n\n  template<typename _CharT>\n    class messages_byname : public messages<_CharT>\n    {\n    public:\n      typedef _CharT\t\t\tchar_type;\n      typedef basic_string<_CharT>\tstring_type;\n\n      explicit\n      messages_byname(const char* __s, size_t __refs = 0);\n\n    protected:\n      virtual\n      ~messages_byname()\n      { }\n    };\n\n  // Include host and configuration specific messages functions.\n  #include <bits/messages_members.h>\n\n\n  // Subclause convenience interfaces, inlines.\n  // NB: These are inline because, when used in a loop, some compilers\n  // can hoist the body out of the loop; then it's just as fast as the\n  // C is*() function.\n  //@{\n  /// Convenience interface to ctype.is().\n  template<typename _CharT>\n    inline bool\n    isspace(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::space, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isprint(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::print, __c); }\n\n  template<typename _CharT>\n    inline bool\n    iscntrl(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::cntrl, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isupper(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::upper, __c); }\n\n  template<typename _CharT>\n    inline bool islower(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::lower, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isalpha(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alpha, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isdigit(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::digit, __c); }\n\n  template<typename _CharT>\n    inline bool\n    ispunct(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::punct, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isxdigit(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::xdigit, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isalnum(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::alnum, __c); }\n\n  template<typename _CharT>\n    inline bool\n    isgraph(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).is(ctype_base::graph, __c); }\n\n  template<typename _CharT>\n    inline _CharT\n    toupper(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).toupper(__c); }\n\n  template<typename _CharT>\n    inline _CharT\n    tolower(_CharT __c, const locale& __loc)\n    { return use_facet<ctype<_CharT> >(__loc).tolower(__c); }\n  //@}\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "tests/inputs/logos.x",
    "content": "# https://github.com/theos/logos#source-file-tweakx \n%hook NSObject\n\n- (NSString *)description {\n\treturn [%orig stringByAppendingString:@\" (of doom)\"];\n}\n\n%new - (void)helloWorld {\n\tNSLog(@\"Awesome!\");\n}\n\n%end\n"
  },
  {
    "path": "tests/inputs/logos.xm",
    "content": "# https://github.com/theos/logos#source-file-tweakx \n# c++\n%hook NSObject\n\n- (NSString *)description {\n\treturn [%orig stringByAppendingString:@\" (of doom)\"];\n}\n\n%new - (void)helloWorld {\n\tNSLog(@\"Awesome!\");\n}\n\n%end\n"
  },
  {
    "path": "tests/inputs/logtalk.lgt",
    "content": "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n% https://raw.githubusercontent.com/LogtalkDotOrg/logtalk3/master/core/logtalk.lgt\n%  \n%  This file is part of Logtalk <http://logtalk.org/>\n%  Copyright 1998-2016 Paulo Moura <pmoura@logtalk.org>\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%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n% the compiler/runtime must be able to call some of the code generated\n% by the compilation of the `logtalk` object directly, thus forcing us\n% to fix the code prefix that is used in its compilation\n:- set_logtalk_flag(code_prefix, '$').\n\n\n:- if(current_logtalk_flag(prolog_dialect, lean)).\n\t% avoid a warning when embedding Logtalk in Lean Prolog\n\t:- dynamic('$lgt_parent_file_'/2).\n:- endif.\n\n\n:- object(logtalk).\n\n\t:- info([\n\t\tversion is 1.2,\n\t\tauthor is 'Paulo Moura',\n\t\tdate is 2015/08/26,\n\t\tcomment is 'Built-in object providing message printing, debugging, library, source file, and hacking methods.']).\n\n\t:- built_in.\n\n\t:- set_logtalk_flag(context_switching_calls, allow).\n\t:- set_logtalk_flag(dynamic_declarations, deny).\n\t:- set_logtalk_flag(complements, deny).\n\t:- set_logtalk_flag(events, deny).\n\t:- if(current_logtalk_flag(threads, supported)).\n\t\t:- threaded.\n\t:- endif.\n\n\t% message printing predicates\n\n\t:- public(print_message/3).\n\t:- mode(print_message(+nonvar, +nonvar, +nonvar), one).\n\t:- info(print_message/3, [\n\t\tcomment is 'Prints a message of the given kind for the specified component.',\n\t\targnames is ['Kind', 'Component', 'Message']\n\t]).\n\n\t:- public(print_message_tokens/3).\n\t:- mode(print_message_tokens(@stream_or_alias, +atom, @list(nonvar)), one).\n\t:- info(print_message_tokens/3, [\n\t\tcomment is 'Print the messages tokens to the given stream, prefixing each line with the specified atom.',\n\t\targnames is ['Stream', 'Prefix', 'Tokens']\n\t]).\n\n\t:- public(print_message_token/4).\n\t:- multifile(print_message_token/4).\n\t:- dynamic(print_message_token/4).\n\t:- mode(print_message_token(@stream_or_alias, @atom, @nonvar, @list(nonvar)), zero_or_one).\n\t:- info(print_message_token/4, [\n\t\tcomment is 'User-defined hook predicate for printing a message token (at_same_line, nl, flush, Format-Arguments, term(Term,Options), ansi(Attributes,Format,Arguments), begin(Kind,Variable), and end(Variable)).',\n\t\targnames is ['Stream', 'Prefix', 'Token', 'Tokens']\n\t]).\n\n\t:- public(message_tokens//2).\n\t:- multifile(message_tokens//2).\n\t:- dynamic(message_tokens//2).\n\t:- mode(message_tokens(+nonvar, +nonvar), zero_or_one).\n\t:- info(message_tokens//2, [\n\t\tcomment is 'User-defined hook grammar rule for converting a message into a list of tokens (at_same_line, nl, flush, Format-Arguments, term(Term,Options), ansi(Attributes,Format,Arguments), begin(Kind,Variable), and end(Variable)).',\n\t\targnames is ['Message', 'Component']\n\t]).\n\n\t:- public(message_prefix_stream/4).\n\t:- multifile(message_prefix_stream/4).\n\t:- dynamic(message_prefix_stream/4).\n\t:- mode(message_prefix_stream(?nonvar, ?nonvar, ?atom, ?stream_or_alias), zero_or_more).\n\t:- info(message_prefix_stream/4, [\n\t\tcomment is 'Message line prefix and output stream to be used when printing a message given its kind and component.',\n\t\targnames is ['Kind', 'Component', 'Prefix', 'Stream']\n\t]).\n\n\t:- public(message_hook/4).\n\t:- multifile(message_hook/4).\n\t:- dynamic(message_hook/4).\n\t:- mode(message_hook(+nonvar, +nonvar, +nonvar, +list(nonvar)), zero_or_one).\n\t:- info(message_hook/4, [\n\t\tcomment is 'User-defined hook predicate for intercepting message printing calls.',\n\t\targnames is ['Message', 'Kind', 'Component', 'Tokens']\n\t]).\n\n\t% question asking predicates\n\n\t:- public(ask_question/5).\n\t:- meta_predicate(ask_question(*, *, *, 1, *)).\n\t:- mode(ask_question(+nonvar, +nonvar, +nonvar, +callable, -term), one).\n\t:- info(ask_question/5, [\n\t\tcomment is 'Asks a question and reads the answer until the check predicate is true.',\n\t\targnames is ['Kind', 'Component', 'Question', 'Check', 'Answer']\n\t]).\n\n\t:- public(question_hook/6).\n\t:- multifile(question_hook/6).\n\t:- dynamic(question_hook/6).\n\t:- meta_predicate(question_hook(*, *, *, *, 1, *)).\n\t:- mode(question_hook(+nonvar, +nonvar, +nonvar, +list(nonvar), +callable, -term), zero_or_one).\n\t:- info(question_hook/6, [\n\t\tcomment is 'User-defined hook predicate for intercepting question asking calls.',\n\t\targnames is ['Question', 'Kind', 'Component', 'Tokens', 'Check', 'Answer']\n\t]).\n\n\t:- public(question_prompt_stream/4).\n\t:- multifile(question_prompt_stream/4).\n\t:- dynamic(question_prompt_stream/4).\n\t:- mode(question_prompt_stream(?nonvar, ?nonvar, ?atom, ?stream_or_alias), zero_or_more).\n\t:- info(question_prompt_stream/4, [\n\t\tcomment is 'Prompt and input stream to be used when asking a question given its kind and component.',\n\t\targnames is ['Kind', 'Component', 'Prompt', 'Stream']\n\t]).\n\n\t% debugging predicates\n\n\t:- public(trace_event/2).\n\t:- multifile(trace_event/2).\n\t:- dynamic(trace_event/2).\n\t:- mode(trace_event(@callable, @execution_context), zero).\n\t:- info(trace_event/2, [\n\t\tcomment is 'Trace event handler. The runtime calls all trace event handlers using a failure-driven loop before calling the debug event handler.',\n\t\targnames is ['Event', 'ExecutionContext']\n\t]).\n\n\t:- public(debug_handler_provider/1).\n\t:- multifile(debug_handler_provider/1).\n\t:- mode(debug_handler_provider(?object_identifier), zero_or_one).\n\t:- info(debug_handler_provider/1, [\n\t\tcomment is 'Declares an object as the debug handler provider. There should be at most one debug handler provider loaded at any given moment.',\n\t\targnames is ['Provider']\n\t]).\n\t% workaround the lack of support for static multifile predicates in Qu-Prolog and XSB\n\t:- if((current_logtalk_flag(prolog_dialect, Dialect), (Dialect==xsb; Dialect==qp))).\n\t\t:- dynamic(debug_handler_provider/1).\n\t:- endif.\n\n\t:- public(debug_handler/2).\n\t:- multifile(debug_handler/2).\n\t:- mode(debug_handler(?entity_identifier, ?atom), zero_or_more).\n\t:- info(debug_handler/2, [\n\t\tcomment is 'Debug event handler. The defined events are unification events - fact(Entity,Fact,Clause,Line) and rule(Entity,Head,Clause,Line) - and goal events - top_goal(Goal,CompiledGoal) and goal(Goal,CompiledGoal).',\n\t\targnames is ['Event', 'ExecutionContext']\n\t]).\n\t% workaround the lack of support for static multifile predicates in Qu-Prolog and XSB\n\t:- if((current_logtalk_flag(prolog_dialect, Dialect), (Dialect==xsb; Dialect==qp))).\n\t\t:- dynamic(debug_handler/2).\n\t:- endif.\n\n\t% file and library predicates\n\n\t:- public(expand_library_path/2).\n\t:- mode(expand_library_path(+atom, ?atom), zero_or_one).\n\t:- info(expand_library_path/2, [\n\t\tcomment is 'Expands a library name into its full path. Uses a depth bound to prevent loops.',\n\t\targnames is ['Library', 'Path']\n\t]).\n\n\t:- public(loaded_file/1).\n\t:- mode(loaded_file(?atom), zero_or_more).\n\t:- info(loaded_file/1, [\n\t\tcomment is 'Enumerates, by backtracking, all loaded files, returning their full paths.',\n\t\targnames is ['Path']\n\t]).\n\n\t:- public(loaded_file_property/2).\n\t:- mode(loaded_file_property(?atom, ?compound), zero_or_more).\n\t:- info(loaded_file_property/2, [\n\t\tcomment is 'Enumerates, by backtracking, all loaded file properties. Valid properties are: basename/1, directory/1, mode/1, flags/1, text_properties/1 (encoding/1 and bom/1), target/1, modified/1, parent/1, library/1, object/1, protocol/1, and category/1.',\n\t\targnames is ['Path', 'Property']\n\t]).\n\n\t% hacking predicates\n\n\t:- public(compile_aux_clauses/1).\n\t:- mode(compile_aux_clauses(@list(clause)), one).\n\t:- info(compile_aux_clauses/1, [\n\t\tcomment is 'Compiles a list of auxiliary clauses.',\n\t\targnames is ['Clauses']\n\t]).\n\n\t:- public(entity_prefix/2).\n\t:- mode(entity_prefix(?entity_identifier, ?atom), zero_or_one).\n\t:- info(entity_prefix/2, [\n\t\tcomment is 'Converts between an entity identifier and the entity prefix that is used for its compiled code. When none of the arguments is instantiated, it returns the identifier and the prefix of the entity under compilation, if any.',\n\t\targnames is ['Entity', 'Prefix']\n\t]).\n\n\t:- public(compile_predicate_heads/4).\n\t:- mode(compile_predicate_heads(@list(callable), ?entity_identifier, -list(callable), @execution_context), zero_or_one).\n\t:- mode(compile_predicate_heads(@conjunction(callable), ?entity_identifier, -conjunction(callable), @execution_context), zero_or_one).\n\t:- mode(compile_predicate_heads(@callable, ?entity_identifier, -callable, @execution_context), zero_or_one).\n\t:- info(compile_predicate_heads/4, [\n\t\tcomment is 'Compiles clause heads. The heads are compiled in the context of the entity under compilation when the entity argument is not instantiated.',\n\t\targnames is ['Heads', 'Entity', 'CompiledHeads', 'ExecutionContext']\n\t]).\n\n\t:- public(compile_predicate_indicators/3).\n\t:- mode(compile_predicate_indicators(@list(predicate_indicator), ?entity_identifier, -list(predicate_indicator)), zero_or_one).\n\t:- mode(compile_predicate_indicators(@conjunction(predicate_indicator), ?entity_identifier, -conjunction(predicate_indicator)), zero_or_one).\n\t:- mode(compile_predicate_indicators(@predicate_indicator, ?entity_identifier, -predicate_indicator), zero_or_one).\n\t:- info(compile_predicate_indicators/3, [\n\t\tcomment is 'Compiles predicate indicators. The predicate are compiled in the context of the entity under compilation when the entity argument is not instantiated.',\n\t\targnames is ['PredicateIndicators', 'Entity', 'CompiledPredicateIndicators']\n\t]).\n\n\t:- public(decompile_predicate_heads/4).\n\t:- mode(decompile_predicate_heads(@list(callable), -entity_identifier, -atom, -list(callable)), zero_or_one).\n\t:- mode(decompile_predicate_heads(@conjunction(callable), -entity_identifier, -atom, -conjunction(callable)), zero_or_one).\n\t:- mode(decompile_predicate_heads(@callable, -entity_identifier, -atom, -callable), zero_or_one).\n\t:- info(decompile_predicate_heads/4, [\n\t\tcomment is 'Decompiles clause heads. All compiled clause heads must belong to the same entity, which must be loaded.',\n\t\targnames is ['CompiledHeads', 'Entity', 'Type', 'Heads']\n\t]).\n\n\t:- public(decompile_predicate_indicators/4).\n\t:- mode(decompile_predicate_indicators(@list(predicate_indicator), -entity_identifier, -atom, -list(predicate_indicator)), zero_or_one).\n\t:- mode(decompile_predicate_indicators(@conjunction(predicate_indicator), -entity_identifier, -atom, -conjunction(predicate_indicator)), zero_or_one).\n\t:- mode(decompile_predicate_indicators(@predicate_indicator, -entity_identifier, -atom, -predicate_indicator), zero_or_one).\n\t:- info(decompile_predicate_indicators/4, [\n\t\tcomment is 'Decompiles predicate indicators. All compiled predicate indicators must belong to the same entity, which must be loaded.',\n\t\targnames is ['CompiledPredicateIndicators', 'Entity', 'Type', 'PredicateIndicators']\n\t]).\n\n\t:- public(execution_context/7).\n\t:- mode(execution_context(?nonvar, ?entity_identifier, ?object_identifier, ?object_identifier, ?object_identifier, @list(callable), @list(callable)), zero_or_one).\n\t:- info(execution_context/7, [\n\t\tcomment is 'Execution context term data. Execution context terms should be considered opaque terms subject to change without notice.',\n\t\targnames is ['ExecutionContext', 'Entity', 'Sender', 'This', 'Self', 'MetaCallContext', 'Stack']\n\t]).\n\n\tprint_message(Kind, Component, Message) :-\n\t\tmessage_term_to_tokens(Message, Kind, Component, Tokens),\n\t\t(\tnonvar(Message),\n\t\t\tmessage_hook(Message, Kind, Component, Tokens) ->\n\t\t\t% message intercepted; assume that the message is printed\n\t\t\ttrue\n\t\t;\tdefault_print_message(Kind, Component, Tokens)\n\t\t).\n\n\t% message_term_to_tokens(@term, @term, @term, -list)\n\t%\n\t% translates a message term to tokens\n\tmessage_term_to_tokens(Message, Kind, Component, Tokens) :-\n\t\t(\tvar(Message) ->\n\t\t\tTokens = ['Non-instantiated ~q message for component ~q!'-[Kind, Component], nl]\n\t\t;\tphrase(message_tokens(Message, Component), Tokens) ->\n\t\t\ttrue\n\t\t;\tTokens = ['Unknown ~q message for component ~q: ~q'-[Kind, Component, Message], nl]\n\t\t).\n\n\t% default_print_message(+atom_or_compound, +atom, +compound, +list, +compound)\n\t%\n\t% print a message that was not intercepted by the user\n\tdefault_print_message(silent, _, _) :-\n\t\t!.\n\tdefault_print_message(silent(_), _, _) :-\n\t\t!.\n\tdefault_print_message(banner, _, _) :-\n\t\t\\+ current_logtalk_flag(report, on),\n\t\t!.\n\tdefault_print_message(comment, _, _) :-\n\t\t\\+ current_logtalk_flag(report, on),\n\t\t!.\n\tdefault_print_message(comment(_), _, _) :-\n\t\t\\+ current_logtalk_flag(report, on),\n\t\t!.\n\tdefault_print_message(warning, _, _) :-\n\t\tcurrent_logtalk_flag(report, off),\n\t\t!.\n\tdefault_print_message(warning(_), _, _) :-\n\t\tcurrent_logtalk_flag(report, off),\n\t\t!.\n\tdefault_print_message(Kind, Component, Tokens) :-\n\t\t(\tmessage_prefix_stream(Kind, Component, Prefix, Stream) ->\n\t\t\ttrue\n\t\t;\t% no user-defined prefix and stream; use default definition\n\t\t\tdefault_message_prefix_stream(Kind, Prefix, Stream) ->\n\t\t\ttrue\n\t\t;\t% no such kind of message; use \"information\" instead\n\t\t\tdefault_message_prefix_stream(information, Prefix, Stream)\n\t\t),\n\t\t% add begin/2 and end/1 tokens to, respectively, the start and the end of the list of tokens\n\t\t% but pass them using discrete arguments instead of doing an expensive list append operation;\n\t\t% these two tokens can be intercepted by the user for supporting e.g. message coloring\n\t\tfunctor(Kind, Functor, _),\n\t\tprint_message_tokens_([begin(Functor,Ctx), Prefix-[]| Tokens], Stream, Prefix),\n\t\tprint_message_tokens_([end(Ctx)], Stream, Prefix).\n\n\t% default_message_prefix_stream(?atom_or_compound, ?atom, ?stream_or_alias)\n\t%\n\t% default definitions for any component for the line prefix and output stream used\n\t% when printing messages; the definitions used here are based on Quintus Prolog and\n\t% are also used in other Prolog compilers\n\tdefault_message_prefix_stream(banner,         '',       user_output).\n\tdefault_message_prefix_stream(help,           '',       user_output).\n\tdefault_message_prefix_stream(question,       '',       user_output).\n\tdefault_message_prefix_stream(information,    '% ',     user_output).\n\tdefault_message_prefix_stream(information(_), '% ',     user_output).\n\tdefault_message_prefix_stream(comment,        '% ',     user_output).\n\tdefault_message_prefix_stream(comment(_),     '% ',     user_output).\n\tdefault_message_prefix_stream(warning,        '*     ', user_error).\n\tdefault_message_prefix_stream(warning(_),     '*     ', user_error).\n\tdefault_message_prefix_stream(error,          '!     ', user_error).\n\tdefault_message_prefix_stream(error(_),       '!     ', user_error).\n\n\tprint_message_tokens(Stream, Prefix, Tokens) :-\n\t\t(\tTokens = [at_same_line| _] ->\n\t\t\t% continuation message\n\t\t\tprint_message_tokens_(Tokens, Stream, Prefix)\n\t\t;\tTokens = [begin(Kind, Context)| Rest] ->\n\t\t\t% write the prefix after the begin/2 token\n\t\t\tprint_message_tokens_([begin(Kind, Context), Prefix-[]| Rest], Stream, Prefix)\n\t\t;\t% write first line prefix\n\t\t\twrite(Stream, Prefix),\n\t\t\tprint_message_tokens_(Tokens, Stream, Prefix)\n\t\t).\n\n\t% if the list of tokens unifies with (-), assume it's a variable and ignore it\n\tprint_message_tokens_((-), _, _).\n\tprint_message_tokens_([], _, _).\n\tprint_message_tokens_([Token| Tokens], Stream, Prefix) :-\n\t\t(\tprint_message_token(Stream, Prefix, Token, Tokens) ->\n\t\t\t% token printing intercepted by user-defined code\n\t\t\ttrue\n\t\t;\t% no user-defined token printing; use Logtalk default\n\t\t\tdefault_print_message_token(Token, Tokens, Stream, Prefix) ->\n\t\t\ttrue\n\t\t;\t% unsupported token\n\t\t\twriteq(Stream, Token)\n\t\t),\n\t\tprint_message_tokens_(Tokens, Stream, Prefix).\n\n\t% if a token unifies with (-), assume it's a variable and ignore it\n\tdefault_print_message_token((-), _, _, _).\n\tdefault_print_message_token(at_same_line, _, _, _).\n\tdefault_print_message_token(nl, Tokens, Stream, Prefix) :-\n\t\t(\tTokens == [] ->\n\t\t\tnl(Stream)\n\t\t;\tTokens = [end(_)] ->\n\t\t\tnl(Stream)\n\t\t;\tnl(Stream),\n\t\t\twrite(Stream, Prefix)\n\t\t).\n\tdefault_print_message_token(flush, _, Stream, _) :-\n\t\tflush_output(Stream).\n\tdefault_print_message_token(Format-Arguments, _, Stream, _) :-\n\t\t{format(Stream, Format, Arguments)}.\n\tdefault_print_message_token(term(Term, Options), _, Stream, _) :-\n\t\t{write_term(Stream, Term, Options)}.\n\t% the following tokens were first introduced by SWI-Prolog; we use default definitions\n\t% for compatibility when running Logtalk with other back-end Prolog compilers\n\tdefault_print_message_token(ansi(_, Format, Arguments), _, Stream, _) :-\n\t\t{format(Stream, Format, Arguments)}.\n\tdefault_print_message_token(begin(_, _), _, _, _).\n\tdefault_print_message_token(end(_), _, _, _).\n\n\task_question(Kind, Component, Question, Check, Answer) :-\n\t\tmessage_term_to_tokens(Question, Kind, Component, Tokens),\n\t\t(\tquestion_hook(Question, Kind, Component, Tokens, Check, Answer) ->\n\t\t\t% question asking intercepted; assume that the question was answered\n\t\t\ttrue\n\t\t;\t% print the question text\n\t\t\tdefault_print_message(Kind, Component, Tokens),\n\t\t\t% find the output stream for printing the question prompt\n\t\t\t(\tmessage_prefix_stream(Kind, Component, _, OutputStream) ->\n\t\t\t\ttrue\n\t\t\t;\t% no user-defined prefix and stream; use default definition\n\t\t\t\tdefault_message_prefix_stream(Kind, _, OutputStream) ->\n\t\t\t\ttrue\n\t\t\t;\t% no such kind of message; use \"information\" instead\n\t\t\t\tdefault_message_prefix_stream(information, _, OutputStream)\n\t\t\t),\n\t\t\t% find the prompt and the input stream\n\t\t\t(\tquestion_prompt_stream(Kind, Component, Prompt, InputStream) ->\n\t\t\t\ttrue\n\t\t\t;\tdefault_question_prompt_stream(Kind, _, Prompt, InputStream) ->\n\t\t\t\ttrue\n\t\t\t;\t% no such kind of question; use \"question\" instead\n\t\t\t\tdefault_question_prompt_stream(question, _, Prompt, InputStream)\n\t\t\t),\n\t\t\trepeat,\n\t\t\t\twrite(OutputStream, Prompt),\n\t\t\t\tread(InputStream, Answer),\n\t\t\tcall(Check, Answer),\n\t\t\t!\n\t\t).\n\n\tdefault_question_prompt_stream(question, _, '> ', user_input).\n\n\texpand_library_path(Library, Path) :-\n\t\t{'$lgt_expand_library_path'(Library, Path)}.\n\n\tloaded_file(Path) :-\n\t\t{'$lgt_loaded_file_'(Basename, Directory, _, _, _, _, _)},\n\t\tatom_concat(Directory, Basename, Path).\n\n\tloaded_file_property(Path, Property) :-\n\t\t(\tvar(Path) ->\n\t\t\t{'$lgt_loaded_file_'(Basename, Directory, Mode, Flags, TextProperties, PrologFile, TimeStamp)},\n\t\t\tatom_concat(Directory, Basename, Path)\n\t\t;\t{'$lgt_loaded_file_'(Basename, Directory, Mode, Flags, TextProperties, PrologFile, TimeStamp)},\n\t\t\tatom_concat(Directory, Basename, Path),\n\t\t\t!\n\t\t),\n\t\tloaded_file_property(Property, Basename, Directory, Mode, Flags, TextProperties, PrologFile, TimeStamp).\n\n\tloaded_file_property(basename(Basename), Basename, _, _, _, _, _, _).\n\tloaded_file_property(directory(Directory), _, Directory, _, _, _, _, _).\n\tloaded_file_property(mode(Mode), _, _, Mode, _, _, _, _).\n\tloaded_file_property(flags(Flags), _, _, _, Flags, _, _, _).\n\tloaded_file_property(text_properties(TextProperties), _, _, _, _, TextProperties, _, _).\n\tloaded_file_property(target(PrologFile), _, _, _, _, _, PrologFile, _).\n\tloaded_file_property(modified(TimeStamp), _, _, _, _, _, _, TimeStamp).\n\tloaded_file_property(parent(Parent), Basename, Directory, _, _, _, _, _) :-\n\t\tatom_concat(Directory, Basename, Path),\n\t\t{'$lgt_parent_file_'(Path, Parent)}.\n\tloaded_file_property(object(Object), Basename, Directory, _, _, _, _, _) :-\n\t\t{'$lgt_current_object_'(Object, _, _, _, _, _, _, _, _, _, _),\n\t\t '$lgt_entity_property_'(Object, file_lines(Basename, Directory, _, _))}.\n\tloaded_file_property(protocol(Protocol), Basename, Directory, _, _, _, _, _) :-\n\t\t{'$lgt_current_protocol_'(Protocol, _, _, _, _),\n\t\t '$lgt_entity_property_'(Protocol, file_lines(Basename, Directory, _, _))}.\n\tloaded_file_property(category(Category), Basename, Directory, _, _, _, _, _) :-\n\t\t{'$lgt_current_category_'(Category, _, _, _, _, _),\n\t\t '$lgt_entity_property_'(Category, file_lines(Basename, Directory, _, _))}.\n\tloaded_file_property(library(Library), _, Directory, _, _, _, _, _) :-\n\t\tlogtalk_library_path(Library, _),\n\t\t{'$lgt_expand_library_path'(Library, Directory)}, !.\n\n\tcompile_aux_clauses(Clauses) :-\n\t\t{'$lgt_compile_aux_clauses'(Clauses)}.\n\n\tentity_prefix(Entity, Prefix) :-\n\t\t{'$lgt_entity_prefix'(Entity, Prefix)}.\n\n\tcompile_predicate_heads(Heads, Entity, CompiledHeads, ExecutionContext) :-\n\t\t{'$lgt_compile_predicate_heads'(Heads, Entity, CompiledHeads, ExecutionContext)}.\n\n\tcompile_predicate_indicators(PredicateIndicators, Entity, CompiledPredicateIndicators) :-\n\t\t{'$lgt_compile_predicate_indicators'(PredicateIndicators, Entity, CompiledPredicateIndicators)}.\n\n\tdecompile_predicate_indicators(CompiledPredicateIndicators, Entity, Type, PredicateIndicators) :-\n\t\t{'$lgt_decompile_predicate_indicators'(CompiledPredicateIndicators, Entity, Type, PredicateIndicators)}.\n\n\tdecompile_predicate_heads(THeads, Entity, Type, Heads) :-\n\t\t{'$lgt_decompile_predicate_heads'(THeads, Entity, Type, Heads)}.\n\n\texecution_context(ExecutionContext, Entity, Sender, This, Self, MetaCallContext, Stack) :-\n\t\t{'$lgt_execution_context'(ExecutionContext, Entity, Sender, This, Self, MetaCallContext, Stack)}.\n\n:- end_object.\n\n\n:- if(current_logtalk_flag(prolog_dialect, gnu)).\n\t% workaround apparent gplc bug when dealing with multifile predicates\n\t:- multifile(logtalk_library_path/2).\n\t:- dynamic(logtalk_library_path/2).\n\t:- multifile('$lgt_current_protocol_'/5).\n\t:- dynamic('$lgt_current_protocol_'/5).\n\t:- multifile('$lgt_current_category_'/6).\n\t:- dynamic('$lgt_current_category_'/6).\n:- elif(current_logtalk_flag(prolog_dialect, xsb)).\n\t% workaround XSB atom-based module system\n\t:- import(from(/(format,3), format)).\n:- endif.\n"
  },
  {
    "path": "tests/inputs/machineDefFreshIds.lem",
    "content": "open import Pervasives_extra\n(* https://raw.githubusercontent.com/rems-project/lem/master/examples/ppcmem-model/machineDefFreshIds.lem *)\n\n(*========================================================================*)\n(*                                                                        *)\n(*                ppcmem executable model                                 *)\n(*                                                                        *)\n(*          Susmit Sarkar, University of Cambridge                        *)\n(*          Peter Sewell, University of Cambridge                         *)\n(*          Jade Alglave, Oxford University                               *)\n(*          Luc Maranget, INRIA Rocquencourt                              *)\n(*                                                                        *)\n(*  This file is copyright 2010,2011 Institut National de Recherche en    *)\n(*  Informatique et en Automatique (INRIA), and Susmit Sarkar, Peter      *)\n(*  Sewell, and Jade Alglave.                                             *)\n(*                                                                        *)\n(*  All rights reserved.                                                  *)\n(*                                                                        *)\n(*                                                                        *)\n(*                                                                        *)\n(*                                                                        *)\n(*                                                                        *)\n(*========================================================================*)\n\n(* emacs fontification -*-caml-*- *)\n\n(*: \\section{Fresh Identifiers} :*)\n\n(*: Generation of fresh ids, for flexible unification variables, events, and instruction instances. :*)\n\nopen import MachineDefUtils\n\ntype flexsym = nat\ntype ioid = nat\n\nlet compare_flexsym = compare_num\n\ntype id_state = \n    <| flexsym_state : flexsym;\n    ioid_state : ioid;\n  |>\n\nlet initial_id_state = \n  <| flexsym_state = 0; ioid_state = 0 |>\n\nlet gen_ioid ist = \n  (ist.ioid_state, <| ist with ioid_state = ist.ioid_state + 1 |>)\n\nlet gen_flexsym ist = \n  (ist.flexsym_state, <| ist with flexsym_state = ist.flexsym_state + 1 |>)\n"
  },
  {
    "path": "tests/inputs/magikfile.magik",
    "content": "# Test fixture for Magik language\n# This file covers various comment and code patterns\n\n_package user\n$\n\n# Full line comment before code\n_pragma(classify_level=basic, topic={test})\n_method char16_vector.test_method()\n\t## Method documentation\n\t## @return {_self}\n\t_if _self.size < 2\n\t_then\n\t\t_return _self.lowercase\n\t_endif\n\n\t_local str << _self # end of line comment\n\n\t# Another comment\n\t_local regex << /([A-Z]+)([A-Z][a-z])/\n\tstr << regex.replace_all(str, \"$1_$2\")\n\n\t_return str.lowercase\n_endmethod\n$\n\n# Block comment\n_block\n\t_local l_path << system.pathname_down(\"test\", \"path\")\n\tload_file(l_path)\n_endblock\n$\n\n# Define an exemplar\ndef_slotted_exemplar(\n\t:test_exemplar,\n\t{\n\t\t{:field1, _unset},\n\t\t{:field2, _unset} # inline comment\n\t})\n$\n"
  },
  {
    "path": "tests/inputs/main.f03",
    "content": "! Measure units:\n! - *_px - pixels\n! - *_cl - cells\n! - *_rl - relative (fraction of width, height, cell size, etc)\n\nprogram main\n  use iso_c_binding, only: c_int, c_int32_t, C_NULL_CHAR, C_NULL_PTR, c_loc\n  use raylib\n  use raymath\n  use game\n  use ai\n  use ui\n  implicit none\n\n  type :: Particle\n     real, dimension(2) :: position, velocity\n     integer(c_int32_t) :: color\n     real :: size, lt_sec, lt_t\n  end type Particle\n\n  integer, parameter :: font_size = 128\n  real,    parameter :: particle_min_mag      = 50.0\n  real,    parameter :: particle_max_mag      = 400.0\n  real,    parameter :: particle_min_size     = 2.0\n  real,    parameter :: particle_max_size     = 5.0\n  real,    parameter :: particle_min_lt       = 0.5\n  real,    parameter :: particle_max_lt       = 0.8\n  integer, parameter :: particles_burst_count = 100\n\n  real    :: dt\n  real    :: board_x_px, board_y_px, board_boundary_width, board_boundary_height, board_size_px, cell_size_px\n\n  integer,dimension(board_size_cl, board_size_cl) :: board\n\n  integer :: current_player\n  type(TLine) :: final_line\n  integer :: state\n  type(Font) :: game_font\n  type(Particle) :: particles(particles_burst_count*board_size_cl*board_size_cl + 10)\n  type(Sound) :: click_sound\n  logical :: click_played_on_previous_frame, click_played_on_this_frame\n\n  logical, dimension(2) :: ai_checkboxes\n  integer :: i\n\n  enum, bind(C)\n     enumerator :: STATE_GAME = 0\n     enumerator :: STATE_WON\n     enumerator :: STATE_TIE\n  end enum\n\n  ai_checkboxes(CELL_CROSS) = .false.\n  ai_checkboxes(CELL_KNOTT) = .true.\n  do i=1,size(particles)\n     particles(i)%lt_t = 0.0\n  end do\n\n  call restart_game()\n\n  call set_config_flags(FLAG_WINDOW_RESIZABLE)\n  ! TODO: draw_rectangle_rounded, draw_circle_v, etc (basically anything that renders circles) has rendering artifacts that make some of the pixels of the background visible when FLAG_MSAA_4X_HINT is enabled\n  ! This could be a bug of Raylib. The implementations may not be taking MSAA into account.\n  call set_config_flags(FLAG_MSAA_4X_HINT)\n  call init_window(16*80, 9*80, \"Fortran GOTY\"//C_NULL_CHAR)\n  call init_audio_device()\n  call set_target_fps(60)\n\n  ! TODO: set the working directory to where the executable is located\n  ! This is needed to be able to locate the assets properly\n  game_font = load_font_ex(\"./fonts/Alegreya-Regular.ttf\"//C_NULL_CHAR, font_size, C_NULL_PTR, 0)\n  call set_texture_filter(game_font%texture, TEXTURE_FILTER_BILINEAR)\n  click_sound = load_sound(\"./sounds/misc_26_fixed.ogg\"//C_NULL_CHAR)\n\n  do while (.not. window_should_close())\n     click_played_on_previous_frame = click_played_on_this_frame\n     click_played_on_this_frame = .false.\n     call begin_drawing()\n       call begin_screen_fitting()\n         call clear_background(background_color)\n\n         dt = get_frame_time()\n         board_boundary_width  = screen_width_px*2/3\n         board_boundary_height = screen_height_px\n\n         if (board_boundary_width > board_boundary_height) then\n            board_size_px = board_boundary_height\n            board_x_px = real(board_boundary_width)/2 - board_size_px/2\n            board_y_px = 0\n         else\n            board_size_px = board_boundary_width\n            board_x_px = 0\n            board_y_px = real(board_boundary_height)/2 - board_size_px/2\n         end if\n\n         board_x_px = board_x_px + board_size_px*board_margin_rl\n         board_y_px = board_y_px + board_size_px*board_margin_rl\n         board_size_px = board_size_px - board_size_px*board_margin_rl*2\n\n         cell_size_px = board_size_px/board_size_cl\n\n         select case (state)\n         case (STATE_GAME)\n            call render_game_state()\n         case (STATE_WON)\n            call render_won_state()\n         case (STATE_TIE)\n            call render_tie_state()\n         end select\n\n         call render_ai_checkboxes(rectangle( &\n              board_boundary_width, &\n              0, &\n              screen_width_px - board_boundary_width, &\n              board_boundary_height))\n       call end_screen_fitting()\n     call end_drawing()\n  end do\n\ncontains\n  pure function lerp(a, b, t) result(c)\n    real, intent(in) :: a, b, t\n    real :: c\n    c = a + (b - a)*t\n  end function lerp\n\n  subroutine spawn_random_particles_along_line(start, end, count, color)\n    real, dimension(2),  intent(in) :: start, end\n    integer,             intent(in) :: count\n    integer(c_int32_t),  intent(in) :: color\n\n    real, dimension(2) :: position\n    real :: t\n    integer :: i\n\n    do i=1,count\n       call random_number(t)\n       position = start + (end - start)*t\n       call spawn_random_particle_at(position, color)\n    end do\n  end subroutine spawn_random_particles_along_line\n\n  subroutine spawn_random_particles_in_region(region, count, color)\n    type(Rectangle),intent(in) :: region\n    integer,intent(in) :: count\n    integer(c_int32_t),intent(in) :: color\n\n    real, dimension(2) :: position, t\n    integer :: i\n\n    do i=1,count\n       call random_number(t)\n       position = [region%x, region%y] + [region%width, region%height]*t\n       call spawn_random_particle_at(position, color)\n    end do\n  end subroutine spawn_random_particles_in_region\n\n  subroutine spawn_random_particle_at(position,color)\n    real, dimension(2), intent(in) :: position\n    integer(c_int32_t), intent(in) :: color\n\n    type(Particle) :: p\n    real :: angle, mag, t\n    real, parameter :: pi = 4.D0*DATAN(1.D0)\n\n    p%position = position\n\n    call random_number(t)\n    angle = 2.0*pi*t\n\n    call random_number(t)\n    mag = lerp(particle_min_mag, particle_max_mag, t)\n    p%velocity = [cos(angle), sin(angle)]*mag\n\n    p%color = color\n\n    call random_number(t)\n    p%size = lerp(particle_min_size, particle_max_size, t)\n\n    call random_number(t)\n    p%lt_sec = lerp(particle_min_lt, particle_max_lt, t)\n    p%lt_t = 1.0\n\n    call spawn_particle(p)\n  end subroutine spawn_random_particle_at\n\n  subroutine spawn_particle(p)\n    type(Particle),intent(in) :: p\n    type(Particle) :: pi\n    integer :: i\n\n    do i=1,size(particles)\n       pi = particles(i)\n       if (pi%lt_t <= 0.0) then\n          particles(i) = p\n          return\n       end if\n    end do\n  end subroutine spawn_particle\n\n  subroutine render_particles(dt)\n    real,intent(in) :: dt\n    type(Particle) :: p\n    integer :: i\n\n    do i=1,size(particles)\n       p = particles(i)\n       if (p%lt_t > 0.0) then\n          particles(i)%velocity = p%velocity*0.98\n          particles(i)%position = p%position + particles(i)%velocity*dt\n          particles(i)%lt_t = (p%lt_t*p%lt_sec - dt)/p%lt_sec\n          call draw_circle_v(Vector2(p%position), p%size, color_alpha(p%color, p%lt_t))\n       end if\n    end do\n  end subroutine render_particles\n\n  subroutine render_ai_checkboxes(boundary)\n    real,parameter :: checkbox_width_rl = 0.45\n    real,parameter :: checkbox_height_rl = 0.10\n    real,parameter :: checkbox_padding_rl = 0.05\n    type(Rectangle),intent(in) :: boundary\n\n    type(Rectangle) :: cross_boundary, knott_boundary\n    real :: checkbox_height_px, checkbox_padding_px\n    type(Vector2) :: text_pos, text_size\n\n    checkbox_height_px = boundary%height*checkbox_height_rl\n    checkbox_padding_px = boundary%height*checkbox_padding_rl\n\n    cross_boundary%width = boundary%width*checkbox_width_rl\n    cross_boundary%height = checkbox_height_px\n    cross_boundary%x = boundary%x + boundary%width/2 - cross_boundary%width/2\n    cross_boundary%y = boundary%y + boundary%height/2 - checkbox_height_px - checkbox_padding_px*0.5\n\n    knott_boundary%width = boundary%width*checkbox_width_rl\n    knott_boundary%height = checkbox_height_px\n    knott_boundary%x = boundary%x + boundary%width/2 - knott_boundary%width/2\n    knott_boundary%y = boundary%y + boundary%height/2 + checkbox_padding_px*0.5\n\n    text_size = measure_text_ex(game_font, \"AI\"//C_NULL_CHAR, checkbox_height_px, 0.0)\n    text_pos = Vector2( &\n         [cross_boundary%x, &\n         ! cross_boundary%x + cross_boundary%width/2 - text_size%x/2, &\n         cross_boundary%y - checkbox_height_px - checkbox_padding_px])\n    call draw_text_ex(game_font, \"AI\"//C_NULL_CHAR, text_pos,checkbox_height_px, 0.0, restart_button_color)\n\n    call checkbox(cross_checkbox_id,CELL_CROSS,cross_boundary,ai_checkboxes(CELL_CROSS))\n    call checkbox(knott_checkbox_id,CELL_KNOTT,knott_boundary,ai_checkboxes(CELL_KNOTT))\n  end subroutine render_ai_checkboxes\n\n  subroutine render_tie_state()\n    call render_board(board_x_px, board_y_px, board_size_px, board)\n    call render_particles(dt)\n\n    if (restart_button(game_font, board_x_px, board_y_px, board_size_px)) then\n      call restart_game()\n    end if\n  end subroutine render_tie_state\n\n  subroutine render_won_state()\n    call render_board(board_x_px, board_y_px, board_size_px, board)\n    call render_particles(dt)\n\n    call strikethrough(final_line, Square([board_x_px, board_y_px], board_size_px))\n    if (restart_button(game_font, board_x_px, board_y_px, board_size_px)) then\n       call restart_game()\n    end if\n  end subroutine render_won_state\n\n  subroutine render_game_state()\n    integer           :: x_cl, y_cl\n    real              :: board_cell_size\n    real,dimension(2) :: start, end\n\n    board_cell_size = board_size_px/board_size_cl\n\n    if (ai_checkboxes(current_player)) then\n       call render_board(board_x_px, board_y_px, board_size_px, board)\n\n       if (.not. ai_next_move(board, current_player, x_cl, y_cl)) then\n          board(x_cl, y_cl) = current_player\n          if (.not. click_played_on_previous_frame) then\n             call play_sound(click_sound)\n             click_played_on_this_frame = .true.\n          end if\n          if (player_won(board, CELL_CROSS, [x_cl, y_cl], final_line)) then\n             state = STATE_WON\n             call map_tline_on_screen(final_line, Square([board_x_px, board_y_px], board_size_px), start, end)\n             call spawn_random_particles_along_line(start, end, particles_burst_count*3, strikethrough_color)\n             return\n          end if\n          if (player_won(board, CELL_KNOTT, [x_cl, y_cl], final_line)) then\n             state = STATE_WON\n             call map_tline_on_screen(final_line, Square([board_x_px, board_y_px], board_size_px), start, end)\n             call spawn_random_particles_along_line(start, end, particles_burst_count*3, strikethrough_color)\n             return\n          end if\n          call spawn_random_particles_in_region( &\n               Rectangle(board_x_px + (x_cl - 1)*board_cell_size,   &\n                         board_y_px + (y_cl - 1)*board_cell_size,   &\n                         board_cell_size,        &\n                         board_cell_size),       &\n               particles_burst_count,                               &\n               shape_colors(current_player))\n          current_player = 3 - current_player\n          if (board_full(board)) then\n             state = STATE_TIE\n             return\n          end if\n       else\n          state = STATE_TIE\n          return\n       end if\n    else\n       if (render_board_clickable(board_x_px, board_y_px, board_size_px, board, x_cl, y_cl)) then\n          board(x_cl, y_cl) = current_player\n          if (.not. click_played_on_previous_frame) then\n             call play_sound(click_sound)\n             click_played_on_this_frame = .true.\n          end if\n          if (player_won(board, CELL_CROSS, [x_cl, y_cl], final_line)) then\n             state = STATE_WON\n             call map_tline_on_screen(final_line, Square([board_x_px, board_y_px], board_size_px), start, end)\n             call spawn_random_particles_along_line(start, end, particles_burst_count*3, strikethrough_color)\n             return\n          end if\n          if (player_won(board, CELL_KNOTT, [x_cl, y_cl], final_line)) then\n             state = STATE_WON\n             call map_tline_on_screen(final_line, Square([board_x_px, board_y_px], board_size_px), start, end)\n             call spawn_random_particles_along_line(start, end, particles_burst_count*3, strikethrough_color)\n             return\n          end if\n          call spawn_random_particles_in_region( &\n               Rectangle(board_x_px + (x_cl - 1)*board_cell_size,   &\n                         board_y_px + (y_cl - 1)*board_cell_size,   &\n                         board_cell_size,        &\n                         board_cell_size),       &\n               particles_burst_count,                       &\n               shape_colors(current_player))\n          current_player = 3 - current_player\n          if (board_full(board)) then\n             state = STATE_TIE\n             return\n          end if\n       end if\n    end if\n    call render_particles(dt)\n  end subroutine render_game_state\n\n  subroutine restart_game()\n    board(:,:) = 0\n    state = STATE_GAME\n    current_player = CELL_CROSS\n  end subroutine restart_game\nend program\n\n! # Roadmap\n! - TODO: customizable board size\n! - TODO: sound volume controls\n! - TODO: accessibility: control via keyboard\n"
  },
  {
    "path": "tests/inputs/master.blade.php",
    "content": "\n{{-- https://laravel.com/docs/master/blade\n--}}\n<!-- Stored in resources/views/layouts/master.blade.php -->\n\n<html>\n    <head>\n        <title>App Name - @yield('title')</title>\n    </head>\n    <body>\n        @section('sidebar')\n            This is the master sidebar.\n        @show\n\n        <div class=\"container\">\n            @yield('content')\n        </div>\n    </body>\n</html>\n\n<!-- Stored in resources/views/child.blade.php -->\n\n@extends('layouts.master')\n\n@section('title', 'Page Title')\n\n@section('sidebar')\n    @parent\n\n    <p>This is appended to the master sidebar.</p>\n@endsection\n\n@section('content')\n    <p>This is my body content.</p>\n@endsection\n\n{{-- This comment will not be present in the rendered HTML --}}\n"
  },
  {
    "path": "tests/inputs/matlab_line_colors.m",
    "content": "%{\nhttps://www.mathworks.com/matlabcentral/fileexchange/42673-beautiful-and-distinguishable-line-colors-colormap\n%}\n\n% LINE COLORS\nN=6;\nX = linspace(0,pi*3,1000);\nY = bsxfun(@(x,n)sin(x+2*n*pi/N), X.', 1:N);\nC = linspecer(N);\naxes('NextPlot','replacechildren', 'ColorOrder',C);\nplot(X,Y,'linewidth',5)\nylim([-1.1 1.1]);\n\n%{\n  SIMPLER LINE COLOR EXAMPLE\n%}\nN = 6; X = linspace(0,pi*3,1000);\nC = linspecer(N)\nhold off;\nfor ii=1:N\nY = sin(X+2*ii*pi/N);\nplot(X,Y,'color',C(ii,:),'linewidth',3);\nhold on;\nend\n\n%{\n  COLORMAP EXAMPLE\n%}\nA = rand(15);\nfigure; imagesc(A); % default colormap\nfigure; imagesc(A); colormap(linspecer); % linspecer colormap\n"
  },
  {
    "path": "tests/inputs/md5.rkt",
    "content": "#lang racket/base\n\n(provide md5)\n\n;;; Copyright (c) 2005-2014, PLT Design Inc.\n;;; Copyright (c) 2002, Jens Axel Soegaard\n;;;\n;;; Distributed under the same terms as Racket, by permission.\n;;;\n;;; md5.scm  --  Jens Axel Soegaard, 16 oct 2002\n\n;;; Summary\n;; This is an implementation of the md5 message-digest algorithm in R5RS\n;; Scheme.  The algorithm takes an arbitrary byte-string or an input port, and\n;; returns a 128-bit \"fingerprint\" byte string.  The algorithm was invented by\n;; Ron Rivest, RSA Security, INC.  Reference: RFC 1321,\n;; <http://www.faqs.org/rfcs/rfc1321.html>\n\n;;; History\n;; 2002-10-14  /jas\n;; - Bored. Initial attempt. Done. Well, except for faulty output.\n;; 2002-10-15  /jas\n;; - It works at last\n;; 2002-10-16  /jas\n;; - Added R5RS support\n;; 2003-02-16 / lth\n;; - Removed let-values implementation because Larceny has it already\n;; - Implemented Larceny versions of many bit primitives (note, 0.52 or later\n;;   required due to bignum bug)\n;; - Removed most 'personal idiosyncrasies' to give the compiler a fair chance\n;;   to inline primitives and improve performance some.  Performance in the\n;;   interpreter is still really quite awful.\n;; - Wrapped entire procedure in a big LET to protect the namespace\n;; - Some cleanup of repeated computations\n;; - Moved test code to separate file\n;; 2003-02-17 / lth\n;; - Removed some of the indirection, for a 30% speedup in Larceny's\n;;   interpreter.  Running in the interpreter on my Dell Inspiron 4000 I get a\n;;   fingerprint of \"Lib/Common/bignums-be.sch\" in about 63ms, which is slow\n;;   but adequate.  (The compiled version is not much faster -- most time is\n;;   spent in bignum manipulation, which is compiled in either case.  To do\n;;   this well we must either operate on the bignum representation or redo the\n;;   algorithm to use fixnums only.)\n;; 2003-12-01 / lth\n;; - Reimplemented word arithmetic to use two 16-bit fixnums boxed in a cons\n;;   cell.  In Petit Larceny's interpreter this gives a speedup of a factor of\n;;   almost eight, and in addition this change translates well to other Scheme\n;;   systems that support bit operations on fixnums.  Only 17-bit (signed)\n;;   fixnums are required.\n;; 2003-12-23 / jas\n;; - Trivial port to PLT.  Rewrote the word macro to syntax-rules.  Larceny\n;;   primitives written as syntax-rules macros exanding to their PLT name.\n;; 2005-05-05 / Greg Pettyjohn\n;; - It was failing for strings of length 56 bytes i.e. when the length in bits\n;;   was congruent 448 modulo 512.  Changed step 1 to fix this.  According to\n;;   RFC 1321, the message should still be padded in this case.\n;; 2005-12-23 / Jepri\n;; - Mucked around with the insides to get it to read from a port\n;; - Now it accepts a port or a string as input\n;; - Doesn't explode when handed large strings anymore\n;; - Now much slower\n;; 2006-10-02 / Matthew\n;; - Cleaned up a little\n;; - Despite comment above, it seems consistently faster\n;; 2006-05-11 / Eli\n;; - Cleaned up a lot, removed Larceny-isms\n;; - Heavy optimization: not consing anything throughout the loop\n;; 2007-09-17 / Eli\n;; - making raw output possible\n;; 2009-12-20 / Eli\n;; - `mzscheme' -> `scheme/base'\n;; - moved from mzlib/md5 to file/md5\n;; - made it work on strings again\n\n(require (for-syntax racket/base))\n\n;;; Word arithmetic (32 bit)\n;; Terminology\n;;    word:  32 bit unsigned integer\n;;    byte:   8 bit unsigned integer\n\n;; Words are represented as a cons where the car holds the high 16 bits and the\n;; cdr holds the low 16 bits.  Most good Scheme systems will have fixnums that\n;; hold at least 16 bits as well as fast allocation, so this has a fair chance\n;; at beating bignums for performance.\n\n;; (word c) turns into a quoted pair '(hi . lo) if c is a literal number.  can\n;; create a new word, compute one at compile-time etc\n(define-syntax (word stx)\n  (syntax-case stx ()\n    ;; normal version (checks, allocates)\n    [(word #:new c)\n     #'(let ([n c])\n         (if (<= 0 n 4294967296)\n           (mcons (quotient n 65536) (remainder n 65536))\n           (error 'word \"out of range: ~e\" n)))]\n    ;; use when the number is known to be in range (allocates, no check)\n    [(word #:new+safe c)\n     #'(let ([n c]) (mcons (quotient n 65536) (remainder n 65536)))]\n    ;; default form: compute at compile-time if possible\n    [(word c)\n     (let ([n (syntax-e #'c)])\n       (if (integer? n)\n         (if (<= 0 n 4294967295)\n           (syntax-local-lift-expression\n            #`(mcons #,(quotient n 65536) #,(remainder n 65536)))\n           (raise-syntax-error #f \"constant number out of range\" stx))\n         #'(word #:new c)))]))\n\n;; destructive operations to save on consing\n\n;; destructive cons\n(define (cons! p x y)\n  (set-mcar! p x)\n  (set-mcdr! p y))\n\n;; a := b\n(define (word=! a b)\n  (cons! a (mcar b) (mcdr b)))\n\n;; a := a + b\n(define (word+=! a b)\n  (let ([t1 (+ (mcar a) (mcar b))]\n        [t2 (+ (mcdr a) (mcdr b))])\n    (cons! a\n           (bitwise-and (+ t1 (arithmetic-shift t2 -16)) 65535)\n           (bitwise-and t2 65535))))\n\n(define word<<<!\n  (let* ([masks '#(#x0 #x1 #x3 #x7 #xF #x1F #x3F #x7F #xFF #x1FF #x3FF #x7FF\n                   #xFFF #x1FFF #x3FFF #x7FFF #xFFFF)])\n    (lambda (a s)\n      (let-values ([(hi lo s)\n                    (cond [(< s 16) (values (mcar a) (mcdr a) s)]\n                          [(< s 32) (values (mcdr a) (mcar a) (- s 16))]\n                          [else (error 'word<<< \"shift out of range: ~e\" s)])])\n        (cons!\n         a\n         (bitwise-ior\n          (arithmetic-shift (bitwise-and hi (vector-ref masks (- 16 s))) s)\n          (bitwise-and (arithmetic-shift lo (- s 16))\n                       (vector-ref masks s)))\n         (bitwise-ior\n          (arithmetic-shift (bitwise-and lo (vector-ref masks (- 16 s))) s)\n          (bitwise-and (arithmetic-shift hi (- s 16))\n                       (vector-ref masks s))))))))\n\n;; Bytes and words\n;; The least significant byte of a word is the first\n\n;; Converts a byte string to words, writes the result into `result'\n;; bytes->word-vector! : vector byte-string -> void\n(define (bytes->word-vector! result l-raw)\n  ;; assumption: always getting a byte-string with 64 places\n  ;; (unless (eq? 64 (bytes-length l-raw))\n  ;;   (error 'bytes->word-vector! \"something bad happened\"))\n  (let loop ([n 15])\n    (when (<= 0 n)\n      (let ([m (arithmetic-shift n 2)])\n        (cons! (vector-ref result n)\n               (+ (bytes-ref l-raw (+ 2 m))\n                  (arithmetic-shift (bytes-ref l-raw (+ 3 m)) 8))\n               (+ (bytes-ref l-raw m)\n                  (arithmetic-shift (bytes-ref l-raw (+ 1 m)) 8))))\n      (loop (sub1 n)))))\n\n(define empty-port (open-input-bytes #\"\"))\n\n;; List Helper\n;; read-block! : a-port done-n (vector word) -> (values vector a-port done-n)\n;; reads 512 bytes from the port, writes them into the `result' vector of 16\n;; 32-bit words when the port is exhausted it returns #f for the port and the\n;; last few bytes padded\n(define (read-block! a-port done result)\n  (define-syntax write-words!\n    (syntax-rules ()\n      [(_ done buf) (bytes->word-vector! result (step2 (* 8 done) buf))]))\n  (let ([l-raw (read-bytes 512/8 a-port)])\n    (cond\n      ;; File size was a multiple of 512 bits, or we're doing one more round to\n      ;; add the correct padding from the short case\n      [(eof-object? l-raw)\n       (write-words! done\n         (if (zero? (modulo done 512/8))\n           ;; The file is a multiple of 512 or was 0, so there hasn't been a\n           ;; chance to add the 1-bit pad, so we need to do a full pad\n           (step1 #\"\")\n           ;; We only enter this block when the previous block didn't have\n           ;; enough room to fit the 64-bit file length, so we just add 448\n           ;; bits of zeros and then the 64-bit file length (step2)\n           (make-bytes 448/8 0)))\n       (values #f done)]\n      ;; We read exactly 512 bits, the algorithm proceeds as usual\n      [(eq? (bytes-length l-raw) 512/8)\n       (bytes->word-vector! result l-raw)\n       (values a-port (+ done (bytes-length l-raw)))]\n      ;; We read less than 512 bits, so the file has ended.\n      [else\n       (let ([done (+ done (bytes-length l-raw))])\n         (write-words! done (step1 l-raw))\n         (values\n          (if (> (* 8 (bytes-length l-raw)) 446)\n            ;; However, we don't have enough room to add the correct trailer,\n            ;; so we add what we can, then go for one more round which will\n            ;; automatically fall into the (eof-object? case)\n            empty-port\n            ;; Returning a longer vector than we should, luckily it doesn't\n            ;; matter.  We read less than 512 bits and there is enough room for\n            ;; the correct trailer.  Add trailer and bail\n            #f)\n          done))])))\n\n;; MD5\n;; The algorithm consists of four steps an encoding the result.  All we need to\n;; do, is to call them in order.\n;; md5 : string/bytes/port [bool] -> string\n(define md5\n  (case-lambda\n    [(a-thing) (md5 a-thing #t)]\n    [(a-thing hex-encode?)\n     (let ([a-port\n            (cond [(bytes? a-thing)  (open-input-bytes a-thing)]\n                  [(string? a-thing) (open-input-string a-thing)]\n                  [(input-port? a-thing) a-thing]\n                  [else (raise-type-error 'md5 \"input-port, bytes, or string\"\n                                          a-thing)])])\n       (encode (step4 a-port) hex-encode?))]))\n\n;; Step 1  -  Append Padding Bits\n;; The message is padded so the length (in bits) becomes 448 modulo 512.  We\n;; allways append a 1 bit and then append the proper numbber of 0's.  NB: 448\n;; bits is 14 words and 512 bits is 16 words\n;; step1 : bytes -> bytes\n(define (step1 message)\n  (let* ([nbytes (modulo (- 448/8 (bytes-length message)) 512/8)]\n         [nbytes (if (zero? nbytes) 512/8 nbytes)])\n    (bytes-append message\n                  #\"\\x80\" ; the 1 bit byte => one less 0 bytes to append\n                  (make-bytes (sub1 nbytes) 0))))\n\n;; Step 2  -  Append Length\n;; A 64 bit representation of the bit length b of the message before the\n;; padding of step 1 is appended.  Lower word first.\n;; step2 : number bytes -> bytes\n;;  org-len is the length of the original message in number of bits\n(define (step2 len padded-message)\n  (bytes-append padded-message (integer->integer-bytes len 8 #f #f)))\n\n;; Step 3  -  Initialize MD Buffer\n;; These magic constants are used to initialize the loop in step 4.\n;;\n;;          word A: 01 23 45 67\n;;          word B: 89 ab cd ef\n;;          word C: fe dc ba 98\n;;          word D: 76 54 32 10\n\n;; Step 4  -  Process Message in 16-Word Blocks\n;; For each 16 word block, go through a round one to four.\n;; step4 : input-port -> (list word word word word)\n\n;; Step 3 :-) (magic constants)\n(define (step4 a-port)\n  ;; X is always a vector of 16 words (it changes in read-block!)\n  (define X\n    (vector\n     (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0)\n     (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0)\n     (mcons 0 0) (mcons 0 0) (mcons 0 0) (mcons 0 0)))\n  (define A (word #:new+safe #x67452301))\n  (define B (word #:new+safe #xefcdab89))\n  (define C (word #:new+safe #x98badcfe))\n  (define D (word #:new+safe #x10325476))\n  (define AA (mcons 0 0))\n  (define BB (mcons 0 0))\n  (define CC (mcons 0 0))\n  (define DD (mcons 0 0))\n  (define tmp (mcons 0 0))\n  (let loop ([a-port a-port] [done 0])\n    (if (not a-port)\n      (list A B C D)\n      (let-values ([(b-port done) (read-block! a-port done X)])\n        (define-syntax step\n          (syntax-rules ()\n            [(_ a b c d e f g h)\n             #| This is the `no GC version' (aka C-in-Scheme) of this:\n             (set! a (word+ b (word<<< (word+ (word+ a (e b c d))\n                                              (word+ (vector-ref X f)\n                                                     (word h)))\n                                       g)))\n             |#\n             (begin (e tmp b c d)\n                    (word+=! a tmp)\n                    (word+=! a (vector-ref X f))\n                    (word+=! a (word h))\n                    (word<<<! a g)\n                    (word+=! a b))]))\n        ;;---\n        (word=! AA A) (word=! BB B) (word=! CC C) (word=! DD D)\n        ;;---\n        ;; the last column is generated with\n        ;;  (lambda (i) (inexact->exact (floor (* 4294967296 (abs (sin i))))))\n        ;; for i from 1 to 64\n        (step A B C D F   0  7 3614090360)\n        (step D A B C F   1 12 3905402710)\n        (step C D A B F   2 17  606105819)\n        (step B C D A F   3 22 3250441966)\n        (step A B C D F   4  7 4118548399)\n        (step D A B C F   5 12 1200080426)\n        (step C D A B F   6 17 2821735955)\n        (step B C D A F   7 22 4249261313)\n        (step A B C D F   8  7 1770035416)\n        (step D A B C F   9 12 2336552879)\n        (step C D A B F  10 17 4294925233)\n        (step B C D A F  11 22 2304563134)\n        (step A B C D F  12  7 1804603682)\n        (step D A B C F  13 12 4254626195)\n        (step C D A B F  14 17 2792965006)\n        (step B C D A F  15 22 1236535329)\n        ;;---\n        (step A B C D G   1  5 4129170786)\n        (step D A B C G   6  9 3225465664)\n        (step C D A B G  11 14  643717713)\n        (step B C D A G   0 20 3921069994)\n        (step A B C D G   5  5 3593408605)\n        (step D A B C G  10  9   38016083)\n        (step C D A B G  15 14 3634488961)\n        (step B C D A G   4 20 3889429448)\n        (step A B C D G   9  5  568446438)\n        (step D A B C G  14  9 3275163606)\n        (step C D A B G   3 14 4107603335)\n        (step B C D A G   8 20 1163531501)\n        (step A B C D G  13  5 2850285829)\n        (step D A B C G   2  9 4243563512)\n        (step C D A B G   7 14 1735328473)\n        (step B C D A G  12 20 2368359562)\n        ;;---\n        (step A B C D H   5  4 4294588738)\n        (step D A B C H   8 11 2272392833)\n        (step C D A B H  11 16 1839030562)\n        (step B C D A H  14 23 4259657740)\n        (step A B C D H   1  4 2763975236)\n        (step D A B C H   4 11 1272893353)\n        (step C D A B H   7 16 4139469664)\n        (step B C D A H  10 23 3200236656)\n        (step A B C D H  13  4  681279174)\n        (step D A B C H   0 11 3936430074)\n        (step C D A B H   3 16 3572445317)\n        (step B C D A H   6 23   76029189)\n        (step A B C D H   9  4 3654602809)\n        (step D A B C H  12 11 3873151461)\n        (step C D A B H  15 16  530742520)\n        (step B C D A H   2 23 3299628645)\n        ;;---\n        (step A B C D II  0  6 4096336452)\n        (step D A B C II  7 10 1126891415)\n        (step C D A B II 14 15 2878612391)\n        (step B C D A II  5 21 4237533241)\n        (step A B C D II 12  6 1700485571)\n        (step D A B C II  3 10 2399980690)\n        (step C D A B II 10 15 4293915773)\n        (step B C D A II  1 21 2240044497)\n        (step A B C D II  8  6 1873313359)\n        (step D A B C II 15 10 4264355552)\n        (step C D A B II  6 15 2734768916)\n        (step B C D A II 13 21 1309151649)\n        (step A B C D II  4  6 4149444226)\n        (step D A B C II 11 10 3174756917)\n        (step C D A B II  2 15  718787259)\n        (step B C D A II  9 21 3951481745)\n        ;;---\n        (word+=! A AA) (word+=! B BB) (word+=! C CC) (word+=! D DD)\n        ;;---\n        (loop b-port done)))))\n\n;; Each round consists of the application of the following basic functions.\n;; They functions on a word bitwise, as follows.\n;;          F(X,Y,Z) = XY v not(X) Z  (NB: or can be replaced with + in F)\n;;          G(X,Y,Z) = XZ v Y not(Z)\n;;          H(X,Y,Z) = X xor Y xor Z\n;;          I(X,Y,Z) = Y xor (X v not(Z))\n\n#| These functions used to be simple, for example:\n     (define (F x y z)\n       (word-or (word-and x y) (word-and (word-not x) z)))\n   but we don't want to allocate stuff for each operation, so we add an output\n   pair for each of these functions (the `t' argument).  However, this means\n   that if we want to avoid consing, we need either a few such pre-allocated\n   `register' values...  The solution is to use a macro that will perform an\n   operation on the cars, cdrs, and set the result into the target pair.  Works\n   only because these operations are symmetrical in their use of the two\n   halves.\n|#\n\n(define-syntax cons-op!\n  (syntax-rules ()\n    [(cons-op! t (x ...) body)\n     (cons! t (let ([x (mcar x)] ...) body) (let ([x (mcdr x)] ...) body))]))\n\n(define (F t x y z)\n  (cons-op! t (x y z)\n    (bitwise-and (bitwise-ior (bitwise-and x y)\n                              (bitwise-and (bitwise-not x) z))\n                 65535)))\n\n(define (G t x y z)\n  (cons-op! t (x y z)\n    (bitwise-and (bitwise-ior (bitwise-and x z)\n                              (bitwise-and y (bitwise-not z)))\n                 65535)))\n\n(define (H t x y z)\n  (cons-op! t (x y z) (bitwise-xor x y z)))\n\n(define (II t x y z)\n  (cons-op! t (x y z)\n    (bitwise-and (bitwise-xor y (bitwise-ior x (bitwise-not z)))\n                 65535)))\n\n;; Step 5  -  Encoding\n;; To finish up, we convert the word to hexadecimal string - and make sure they\n;; end up in order.\n;; encode : (list word word word word) bool -> byte-string\n\n(define hex-digits #(48 49 50 51 52 53 54 55 56 57 97 98 99 100 101 102))\n;; word->digits : word -> bytes-string,\n;; returns a little endian result, but each byte is hi half and then lo half\n(define (word->digits w)\n  (let ([digit (lambda (n b)\n                 (vector-ref hex-digits\n                             (bitwise-and (arithmetic-shift n (- b)) 15)))]\n        [lo (mcdr w)] [hi (mcar w)])\n    (bytes (digit lo 4) (digit lo 0) (digit lo 12) (digit lo 8)\n           (digit hi 4) (digit hi 0) (digit hi 12) (digit hi 8))))\n(define (word->bytes w)\n  (bytes-append (integer->integer-bytes (mcdr w) 2 #f #f)\n                (integer->integer-bytes (mcar w) 2 #f #f)))\n(define (encode l hex-encode?)\n  (apply bytes-append (map (if hex-encode? word->digits word->bytes) l)))\n"
  },
  {
    "path": "tests/inputs/meson.build",
    "content": "# https://github.com/tiernemi/meson-sample-project/blob/master/meson.build\nproject('sample_cpp_project', 'cpp',\n    version : '1.0',\n    license : [ 'proprietary'],\n    meson_version : '>= 0.50.0',\n    default_options : [ 'warning_level=3', 'buildtype=debugoptimized', 'cpp_std=c++11' ]\n)\n\n# Variables tracking sources and libraries\nlibrary_path = []\nproject_sources = []\nproject_header_files = []\nproject_test_sources = []\nproject_benchmark_sources = []\n\ninc = [include_directories('include')]\n\nsubdir('include')\nsubdir('third_party')\n# This is where you should add in include directories\n\n# This triggers the builds of sources\nsubdir('src')\n# This links all the static libs into the main source file to form a binary\n\nsample_cpp_project_bin_deps = [\n  meson.get_compiler('cpp').find_library('fizz', required : true, dirs : library_path)\n]\n\nsample_cpp_project_bin_dep_libs = [\n  foo_lib,\n  bar_lib,\n  baz_lib,\n]\n\nsample_cpp_project_bin = executable('sample_cpp_project_bin', \n  main_source, \n  include_directories : inc, \n  dependencies : sample_cpp_project_bin_deps,\n  link_with : sample_cpp_project_bin_dep_libs)\n\ngtest = subproject('gtest')\nbenchmark = subproject('benchmark')\n\nif get_option('enable-tests')\n  subdir('tests')\nendif\nif get_option('enable-benchmarks')\n  subdir('benchmarks')\nendif\n\nsubdir('docs')\n\n# This adds the clang format file to the build directory\nconfigure_file(input : '.clang-format',\n               output : '.clang-format',\n\t       copy: true)\nrun_target('format',\n  command : ['clang-format','-i','-style=file',project_sources,project_test_sources,project_benchmark_sources,project_header_files])\n\n# This regex excludes any sources from the third_party, tests, benchmarks \n# and gtest related files.\nregex = '^((?!(third_party|tests|benchmarks|gtest)).)*$'\n# This adds clang tidy support\nconfigure_file(input : '.clang-tidy',\n               output : '.clang-tidy',\n               copy : true)\nrun_target('tidy',\n  command : ['run-clang-tidy.py','-fix', '-j' , '8', 'files', regex ,'-format', '-p='+ meson.build_root()])\n\n"
  },
  {
    "path": "tests/inputs/messages.rb",
    "content": "#!/usr/local/bin/ruby\n# messages.rb - this is a test for the Ruby SLOC counter.\n# You should get 110 SLOC for this file.\n\n# Guru module: private messages among players\n# Copyright (C) 2001, 2002 Josef Spillner, dr_maux@user.sourceforge.net\n# This is used as a test case in SLOCCount, a toolsuite that counts\n# source lines of code (SLOC).\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# To contact David A. Wheeler, see his website at:\n#  http://www.dwheeler.com.\n# \n# \n\n# Commands:\n# guru do i have any messages\n# guru tell grubby nice to meet myself :)\n# guru alert grubby\n\ndatabasedir = ENV['HOME'] + \"/.ggz/grubby\"\n\n####################################################################################\n\nclass GuruMessages\n  def initialize\n    @msg = Array.new\n\t@alerts = Array.new\n  end\n  def add(fromplayer, player, message)\n    @entry = Array.new\n\tnewmessage = (fromplayer + \" said: \" + message.join(\" \")).split(\" \")\n    @entry << player << newmessage\n    @msg.push(@entry)\n\tprint \"OK, I make sure he gets the message.\"\n\t$stdout.flush\n\tsleep 1\n  end\n  def tell(player)\n    len = @msg.length\n\ta = 0\n    for i in 0..len\n\t  unless @msg[len-i] == nil\n\t    print @msg[len-i][1][0..@msg[len-i][1].length - 1].join(\" \") + \"\\n\" if player == @msg[len-i][0]\n\t\tif player == @msg[len-i][0]\n  \t      @msg.delete_at(len-i)\n\t\t  a = 1\n\t\tend\n\t  end\n\tend\n\tif a == 0\n\t  print \"Sorry \" + player + \", I guess you're not important enough to get any messages.\"\n\tend\n\t$stdout.flush\n\tsleep 1\n  end\n  def alert(fromplayer, player)\n    @entry = Array.new << fromplayer << player\n    @alerts.push(@entry)\n\tprint \"OK, I alert \" + player + \" when I see him.\"\n\t$stdout.flush\n\tsleep 1\n  end\n  def trigger(player)\n    len = @alerts.length\n\ta = 0\n    for i in 0..len\n\t  unless @alerts[len-i] == nil\n  \t    if player == @alerts[len-i][0]\n\t      print player + \": ALERT from \" + @alerts[len-i][1] + \"\\n\"\n\t      @alerts.delete_at(len-i)\n\t\t  a = 1\n\t\tend\n\t  end\n\tend\n\tif a == 1\n\t  $stdout.flush\n\t  sleep 1\n\t  return 1\n\tend\n\treturn 0\n  end\nend\n\ninput = $stdin.gets.chomp.split(/\\ /)\n\nmode = 0\nif (input[1] == \"do\") && (input[2] == \"i\") && (input[3] == \"have\") &&\n  (input[4] == \"any\") && (input[5] == \"messages\")\n  mode = 1\n  player = ARGV[0]\nend\nif (input[1] == \"tell\")\n  mode = 2\n  fromplayer = ARGV[0]\n  player = input[2]\n  message = input[3..input.length]\nend\nif(input[1] == \"alert\")\n  mode = 3\n  fromplayer = ARGV[0]\n  player = input[2]\nend\n\nm = nil\nbegin\n  File.open(databasedir + \"/messages\") do |f|\n    m = Marshal.load(f)\n  end\nrescue\n  m = GuruMessages.new\nend\n\nif mode == 0\n  ret = m.trigger ARGV[0]\n  if ret == 0\n    exit\n  end\nend\nif mode == 1\n  if player != nil\n    m.tell player\n  else\n    print \"If you mind telling me who you are?\"\n    $stdout.flush\n\tsleep 1\n  end\nend\nif mode == 2\n  m.add fromplayer, player, message\nend\nif mode == 3\n  m.alert fromplayer, player\nend\n\nFile.open(databasedir + \"/messages\", \"w+\") do |f|\n  Marshal.dump(m, f)\nend\n\n"
  },
  {
    "path": "tests/inputs/mfile.mk",
    "content": "#!/usr/bin/make -f\n#\n#   Copyright information\n#\n#\tCopyright (C) 2012 Jari Aalto\n#\n#   License\n#\n#\tThis program is free software; you can redistribute it and/or modify\n#\tit under the terms of the GNU General Public License as published by\n#\tthe Free Software Foundation; either version 2 of the License, or\n#\t(at your option) any later version.\n#\n#\tThis program is distributed in the hope that it will be useful,\n#\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n#\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n#\tGNU General Public License for more details.\n#\n#\tYou should have received a copy of the GNU General Public License\n#\talong with this program. If not, see <http://www.gnu.org/licenses/>.\n\nifneq (,)\nThis makefile requires GNU Make.\nendif\n\nPACKAGE\t\t= cloc\n\nDESTDIR\t\t=\nprefix\t\t= /usr\nexec_prefix\t= $(prefix)\nman_prefix\t= $(prefix)/share\nmandir\t\t= $(man_prefix)/man\nbindir\t\t= $(exec_prefix)/bin\nsharedir\t= $(prefix)/share\n\nBINDIR\t\t= $(DESTDIR)$(bindir)\nDOCDIR\t\t= $(DESTDIR)$(sharedir)/doc\nLOCALEDIR\t= $(DESTDIR)$(sharedir)/locale\nSHAREDIR\t= $(DESTDIR)$(sharedir)/$(PACKAGE)\nLIBDIR\t\t= $(DESTDIR)$(prefix)/lib/$(PACKAGE)\nSBINDIR\t\t= $(DESTDIR)$(exec_prefix)/sbin\nETCDIR\t\t= $(DESTDIR)/etc/$(PACKAGE)\n\n# 1 = regular, 5 = conf, 6 = games, 8 = daemons\nMANDIR\t\t= $(DESTDIR)$(mandir)\nMANDIR1\t\t= $(MANDIR)/man1\nMANDIR5\t\t= $(MANDIR)/man5\nMANDIR6\t\t= $(MANDIR)/man6\nMANDIR8\t\t= $(MANDIR)/man8\n\nBIN\t\t= $(PACKAGE)\nPL_SCRIPT\t= $(BIN)\n\nINSTALL_OBJS_BIN = $(PL_SCRIPT)\nINSTALL_OBJS_MAN = *.1\n\nINSTALL\t\t= /usr/bin/install\nINSTALL_BIN\t= $(INSTALL) -m 755\nINSTALL_DATA\t= $(INSTALL) -m 644\n\nall: man\n\t@echo \"Nothing to compile for a Perl script.\"\n\t@echo \"Try 'make help' or 'make -n DESTDIR= prefix=/usr/local install'\"\n\n# Rule: help - display Makefile rules\nhelp:\n\t@grep \"^# Rule:\" Makefile | sort\n\n# Rule: clean - remove temporary files\nclean:\n\t# clean\n\trm -f *[#~] *.\\#* *.x~~ pod*.tmp *.1\n\trm -rf tmp\n\ndistclean: clean\n\nrealclean: clean\n\n# Rule: man - Generate or update manual page\nman:\n\tmake -f pod2man.mk PACKAGE=$(PACKAGE) makeman\n\n# Rule: doc - Generate or update all documentation\ndoc: man\n\n# Rule: test-perl - Check program syntax\ntest-perl:\n\t# perl-test - Check syntax\n\tperl -cw $(PL_SCRIPT)\n\n# Rule: test-pod - Check POD syntax\ntest-pod:\n\tpodchecker *.pod\n\n# Rule: test-code - Check that the counter works\ntest-code:\n\tt/00_C.t\n\n# Rule: test - Run tests\ntest: test-perl test-pod test-code\n\ninstall-man: test-pod man\n\t# install-man\n\t$(INSTALL_BIN) -d $(MANDIR1)\n\t$(INSTALL_DATA) $(INSTALL_OBJS_MAN) $(MANDIR1)\n\ninstall-bin: test-perl\n\t# install-bin - Install programs\n\t$(INSTALL_BIN) -d $(BINDIR)\n\tfor f in $(INSTALL_OBJS_BIN); \\\n\tdo \\\n\t\tdest=$${f%.pl}; \\\n\t\t$(INSTALL_BIN) $$f $(BINDIR)/$$dest; \\\n\tdone\n\n# Rule: install - Standard install\ninstall: install-bin install-man\n\n# Rule: install-test - for Maintainer only\ninstall-test:\n\trm -rf tmp\n\tmake DESTDIR=$$(pwd)/tmp prefix=/usr install\n\tfind tmp | sort\n\n# Rule: dist - for Maintainer only, make distribution\ndist: clean\n\t[ -f version ] || fail-version-file-is-missing\n\n\trelease=$(PACKAGE)-$$(cat version); \\\n\trm -rf /tmp/$$release ; \\\n\tmkdir -vp /tmp/$$release ; \\\n\tcp -rav . /tmp/$$release/ ; \\\n    find /tmp/$$release/ -type d \\\n      \\( -name .svn -o -name .git -o -name .hg \\) | xargs -r rm -r; \\\n\ttar -C /tmp -zvcf /tmp/$$release.tar.gz $$release ; \\\n\techo \"DONE: /tmp/$$release.tag.gz\"\n\n.PHONY: clean distclean realclean install install-bin install-man\n\n# End of file\n"
  },
  {
    "path": "tests/inputs/modules1-func1.pp",
    "content": "# this is a Puppet function\n# /root/examples/modules1-func1.pp\nfunction ntp::func {\n  return('foobar')\n}\n"
  },
  {
    "path": "tests/inputs/modules1-func2.pp",
    "content": "# this is a Puppet function with args\n# /root/examples/modules1-func2.pp\nfunction ntp::my_func ($arg1, $arg2) {\n  return(\"${arg1} and ${arg2}\")\n}\n"
  },
  {
    "path": "tests/inputs/modules1-ntp1.pp",
    "content": "# this is a Puppet manifest\n# /root/examples/modules1-ntp1.pp\n\nclass ntp {\n  case $operatingsystem {\n    centos, redhat: {\n      $service_name = 'ntpd'\n      $conf_file    = 'ntp.conf.el'\n    }\n    debian, ubuntu: {\n      $service_name = 'ntp'\n      $conf_file    = 'ntp.conf.debian'\n    }\n  }\n\n  package { 'ntp':\n    ensure => installed,\n  }\n  file { 'ntp.conf':\n    path    => '/etc/ntp.conf',\n    ensure  => file,\n    require => Package['ntp'],\n    source  => \"/root/examples/answers/${conf_file}\"\n  }\n  service { 'ntp':\n    name      => $service_name,\n    ensure    => running,\n    enable    => true,\n    subscribe => File['ntp.conf'],\n  }\n}\n"
  },
  {
    "path": "tests/inputs/modules1-typealias.pp",
    "content": "# this is a Puppet type alias\n# /root/examples/modules1-typealias\ntype Ntp::MyType = String\n"
  },
  {
    "path": "tests/inputs/moonbit.mbt",
    "content": "///|\n///without spaces\n/// 返回一个新数组，其中元素被反转。\n///\n/// # 示例\n///\n/// ```\n/// reverse([1,2,3,4]) |> println()\n/// ```\nfn reverse[T](xs : Array[T]) -> Array[T] {\n  Array::rev(xs)\n}\n\ntest {\n  assert_eq!(reverse([1,2,3,4]), [4, 3, 2, 1]) // pass\n  assert_eq!(reverse([1,2,3,4]), [4, 3, 2, 1]) //pass\n  let _ = \"https://github.com\"\n}\n\nfn main {\n  let greeting =\n    #|\n    #|     (\\(\\\n    #|     ( -.-)\n    #|     o_(\")(\")\n    #|     __  __     ____         __  ___                  ____  _ __\n    #|    / / / /__  / / /___     /  |/  /___  ____  ____  / __ )(_) /_\n    #|   / /_/ / _ \\/ / / __ \\   / /|_/ / __ \\/ __ \\/ __ \\/ __  / / __/\n    #|  / __  /  __/ / / /_/ /  / /  / / /_/ / /_/ / / / / /_/ / / /_\n    #| /_/ /_/\\___/_/_/\\____/  /_/  /_/\\____/\\____/_/ /_/_____/_/\\__/\n    #|\n  println(greeting)\n\n    // Define two array of Int.\n  let arr1 : Array[Int] = [1, 2, 3, 4, 5]\n\n  // Let compiler infer the type.\n  let arr2 = [6, 7, 8, 9, 10]\n\n  // Get the length of the array.\n  println(arr1.length())\n\n  // Access the element of the array.\n  println(arr1[1]) \n\n  // We change the elements inside the array. \n  // The binding of arr1 is immutable, it still points to the same array.\n  // The internal mutability of the array is defined by the standard library and \n  // is not affected by the binding.\n  arr1.push(6) \n  arr1[1] = 10\n  println(\"push and change element:\")\n  println(arr1)\n}\n"
  },
  {
    "path": "tests/inputs/moonbit.mbti",
    "content": "package moonbitlang/core/array\n\nalias @moonbitlang/core/quickcheck as @quickcheck\n\n// Values\n\n// Types and methods\nimpl FixedArray {\n  all[T](Self[T], (T) -> Bool) -> Bool\n}\n\n// Type aliases\n\n// Traits\n"
  },
  {
    "path": "tests/inputs/nested.lua",
    "content": "-- single line comment  issue #371\n\n--[[\nmulti \nline \ncomment\n]]\n\n--[[\nalso a comment\n--]]\n\nprint(\"hello, world\")\nprint([[not a comment]])\n\n--[===[\nmulti \nline \ncomment\n--[==[\nstill comment\n--[=[\nstill comment\n--[[\nstill comment\n--]]\n--]=]\n--]==]\n--]===]\n"
  },
  {
    "path": "tests/inputs/nomad_job.hcl",
    "content": "/*\n https://www.nomadproject.io/docs/job-specification/index.html\n */\n\n# This declares a job named \"docs\". There can be exactly one\n# job declaration per job file.\njob \"docs\" {\n  # Specify this job should run in the region named \"us\". Regions\n  # are defined by the Nomad servers' configuration.\n  region = \"us\"\n\n  # Spread the tasks in this job between us-west-1 and us-east-1.\n  datacenters = [\"us-west-1\", \"us-east-1\"]\n\n  # Run this job as a \"service\" type. Each job type has different\n  # properties. See the documentation below for more examples.\n  type = \"service\"\n\n  # Specify this job to have rolling updates, two-at-a-time, with\n  # 30 second intervals.\n  update {\n    stagger      = \"30s\"\n    max_parallel = 2\n  }\n\n  # A group defines a series of tasks that should be co-located\n  # on the same client (host). All tasks within a group will be\n  # placed on the same host.\n  group \"webs\" {\n    # Specify the number of these tasks we want.\n    count = 5\n\n    # Create an individual task (unit of work). This particular\n    # task utilizes a Docker container to front a web application.\n    task \"frontend\" {\n      # Specify the driver to be \"docker\". Nomad supports\n      # multiple drivers.\n      driver = \"docker\"\n\n      # Configuration is specific to each driver.\n      config {\n        image = \"hashicorp/web-frontend\"\n      }\n\n      # The service block tells Nomad how to register this service\n      # with Consul for service discovery and monitoring.\n      service {\n        # This tells Consul to monitor the service on the port\n        # labelled \"http\". Since Nomad allocates high dynamic port\n        # numbers, we use labels to refer to them.\n        port = \"http\"\n\n        check {\n          type     = \"http\"\n          path     = \"/health\"\n          interval = \"10s\"\n          timeout  = \"2s\"\n        }\n      }\n\n      # It is possible to set environment variables which will be\n      # available to the task when it runs.\n      env {\n        \"DB_HOST\" = \"db01.example.com\"\n        \"DB_USER\" = \"web\"\n        \"DB_PASS\" = \"loremipsum\"\n      }\n\n      # Specify the maximum resources required to run the task,\n      # include CPU, memory, and bandwidth.\n      resources {\n        cpu    = 500 # MHz\n        memory = 128 # MB\n\n        network {\n          mbits = 100\n\n          # This requests a dynamic port named \"http\". This will\n          # be something like \"46283\", but we refer to it via the\n          # label \"http\".\n          port \"http\" {}\n\n          # This requests a static port on 443 on the host. This\n          # will restrict this task to running once per host, since\n          # there is only one port 443 on each host.\n          port \"https\" {\n            static = 443\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/notes.typ",
    "content": "/*\n  https://github.com/tudborg/notes.typ/raw/main/notes.typ\n  Keep track of a running note counter, and associated notes.\n*/\n\n#let note_state_prefix = \"notes-\"\n#let note_default_group = \"default\"\n\n#let note_default_display_fn(note) = {\n  h(0pt, weak: true)\n  super([[#note.index]])\n}\n\n#let add_note(\n  // The location of the note. This is used to derive\n  // what the note counter should be for this note.\n  loc,\n  // The note itself.\n  text,\n  // The offset which will be added to the 0-based counter index\n  // when the index stored in the state.\n  offset: 1,\n  // the display function that creates the returned content from put.\n  // Put can't return a pure index number because the counter\n  // and state updates need to output content.\n  display: note_default_display_fn,\n  // The state group to track notes in.\n  // A group acts independent (both counter and set of notes)\n  // from other groups.\n  group: note_default_group\n) = {\n  let s = state(note_state_prefix + group, ())\n  let c = counter(note_state_prefix + group)\n  // find any existing note that hasn't been printed yet,\n  // containing the exact same text:\n  let existing = s.at(loc).filter((n) => n.text == text)\n  // If we found an existing note use that,\n  // otherwise the note is the current location's counter + offset\n  // and the given text (the counter is 0-based, we want 1-based indices)\n  let note = if existing.len() > 0 {\n    existing.first()\n  } else {\n    (text: text, index: c.at(loc).first() + offset, page: loc.page())\n  }\n\n  // If we didn't find an existing index, increment the counter\n  // and add the note to the \"notes\" state.\n  if existing.len() == 0 {\n    c.step()\n    s.update(notes => notes + (note,))\n  }\n  \n  // Output the note marker\n  display(note)\n}\n\n// get notes at specific location\n#let get_notes(loc, group: note_default_group) = {\n  state(note_state_prefix + group, ()).at(loc)\n}\n\n// Reset the note group to empty.\n// Note: The counter does not reset by default.\n#let reset_notes(group: note_default_group, reset_counter: false) = {\n  if reset_counter {\n    counter(note_state_prefix + group).update(0)\n  }\n  state(note_state_prefix + group, ()).update(())\n}\n\n//\n// Helpers for nicer in-document ergonomics\n//\n\n#let render_notes(fn, group: note_default_group, reset: true, reset_counter: false) = {\n  locate(loc => fn(get_notes(loc, group: group)))\n  if reset {\n    reset_notes(group: group, reset_counter: reset_counter)\n  }\n}\n\n// Create a new note at the current location\n#let note(note, ..args) = {\n  locate((loc) => add_note(loc, note, ..args))\n}\n\n// The quick-start option that outputs something useful by default.\n// This is a sane-defaults call to `render_notes`.\n#let notes(\n  size: 8pt,\n  font: \"Roboto\",\n  line: line(length: 100%, stroke: 1pt + gray),\n  padding: (top: 3mm),\n  alignment: bottom,\n  numberings: \"1\",\n  group: note_default_group,\n  reset: true,\n  reset_counter: false\n) = {\n  let render(notes) = {\n    if notes.len() > 0 {\n      set align(alignment)\n      block(breakable: false, pad(..padding, {\n        if line != none { line }\n        set text(size: size, font: font)\n        for note in notes {\n          [/ #text(font: \"Roboto Mono\")[[#numbering(numberings, note.index)]]: #note.text]\n        }\n      }))\n    }\n  }\n  render_notes(group: group, reset: reset, reset_counter: reset_counter, render)\n}\n\n//\n// Examples\n//\n\n#set page(height: 5cm, width: 15cm)\n\n= Example\n\n- Having a flexible note-keeping system is important #note[Citation needed]\n- It's pretty easy to implement with Typst #note[Fact]\n- Everyone really likes the name \"Typst\" #note[Citation needed]\n\n\n\n// Print notes since last print:\n#notes()\n#pagebreak()\n\nThese notes won't be printed on this page, so they accumulate onto next page.\n\n- Hello World #note[Your first program]\n- Foo Bar #note[Does not serve beverages]\n#pagebreak()\n\n- Orange #note[A Color]\n- Blue #note[A Color]\n// Notice that the \"Citation needed\" gets a new index\n// because we've re-used it since we printed the initial \"Citation needed\"\n- All colors are great #note[Citation needed]\n#notes()\n#pagebreak()\n\n#set page(\n  height: 8cm,\n  footer: notes(padding: (bottom: 5mm)),\n  margin: (rest: 5mm, bottom: 3cm)\n)\n\n= Footnotes\n\nIt is of course also possible to place the notes _in_ the page footer.\nThis is the way to implement footnotes.\n\n- Black#note[Debateably a color]\n- White#note[Debateably a color]\n#pagebreak()\n\n- Orange#note[A Color]\n- Blue#note[A Color]\n- Purple#note[Also a color]\n\n#pagebreak()\n\n= Note groups\n\nThis page still has footnotes (using the default note group)\nbut we can also name a new group for custom notes.\n\n#let mynote = note.with(group: \"custom\")\n#let mynotes = notes.with(\n  group: \"custom\",\n  font: \"Comic Neue\",\n  size: 12pt,\n  numberings: \"a.\",\n  line: none,\n  alignment: right + top\n)\n\n- This is in it's own group#mynote[Custom]\n- Regular footnote here#note[Regular footnote]\n- Same custom note#mynote[Custom]\n\n#mynotes()\n"
  },
  {
    "path": "tests/inputs/nu-example.nu",
    "content": "# Source: https://github.com/nushell/nu_scripts/blob/e82487722bce88c11f6b31788142b29e4c40bda4/games/paperclips/game.nu\n\n# nu-niversal paperclips - a (somewhat) faithful clone of Universal Paperclips\n# play the original at: https://www.decisionproblem.com/paperclips/index2.html\n\n# NOTE: scalars are off cuz i'm counting by pennies instead of dollars and cents\n\nconst carriage_return = \"\\n\\r\"\n\n# Resets cursor to home position and hides it to prevent visual distraction\ndef reset-cursor [] {\n  print -n \"\\e[H\"  # Move cursor to home position (top-left)\n  print -n \"\\e[?25l\"  # Hide cursor\n}\n\n# Clears all content from cursor position to end of screen\ndef clear-to-end [] {\n  print -n \"\\e[J\"  # Clear from cursor to end of screen\n}\n\n# Updates the terminal display with current game state\ndef refresh-game-view [state] {\n  reset-cursor\n  render-game-display $state\n}\n\ndef make-paperclip [state, amount: int] {\n  mut new_state = $state\n  $new_state.paperclips.total += $amount\n  $new_state.paperclips.stock += $amount\n  $new_state.wire.length -= $amount\n  $new_state.paperclips.current_second_clips += $amount  # Add this line\n  $new_state\n}\n\ndef sell-paperclips [state] {\n  if $state.paperclips.stock == 0 { return $state }\n  # numbers picked by the OG, i haven't sussed out exactly why.\n  if (random float 0.0..1.0) > ($state.market.demand / 100) { return $state }\n  mut amount = 0.7 * ($state.market.demand ** 1.15) | math floor\n  if $amount > $state.paperclips.stock { $amount = $state.paperclips.stock }\n  mut new_state = $state\n  let transaction = $amount * $state.paperclips.price\n  $new_state.money += $transaction\n  $new_state.paperclips.stock -= $amount\n  $new_state\n}\n\ndef update-demand [state] {\n  let marketing = 1.1 ** ($state.market.level - 1)\n  mut new_state = $state\n  $new_state.market.demand = ((.8 / $state.paperclips.price) * $marketing) * 1000\n  $new_state\n}\n\ndef get-user-input [] {\n  let key = (input listen --types [key])\n  if ($key.code == 'c') and ($key.modifiers == ['keymodifiers(control)']) {\n    print -n \"\\e[?25h\"  # Show cursor before exiting\n    exit\n  }\n  $key.code | job send 0\n}\n\ndef format-text [prefix: string, value: number, --money --round] {\n  mut value = $value\n  if $money {\n    $value = $value / 100.0 | math round --precision 2\n  }\n  if $round {\n    $value = $value | math round --precision 2\n  }\n  # e.g. \"Paperclips: XXX\\n\\r\" or \"Unsold Inventory: $X.XX\\n\\r\"\n  $\"($prefix): (if $money { \"$\" } else { })($value | into string --group-digits)(if $round { \"%\" } else { })($carriage_return)\"\n}\n\n# Prints text after clearing the current line with ANSI escape code\ndef clear-line [text] {\n  print -n $\"\\e[2K($text)\"\n}\n\ndef render-game-display [state] {\n  # Game title and stats\n  clear-line (format-text \"Paperclips\" $state.paperclips.total)\n  clear-line $carriage_return\n\n  # Business section\n  clear-line \"Business:\\n\\r\"\n  clear-line \"---------------\\n\\r\"\n  clear-line (format-text 'Available Funds' $state.money --money)\n  clear-line (format-text 'Unsold Inventory' $state.paperclips.stock)\n  clear-line (format-text 'Price Per Clip' $state.paperclips.price --money)\n  clear-line (format-text 'Public Demand' $state.market.demand --round)\n  clear-line $carriage_return\n  clear-line (format-text 'Marketing Level' $state.market.level)\n  clear-line (format-text 'Marketing cost' $state.market.cost --money)\n  clear-line $carriage_return\n\n  # Manufacturing section\n  clear-line \"Manufacturing:\\n\\r\"\n  clear-line \"---------------\\n\\r\"\n  clear-line (format-text 'Clips per Second' $state.paperclips.rate)\n  clear-line $carriage_return\n\n  # Wire section\n  if $state.wire.length == 1 { \"inch\" } else { \"inches\" }\n  clear-line $\"Wire: ($state.wire.length | into string -g) (\n    if $state.wire.length == 1 { \"inch\" } else { \"inches\" }\n  )\\n\\r\"\n  clear-line (format-text 'Wire cost' $state.wire.cost --money)\n  clear-line $carriage_return\n\n  # Autoclippers (conditional)\n  if $state.autoclippers.unlocked {\n    clear-line (format-text \"Autoclippers\" $state.autoclippers.count)\n    clear-line (format-text 'Autoclipper cost' $state.autoclippers.cost --money)\n    clear-line $carriage_return\n  }\n\n  # Controls\n  clear-line $\"($state.control_line)\\n\\r\"\n\n  # Clean up any trailing content from previous longer displays\n  clear-to-end\n}\n\ndef main [] {\n  reset-cursor\n  print \"Welcome to nu-niversal paperclips!\"\n  clear-to-end\n  sleep 2sec\n  reset-cursor\n  let table_name = \"clip_message_queue\"\n\n  mut state = {\n    delta_time: 0sec\n    paperclips: {\n      total: 0\n      stock: 0\n      price: 25\n      rate: 0  # Changed from -1 to 0: This will show last second's rate\n      current_second_clips: 0  # Add: Accumulator for current second\n    }\n    last_second_timestamp: (date now)  # Add: Track when current second started\n    market: {\n      demand: 0\n      level: 1\n      cost: 10000\n    }\n    money: 0\n    control_line: \"controls: [a]dd paperclip; buy [w]ire; price [u]p; price [d]own; [q]uit\"\n    wire: {\n      length: 1000\n      cost: 2000\n    }\n    autoclippers: {\n      count: 0\n      unlocked: false\n      cost: 1000\n      multiplier: 1.25\n    }\n  }\n  let save_exists = ('./gamestate.nuon' | path exists)\n  if $save_exists {\n    $state = open './gamestate.nuon'\n  }\n  # initial setup\n  $state = update-demand $state\n  refresh-game-view $state\n  get-user-input\n\n  loop {\n    let seconds = $state.delta_time\n    if ($seconds) > (1sec) {\n      $state.delta_time -= $seconds\n      # TODO: tweak numbers\n      if (random bool --bias 0.5) {\n        let deviation = (0.75 + (random float 0.0..0.50))\n        $state.wire.cost *= $deviation\n        if $state.wire.cost < 1200 {\n          $state.wire.cost = 1200\n        } else if $state.wire.cost > 3000 {\n          $state.wire.cost = 3000\n        }\n      }\n      $state = update-demand $state\n\n      # Calculate total autoclipper production for this time period\n      let amount = (($seconds | into int | $in / 1000000000) * $state.autoclippers.count) | math round\n      mut index = 0\n      while $index < $amount {\n        $state = make-paperclip $state 1\n        $index += 1\n      }\n\n      $state = sell-paperclips $state\n    }\n    let prev = date now\n\n    # Check if a second has passed and roll over counters\n    let now = date now\n    if ($now - $state.last_second_timestamp) >= 1sec {\n      $state.paperclips.rate = $state.paperclips.current_second_clips\n      $state.paperclips.current_second_clips = 0\n      $state.last_second_timestamp = $now\n    }\n\n    if (($state.paperclips.total > 9) and ($state.autoclippers.count < 1)) and not $state.autoclippers.unlocked {\n      $state.autoclippers.unlocked = true\n      $state.control_line += \"; [b]uy autoclipper\"\n    }\n\n    # Update display with current game state\n    refresh-game-view $state\n\n    try {\n      let key = job recv --timeout 0sec\n      match $key {\n        \"a\" => {\n          # TODO: add some way to grow amount?\n          $state = make-paperclip $state 1\n        }\n        \"b\" => {\n          if $state.money >= $state.autoclippers.cost {\n            $state.money -= $state.autoclippers.cost\n            $state.autoclippers.count += 1\n            $state.autoclippers.cost = ($state.autoclippers.cost * 1.25 | math round)\n          }\n        }\n        \"d\" => {\n          if $state.paperclips.price > 1 {\n            $state.paperclips.price -= 1\n            $state = update-demand $state\n          }\n        }\n        \"q\" => {\n          if not $save_exists {\n            $state | save gamestate.nuon\n          } else {\n            $state | save gamestate.nuon --force\n          }\n          print -n \"\\e[?25h\"  # Show cursor before exiting\n          break\n        }\n        \"u\" => {\n          $state.paperclips.price += 1\n          $state = update-demand $state\n        }\n        \"w\" => {\n          if $state.money >= $state.wire.cost {\n            $state.wire.length += 1000\n            $state.money -= $state.wire.cost\n          }\n        }\n        _ => {\n          \"\"\n        }\n      }\n      job spawn { get-user-input }\n    }\n\n    # for 60fps framerate lock\n    sleep 16.666ms\n    let now = date now\n    let delta = $now - $prev\n    $state.delta_time += $delta\n  }\n}\n"
  },
  {
    "path": "tests/inputs/nuon-example.nuon",
    "content": "# Source: https://www.nushell.sh/book/loading_data.html#nuon\n\n{\n  menus: [\n    # Configuration for default nushell menus\n    # Note the lack of source parameter\n    {\n      name: completion_menu\n      only_buffer_difference: false\n      marker: \"| \"\n      type: {\n          layout: columnar\n          columns: 4\n          col_width: 20   # Optional value. If missing all the screen width is used to calculate column width\n          col_padding: 2\n      }\n      style: {\n          text: green\n          selected_text: green_reverse\n          description_text: yellow\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "tests/inputs/offline.jcl",
    "content": "//* https://www.ibm.com/support/knowledgecenter/en/SSB23S_1.1.0.12/gtps3/espoljcl.html\n//TRAP     JOB MSGLEVEL=1,CLASS=S,MSGCLASS=S\n/*ROUTE PRINT YOURND(YOURID)\n/*ROUTE PUNCH YOURND(YOURID)\n//STEP1  EXEC PGM=TRAP,REGION=90M\n//STEPLIB  DD DSN=ACP.LINK.ZCUR.BSS,DISP=SHR\n//***********************************\n//* Input from a file system file\n//***********************************\n//DATAIN   DD PATH='/u/myfile/ei.out',\n//         PATHOPTS=(ORDONLY)\n//***********************************\n//* Input from a general tape\n//***********************************\n//*DATAIN   DD DSN=GEN.TAPE,\n//*            UNIT=VTAPE,DISP=(OLD,PASS),\n//*            VOL=SER=A00099,\n//*            DCB=OPTCD=B\n//***********************************\n//* Input from an RTA tape\n//***********************************\n//*DATAIN   DD DSN=RTA.TAPE,UNIT=(VTAPE,,DEFER),LABEL=(,SL),\n//*         VOL=SER=A00280,DISP=(OLD,KEEP),DCB=OPTCD=B\n//*** END OF INPUT STATEMENTS *******\n//NUCL     DD DUMMY\n//TMEIIN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=132,RECFM=FB),\n//         SPACE=(TRK,(500,100),RLSE)\n//TMEIOUT  DD  DSN=*.TMEIIN,DISP=(OLD,PASS),VOL=REF=*.TMEIIN\n//EIDAIN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=32,RECFM=FB),\n//         SPACE=(TRK,(500,100),RLSE)                       \n//EIDAOUT  DD  DSN=*.EIDAIN,DISP=(OLD,PASS),VOL=REF=*.EIDAIN\n//EIAPIN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=9,RECFM=FB),\n//         SPACE=(TRK,(10,5),RLSE)\n//EIAPOUT  DD  DSN=*.EIAPIN,DISP=(OLD,PASS),VOL=REF=*.EIAPIN\n//TMMAIN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=64,RECFM=FB),\n//         SPACE=(TRK,(50,25),RLSE)\n//TMMAOUT  DD  DSN=*.TMMAIN,DISP=(OLD,PASS),VOL=REF=*.TMMAIN\n//TM12IN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=52,RECFM=FB),\n//         SPACE=(TRK,(50,5),RLSE)\n//MA12IN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=52,RECFM=FB),\n//         SPACE=(TRK,(50,5),RLSE)\n//MA12OUT  DD  DSN=*.MA12IN,DISP=(OLD,PASS),VOL=REF=*.MA12IN\n//SU12IN   DD  UNIT=SYSDA,DCB=(BLKSIZE=0,LRECL=80,RECFM=FB),\n//         SPACE=(TRK,(50,5),RLSE)\n//SU12OUT  DD  DSN=*.SU12IN,DISP=(OLD,PASS),VOL=REF=*.SU12IN\n//GROUPS   DD DUMMY\n//SYSOUT   DD SYSOUT=*\n//SYSPRINT DD SYSOUT=*\n//OPTRPT   DD SYSOUT=*\n//DATASUM  DD SYSOUT=*\n//CONTENTS DD SYSOUT=*\n//GRPRPT   DD SYSOUT=*\n//SUMMRY   DD SYSOUT=*\n//DETAIL   DD SYSOUT=*\n//RESOURCE DD SYSOUT=*\n//OPTIONS DD *\nRUN TYPE EI\nRUN NO 1\nDETAIL YES\nCOMP YES\n/*\n//                              \n"
  },
  {
    "path": "tests/inputs/openharmony.ets",
    "content": "// https://github.com/openharmony/docs/blob/master/en/application-dev/quick-start/start-with-ets.md\n// index.ets\n@Entry\n@Component\nstruct Index {\n  @State message: string = 'Hello World'\n\n  build() {\n    Row() {\n/*\n      Column() {\n        Text(this.message)\n          .fontSize(50)\n          .fontWeight(FontWeight.Bold)\n      }\n      .width('100%')\n*/\n    }\n    .height('100%')\n  }\n}\n"
  },
  {
    "path": "tests/inputs/orgmode.org",
    "content": "#+title: Example Org File\n\nHello, world\n\n# comment 1\n\n#+begin_comment\ncomment 2\n#+end_comment\n\n* COMMENT comment3\njust a comment\n\n* About Org\nA GNU Emacs major mode for keeping notes, authoring documents, computational notebooks, literate programming, maintaining to-do lists, planning projects, and more — in a fast and effective plain text system.\n\nOrg is a highly flexible structured plain text file format, composed of a few simple, yet versatile, structures — constructed to be both simple enough for the novice and powerful enough for the expert.\n\n#+begin_src python\n  print(\"hello world\")\n#+end_src\n"
  },
  {
    "path": "tests/inputs/page_layout.aspx",
    "content": "<!--\nhttps://www.tutorialspoint.com/asp.net/asp.net_first_example.htm\n -->\n<!-- directives -->\n<% @Page Language=\"C#\" %>\n\n<!-- code section -->\n<script runat=\"server\">\n\n   private void convertoupper(object sender, EventArgs e)\n   {\n      string str = mytext.Value;\n      changed_text.InnerHtml = str.ToUpper();\n   }\n</script>\n\n<!-- Layout -->\n<html>\n   <head> \n      <title> Change to Upper Case </title> \n   </head>\n   \n   <body>\n      <h3> Conversion to Upper Case </h3>\n      \n      <form runat=\"server\">\n         <input runat=\"server\" id=\"mytext\" type=\"text\" />\n         <input runat=\"server\" id=\"button1\" type=\"submit\" value=\"Enter...\" OnServerClick=\"convertoupper\"/>\n         \n         <hr />\n         <h3> Results: </h3>\n         <span runat=\"server\" id=\"changed_text\" />\n      </form>\n      \n   </body>\n   \n</html>\n"
  },
  {
    "path": "tests/inputs/pages.wxml",
    "content": "<!-- https://developers.weixin.qq.com/miniprogram/en/dev/reference/wxml/ -->\n<!-- wxml -->\n\n\n<template name=\"staffName\">\n  <view>\n    FirstName: {{firstName}}, LastName: {{lastName}}\n  </view>\n</template>\n\n<template is=\"staffName\" data=\"{{...staffA}}\"></template>\n<template is=\"staffName\" data=\"{{...staffB}}\"></template>\n<template is=\"staffName\" data=\"{{...staffC}}\"></template>\n"
  },
  {
    "path": "tests/inputs/pages.wxss",
    "content": "// https://developers.weixin.qq.com/miniprogram/en/dev/reference/wxs/07basiclibrary.html\nconsole.log(undefined === JSON.stringify());\nconsole.log(undefined === JSON.stringify(undefined));\nconsole.log(\"null\"===JSON.stringify(null));\n"
  },
  {
    "path": "tests/inputs/parser_1.civet",
    "content": "{ fail } from node:assert\n{ tokens, type Token } from ./tokens.civet\n           /*\ntype * as Ast from ./astTypes.civet\nassert from ./assert.civet\n           */\n\n/// TokenType ::= keyof typeof tokens\n/// tokenEntries := Object.entries(tokens) as [TokenType, Token][]\n\nclass TokenStream <: Iterable<[string, TokenType, readonly [number, number]]>\n    #sourceLocation = [1, 1] as tuple\n    @(#program: string)\n\n    :iterator() ###\n        :outer while #program# ###\n            for [type, token] of tokenEntries\n                length := token.matchLength #program\n            /// if length > 0\n            //      chunk := #program[..<length]        // comment\n            ///     #program |>= &[length<=..]\n            ///     yield [chunk, type, #sourceLocation] as tuple\n            ///     linesInChunk := chunk.split '\\n'\n            //      if linesInChunk# > 1        // comment\n                        #sourceLocation.0 += linesInChunk# - 1\n                        #sourceLocation.1 = 1\n                    #sourceLocation.1 += linesInChunk.-1#\n                    continue outer\n            throw new SyntaxError\n                `Unrecognized token starting with '${#program.0}' at input:${#sourceLocation.join ':'}`\n\nfunction collectUntil<T>(iter: Iterator<T>, pred: (arg: T) => boolean)\n    loop\n        next := iter.next()\n        break if next.done or pred next.value\n        yield next.value\n\nprocessExpression := (expr: string, line: number, column: number) =>\n    processSplits := (parts: string[]): Ast.NumberSyntaxTree =>\n        if parts# % 2 is 0\n            throw new SyntaxError `Incomplete expression: '${parts.join ''}' (near input:${line}:${column})`\n        if parts# > 2\n            type := switch parts.-2\n                '+'\n                    'addition' as const\n                '_'\n                    'subtraction' as const\n                else\n                    throw new SyntaxError\n                        `Missing operator in expression containing '${parts[-3...].join ''}' (near input:${line}:${column})`\n            {\n                type\n                value:\n                    . processSplits parts[...-2]\n                    . processSplits [parts.-1] \n            }\n        else\n            part := parts.0\n            switch part\n                '+', '_'\n                    throw new SyntaxError `Unexpected operator with no operands (near input:${line}:${column})`\n                /\\p{Letter}+/v\n                    type: 'variable', value: part\n                /[0-9]+/\n                    type: 'literal', value: Number part\n                else\n                    fail();\n    \n    splitsAndEmpty := expr.split /(\\+|_|\\p{Letter}+|[0-9]+)/gv\n    splits := splitsAndEmpty.flatMap (el, i) =>\n        if i % 2 is 0\n            assert => el is ''\n            []\n        else\n            [el]\n    return processSplits splits\n"
  },
  {
    "path": "tests/inputs/parser_2.civet",
    "content": "civet coffeeComment\n{ fail } from node:assert\n{ tokens, type Token } from ./tokens.civet\n           /*\ntype * as Ast from ./astTypes.civet\nassert from ./assert.civet\n           */\n\n/// TokenType ::= keyof typeof tokens\n/// tokenEntries := Object.entries(tokens) as [TokenType, Token][]\n\nclass TokenStream <: Iterable<[string, TokenType, readonly [number, number]]>\n    #sourceLocation = [1, 1] as tuple\n    @(#program: string)\n\n    :iterator() ###\n        :outer while #program# ###\n            for [type, token] of tokenEntries\n                length := token.matchLength #program\n            /// if length > 0\n            //      chunk := #program[..<length]        // comment\n            ///     #program |>= &[length<=..]\n            ///     yield [chunk, type, #sourceLocation] as tuple\n            ///     linesInChunk := chunk.split '\\n'\n            //      if linesInChunk# > 1        // comment\n                        #sourceLocation.0 += linesInChunk# - 1\n                        #sourceLocation.1 = 1\n                    #sourceLocation.1 += linesInChunk.-1#\n                    continue outer\n            throw new SyntaxError\n                `Unrecognized token starting with '${#program.0}' at input:${#sourceLocation.join ':'}`\n\n#function collectUntil<T>(iter: Iterator<T>, pred: (arg: T) => boolean)\n#    loop\n#        next := iter.next()\n#        break if next.done or pred next.value\n#        yield next.value\n"
  },
  {
    "path": "tests/inputs/pascal.inc",
    "content": "(* https://en.wikibooks.org/wiki/Pascal_Programming/Examples *)\n{...........................................................................}\nProcedure PrinterTest;   { works in the text mode}\n\n  begin\n    rejestr.dx:=LPT1;  { Port Number to which the printer is attached ;  0 = LPT1 }\n    rejestr.ah:=2;     { Function Number ; printer port status }\n    Intr($17,rejestr); {BIOS Interrupt #17 : initializes the indicated printer port and returns its status }\n    if rejestr.ah=144  { 10010000B : (bit 7) =1  i (bit 4) =1  }\n       then writeLn('Printer on LPT1 is OK')\n       else writeLn('Printer on LPT1 is not OK');\n       WriteLst(Reset);\n  end; { Procedure PrinterTest }\n"
  },
  {
    "path": "tests/inputs/pek_example.pek",
    "content": "// https://github.com/nektro/zig-pek/tree/master\n// language request: pek #855 \n\nhtml[lang=\"en\"](\n    head(\n        title(\"Pek Example\")\n        meta[charset=\"UTF-8\"]\n        meta[name=\"viewport\" content=\"width=device-width,initial-scale=1\"]\n    )\n    body(\n        h1(\"Pek Example\")\n        hr\n        p(\"This is an example HTML document written in \"a[href=\"https://github.com/nektro/zig-pek\"](\"Pek\")\".\")\n    )\n)\n"
  },
  {
    "path": "tests/inputs/ping_pong.lfe",
    "content": "#|\n  https://raw.githubusercontent.com/rvirding/lfe/develop/examples/ping_pong.lfe\n |#\n;; Copyright (c) Tim Dysinger tim <[<-on->]> dysinger.net\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(defmodule ping_pong\n  (export (start_link 0) (ping 0))\n  (export (init 1) (handle_call 3) (handle_cast 2)\n          (handle_info 2) (terminate 2) (code_change 3))\n  (behaviour gen_server))        ;Just indicates intent\n\n(defun start_link ()\n  (: gen_server start_link\n    (tuple 'local 'ping_pong) 'ping_pong (list) (list)))\n\n;; Client API\n\n(defun ping ()\n  (: gen_server call 'ping_pong 'ping))\n\n;; Gen_server callbacks\n\n(defrecord state (pings 0))\n\n(defun init (args)\n  (tuple 'ok (make-state pings 0)))\n\n(defun handle_call (req from state)\n  (let* ((new-count (+ (state-pings state) 1))\n         (new-state (set-state-pings state new-count)))\n    (tuple 'reply (tuple 'pong new-count) new-state)))\n\n(defun handle_cast (msg state)\n  (tuple 'noreply state))\n\n(defun handle_info (info state)\n  (tuple 'noreply state))\n\n(defun terminate (reason state)\n  'ok)\n\n(defun code_change (old-vers state extra)\n  (tuple 'ok state))\n"
  },
  {
    "path": "tests/inputs/plain_text.txt",
    "content": "\n                Release Notes for cloc version 1.92\n                   https://github.com/AlDanial/cloc\n                             Dec. 5, 2021\n\nNew Languages and File Types:\n    o GraphQL\n    o Metal Shading Language\n    o PlantUML\n    o Properties\n    o Umka\n\nUpdates:\n    o The .bzl and .bazel extensions are now associated with Starlark.\n    o Added support for Puppet functions and type aliases.\n    o Removed reliance on XML definition with --force-lang-def\n    o Fixed broken --csv-delimiter handling.\n    o Fixed broken interaction of --vcs=git with --max-file-size;\n      support floating point value for --max-file-size.\n    o Improved support for uniform handling of uppercase and\n      lowercase filenames and extensions on Windows.\n    o Recognize CMakeLists.txt on Windows.\n    o Fixed handling of --unicode for small files.\n    o Updated Dockerfile to produce a smaller image.\n    o Improved contents of --ignored file (now includes skipped\n      binary files and does not include directory names).\n    o Identify SCSS separately from Sass.\n    o Updated Sass filters to handle C++ style comments.\n    o Improved support for Assembly.\n    o Recognize :: comments in DOS batch files.\n    o Properly handle explicitly-excluded files (for example,\n      .gitignore) with --diff.\n\n"
  },
  {
    "path": "tests/inputs/plantuml.puml",
    "content": "' https://plantuml.com/commons\n@startuml\n/'\nmany lines comments\nhere\n'/\n\n/' case 1 '/   A -> B : AB-First step \n               B -> C : BC-Second step\n/' case 2 '/   D -> E : DE-Third step\n\n@enduml\n"
  },
  {
    "path": "tests/inputs/pointillism.pde",
    "content": "/**\n * Pointillism\n * by Daniel Shiffman. \n * \n * Mouse horizontal location controls size of dots. \n * Creates a simple pointillist effect using ellipses colored\n * according to pixels in an image. \n */\n\nPImage img;\nint smallPoint, largePoint;\n\nvoid setup() {\n  size(640, 360);\n  img = loadImage(\"moonwalk.jpg\");\n  smallPoint = 4;\n  largePoint = 40;\n  imageMode(CENTER);\n  noStroke();\n  background(255);\n}\n\nvoid draw() {\n  float pointillize = map(mouseX, 0, width, smallPoint, largePoint);\n  int x = int(random(img.width));\n  int y = int(random(img.height));\n  color pix = img.get(x, y);\n  fill(pix, 128);\n  ellipse(x, y, pointillize, pointillize);\n}\n\n// https://processing.org/examples/pointillism.html\n"
  },
  {
    "path": "tests/inputs/poly_constructor.jai",
    "content": "/*\nhttp://the-witness.net/news/2018/03/testing-the-jai-compiler/\nwith init_thing commented out\n*/\n#import \"Basic\";\n\nThing :: struct {\n    mem : *u8;\n    value := 42;\n    #constructor init_thing;\n    #destructor free_thing;\n}\n\n// init_thing :: (using thing : *$T) {\n//     mem = alloc(1000);\n// }\n\nfree_thing :: (using thing: *$T) {\n    free(mem);\n    mem = null;\n    print(\"Thing memory freed.\\n\");\n}\n\nmain :: () {\n    {\n        our_thing : Thing; // Constructor fires off.\n        print(\"%\\n\", our_thing);\n    } // Destructor fires off.\n}\n"
  },
  {
    "path": "tests/inputs/pop_by_country.xq",
    "content": "(: http://exist-db.org/exist/apps/demo/examples/basic/mondial.html :)\n (: This script accesses the mondial database, which can be found at http://dbis.informatik.uni-goettingen.de/Mondial/ :) for $country in /mondial/country let $cities := (for $city in $country//city[population] order by xs:integer($city/population[1]) descending return $city) order by $country/name return <country name=\"{$country/name}\"> { subsequence($cities, 1, 3) } </country>\n"
  },
  {
    "path": "tests/inputs/prob060-andreoss.p6",
    "content": "use v6;\n\n# https://github.com/Raku/examples/raw/master/categories/euler/prob060-andreoss.pl\n\n=begin pod\n\n=TITLE Prime pair sets \n\n=AUTHOR Andrei Osipov\n\nThe primes 3, 7, 109, and 673, are quite remarkable. By taking any two\nprimes and concatenating them in any order the result will always be\nprime. For example, taking 7 and 109, both 7109 and 1097 are\nprime. The sum of these four primes, 792, represents the lowest sum\nfor a set of four primes with this property.\n\nFind the lowest sum for a set of five primes for which any two primes\nconcatenate to produce another prime.\n\n=end   pod\n\nsubset Prime of Int where *.is-prime;\n\n\nsub infix:«R»($a, $b) {\n    +( $a ~ $b ) & +( $b ~ $a ) ~~ Prime \n}\n\nmulti are-remarkable()          { True }\nmulti are-remarkable($a)        { True }\nmulti are-remarkable($a, *@xs)  {\n    $a R @xs.all\n}\n\nsub get-remarkable(  :@primes   is copy\n                   , *@sequence\n                  ) {\n    gather while my $x = @primes.shift {\n        if are-remarkable $x, @sequence {\n            take(|@sequence , $x) if @sequence;\n            take $_\n                for get-remarkable\n                     :@primes\n                    , @sequence, $x\n        }\n    }\n}\n\nsub MAIN(  Int  :$limit   = 10_000\n         , Bool :$verbose = False\n         , Int  :$size    = 5\n        ) {\n    \n    my @primes = grep Prime , 1 .. $limit;\n    \n    for get-remarkable :@primes -> @r {\n        \n        say @r.perl if $verbose ;\n\n        if @r == $size {\n            $verbose\n                ?? say \"The sequence is @r[], the sum is {[+] @r}\"\n                !! say [+] @r\n            and last\n        }\n    }\n    \n    say \"Done in {now - BEGIN now}.\" if $verbose;\n}\n\n"
  },
  {
    "path": "tests/inputs/proguard-project-app.pro",
    "content": "# https://raw.githubusercontent.com/krschultz/android-proguard-snippets/master/examples/proguard-project-app.pro\n# The simpliest strategy is to not run proguard against your project's own code.\n# This doesn't provide the benefits of optimization & obfuscation against your \n# project, but will still strip the libraries. The advantage is that your app will\n# work without any subsequent effort. If you choose this strategy, the proguard\n# configuration for the project is simply the line below.\n\n-keep class com.yourpackage.app.** { *; }\n\n# The more involved strategy is to specifically provide rules to keep portions of your\n# app's codebase unmodified while allowing proguard to optimize the rest. \n\n# The first decision is whether or not you want to obfuscate your code. This provides no\n# performance benefit but makes it harder for other people to read your source code. \n# Unfortunately obfuscation can cause issues for code that uses reflection or a few other\n# techniques. The default is to obfuscate.\n\n-dontobfuscate\n\n# Additionally you will need to keep specific classes. A common use case is keeping all\n# of the models that are JSON parsed using something like Jackson.\n\n-keep class com.yourpackage.app.model.User { *; }\n\n"
  },
  {
    "path": "tests/inputs/qsort_demo.m",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n\n/*\n        Al Danial April 25 2000\n*/\n\n#define ELEMENTS 1000\n\nstatic int compar_string(const void *a, const void *b){\n        return (strcmp( (char *)a, (char *)b));\n}\n\nint comp(const void *a, const void *b ) {\n    return *(int *)a - * (int *)b;\n}\n\nmain(){\n\n        int x, i;\n        char *string;\n        struct sort_test_t {\n                int s;\n        } ;\n\n        struct sort_test_t sort_test[ELEMENTS];\n\n        /* inititalize the array */\n        for (i=0;i<ELEMENTS;i++) {\n                /* produce a random variable */\n                x=1+(100000.0*rand()/(RAND_MAX+1.0));\n                /* load the variable into the string as an array */\n                sort_test[i].s = (int) x;\n                /*\n                printf(\"unsorted %d %d\\n\", i, sort_test[i].s);\n                */\n        }\n\n        /* sort the array */\n        qsort(sort_test, ELEMENTS, sizeof(sort_test[0]), &comp);\n\n        /* output the sorted array */\n        for (i=0;i<ELEMENTS;i++) {\n                printf(\"sorted %d %d\\n\", i, sort_test[i].s);\n        }\n\n}\n"
  },
  {
    "path": "tests/inputs/queue.p",
    "content": "// https://github.com/compuphase/pawn/tree/main/examples/queue.p\n/* Priority queue (for simple text strings) */\n#include <string>\n\n@start()\n    {\n    var msg[.text{40}, .priority]\n\n    /* insert a few items (read from console input) */\n    printf \"Please insert a few messages and their priorities; \" ...\n           \"end with an empty string\\n\"\n    for ( ;; )\n        {\n        printf \"Message:  \"\n        getstring msg.text, .pack = true\n        if (strlen(msg.text) == 0)\n            break\n        printf \"Priority: \"\n        msg.priority = getvalue()\n        if (!insert(msg))\n            {\n            printf \"Queue is full, cannot insert more items\\n\"\n            break\n            }\n        }\n\n    /* now print the messages extracted from the queue */\n    printf \"\\nContents of the queue:\\n\"\n    while (extract(msg))\n        printf \"[%d] %s\\n\", msg.priority, msg.text\n    }\n\nconst queuesize = 10\nvar queue[queuesize][.text{40}, .priority]\nvar queueitems = 0\n\ninsert(const item[.text{40}, .priority])\n    {\n    /* check if the queue can hold one more message */\n    if (queueitems == queuesize)\n        return false            /* queue is full */\n\n    /* find the position to insert it to */\n    var pos = queueitems        /* start at the bottom */\n    while (pos > 0 && item.priority > queue[pos-1].priority)\n        --pos                   /* higher priority: move up a slot */\n\n    /* make place for the item at the insertion spot */\n    for (var i = queueitems; i > pos; --i)\n        queue[i] = queue[i-1]\n\n    /* add the message to the correct slot */\n    queue[pos] = item\n    queueitems++\n\n    return true\n    }\n\nextract(item[.text{40}, .priority])\n    {\n    /* check whether the queue has one more message */\n    if (queueitems == 0)\n        return false\n        /* queue is empty */\n\n    /* copy the topmost item */\n    item = queue[0]\n    --queueitems\n\n    /* move the queue one position up */\n    for (var i = 0; i < queueitems; ++i)\n        queue[i] = queue[i+1]\n\n    return true\n    }\n"
  },
  {
    "path": "tests/inputs/rand.apl",
    "content": "⍝ https://github.com/vendethiel/trying.apl\n⍝ monadic: roll\n?3 4 5\n\n⍝ just generate dices 25x 1d20\n?25⍴20\n\n⍝ how many critical hits? sum of the dies that rolled 20\n?25⍴20\n\n⍝ dyadic: deal\n⍝ same as ?⍵⍴⍺\n3?1000\n"
  },
  {
    "path": "tests/inputs/ranges.surql",
    "content": "/*\nhttps://surrealdb.com/docs/surrealql/statements/select#example-usage\n   */\n-- Select all person records with IDs between the given range\nSELECT * FROM person:1..1000;\n#  Select all records for a particular location, inclusive\nSELECT * FROM temperature:['London', NONE]..=['London', time::now()];\n-- Select all temperature records with IDs less than a maximum value\nSELECT * FROM temperature:..['London', '2022-08-29T08:09:31'];\n-- Select all temperature records with IDs greater than a minimum value\nSELECT * FROM temperature:['London', '2022-08-29T08:03:39']..;\n-- Select all temperature records with IDs between the specified range\nSELECT * FROM temperature:['London', '2022-08-29T08:03:39']..['London', '2022-08-29T08:09:31'];\n"
  },
  {
    "path": "tests/inputs/razor.cshtml",
    "content": "@{\n// This is a Razor code block\n/* Which also supports this style of comments */\nViewBag.Title = \"Customers\";\nLayout = \"~/Views/Shared/_Layout.cshtml\";\n}\n@* This is commented out HTML and C#\nThe version: @VersionResolver.Version *@\n"
  },
  {
    "path": "tests/inputs/reStructuredText.rst",
    "content": "Versions\n========\n\n.. Time summaries may be displayed for the following releases:\n\n3.3.0\n-----\n\n- Period starting: 2008-01-01\n- Period ending: 2008-05-31\n\n3.4.0\n-----\n\n- Period starting: 2008-06-01\n- Period ending: 2018-05-31\n\n..\n This is the end of the test file\n for rst format\n"
  },
  {
    "path": "tests/inputs/reactive.svelte",
    "content": "<!--\n https://svelte.dev/examples#reactive-assignments -->\n<script>\n\tlet count = 0;\n\n\tfunction handleClick() {\n\t\tcount += 1;\n\t}\n</script>\n\n<button on:click={handleClick}>\n\tClicked {count} {count === 1 ? 'time' : 'times'}\n</button>\n"
  },
  {
    "path": "tests/inputs/regex_limit.gradle",
    "content": "war {\n    from ('src') {\n        exclude 'com/**'\n        exclude 'org/**'\n        exclude \"abc/*\"\n        into '/WEB-INF/classes'\n    }\n}  /* this\nis a comment \n spanning 1 code line and 2 comment lines */\nwar.dependsOn longStringTypedHere\neclipse {\n    wtp {\n        component {\n            resource sourcePath: \"$WEBDIR_NAME\", deployPath: \"/\"\n        }\n    }\n}\ntasks.eclipse.dependsOn longStringTypedHere\n"
  },
  {
    "path": "tests/inputs/ring.pony",
    "content": "/*\n * https://github.com/ponylang/ponyc/raw/908402b60f083d66d3b59a1879efb6adee5ca3cc/examples/ring/main.pony\n */\n\n\"\"\"\nA ring is a group of processes connected to each other using\nunidirectional links through which messages can pass from process to\nprocess in a cyclic manner.\n\nThe logic of this program is as follows:\n* Each process in a ring is represented by the actor `Ring`\n* `Main` creates Ring by instantiating `Ring` actors based on the\n  arguments passed and links them with each other by setting the next\n  actor as the previous ones number and at the end linking the last actor\n  to the first one thereby closing the links and completing the ring\n* Once the ring is complete messages can be passed by calling the `pass`\n  behaviour on the current `Ring` to its neighbour.\n* The program prints the id of the last `Ring` to receive a message\n\nFor example if you run this program with the following options `--size 3`\nand `--pass 2`. It will create a ring that looks like this:\n\n\n        *  *              *  *\n     *        *        *        *\n    *     1    *_ _ _ *     2    *\n    *          *      *          *\n     *        *        *        *\n        *  *              *  *\n          \\                 /\n           \\               /\n            \\             /\n             \\    *  *   /\n               *        *\n              *     3    *\n              *          *\n               *        *\n                  *  *\n\nand print 3 as the id of the last Ring actor that received the\nmessage.\n\"\"\"\n\nuse \"collections\"\n\nactor Ring\n  let _id: U32\n  let _env: Env\n  var _next: (Ring | None)\n\n  new create(id: U32, env: Env, neighbor: (Ring | None) = None) =>\n    _id = id\n    _env = env\n    _next = neighbor\n\n  be set(neighbor: Ring) =>\n    _next = neighbor\n\n  be pass(i: USize) =>\n    if i > 0 then\n      match _next\n      | let n: Ring =>\n        n.pass(i - 1)\n      end\n    else\n      _env.out.print(_id.string())\n    end\n\nactor Main\n  var _ring_size: U32 = 3\n  var _ring_count: U32 = 1\n  var _pass: USize = 10\n\n  var _env: Env\n\n  new create(env: Env) =>\n    _env = env\n\n    try\n      parse_args()?\n      setup_ring()\n    else\n      usage()\n    end\n\n  fun ref parse_args() ? =>\n    var i: USize = 1\n\n    while i < _env.args.size() do\n      // Every option has an argument.\n      var option = _env.args(i)?\n      var value = _env.args(i + 1)?\n      i = i + 2\n\n      match option\n      | \"--size\" =>\n        _ring_size = value.u32()?\n      | \"--count\" =>\n        _ring_count = value.u32()?\n      | \"--pass\" =>\n        _pass = value.usize()?\n      else\n        error\n      end\n    end\n\n  fun setup_ring() =>\n    for j in Range[U32](0, _ring_count) do\n      let first = Ring(1, _env)\n      var next = first\n\n      for k in Range[U32](0, _ring_size - 1) do\n        let current = Ring(_ring_size - k, _env, next)\n        next = current\n      end\n\n      first.set(next)\n\n      if _pass > 0 then\n        first.pass(_pass)\n      end\n    end\n\n  fun usage() =>\n    _env.out.print(\n      \"\"\"\n      rings OPTIONS\n        --size N number of actors in each ring\n        --count N number of rings\n        --pass N number of messages to pass around each ring\n      \"\"\"\n      )\n"
  },
  {
    "path": "tests/inputs/robotframework.robot",
    "content": "# https://bitbucket.org/robotframework/webdemo/src/master/login_tests/resource.txt\nComment https://bitbucket.org/robotframework/webdemo/src/master/login_tests/resource.txt\n*** Settings ***\nDocumentation     A resource file with reusable keywords and variables.\n...\n...               The system specific keywords created here form our own\n...               domain specific language. They utilize keywords provided\n...               by the imported Selenium2Library.\nLibrary           Selenium2Library\n\n*** Variables ***\n${SERVER}         localhost:7272\n${BROWSER}        Firefox\n${DELAY}          0\n${VALID USER}     demo\n${VALID PASSWORD}    mode\n${LOGIN URL}      http://${SERVER}/\n${WELCOME URL}    http://${SERVER}/welcome.html\n${ERROR URL}      http://${SERVER}/error.html\n\n*** Keywords ***\nOpen Browser To Login Page\n    Open Browser    ${LOGIN URL}    ${BROWSER}\n    Maximize Browser Window\n    Set Selenium Speed    ${DELAY}\n    Login Page Should Be Open\n\nLogin Page Should Be Open\n    Title Should Be    Login Page\n\nGo To Login Page\n    Go To    ${LOGIN URL}\n    Login Page Should Be Open\n\nInput Username\n    [Arguments]    ${username}\n    Input Text    username_field    ${username}\n\nInput Password\n    [Arguments]    ${password}\n    Input Text    password_field    ${password}\n\nSubmit Credentials\n    Click Button    login_button\n\nWelcome Page Should Be Open\n    Location Should Be    ${WELCOME URL}\n    Title Should Be    Welcome Page\n\n"
  },
  {
    "path": "tests/inputs/robotframework.tsv",
    "content": "# https://bitbucket.org/robotframework/webdemo/src/master/login_tests/resource.txt\nComment https://bitbucket.org/robotframework/webdemo/src/master/login_tests/resource.txt\n*** Settings ***\nDocumentation     A resource file with reusable keywords and variables.\n...\n...               The system specific keywords created here form our own\n...               domain specific language. They utilize keywords provided\n...               by the imported Selenium2Library.\nLibrary           Selenium2Library\n\n*** Variables ***\n${SERVER}         localhost:7272\n${BROWSER}        Firefox\n${DELAY}          0\n${VALID USER}     demo\n${VALID PASSWORD}    mode\n${LOGIN URL}      http://${SERVER}/\n${WELCOME URL}    http://${SERVER}/welcome.html\n${ERROR URL}      http://${SERVER}/error.html\n\n*** Keywords ***\nOpen Browser To Login Page\n    Open Browser    ${LOGIN URL}    ${BROWSER}\n    Maximize Browser Window\n    Set Selenium Speed    ${DELAY}\n    Login Page Should Be Open\n\nLogin Page Should Be Open\n    Title Should Be    Login Page\n\nGo To Login Page\n    Go To    ${LOGIN URL}\n    Login Page Should Be Open\n\nInput Username\n    [Arguments]    ${username}\n    Input Text    username_field    ${username}\n\nInput Password\n    [Arguments]    ${password}\n    Input Text    password_field    ${password}\n\nSubmit Credentials\n    Click Button    login_button\n\nWelcome Page Should Be Open\n    Location Should Be    ${WELCOME URL}\n    Title Should Be    Welcome Page\n\n"
  },
  {
    "path": "tests/inputs/roku.brs",
    "content": "REM cut/paste from https://sdkdocs.roku.com/display/sdkdoc/Program+Statements#ProgramStatements-REM\nDim c[5, 4, 6]\nFor x = 1 To 5\n    For y = 1 To 4\n        For z = 1 To 6\n            c[x, y, z] = k\n            k = k + 1\n        End for\n    End for\nEnd for\n' a comment\nrem another one \nk=0\nFor x = 1 To 5\n    For y = 1 To 4\n        For z = 1 To 6\n            If c[x, y, z] <> k Then print\"error\" : Stop\n            If c[x][y][z] <> k Then print \"error\": Stop\n            k = k + 1\n        End for\n    End for\nEnd for\n"
  },
  {
    "path": "tests/inputs/rules.sss",
    "content": "// https://github.com/postcss/sugarss/raw/master/test/cases/rules.sss\na\n  b\n    color: black\n\na,\nb\n  color: black\n\na /* -> */ b // go down\nem\n  color: black\n\n/*\nfont:\n  family: serif */\n\nfont:\n  family: serif\n\n[attr=;]\n  color: black\n"
  },
  {
    "path": "tests/inputs/sample.R",
    "content": "# http://www.rexamples.com/14/Sample%28%29\nprint(sample(1:3))\nprint(sample(1:3, size=3, replace=FALSE))  # same as previous line\nprint(sample(c(2,5,3), size=4, replace=TRUE)\nprint(sample(1:2, size=10, prob=c(1,3), replace=TRUE))\n"
  },
  {
    "path": "tests/inputs/sample.bicep",
    "content": "/*\n https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/file\n */\nmetadata description = 'Creates a storage account and a web app'\n\n@description('The prefix to use for the storage account name.')\n@minLength(3)\n@maxLength(11)\nparam storagePrefix string\n\nparam storageSKU string = 'Standard_LRS'\nparam location string = resourceGroup().location\n\n    // Generate a unique name for the storage account\nvar uniqueStorageName = '${storagePrefix}${uniqueString(resourceGroup().id)}'\n\n// Create a storage account\nresource stg 'Microsoft.Storage/storageAccounts@2025-01-01' = {\n  name: uniqueStorageName\n  location: location\n  sku: {\n    name: storageSKU\n  }\n  kind: 'StorageV2'\n  properties: {\n    supportsHttpsTrafficOnly: true\n  }\n}\n\n// Deploy the web app module\nmodule webModule './webApp.bicep' = {\n  name: 'webDeploy'\n  params: {\n    skuName: 'S1'\n    location: location\n  }\n}\n"
  },
  {
    "path": "tests/inputs/sample.ejs",
    "content": "<!DOCTYPE html>\n<!--\n  This example demonstrates how to compile and render EJS templates in the\n  browser. It is usually recommended to always embed a precompiled function\n  in the HTML, rather than compile it on-the-fly, but this demonstrates that\n  it is possible.\n  To use this example, first run `jake build` in the EJS root directory to\n  produce the client-side ejs.js and ejs.min.js. Alternatively, you can\n  download the prebuilt client scripts (both minified and not) in GitHub\n  releases.\n  -->\n<html>\n  <head>\n    <script src=\"../ejs.js\"></script>\n    <!-- `type` can be anything but application/javascript -->\n    <script id=\"users\" type=\"text/template\">\n      <% if (names.length) { %>\n        <ul>\n          <% names.forEach(function(name){ %>\n            <li><%= name %></li>\n          <% }) %>\n        </ul>\n      <% } %>\n    </script>\n    <script>\n      onload = function () {\n        // get the EJS template as a string\n        var templ = document.getElementById('users').innerHTML;\n        console.log('EJS template:');\n        console.log(templ);\n        // data to output to the template function\n        var data = { names: ['loki', 'tobi', 'jane'] };\n        // stores the rendered HTML\n        var html = ejs.compile(templ)(data);\n        console.log('Rendered HTML:');\n        console.log(html);\n        // inject the rendered data to <body>\n        document.body.innerHTML = html;\n        console.log('HTML injected to <body>');\n      }\n    </script>\n  </head>\n  <body>\n  </body>\n</html>\n"
  },
  {
    "path": "tests/inputs/schema.prisma",
    "content": "// https://github.com/prisma/prisma-examples/raw/cd56a2a36e7f28d6043830c3dd78097bdf28ea2c/javascript/grpc/prisma/schema.prisma\ndatasource db {\n  provider = \"sqlite\"\n  url      = \"file:./dev.db\"\n}\n\ngenerator client {\n  provider = \"prisma-client-js\"\n}\n\nmodel Post {\n  authorId  Int?\n  content   String?\n  id        Int     @default(autoincrement()) @id\n  published Boolean @default(false)\n  title     String\n  author    User?   @relation(fields: [authorId], references: [id])\n}\n\n\nmodel User {\n  email String  @unique\n  id    Int     @default(autoincrement()) @id\n  name  String?\n  posts Post[]\n}\n\n"
  },
  {
    "path": "tests/inputs/scheme.sls",
    "content": ";;; https://www.scheme.com/tspl3/examples.html\n;;; make-matrix creates a matrix (a vector of vectors).\n(define make-matrix\n  (lambda (rows columns)\n    (do ((m (make-vector rows))\n         (i 0 (+ i 1)))\n        ((= i rows) m)\n        (vector-set! m i (make-vector columns)))))\n\n;;; matrix? checks to see if its argument is a matrix.\n;;; It isn't foolproof, but it's generally good enough.\n(define matrix?\n  (lambda (x)\n    (and (vector? x)\n         (> (vector-length x) 0)\n         (vector? (vector-ref x 0)))))\n\n;; matrix-rows returns the number of rows in a matrix.\n(define matrix-rows\n   (lambda (x)\n      (vector-length x)))\n\n;; matrix-columns returns the number of columns in a matrix.\n(define matrix-columns\n   (lambda (x)\n      (vector-length (vector-ref x 0))))\n\n;;; matrix-ref returns the jth element of the ith row.\n(define matrix-ref\n  (lambda (m i j)\n    (vector-ref (vector-ref m i) j)))\n\n;;; matrix-set! changes the jth element of the ith row.\n(define matrix-set!\n  (lambda (m i j x)\n    (vector-set! (vector-ref m i) j x)))\n\n;;; mul is the generic matrix/scalar multiplication procedure\n(define mul\n  (lambda (x y)\n    ;; mat-sca-mul multiplies a matrix by a scalar.\n    (define mat-sca-mul\n       (lambda (m x)\n          (let* ((nr (matrix-rows m))\n                 (nc (matrix-columns m))\n                 (r  (make-matrix nr nc)))\n             (do ((i 0 (+ i 1)))\n                 ((= i nr) r)\n                 (do ((j 0 (+ j 1)))\n                     ((= j nc))\n                     (matrix-set! r i j\n                        (* x (matrix-ref m i j))))))))\n\n    ;; mat-mat-mul multiplies one matrix by another, after verifying\n    ;; that the first matrix has as many columns as the second\n    ;; matrix has rows.\n    (define mat-mat-mul\n       (lambda (m1 m2)\n          (let* ((nr1 (matrix-rows m1))\n                 (nr2 (matrix-rows m2))\n                 (nc2 (matrix-columns m2))\n                 (r   (make-matrix nr1 nc2)))\n             (if (not (= (matrix-columns m1) nr2))\n                 (match-error m1 m2))\n             (do ((i 0 (+ i 1)))\n                 ((= i nr1) r)\n                 (do ((j 0 (+ j 1)))\n                     ((= j nc2))\n                     (do ((k 0 (+ k 1))\n                          (a 0\n                             (+ a\n                                (* (matrix-ref m1 i k)\n                                   (matrix-ref m2 k j)))))\n                         ((= k nr2)\n                          (matrix-set! r i j a))))))))\n\n   ;; type-error is called to complain when mul receives an invalid\n   ;; type of argument.\n    (define type-error\n       (lambda (what)\n          (error 'mul\n             \"~s is not a number or matrix\"\n             what)))\n\n    ;; match-error is called to complain when mul receives a pair of\n    ;; incompatible arguments.\n    (define match-error\n       (lambda (what1 what2)\n          (error 'mul\n             \"~s and ~s are incompatible operands\"\n             what1\n             what2)))\n\n    ;; body of mul; dispatch based on input types\n    (cond\n      ((number? x)\n       (cond\n         ((number? y) (* x y))\n         ((matrix? y) (mat-sca-mul y x))\n         (else (type-error y))))\n      ((matrix? x)\n       (cond\n         ((number? y) (mat-sca-mul x y))\n         ((matrix? y) (mat-mat-mul x y))\n         (else (type-error y))))\n      (else (type-error x)))))\n"
  },
  {
    "path": "tests/inputs/script1-hadoop.pig",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one\r\n * or more contributor license agreements.  See the NOTICE file\r\n * distributed with this work for additional information\r\n * regarding copyright ownership.  The ASF licenses this file\r\n * to you under the Apache License, Version 2.0 (the\r\n * \"License\"); you may not use this file except in compliance\r\n * with the License.  You may obtain a copy of the License at\r\n *\r\n *     http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\n-- Query Phrase Popularity (Hadoop cluster)\r\n\r\n-- This script processes a search query log file from the Excite search engine and finds search phrases that occur with particular high frequency during certain times of the day. \r\n\r\n\r\n-- Register the tutorial JAR file so that the included UDFs can be called in the script.\r\nREGISTER ./tutorial.jar;\r\n\r\n-- Use the  PigStorage function to load the excite log file into the raw bag as an array of records.\r\n-- Input: (user,time,query) \r\nraw = LOAD 'excite.log.bz2' USING PigStorage('\\t') AS (user, time, query);\r\n\r\n\r\n-- Call the NonURLDetector UDF to remove records if the query field is empty or a URL. \r\nclean1 = FILTER raw BY org.apache.pig.tutorial.NonURLDetector(query);\r\n\r\n-- Call the ToLower UDF to change the query field to lowercase. \r\nclean2 = FOREACH clean1 GENERATE user, time, org.apache.pig.tutorial.ToLower(query) as query;\r\n\r\n-- Because the log file only contains queries for a single day, we are only interested in the hour.\r\n-- The excite query log timestamp format is YYMMDDHHMMSS.\r\n-- Call the ExtractHour UDF to extract the hour (HH) from the time field.\r\nhoured = FOREACH clean2 GENERATE user, org.apache.pig.tutorial.ExtractHour(time) as hour, query;\r\n\r\n-- Call the NGramGenerator UDF to compose the n-grams of the query.\r\nngramed1 = FOREACH houred GENERATE user, hour, flatten(org.apache.pig.tutorial.NGramGenerator(query)) as ngram;\r\n\r\n-- Use the  DISTINCT command to get the unique n-grams for all records.\r\nngramed2 = DISTINCT ngramed1;\r\n\r\n-- Use the  GROUP command to group records by n-gram and hour. \r\nhour_frequency1 = GROUP ngramed2 BY (ngram, hour);\r\n\r\n-- Use the  COUNT function to get the count (occurrences) of each n-gram. \r\nhour_frequency2 = FOREACH hour_frequency1 GENERATE flatten($0), COUNT($1) as count;\r\n\r\n-- Use the  GROUP command to group records by n-gram only. \r\n-- Each group now corresponds to a distinct n-gram and has the count for each hour.\r\nuniq_frequency1 = GROUP hour_frequency2 BY group::ngram;\r\n\r\n-- For each group, identify the hour in which this n-gram is used with a particularly high frequency.\r\n-- Call the ScoreGenerator UDF to calculate a \"popularity\" score for the n-gram.\r\nuniq_frequency2 = FOREACH uniq_frequency1 GENERATE flatten($0), flatten(org.apache.pig.tutorial.ScoreGenerator($1));\r\n\r\n-- Use the  FOREACH-GENERATE command to assign names to the fields. \r\nuniq_frequency3 = FOREACH uniq_frequency2 GENERATE $1 as hour, $0 as ngram, $2 as score, $3 as count, $4 as mean;\r\n\r\n-- Use the  FILTER command to move all records with a score less than or equal to 2.0.\r\nfiltered_uniq_frequency = FILTER uniq_frequency3 BY score > 2.0;\r\n\r\n-- Use the  ORDER command to sort the remaining records by hour and score. \r\nordered_uniq_frequency = ORDER filtered_uniq_frequency BY hour, score;\r\n\r\n-- Use the  PigStorage function to store the results. \r\n-- Output: (hour, n-gram, score, count, average_counts_among_all_hours)\r\nSTORE ordered_uniq_frequency INTO 'script1-hadoop-results' USING PigStorage();\r\n"
  },
  {
    "path": "tests/inputs/sdp_parser.jspeg",
    "content": "/*\nExerpt from\n  https://github.com/StoneCypher/short_offer/raw/main/src/peg/sdp_parser.pegjs\n*/\n{\n\n\n\n  function not_null(n) {\n    return n === null? '' : n;\n  }\n\n\n\n  function ast(kind, value) {\n\n    const uses_short_nl = false; // todo\n\n    let retval = {\n      kind,\n      value,\n      uses_short_nl,\n      loc: location()\n    };\n\n    if (kind === 'standard_moz_origin') {\n      retval.moz_ver = value[0].value;\n      retval.sess    = value[1];\n      value          = '';\n    }\n\n    if (['standard_origin',\n         'standard_local_candidate',\n         'standard_guid_local_candidate',\n         'standard_guid_local_candidate_ffus',\n         'standard_remote_candidate',\n         'standard_remote_candidate_ffus',\n         'standard_agen_tcp_candidate',\n         'standard_agen_tcp6_candidate',\n         'standard_agen_udp4_candidate',\n         'standard_agen_udp6_host_candidate'\n        ].includes(kind)) {\n      retval.items = value;\n      retval.value = '';\n    }\n\n    return retval;\n\n  }\n\n\n\n}\n\n// truncated\n"
  },
  {
    "path": "tests/inputs/sdp_parser.peg",
    "content": "/*\nExerpt from\n  https://github.com/StoneCypher/short_offer/raw/main/src/peg/sdp_parser.pegjs\n*/\n\n\nAIceUFrag8\n  = 'a=ice-ufrag:' data:IceChar8 CapAtSeparator\n  { return ast('a_ice_ufrag_8', data); }\n\n\n\nAFingerprint\n  = 'a=fingerprint:sha-256 ' data:CHex64 CapAtSeparator\n  { return ast('a_fingerprint_sha1_256', data); }\n\n\n\nAGroupBundle0\n  = 'a=group:BUNDLE 0' CapAtSeparator\n  { return ast('a_group_bundle_0'); }\n\n\n\nCClaimIp4\n  = 'c=IN IP4 ' data:IP4 CapAtSeparator\n  { return ast('c_claim_ip4', data); }\n\n\n\nStandardMApplication\n  = 'm=application ' data:Decimal ' UDP/DTLS/SCTP webrtc-datachannel' CapAtSeparator\n  { return ast('standard_m_application', data); }\n\n\n\nUnknownRule\n  = us:UntilSeparator\n  { return ast('unknown_line', us); }\n\n\n\nUntilSeparator\n  = rl:[^'\\r\\n']* '\\r\\n'\n  { return rl.join(''); }\n\n            /*\n\nCapAtSeparator\n  = '\\r\\n'\n\n            */\n\n// UnknownTerminatingString\n  = uts:.* { return ast( 'unknown_terminate', uts.join('') ); }\n"
  },
  {
    "path": "tests/inputs/sdp_parser.peggy",
    "content": "/*\nExerpt from\n  https://github.com/StoneCypher/short_offer/raw/main/src/peg/sdp_parser.pegjs\n*/\n\n\n\nRawDocument\n  = Offer\n  / Answer\n  / UnknownTerminatingString         // junk\n\n\n\nDigit\n  = [0-9]\n\n\n\n// Decimal\n//   = d:Digit+ { return BigInt(d.join(''), 10); }\n\n\n\nHex\n  = [0-9a-fA-F]\n\n\n\nHex2\n  = a:Hex b:Hex { return `${a}${b}`; }\n\n\n\nHex4\n  = a:Hex b:Hex c:Hex d:Hex\n  { return [a,b,c,d].join(''); }\n\n\n\nHex8\n  = a:Hex b:Hex c:Hex d:Hex e:Hex f:Hex g:Hex h:Hex\n  { return [a,b,c,d,e,f,g,h].join(''); }\n\n\n\nHex12\n  = a:Hex b:Hex c:Hex d:Hex e:Hex f:Hex g:Hex h:Hex i:Hex j:Hex k:Hex l:Hex\n  { return [a,b,c,d,e,f,g,h,i,j,k,l].join(''); }\n\n// truncated\n"
  },
  {
    "path": "tests/inputs/sdp_parser.pegjs",
    "content": "/*\nExerpt from\n  https://github.com/StoneCypher/short_offer/raw/main/src/peg/sdp_parser.pegjs\n*/\n\n\nCHex64\n  = a:Hex2 ':' b:Hex2 ':' c:Hex2 ':' d:Hex2 ':' e:Hex2 ':' f:Hex2 ':' g:Hex2 ':' h:Hex2 ':'\n    i:Hex2 ':' j:Hex2 ':' k:Hex2 ':' l:Hex2 ':' m:Hex2 ':' n:Hex2 ':' o:Hex2 ':' p:Hex2 ':'\n    q:Hex2 ':' r:Hex2 ':' s:Hex2 ':' t:Hex2 ':' u:Hex2 ':' v:Hex2 ':' w:Hex2 ':' x:Hex2 ':'\n    y:Hex2 ':' z:Hex2 ':' A:Hex2 ':' B:Hex2 ':' C:Hex2 ':' D:Hex2 ':' E:Hex2 ':' F:Hex2\n  { return [ a,b,c,d,e,f,g,h, i,j,k,l,m,n,o,p, q,r,s,t,u,v,w,x, y,z,A,B,C,D,E,F ].join(''); }\n\n\n\nIceChar\n  = [0-9a-zA-Z/+]\n\n\n\nIceChar4\n  = a:IceChar b:IceChar c:IceChar d:IceChar\n  { return [a,b,c,d].join(''); }\n\n\n\nIceChar8\n  = a:IceChar b:IceChar c:IceChar d:IceChar e:IceChar f:IceChar\n    g:IceChar h:IceChar\n  { return [a,b,c,d,e,f,g,h].join(''); }\n\n\n\nIceChar22\n  = a:IceChar b:IceChar // c:IceChar d:IceChar e:IceChar f:IceChar\n    g:IceChar h:IceChar // i:IceChar j:IceChar k:IceChar l:IceChar\n    m:IceChar n:IceChar // o:IceChar p:IceChar q:IceChar r:IceChar\n    s:IceChar t:IceChar // u:IceChar v:IceChar\n  { return [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v].join(''); }\n\n\n\n// IceChar24\n//   = a:IceChar b:IceChar c:IceChar d:IceChar e:IceChar f:IceChar\n//     g:IceChar h:IceChar i:IceChar j:IceChar k:IceChar l:IceChar\n//     m:IceChar n:IceChar o:IceChar p:IceChar q:IceChar r:IceChar\n    s:IceChar t:IceChar u:IceChar v:IceChar w:IceChar x:IceChar\n  { return [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x].join(''); }\n\n// truncated\n"
  },
  {
    "path": "tests/inputs/sdp_parser.tspeg",
    "content": "/*\nExerpt from\n  https://github.com/StoneCypher/short_offer/raw/main/src/peg/sdp_parser.pegjs\n*/\n\nIceChar24\n  = a:IceChar b:IceChar c:IceChar d:IceChar e:IceChar f:IceChar\n    g:IceChar h:IceChar i:IceChar j:IceChar k:IceChar l:IceChar\n    m:IceChar n:IceChar o:IceChar p:IceChar q:IceChar r:IceChar\n    s:IceChar t:IceChar u:IceChar v:IceChar w:IceChar x:IceChar\n  { return [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x].join(''); }\n\n\n\nIceChar32\n  = a:IceChar  b:IceChar  c:IceChar  d:IceChar  e:IceChar  f:IceChar\n    g:IceChar  h:IceChar  i:IceChar  j:IceChar  k:IceChar  l:IceChar\n    m:IceChar  n:IceChar  o:IceChar  p:IceChar  q:IceChar  r:IceChar\n    s:IceChar  t:IceChar  u:IceChar  v:IceChar  w:IceChar  x:IceChar\n    y:IceChar  z:IceChar  aa:IceChar ab:IceChar ac:IceChar ad:IceChar\n    ae:IceChar af:IceChar\n  { return [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,ab,ac,ad,ae,af].join(''); }\n\n// \n// \n// GUID\n//   = a:Hex8 '-' b:Hex4 '-' c:Hex4 '-' d:Hex4 '-' e:Hex12\n//   { return [a,b,c,d,e].join(''); }\n// \n// \n// \n// IP4\n//   = a:Decimal '.' b:Decimal '.' c:Decimal '.' d:Decimal\n//   { return ((((( (a*256n) +b) *256n) +c) *256n) +d).toString(); }\n// \n// \n// \nM_h16\n  = d:(\":\" h16) { return `:${d[1]}`; }\n\n\n\n/* cribbed from https://git.insoft.cz/insoft/modified-sip.js/-/blob/3081a21bd47215679f7f1dac8c771ae6f3d7193b/src/grammar/src/grammar.pegjs\nIP6\n  = a:h16 \":\" b:h16 \":\" c:h16 \":\" d:h16 \":\" e:h16 \":\" f:h16 \":\" g:ls32 { return `${a}:${b}:${c}:${d}:${e}:${f}:${g}`; }\n  /      \"::\" b:h16 \":\" c:h16 \":\" d:h16 \":\" e:h16 \":\" f:h16 \":\" g:ls32 { return `::${b}:${c}:${d}:${e}:${f}:${g}`; }\n  /      \"::\" b:h16 \":\" c:h16 \":\" d:h16 \":\" e:h16 \":\" f:ls32           { return `::${b}:${c}:${d}:${e}:${f}`; }\n  /      \"::\" b:h16 \":\" c:h16 \":\" d:h16 \":\" e:ls32                     { return `::${b}:${c}:${d}:${e}`; }\n  /      \"::\" b:h16 \":\" c:h16 \":\" d:ls32                               { return `::${b}:${c}:${d}`; }\n */      \"::\" b:h16 \":\" c:ls32                                         { return `::${b}:${c}`; }\n  /      \"::\" b:ls32                                                   { return `::${b}`; }\n  /      \"::\" b:h16                                                    { return `::${b}`; }\n\n\n  // truncated\n"
  },
  {
    "path": "tests/inputs/send_msg.applescript",
    "content": "(*\nhttps://code.tutsplus.com/the-ultimate-beginners-guide-to-applescript--mac-3436t\n*)\n-- Variables\nset recipientName to \"John Doe\"\nset recipientAddress to \"nobody@nowhere.com\"\nset theSubject to \"AppleScript Automated Email\"\nset theContent to \"This email was created and sent using AppleScript!\"\n\n--Mail Tell Block\ntell application \"Mail\"\n\n--Create the message\nset theMessage to make new outgoing message with properties {subject:theSubject, content:theContent, visible:true}\n\n--Set a recipient\ntell theMessage\nmake new to recipient with properties {name:recipientName, address:recipientAddress}\n\n--Send the Message\nsend\n\nend tell\nend tell\n"
  },
  {
    "path": "tests/inputs/server_side.aspx",
    "content": "<!--\nhttps://www.tutorialspoint.com/asp.net/asp.net_first_example.htm\n -->\n<!-- directives -->\n<% @Page Language=\"C#\" %>\n\n<!-- code section -->\n<script runat=\"server\">\n\n   private void convertoupper(object sender, EventArgs e)\n   {\n      string str = mytext.Value;\n      changed_text.InnerHtml = str.ToUpper();\n   }\n</script>\n\n<!-- Layout -->\n<html>\n   <head> \n      <title> Change to Upper Case </title> \n   </head>\n   \n   <body>\n      <h3> Conversion to Upper Case </h3>\n      \n     <%--\n      <form runat=\"server\">\n         <input runat=\"server\" id=\"mytext\" type=\"text\" />\n         <input runat=\"server\" id=\"button1\" type=\"submit\" value=\"Enter...\" OnServerClick=\"convertoupper\"/>\n         \n         <hr />\n         <h3> Results: </h3>\n         <span runat=\"server\" id=\"changed_text\" />\n      </form>\n       --%>\n      \n   </body>\n   \n</html>\n"
  },
  {
    "path": "tests/inputs/sharpsign.cl",
    "content": ";;; In this example, some debugging code is commented out with #|...|#\n;;; Note that this kind of comment can occur in the middle of a line\n;;; (because a delimiter marks where the end of the comment occurs)\n;;; where a semicolon comment can only occur at the end of a line \n;;; (because it comments out the rest of the line).\n (defun add3 (n) #|(format t \"~&Adding 3 to ~D.\" n)|# (+ n 3))\n\n;;; The examples that follow show issues related to #| ... |# nesting.\n\n;;; In this first example, #| and |# always occur properly paired,\n;;; so nesting works naturally.\n (defun mention-fun-fact-1a ()\n   (format t \"CL uses ; and #|...|# in comments.\"))\n=>  MENTION-FUN-FACT-1A\n (mention-fun-fact-1a)\n>>  CL uses ; and #|...|# in comments.\n=>  NIL\n #| (defun mention-fun-fact-1b ()\n      (format t \"CL uses ; and #|...|# in comments.\")) |#\n (fboundp 'mention-fun-fact-1b) =>  NIL\n\n;;; In this example, vertical-bar followed by sharpsign needed to appear\n;;; in a string without any matching sharpsign followed by vertical-bar\n;;; having preceded this.  To compensate, the programmer has included a\n;;; slash separating the two characters.  In case 2a, the slash is \n;;; unnecessary but harmless, but in case 2b, the slash is critical to\n;;; allowing the outer #| ... |# pair match.  If the slash were not present,\n;;; the outer comment would terminate prematurely.\n (defun mention-fun-fact-2a ()\n   (format t \"Don't use |\\# unmatched or you'll get in trouble!\"))\n=>  MENTION-FUN-FACT-2A\n (mention-fun-fact-2a)\n>>  Don't use |# unmatched or you'll get in trouble!\n=>  NIL\n #| (defun mention-fun-fact-2b ()\n      (format t \"Don't use |\\# unmatched or you'll get in trouble!\") |#\n (fboundp 'mention-fun-fact-2b) =>  NIL\n\n;;; In this example, the programmer attacks the mismatch problem in a\n;;; different way.  The sharpsign vertical bar in the comment is not needed\n;;; for the correct parsing of the program normally (as in case 3a), but \n;;; becomes important to avoid premature termination of a comment when such \n;;; a program is commented out (as in case 3b).\n (defun mention-fun-fact-3a () ; #|\n   (format t \"Don't use |# unmatched or you'll get in trouble!\"))\n=>  MENTION-FUN-FACT-3A\n (mention-fun-fact-3a)\n>>  Don't use |# unmatched or you'll get in trouble!\n=>  NIL\n #|\n (defun mention-fun-fact-3b () ; #|\n   (format t \"Don't use |# unmatched or you'll get in trouble!\"))\n |#\n (fboundp 'mention-fun-fact-3b) =>  NIL\n\n"
  },
  {
    "path": "tests/inputs/slug.astro",
    "content": "---\nimport { API, useAPI } from \"../../../lib/hooks/useAPI.astro\";\nimport Spinner from \"../../components/other/Spinner.astro\";\nimport Layout from \"../../layouts/Layout.astro\";\n\nconst announcement_title = (Astro.url.pathname.split(\"/\").pop() as string).replace(/-/g, \" \");\nlet announcement: ({ id: number; title: string; date: number; content: string; views: number } & { images: string[] }) | undefined;\ntry {\n\tconst res_announcement = await useAPI(API.Announcements.getByTitle, { UrlArgs: { title: announcement_title } });\n\tannouncement = res_announcement.data;\n\tif (!announcement) return Astro.redirect(\"/404\");\n} catch (e) {\n\treturn Astro.redirect(\"/404\");\n}\nconst imgSrc = \"/anakoinoseis/images/\" + announcement.id + \"/\";\nconst imgThumbSrc = \"/anakoinoseis/images/\" + announcement.id + \"/thumb_\";\n---\n\n<Layout title={announcement.title} imageUrl={announcement.images[0]}>\n\t<section class=\"relative flex flex-col p-12 max-sm:p-4 overflow-auto items-center gap-y-6\">\n\t\t<h1\n\t\t\tclass=\"heading w-[25ch] max-sm:w-[25ch] text-5xl max-sm:text-3xl text-center font-bold text-red-900 font-anaktoria drop-shadow-[-1px_2px_1px_rgba(0,0,0,0.25)]\"\n\t\t>\n\t\t\t{announcement.title}\n\t\t</h1>\n\t\t<div class=\"max-w-[720px] h-[360px] shadow-lg shadow-slate-800\">\n\t\t\t<img src={imgSrc + announcement.images[1]} alt={announcement?.title as string} class=\"w-[720px] object-cover h-full\" />\n\t\t</div>\n\t\t<div class=\"text-xl mt-4 self-start\">\n\t\t\t{announcement.content}\n\t\t</div>\n\t\t<div id=\"imgContainer\" class=\"flex items-center\">\n\t\t\t<div class=\"flex flex-row flex-wrap mt-4 gap-y-6 loading items-center justify-evenly self-center\">\n\t\t\t\t{\n\t\t\t\t\tannouncement.images.map((image, i) => (\n\t\t\t\t\t\t<div class=\"imgLoader group/img\">\n\t\t\t\t\t\t\t<div class=\"hidden group-[:is(.loading)]/img:block w-[320px] h-[240px] \">\n\t\t\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div class=\"hidden group-[:is(.loaded)]/img:block max-w-[320px] h-[240px] transition-shadow hover:shadow-lg !shadow-slate-800\">\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tdata-src={imgThumbSrc + image}\n\t\t\t\t\t\t\t\t\talt={announcement?.title as string}\n\t\t\t\t\t\t\t\t\tclass=\"w-[400px] object-cover h-full\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t))\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</section>\n\t<!-- <div id=\"imageCarouselContainer\" class=\"fixed inset-0 bg-[rgba(40,10,10,0.4)] backdrop-blur-[3px] grid place-content-center\">\n\t\t<div\n\t\t\tid=\"controlsContainer\"\n\t\t\tclass=\"grid grid-cols-[max-content,1fr,max-content] justify-center items-center p-8 bg-[rgba(40,10,10,0.75)] rounded-md shadow-lg shadow-[rgba(40,10,10,1)] backdrop-blur-[3px]\"\n\t\t>\n\t\t\t<i class=\"pr-8 fa-solid fa-chevron-left font-bold text-2xl text-white max-sm:text-xs max-sm:px-2 max-3xs:text-xs\"></i>\n\t\t\t<div id=\"imageCarousel\" data-index=\"0\">\n\t\t\t\t<div class=\"imgLoader group/img\">\n\t\t\t\t\t<div class=\"hidden group-[:is(.loading)]/img:block w-[320px] h-[240px]\">\n\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"hidden group-[:is(.loaded)]/img:block max-w-[320px] h-[240px] transition-shadow hover:shadow-lg !shadow-slate-800\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<img alt={announcement.title} class=\"w-[400px] object-cover h-full\" />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div id=\"thumbContainer\" class=\"flex flex-row pt-8\">\n\t\t\t\t\t<img alt={announcement.title}/>\n\t\t\t\t\t<img alt={announcement.title}/>\n\t\t\t\t\t<img alt={announcement.title}/>\n\t\t\t\t\t<img alt={announcement.title}/>\n\t\t\t\t\t<img alt={announcement.title}/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<i class=\"pl-8 fa-solid fa-chevron-right font-bold text-2xl text-white max-sm:text-xs max-sm:px-2 max-3xs:text-xs\"></i>\n\t\t</div>\n\t</div> -->\n</Layout>\n<script>\n\timport { onElementMount, asyncQueue, sleep } from \"../../../lib/utils.client\";\n\tonElementMount(\"#imgContainer\", async el => {\n\t\tconst imgs = [...el.querySelectorAll(\"img\")];\n\t\tconst imgContainers = [...el.querySelectorAll(\".imgLoader\")];\n\t\tconst jobs = imgs.map((img, i) => async () => {\n\t\t\tlet loaded = false;\n\t\t\timgContainers[i].classList.add(\"loading\");\n\t\t\timg.addEventListener(\"load\", () => {\n\t\t\t\tloaded = true;\n\t\t\t\timgContainers[i].classList.remove(\"loading\");\n\t\t\t\timgContainers[i].classList.add(\"loaded\");\n\t\t\t});\n\t\t\timg.src = img.dataset.src as string;\n\t\t\twhile (!loaded) {\n\t\t\t\tawait sleep(20);\n\t\t\t}\n\t\t});\n\t\tawait asyncQueue(jobs, 5);\n\t});\n</script>\n"
  },
  {
    "path": "tests/inputs/solidity.sol",
    "content": "// https://ethereumbuilders.gitbooks.io/guide/content/en/solidity_tutorials.html\nct Coin {\n    address minter;\n    mapping (address => uint) balances;\n    function Coin() {\n        minter = msg.sender;\n    }\n    function mint(address owner, uint amount) {\n        if (msg.sender != minter) return;\n        balances[owner] += amount;\n    } /*\na comment */\n    function send(address receiver, uint amount) {\n        if (balances[msg.sender] < amount) return;\n        balances[msg.sender] -= amount;\n        balances[receiver] += amount;\n    }\n    function queryBalance(address addr) constant returns (uint balance) {\n        return balances[addr];\n    }\n}\n"
  },
  {
    "path": "tests/inputs/specman_e.e",
    "content": "this text is ignored\nhttp://www.asic-world.com/code/specman_examples/mem_op_monitor.e\n<'\nstruct mem_op_monitor {\n  mem_object : mem_base_object;\n  mem_scoreboard : mem_scoreboard;\n  -- event clk is fall('memory_tb.clk') @sim;\n\n  output_monitor()@clk is {\n    while (TRUE) {\n    /*\n      wait cycle;\n      if (('memory_tb.chip_en' == 1) && ('memory_tb.read_write' == 0)) {\n    */\n         outf(\"Output_monitor : Detected memory read access-> Address : %x   Data : %x\\n\", 'memory_tb.address','memory_tb.data_out');\n\t// mem_object.addr = 'memory_tb.address';\n\t mem_object.data = 'memory_tb.data_out';  -- more comment\n         mem_scoreboard.post_output(mem_object);\n      };\n    };\n  };\n};\n'>\nmore text that should\nbe ignored\n<'\n a = 5 // this is more code\n'>\n"
  },
  {
    "path": "tests/inputs/specman_e2.e",
    "content": "<'\n// All components should have their own package.\npackage foo_mon;\n\nunit foo_mon_u {\n\n    check() is also {\n        if (CFG[ooo].foo_test_record_en) {\n            // Following line has code segment delimiter sneakily hidden away\n            // The usage model is \"writing e code from an e module\"\n            writef(static, \"        TEST_START \\\"chk\\\";\\n    };\\n};\\n'>\");\n            this_is_not_a_comment();\n            // Following line has code segment delimiter sneakily hidden away\n            writef(static, \"        TEST_DONE \\\"chk\\\";\\n    };\\n};\\n<'\");\n        };\n    };\n\n};\n'>\n"
  },
  {
    "path": "tests/inputs/squirrel_table.nut",
    "content": "/*\n http://www.squirrel-lang.org/\n*/\nlocal table = {\n\ta = \"10\"\n\tsubtable = {\n\t\tarray = [1,2,3]\n\t},\n\t[10 + 123] = \"expression index\"\n}\n \nlocal array=[ 1, 2, 3, { a = 10, b = \"string\" } ];\n \nforeach (i,val in array)\n{\n\t::print(\"the type of val is\"+typeof val);\n}\n \n/////////////////////////////////////////////\n \nclass Entity\n{\t\n\tconstructor(etype,entityname)\n\t{\n\t\tname = entityname;\n\t\ttype = etype;\n\t}\n\t\t\t\t\t\t\t\t\t\n\tx = 0;\n\ty = 0;\n\tz = 0;\n\tname = null;\n\ttype = null;\n}\n \nfunction Entity::MoveTo(newx,newy,newz)\n{\n\tx = newx;\n\ty = newy;\n\tz = newz;\n}\n"
  },
  {
    "path": "tests/inputs/stata.do",
    "content": "// A Quick Tour of Stata\n// Germán Rodríguez - Fall 2015\n/*\n http://data.princeton.edu/stata/\n*/\n\nversion 14\nclear\ncapture log close\nlog using QuickTour, text replace\n\ndisplay 2+2\ndisplay 2 * ttail(20,2.1)\n\n// load sample data and inspect\nsysuse lifeexp\ndesc\nsummarize lexp gnppc\nlist country gnppc if missing(gnppc)\n\ngraph twoway scatter lexp gnppc, ///\n  title(Life Expectancy and GNP ) xtitle(GNP per capita)\n// save the graph in PNG format\ngraph export scatter.png, width(400) replace\t\ngen loggnppc = log(gnppc)\nregress lexp loggnppc\n\npredict plexp\n\ngraph twoway (scatter lexp loggnppc) (lfit lexp loggnppc) ///\n\t,  title(Life Expectancy and GNP) xtitle(log GNP per capita)\ngraph export fit.png, width(400) replace\n\nlist country lexp plexp if lexp < 55, clean\nlist gnppc loggnppc lexp plexp if country == \"United States\", clean\nlog close\n"
  },
  {
    "path": "tests/inputs/statcsv.nim",
    "content": "# https://github.com/nim-lang/Nim/blob/devel/examples/statcsv.nim\n# Example program to show the parsecsv module\n# This program reads a CSV file and computes sum, mean, minimum, maximum and\n# the standard deviation of its columns.\n# The CSV file can have a header which is then used for the output.\n\nimport os, streams, parsecsv, strutils, math, stats\n\nif paramCount() < 1:\n  quit(\"Usage: statcsv filename[.csv]\")\n\nvar filename = addFileExt(paramStr(1), \"csv\")\nvar s = newFileStream(filename, fmRead)\nif s == nil: quit(\"cannot open the file \" & filename)\n\nvar\n  x: CsvParser\n  header: seq[string]\n  res: seq[RunningStat]\nopen(x, s, filename, separator=';', skipInitialSpace = true)\nwhile readRow(x):\n  if processedRows(x) == 1:\n    newSeq(res, x.row.len) # allocate space for the result\n    if validIdentifier(x.row[0]):\n      # header line:\n      header = x.row\n    else:\n      newSeq(header, x.row.len)\n      for i in 0..x.row.len-1: header[i] = \"Col \" & $(i+1)\n  else:\n    # data line:\n    for i in 0..x.row.len-1:\n      push(res[i], parseFloat(x.row[i]))\nx.close()\n\n# Write results:\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(header[i])\nstdout.write(\"\\nSum\")\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(res[i].sum)\nstdout.write(\"\\nMean\")\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(res[i].mean)\n#[\nstdout.write(\"\\nMin\")\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(res[i].min) ]#\nstdout.write(\"\\nMax\")\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(res[i].max)\nstdout.write(\"\\nStdDev\")\nfor i in 0..header.len-1:\n  stdout.write(\"\\t\")\n  stdout.write(res[i].standardDeviation)\nstdout.write(\"\\n\")\n"
  },
  {
    "path": "tests/inputs/streamlines.pro",
    "content": "; http://www.harrisgeospatial.com/docs/streamlines.html\n\n; Read the data.\n\nRESTORE, FILEPATH('globalwinds.dat', SUBDIR=['examples','data'])\n\n \n\n; Set up the map projection, grid, and continents.\n\nmap = MAP('Equirectangular', POSITION=[0.1,0.1,0.9,0.9], $\n\n    LIMIT=[0,-160,80,-50], TITLE='Wind Streamlines')\n\n \n\n; Change some map grid properties.\n\ngrid = map.MAPGRID\n\ngrid.LINESTYLE = \"dotted\"\n\ngrid.ANTIALIAS = 0\n\ngrid.LABEL_POSITION = 0\n\ngrid.LABEL_ANGLE = 0\n\ngrid.FONT_SIZE=11\n\n \n\ncont = MAPCONTINENTS(FILL_COLOR=\"light gray\")\n\n \n\n; Display the streamlines on top of the map.\n\nstream = STREAMLINE(u, v, x, y, /OVERPLOT, $\n\n    STREAMLINE_STEPSIZE=0.05, $\n\n   RGB_TABLE=33, AUTO_COLOR=1, THICK=5)\n"
  },
  {
    "path": "tests/inputs/string.gleam",
    "content": "// https://github.com/gleam-lang/stdlib/raw/main/src/gleam/string.gleam\n//// Strings in Gleam are UTF-8 binaries. They can be written in your code a\n//// text surrounded by `\"double quotes\"`.\n\nimport gleam/string_builder\nimport gleam/dynamic.{Dynamic}\nimport gleam/iterator\nimport gleam/list\nimport gleam/order\nimport gleam/result\n\npub type String =\n  String\n\n/// A UtfCodepoint is the integer representation of a valid UTF codepoint\npub type UtfCodepoint =\n  UtfCodepoint\n\n/// Determine if a string is empty.\n///\n/// ## Examples\n///\n///    > is_empty(\"\")\n///    True\n///\n///    > is_empty(\"the world\")\n///    False\n///\npub fn is_empty(str: String) -> Bool {\n  str == \"\"\n}\n\n/// Get the number of grapheme clusters in a given string.\n///\n/// This function has to iterate across the whole string to count the number of\n/// graphemes, so it runs in linear time.\n///\n/// ## Examples\n///\n///    > length(\"Gleam\")\n///    5\n///\n///    > length(\"ß↑e̊\")\n///    3\n///\n///    > length(\"\")\n///    0\n///\npub external fn length(String) -> Int =\n  \"string\" \"length\"\n\n///\n/// Reverse a string.\n///\n/// This function has to iterate across the whole string so it runs in linear\n/// time.\n///\n/// ## Examples\n///\n///    > reverse(\"stressed\")\n///    \"desserts\"\n///\npub fn reverse(string: String) -> String {\n  string\n  |> string_builder.from_string\n  |> string_builder.reverse\n  |> string_builder.to_string\n}\n"
  },
  {
    "path": "tests/inputs/style.scss",
    "content": "\n\n/* style.scss */\n\n#navbar {\n  width: 80%;\n  height: 23px;\n\n  ul { list-style-type: none; }\n  li {\n    float: left;\n    a { font-weight: bold; }\n  }\n}\n\n\n/* style.scss */\n\n.fakeshadow {\n  border: {\n    style: solid;\n    left: {\n      width: 4px;\n      color: #888;\n    }\n    right: {\n      width: 2px;\n      color: #ccc;\n    }\n  }\n}\n/* style.scss */\n\n$main-color: #ce4dd6;\n$style: solid;\n\n#navbar {\n  border-bottom: {\n    color: $main-color;\n    style: $style;\n  }\n}\n\na {\n  color: $main-color;\n  &:hover { border-bottom: $style 1px; }\n}\n\n\n/* style.scss */\n\na {\n  color: #ce4dd6;\n  &:hover { color: #ffb3ff; }\n  &:visited { color: #c458cb; }\n}\n\n"
  },
  {
    "path": "tests/inputs/swig_example.i",
    "content": "// http://www.swig.org/tutorial.html\n/* File : \n   example.c \n */\n \n #include <time.h>\n double My_variable = 3.0;\n \n int fact(int n) {\n     if (n <= 1) return 1;\n     else return n*fact(n-1);\n }\n \n int my_mod(int x, int y) {\n     return (x%y);\n }\n \t\n char *get_time()\n {\n     time_t ltime;\n     time(&ltime);\n     return ctime(&ltime);\n }\n"
  },
  {
    "path": "tests/inputs/temp.c",
    "content": "\n\nmain() {\n int i;\n}\n"
  },
  {
    "path": "tests/inputs/templ_example.templ",
    "content": "package test \n\nimport \"time\"\n\n// Line comment\n\n/*\nmulti\nline\ncomment\n*/\n\ntempl templ_function() {\n    <div>A div</div>\n    // <div>A commented div</div>\n    /* <div>A multiline commented div </div> */\n}\n\nfunc golang_function() {\n    a := 5\n    // a = 6\n    /* \n    a = 7\n    */\n}\n"
  },
  {
    "path": "tests/inputs/test.Dsr",
    "content": "VERSION 1.0 CLASS\nBEGIN\n  MultiUse = -1  'True\n  Persistable = 0  'NotPersistable\n  DataBindingBehavior = 0  'vbNone\n  DataSourceBehavior  = 0  'vbNone\n  MTSTransactionMode  = 0  'NotAnMTSObject\nEND\nAttribute VB_Name = \"TestClass\"\nAttribute VB_GlobalNameSpace = False\n\n' This is a comment in a Dsr file\nOption Explicit\n\nPublic Sub TestMethod()\n    ' Method implementation\n    Dim x As Integer\n    x = 42\n    Debug.Print \"Value: \" & x\nEnd Sub"
  },
  {
    "path": "tests/inputs/test.Rmd",
    "content": "---\ntitle: \"Untitled\"\nauthor: \"cloc test\"\ndate: \"5/12/2018\"\noutput: html_document\n---\n\n```{r setup, include=FALSE}\nknitr::opts_chunk$set(echo = TRUE)\n```\n\n## R Markdown\n\nThis is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.\n\nWhen you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:\n\n```{r cars}\nsummary(cars)\n# summary(cars)\n```\n\n## Including Plots\n\nYou can also embed plots, for example:\n\n```{r pressure, echo=FALSE}\nplot(pressure)\n\nplot(cars)\n```\n\nNote that the `echo = FALSE` parameter was added to the code chunk to prevent printing of the R code that generated the plot.\n"
  },
  {
    "path": "tests/inputs/test.hs",
    "content": "\n-- This literate program prompts the user for a number\n-- and prints the factorial of that number:\n\n{- This is a comment. -}\n{- This is a comment,\n   too -}\n\n{-# this is a pragma, COUNT IT -}\n\n main :: IO ()\n main = do putStr \"Enter a number: \"\n           l <- readLine\n           putStr \"n!= \"\n           print (fact (read l))\n fact :: Integer -> Integer\n fact 0 = 1\n fact n = n * fact (n-1)\n\n"
  },
  {
    "path": "tests/inputs/test.rego",
    "content": "package example.policy\n\nimport future.keywords.every\n\ndefault valid := false # unless otherwise defined, valid is false\n\nvalid if { # valid is true if...\n\tcount(violation) == 0 # there are zero violations.\n}\n\nviolation contains msg if { # violation is true if...\n    some i in input {\n        # every item in input must have a \"name\" field\n        not input[i].name;\n        msg := sprintf(\"Item %d is missing a 'name' field\", [i])\n    }\n}\n\nviolation contains msg if { # violation is true if...\n    some i in input {\n        # every item in input must have a numeric \"value\" field\n        not input[i].value || not is_number(input[i].value);\n        msg := sprintf(\"Item %d is missing a numeric 'value' field\", [i])\n    }\n}"
  },
  {
    "path": "tests/inputs/test.vbhtml",
    "content": "@{\n    ' VB.NET code in a vbhtml file\n    ViewBag.Title = \"Test Page\"\n    Dim message As String = \"Hello from VB.NET\"\n}\n\n<!DOCTYPE html>\n<html>\n<head>\n    <title>@ViewBag.Title</title>\n</head>\n<body>\n    <h1>@message</h1>\n    @If True Then\n        @<p>This is a VB.NET HTML template</p>\n    End If\n</body>\n</html>"
  },
  {
    "path": "tests/inputs/test.vbs",
    "content": "' VBScript test file\n' This is a comment\nDim greeting\ngreeting = \"Hello, World!\"\nWScript.Echo greeting\n\n' Another comment\nIf 1 = 1 Then\n    WScript.Echo \"True\"\nEnd If"
  },
  {
    "path": "tests/inputs/test1.inc",
    "content": "<?php\n\n  /**\n  * Test file for php_count, part of SLOCCount.  This is a C-style comment.\n  * This file is different from .php.\n  */\n\n  // This is a C++-style comment.\n\n  # This is a shell-style comment.\n\n  # Here are 9 lines of code:\n\n  function get()\n  {\n    $total = 0;\n    $simplestring = 'hello';\n    $simplestring = '\\\\hello\\'';\n    $funkystring = \"hello\";\n    $funkystring = \"$hi\\\\\\\"\";\n    return 0;\n  }\n?>\n"
  },
  {
    "path": "tests/inputs/test1.lhs",
    "content": "\\documentstyle{article}\n\n\\begin{document}\n\n\\section{Introduction}\n\nThis is a trivial program that prints the first 20\nfactorials.  It should have 2 lines of code.\n\n\\begin{code}\nmain :: IO ()\nmain =  print [ (n, product [1..n]) | n <- [1..20]]\n\\end{code}\n\n\\end{document}\n"
  },
  {
    "path": "tests/inputs/test1.php",
    "content": "<?php\n\n  /**\n  * Test file for php_count, part of SLOCCount.  This is a C-style comment.\n  */\n\n  // This is a C++-style comment.\n\n  # This is a shell-style comment.\n\n  # Here are 13 lines of code:\n\n  function get()\n  {\n    $total = 0;\n    $simplestring = 'hello';\n    $simplestring = '\\\\hello\\'';\n    $funkystring = \"hello\";\n    $funkystring = \"$hi\\\\\\\"\";\n    $heretest <<<  wiggle\njuggle\n   wiggle  /* This doesn't end the string, so this isn't a C comment.\nwiggle;\n    return 0;\n  }\n\n?>\n"
  },
  {
    "path": "tests/inputs/test2.lhs",
    "content": "\nThis is an extract of a larger literate Haskell file for testing\nSLOCCount.  It should have 21 lines of code.\n\nThis dumps the tree in dot format, which is very handy for visualizing\nthe trees.\n\n> dotTree name t = \"digraph \" ++ filter dotChars name ++ \" { \" ++ (dotTree' t 0) ++ \" }\"\n\n> dotTree' Empty _ = \"\"\n> dotTree' t i | is_leaf t = \"n\"++(show i)++\" [label=\\\"\"++(show $ x_span t)++\n>                            \"\\\",shape=box]; \"\n>              | otherwise = \"n\"++(show i)++\" [label=\\\"\"++(show $ x_span t)++\"\\\"]; \" ++\n>\t\t\t     \"n\"++(show i)++\" -> n\"++(show (2*i+1))++\"; \"++\n>                            \"n\"++(show i)++\" -> n\"++(show (2*i+2))++\"; \"++\n>                            dotTree' (left t) (2*i+1) ++\n>                            dotTree' (right t) (2*i+2)\n>   where is_leaf Node { left = Empty, right = Empty } = True\n>         is_leaf _ = False\n> {- this is a comment\n\nfoo bar baz\n\n>    that\n>    spans literate blocks -}\n\n> dotChars '.' = False\n> dotChars '/' = False\n> dotChars _ = True\n\nThese functions fill in the monotonically increasing index values for\nthe lines in the finite map.  They also do appropriate things to combine\nthe world values.\n\n> idxList [] n = []\n> idxList (x:xs) n = (x {idx=n}):(idxList xs (n+1))\n\n> idxFM' fm (x,k) = addToFM (delFromFM fm k) k (y {idx=toInteger x})\n>\twhere y = case lookupFM fm k of\n>                   Just foo -> foo\n>                   Nothing  -> error $ \"No such key: \" ++ show k\n\n> idxFM fm = foldl idxFM' fm (zip [1..sizeFM fm] $ keysFM fm)\n\n"
  },
  {
    "path": "tests/inputs/test_w_cpp_comments.svelte",
    "content": "<script lang=\"ts\">\n  /* Block comment\n\n      This is a block comment.\n  */\n\n  /**\n   * JsDoc\n   */\n  const test = 'hi';\n\n  // Single-line comment.\n  let { name }: { name: string; } = $props();\n</script>\n"
  },
  {
    "path": "tests/inputs/tictactoe3d.ring",
    "content": "# from https://raw.githubusercontent.com/ring-lang/ring/master/applications/tictactoe3d/tictactoe3d.ring\n\n/*\n**\n**\tGame  \t\t\t : TicTacToe 3D \n**\tDate   \t\t\t : 2017/08/30\n**  \tAuthor \t\t\t : Mahmoud Fayed <msfclipper@yahoo.com>\n**\n**\tNote :  The CheckWinner() function is \n**\t\t\twritten by Abdulrahman Mahmoud \n**\t\t\tSee ring/applications/tictactoe\n**\n*/\n\n# Load Libraries\n\tload \"gamelib.ring\"\t\t# RingAllegro Library\n\tload \"opengl21lib.ring\"\t\t# RingOpenGL  Library\n\n#==============================================================\n# To Support macOS\n\tal_run_main()\t\n\tfunc al_game_start \t# Called by al_run_main()\n\t\tmain()\t\t# Now we call our main function\n#==============================================================\n\nfunc main\n\tnew TicTacToe3D {\n\t\tstart()\n\t}\n\nclass TicTacToe3D from GameLogic\n\n\tFPS\t= 120\n\tTITLE\t= \"TicTacToe 3D\"\n\tICON\t= \"image/o.png\"\n\n\toBackground\t= new GameBackground\n\toGameSound\t= new GameSound\n\toGameCube\t= new GameCube\n\toGameOver\t= new GameOver\n\toGameInterface\t= new GameInterface \n\n\tfunc loadresources\n\t\toGameOver.loadresources()\n\t\toGameSound.loadresources()\n\t\toBackGround.loadresources()\n\t\toGameCube.loadresources()\n\n\tfunc destroyResources\n\t\toGameOver.destroyResources()\n\t\toGameSound.destroyResources()\n\t\toBackGround.destroyResources()\n\t\toGameCube.destroyResources()\n\n\tfunc drawScene\n\t\toBackground.update()\n\t\toGameInterface.update(self)\n\n\tfunc MouseClickEvent\n\t\toGameInterface.MouseClickEvent(self)\n"
  },
  {
    "path": "tests/inputs/tnsdl.sdl",
    "content": "PROCEDURE do_something;\n\nRETURNS error_t;\n\nDCL\n    status              error_t := 0, /* this is the result */\n    dummy               dummy_t;      /* dummy variable,\n                                         not impacting the flow */\n\nSTART;\n\n    /* let's invoke\n       some_function */\n    TASK status := some_function ();\n    DECISION ( status );\n    ( success_ec ):\n        TASK dummy := T;\n    ELSE:\n        TASK printf( @'We failed' );\n    ENDDECISION;\n\n   RETURN status;\nENDPROCEDURE do_something;\n"
  },
  {
    "path": "tests/inputs/toml.pest",
    "content": "// pest. The Elegant Parser\n// Copyright (c) 2018 Dragoș Tiselice\n//\n// Licensed under the Apache License, Version 2.0\n// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT\n// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your\n// option. All files in the project carrying such notice may not be copied,\n// modified, or distributed except according to those terms.\n\ntoml = { SOI ~ (table | array_table | pair)* ~ EOI }\n\ntable       = { \"[\" ~ key ~ (\".\" ~ key)* ~ \"]\" ~ pair* }\narray_table = { \"[[\" ~ key ~ (\".\" ~ key)* ~ \"]]\" ~ pair* }\npair        = { key ~ \"=\" ~ value }\n\nkey   = @{ identifier | string | literal }\nvalue = _{\n    inline_table |\n    array |\n    multi_line_string |\n    string |\n    multi_line_literal |\n    literal |\n    date_time |\n    local_date_time |\n    full_date |\n    partial_time |\n    float |\n    integer |\n    boolean\n}\n\ninline_table = { \"{\" ~ pair ~ (\",\" ~ pair)* ~ \",\"? ~ \"}\" | \"{\" ~ \"}\" }\n\narray = { \"[\" ~ value ~ (\",\" ~ value)* ~ \",\"? ~ \"]\" | \"[\" ~ \"]\" }\n\nidentifier = { (ASCII_ALPHANUMERIC | \"_\" | \"-\")+ }\n\nmulti_line_string  = @{ \"\\\"\\\"\\\"\" ~ inner ~ \"\\\"\\\"\\\"\" }\nstring             = @{ \"\\\"\" ~ inner ~ \"\\\"\" }\ninner              = @{ (!(\"\\\"\" | \"\\\\\" | \"\\u{0000}\" | \"\\u{001F}\") ~ ANY)* ~ (escape ~ inner)? }\nmulti_line_literal = @{ \"'''\" ~ (!\"'''\" ~ ANY)* ~ \"'''\" }\nliteral            = @{ \"'\" ~ (!\"'\" ~ ANY)* ~ \"'\" }\n\n// another comment\n\nescape  = @{ \"\\\\\" ~ (\"b\" | \"t\" | \"n\" | \"f\" | \"r\" | \"\\\"\" | \"\\\\\" | unicode | NEWLINE)? }\nunicode = @{ \"u\" ~ ASCII_HEX_DIGIT{4} | \"U\" ~ ASCII_HEX_DIGIT{8} }\n\ndate_time       = ${ full_date ~ \"T\" ~ full_time }\nlocal_date_time = ${ full_date ~ \"T\" ~ partial_time }\n\npartial_time = ${ time_hour ~ \":\" ~ time_minute ~ \":\" ~ time_second ~ time_secfrac? }\nfull_date    = ${ date_fullyear ~ \"-\" ~ date_month ~ \"-\" ~ date_mday }\nfull_time    = ${ partial_time ~ time_offset }\n\ndate_fullyear = @{ ASCII_DIGIT{4} }\ndate_month    = @{ ASCII_DIGIT{2} }\ndate_mday     = @{ ASCII_DIGIT{2} }\n\ntime_hour    = @{ ASCII_DIGIT{2} }\ntime_minute  = @{ ASCII_DIGIT{2} }\ntime_second  = @{ ASCII_DIGIT{2} }\ntime_secfrac = @{ \".\" ~ ASCII_DIGIT+ }\ntime_offset  = ${ \"Z\" | (\"+\" | \"-\") ~ time_hour ~ \":\" ~ time_minute }\n\ninteger = @{ (\"+\" | \"-\")? ~ int }\nfloat   = @{ (\"+\" | \"-\")? ~ int ~ (\".\" ~ digits ~ exp? | exp)? }\nint     = @{ \"0\" | (ASCII_NONZERO_DIGIT ~ digits?) }\ndigits  = @{ (ASCII_DIGIT | (\"_\" ~ ASCII_DIGIT))+ }\nexp     = @{ (\"E\" | \"e\") ~ (\"+\" | \"-\")? ~ int }\n\nboolean = { \"true\" | \"false\" }\n\nWHITESPACE = _{ \" \" | \"\\t\" | NEWLINE }\nCOMMENT    = _{ \"#\" ~ (!NEWLINE ~ ANY)* }\n"
  },
  {
    "path": "tests/inputs/toml_example.toml",
    "content": "# https://github.com/toml-lang/toml#example\n# This is a TOML document.\n\ntitle = \"TOML Example\"\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"
  },
  {
    "path": "tests/inputs/tour.swift",
    "content": "// https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/GuidedTour.html#//apple_ref/doc/uid/TP40014097-CH2-XID_1\n\n//    let implicitInteger = 70\n//    let implicitDouble = 70.0\n//    let explicitDouble: Double = 70\n//\n//\n//\n//    let label = \"The width is \"\n//    let width = 94\n//    let widthLabel = label + String(width)\n\n\n\n    var shoppingList = [\"catfish\", \"water\", \"tulips\", \"blue paint\"]\n    shoppingList[1] = \"bottle of water\"\n    var occupations = [\n          // \"Malcolm\": \"Captain\",\n    \"Kaylee\": \"Mechanic\",\n    ]\n        /* occupations[\"Jayne\"] = \"Public Relations\" */\n\n\n\n    let individualScores = [75, 43, 103, 87, 12]\n    var teamScore = 0\n    for score in individualScores {\n    if score > 50 {\n    teamScore += 3\n    } else {\n    teamScore += 1\n    }\n    }\n    teamScore\n\n\n\n    var optionalString: String? = \"Hello\"\n    optionalString == nil\n    var optionalName: String? = \"John Appleseed\"\n    var greeting = \"Hello!\"\n    if let name = optionalName {\n    greeting = \"Hello, \\(name)\"\n    }\n\n\n\n    let vegetable = \"red pepper\"\n    switch vegetable {\n    case \"celery\":\n    let vegetableComment = \"Add some raisins and make ants on a log.\"\n    case \"cucumber\", \"watercress\":\n    let vegetableComment = \"That would make a good tea sandwich.\"\n    case let x where x.hasSuffix(\"pepper\"):\n    let vegetableComment = \"Is it a spicy \\(x)?\"\n    default:\n    let vegetableComment = \"Everything tastes good in soup.\"\n    }\n\n\n\n    let interestingNumbers = [\n    \"Prime\": [2, 3, 5, 7, 11, 13],\n    \"Fibonacci\": [1, 1, 2, 3, 5, 8],\n    \"Square\": [1, 4, 9, 16, 25],\n    ]\n    var largest = 0\n    for (kind, numbers) in interestingNumbers {\n    for number in numbers {\n    if number > largest {\n    largest = number\n    }\n    }\n    }\n    largest\n\n\n\n    func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool {\n    for item in list {\n    if condition(item) {\n    return true\n    }\n    }\n    return false\n    }\n    func lessThanTen(number: Int) -> Bool {\n    return number < 10\n    }\n    var numbers = [20, 19, 7, 12]\n    hasAnyMatches(numbers, lessThanTen) /*\nFunctions are actually a special case of closures. You can write a closure without a name by surrounding code with braces ({}). Use in to separate the arguments and return type from the body. */\n\n    numbers.map({\n    (number: Int) -> Int in\n    let result = 3 * number\n    return result\n    })\n\n\n\n"
  },
  {
    "path": "tests/inputs/traffic_light.fsl",
    "content": "machine_name: \"Traffic light\";\n\nflow: down;\n\narrange [Green Yellow];\n\nOff 'Enable' -> Red;\nRed 'Next' => Green 'Next' => Yellow 'Next' => Red;\n\n[Red Yellow Green] ~> Off;\n\n// visual styling\n\nstate Red    : { background-color: pink;        corners: rounded; };\nstate Yellow : { background-color: lightyellow; corners: rounded; };\nstate Green  : { background-color: lightgreen;  corners: rounded; };\n\nstate Off : {\n/*\n  background-color : steelblue;\n  text-color  */      : white;\n  shape            : octagon;\n  linestyle        : dashed;\n};\n"
  },
  {
    "path": "tests/inputs/triple_lang_def.txt",
    "content": "Custom Triple JS\n    filter call_regexp_common C++\n    filter remove_inline //.*$\n    extension triple.extension.js\n    3rd_gen_scale 1.48\n    end_of_line_continuation \\\\$\n"
  },
  {
    "path": "tests/inputs/type.wast",
    "content": ";; https://github.com/WebAssembly/spec/blob/master/test/core/type.wast\n;; Test type definitions\n\n(module\n  (type (func))\n  (type $t (func))\n\n  (type (func (param i32)))\n  (type (func (param $x i32)))\n  (type (func (result i32)))\n  (type (func (param i32) (result i32)))\n  (type (func (param $x i32) (result i32)))\n\n  (type (func (param f32 f64)))\n  ;; (type (func (result i64 f32)))\n  ;; (type (func (param i32 i64) (result f32 f64)))\n\n  (type (func (param f32) (param f64)))\n  (type (func (param $x f32) (param f64)))\n  (type (func (param f32) (param $y f64)))\n  (type (func (param $x f32) (param $y f64)))\n  ;; (type (func (result i64) (result f32)))\n  ;; (type (func (param i32) (param i64) (result f32) (result f64)))\n  ;; (type (func (param $x i32) (param $y i64) (result f32) (result f64)))\n\n  (type (func (param f32 f64) (param $x i32) (param f64 i32 i32)))\n  ;; (type (func (result i64 i64 f32) (result f32 i32)))\n  ;; (type\n  ;;   (func (param i32 i32) (param i64 i32) (result f32 f64) (result f64 i32))\n  ;; )\n\n  (type (func (param) (param $x f32) (param) (param) (param f64 i32) (param)))\n  ;; (type\n  ;;   (func (result) (result) (result i64 i64) (result) (result f32) (result))\n  ;; )\n  ;; (type\n  ;;   (func\n  ;;     (param i32 i32) (param i64 i32) (param) (param $x i32) (param)\n  ;;     (result) (result f32 f64) (result f64 i32) (result)\n  ;;   )\n  ;; )\n)\n\n(assert_malformed\n  (module quote \"(type (func (result i32) (param i32)))\")\n  \"result before parameter\"\n)\n(assert_malformed\n  (module quote \"(type (func (result $x i32)))\")\n  \"unexpected token\"\n)\n\n(assert_invalid\n  (module (type (func (result i32 i32))))\n  \"invalid result arity\"\n)\n(assert_invalid\n  (module (type (func (result i32) (result i32))))\n  \"invalid result arity\"\n)\n"
  },
  {
    "path": "tests/inputs/updateSprites.wgsl",
    "content": "/*\nhttps://raw.githubusercontent.com/hexops/mach/main/examples/boids/updateSprites.wgsl\n*/\nstruct Particle {\n  pos : vec2<f32>,\n  vel : vec2<f32>,\n};\nstruct SimParams {\n  deltaT : f32,\n  rule1Distance : f32,\n  rule2Distance : f32,\n  rule3Distance : f32,\n  rule1Scale : f32,\n  rule2Scale : f32,\n  rule3Scale : f32,\n};\nstruct Particles {\n  particles : array<Particle>,\n};\n@binding(0) @group(0) var<uniform> params : SimParams;\n@binding(1) @group(0) var<storage, read> particlesA : Particles;\n@binding(2) @group(0) var<storage, read_write> particlesB : Particles;\n\n// https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp\n@compute @workgroup_size(64)\nfn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {\n  var index : u32 = GlobalInvocationID.x;\n\n  var vPos = particlesA.particles[index].pos;\n  var vVel = particlesA.particles[index].vel;\n  var cMass = vec2<f32>(0.0, 0.0);\n  var cVel = vec2<f32>(0.0, 0.0);\n  var colVel = vec2<f32>(0.0, 0.0);\n  var cMassCount : u32 = 0u;\n  var cVelCount : u32 = 0u;\n  var pos : vec2<f32>;\n  var vel : vec2<f32>;\n\n  for (var i : u32 = 0u; i < arrayLength(&particlesA.particles); i = i + 1u) {\n    if (i == index) {\n      continue;\n    }\n\n    pos = particlesA.particles[i].pos.xy;\n    vel = particlesA.particles[i].vel.xy;\n    if (distance(pos, vPos) < params.rule1Distance) {\n      cMass = cMass + pos;\n      cMassCount = cMassCount + 1u;\n    }\n    if (distance(pos, vPos) < params.rule2Distance) {\n      colVel = colVel - (pos - vPos);\n    }\n    if (distance(pos, vPos) < params.rule3Distance) {\n      cVel = cVel + vel;\n      cVelCount = cVelCount + 1u;\n    }\n  }\n  if (cMassCount > 0u) {\n    var temp = f32(cMassCount);\n    cMass = (cMass / vec2<f32>(temp, temp)) - vPos;\n  }\n  if (cVelCount > 0u) {\n    var temp = f32(cVelCount);\n    cVel = cVel / vec2<f32>(temp, temp);\n  }\n  vVel = vVel + (cMass * params.rule1Scale) + (colVel * params.rule2Scale) +\n      (cVel * params.rule3Scale);\n\n  // clamp velocity for a more pleasing simulation\n  vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1);\n  // kinematic update\n  vPos = vPos + (vVel * params.deltaT);\n  // Wrap around boundary\n  if (vPos.x < -1.0) {\n    vPos.x = 1.0;\n  }\n  if (vPos.x > 1.0) {\n    vPos.x = -1.0;\n  }\n  if (vPos.y < -1.0) {\n    vPos.y = 1.0;\n  }\n  if (vPos.y > 1.0) {\n    vPos.y = -1.0;\n  }\n  // Write back\n  particlesB.particles[index].pos = vPos;\n  particlesB.particles[index].vel = vVel;\n}\n"
  },
  {
    "path": "tests/inputs/utilities.R",
    "content": "# from https://github.com/lme4/lme4\nif(getRversion() < \"2.15\")\n  paste0 <- function(...) paste(..., sep = '')\n\n### Utilities for parsing and manipulating mixed-model formulas\n\n##' From the result of \\code{\\link{findbars}} applied to a model formula and\n##' and the evaluation frame, create the model matrix, etc. associated with\n##' random-effects terms.  See the description of the returned value for a\n##' detailed list.\n##'\n##' @title Create Z, Lambda, Lind, etc.\n##' @param bars a list of parsed random-effects terms\n##' @param fr a model frame in which to evaluate these terms\n##' @return a list with components\n##' \\item{Zt}{transpose of the sparse model matrix for the random effects}\n##' \\item{Lambdat}{transpose of the sparse relative covariance factor}\n##' \\item{Lind}{an integer vector of indices determining the mapping of the\n##'     elements of the \\code{theta} to the \\code{\"x\"} slot of \\code{Lambdat}}\n##' \\item{theta}{initial values of the covariance parameters}\n##' \\item{lower}{lower bounds on the covariance parameters}\n##' \\item{flist}{list of grouping factors used in the random-effects terms}\n##' \\item{cnms}{a list of column names of the random effects according to\n##'     the grouping factors}\n##' @importFrom Matrix sparseMatrix rBind drop0\n##' @importMethodsFrom Matrix coerce\n##' @family utilities\n##' @export\nmkReTrms <- function(bars, fr) {\n  if (!length(bars))\n    stop(\"No random effects terms specified in formula\")\n  stopifnot(is.list(bars), vapply(bars, is.language, NA),\n            inherits(fr, \"data.frame\"))\n  names(bars) <- barnames(bars)\n  term.names <- unlist(lapply(bars, function(x) paste(deparse(x),collapse=\" \")))\n\n  ## auxiliary {named, for easier inspection}:\n  mkBlist <- function(x) {\n    frloc <- fr\n    ## convert grouping variables to factors as necessary\n    ## TODO: variables that are *not* in the data frame are\n    ##  not converted -- these could still break, e.g. if someone\n    ##  tries to use the : operator\n    for (i in all.vars(x[[3]])) {\n        if (!is.null(frloc[[i]])) frloc[[i]] <- factor(frloc[[i]])\n    }\n    if (is.null(ff <- tryCatch(eval(substitute(factor(fac),\n                                               list(fac = x[[3]])), frloc),\n                error=function(e) NULL)))\n        stop(\"couldn't evaluate grouping factor \",\n             deparse(x[[3]]),\" within model frame:\",\n             \" try adding grouping factor to data \",\n             \"frame explicitly if possible\")\n    if (all(is.na(ff)))\n        stop(\"Invalid grouping factor specification, \",\n             deparse(x[[3]]))\n    nl <- length(levels(ff))\n    mm <- model.matrix(eval(substitute( ~ foo, list(foo = x[[2]]))), frloc)\n    nc <- ncol(mm)\n    nseq <- seq_len(nc)\n    sm <- as(ff, \"sparseMatrix\")\n    if (nc > 1)\n      sm <- do.call(rBind, lapply(nseq, function(i) sm))\n    ## hack for NA values contained in factor (FIXME: test elsewhere for consistency?)\n    sm@x[] <- t(mm[!is.na(ff),])\n    ## When nc > 1 switch the order of the rows of sm\n    ## so the random effects for the same level of the\n    ## grouping factor are adjacent.\n    if (nc > 1)\n      sm <- sm[as.vector(matrix(seq_len(nc * nl),\n                                ncol = nl, byrow = TRUE)),]\n    list(ff = ff, sm = sm, nl = nl, cnms = colnames(mm))\n  }\n  blist <- lapply(bars, mkBlist)\n  nl <- vapply(blist, `[[`, 0L, \"nl\")   # no. of levels per term\n                                        # (in lmer jss:  \\ell_i)\n\n  ## order terms stably by decreasing number of levels in the factor\n  if (any(diff(nl) > 0)) {\n    ord <- rev(order(nl))\n    blist <- blist[ord]\n    nl <- nl[ord]\n  }\n  Ztlist <- lapply(blist, \"[[\", \"sm\")\n  Zt <- do.call(rBind, Ztlist)\n  names(Ztlist) <- term.names\n  q <- nrow(Zt)\n\n  ## Create and install Lambdat, Lind, etc.  This must be done after\n  ## any potential reordering of the terms.\n  cnms <- lapply(blist, \"[[\", \"cnms\")   # list of column names of the\n                                        # model matrix per term\n  nc <- vapply(cnms, length, 0L)\t# no. of columns per term\n                                        # (in lmer jss:  p_i)\n  nth <- as.integer((nc * (nc+1))/2)\t# no. of parameters per term\n                                        # (in lmer jss:  ??)\n  nb <- nc * nl\t\t\t        # no. of random effects per term\n                                        # (in lmer jss:  q_i)\n  stopifnot(sum(nb) == q)\n  boff <- cumsum(c(0L, nb))\t\t# offsets into b\n  thoff <- cumsum(c(0L, nth))\t\t# offsets into theta\n  ### FIXME: should this be done with cBind and avoid the transpose\n  ### operator?  In other words should Lambdat be generated directly\n  ### instead of generating Lambda first then transposing?\n  Lambdat <-\n    t(do.call(sparseMatrix,\n              do.call(rBind,\n                      lapply(seq_along(blist), function(i)\n                      {\n                        mm <- matrix(seq_len(nb[i]), ncol = nc[i],\n                                     byrow = TRUE)\n                        dd <- diag(nc[i])\n                        ltri <- lower.tri(dd, diag = TRUE)\n                        ii <- row(dd)[ltri]\n                        jj <- col(dd)[ltri]\n                        dd[cbind(ii, jj)] <- seq_along(ii) # FIXME: this line unnecessary?\n                        data.frame(i = as.vector(mm[, ii]) + boff[i],\n                                   j = as.vector(mm[, jj]) + boff[i],\n                                   x = as.double(rep.int(seq_along(ii),\n                                                         rep.int(nl[i], length(ii))) +\n                                                   thoff[i]))\n                      }))))\n  thet <- numeric(sum(nth))\n  ll <- list(Zt=Matrix::drop0(Zt), theta=thet, Lind=as.integer(Lambdat@x),\n             Gp=unname(c(0L, cumsum(nb))))\n  ## lower bounds on theta elements are 0 if on diagonal, else -Inf\n  ll$lower <- -Inf * (thet + 1)\n  ll$lower[unique(diag(Lambdat))] <- 0\n  ll$theta[] <- is.finite(ll$lower) # initial values of theta are 0 off-diagonal, 1 on\n  Lambdat@x[] <- ll$theta[ll$Lind]  # initialize elements of Lambdat\n  ll$Lambdat <- Lambdat\n  # massage the factor list\n  fl <- lapply(blist, \"[[\", \"ff\")\n  # check for repeated factors\n  fnms <- names(fl)\n  if (length(fnms) > length(ufn <- unique(fnms))) {\n    fl <- fl[match(ufn, fnms)]\n    asgn <- match(fnms, ufn)\n  } else asgn <- seq_along(fl)\n  names(fl) <- ufn\n  fl <- do.call(data.frame, c(fl, check.names = FALSE))\n  attr(fl, \"assign\") <- asgn\n  ll$flist <- fl\n  ll$cnms <- cnms\n  ll$Ztlist <- Ztlist\n  ll\n} ## {mkReTrms}\n\n##' Create an lmerResp, glmResp or nlsResp instance\n##'\n##' @title Create an lmerResp, glmResp or nlsResp instance\n##' @param fr a model frame\n##' @param REML logical scalar, value of REML for an lmerResp instance\n##' @param family the optional glm family (glmResp only)\n##' @param nlenv the nonlinear model evaluation environment (nlsResp only)\n##' @param nlmod the nonlinear model function (nlsResp only)\n##' @param ... where to look for response information if \\code{fr} is missing.\n##'   Can contain a model response, \\code{y}, offset, \\code{offset}, and weights,\n##'   \\code{weights}.\n##' @return an lmerResp or glmResp or nlsResp instance\n##' @family utilities\n##' @export\nmkRespMod <- function(fr, REML=NULL, family = NULL, nlenv = NULL, nlmod = NULL, ...) {\n\n    if(!missing(fr)){\n        y <- model.response(fr)\n        offset <- model.offset(fr)\n        weights <- model.weights(fr)\n        N <- n <- nrow(fr)\n        etastart_update <- model.extract(fr, \"etastart\")\n    } else {\n        fr <- list(...)\n        y <- fr$y\n        N <- n <- if(is.matrix(y)) nrow(y) else length(y)\n        offset <- fr$offset\n        weights <- fr$weights\n        etastart_update <- fr$etastart\n    }\n\n\n   ## FIXME: may need to add X, or pass it somehow, if we want to use glm.fit\n    ##y <- model.response(fr)\n    if(length(dim(y)) == 1) {\n        ## avoid problems with 1D arrays, but keep names\n        nm <- rownames(y)\n        dim(y) <- NULL\n        if(!is.null(nm)) names(y) <- nm\n    }\n    rho <- new.env()\n    rho$y <- if (is.null(y)) numeric(0) else y\n    if (!is.null(REML)) rho$REML <- REML\n    rho$etastart <- fr$etastart\n    rho$mustart <- fr$mustart\n    ##N <- n <- nrow(fr)\n    if (!is.null(nlenv)) {\n        stopifnot(is.language(nlmod),\n                  is.environment(nlenv),\n                  is.numeric(val <- eval(nlmod, nlenv)),\n                  length(val) == n,\n\t\t  ## FIXME?  Restriction, not present in ole' nlme():\n                  is.matrix(gr <- attr(val, \"gradient\")),\n                  mode(gr) == \"numeric\",\n                  nrow(gr) == n,\n                  !is.null(pnames <- colnames(gr)))\n        N <- length(gr)\n        rho$mu <- as.vector(val)\n        rho$sqrtXwt <- as.vector(gr)\n        rho$gam <-\n            unname(unlist(lapply(pnames,\n                                 function(nm) get(nm, envir=nlenv))))\n    }\n    if (!is.null(offset)) {\n        if (length(offset) == 1L) offset <- rep.int(offset, N)\n        stopifnot(length(offset) == N)\n        rho$offset <- unname(offset)\n    } else rho$offset <- rep.int(0, N)\n    if (!is.null(weights)) {\n        stopifnot(length(weights) == n, all(weights >= 0))\n        rho$weights <- unname(weights)\n    } else rho$weights <- rep.int(1, n)\n    if (is.null(family)) {\n        if (is.null(nlenv)) return(do.call(lmerResp$new, as.list(rho)))\n        return(do.call(nlsResp$new,\n                       c(list(nlenv=nlenv,\n                              nlmod=substitute(~foo, list(foo=nlmod)),\n                              pnames=pnames), as.list(rho))))\n    }\n    stopifnot(inherits(family, \"family\"))\n    ## need weights for initializing evaluation\n    rho$nobs <- n\n    ## allow trivial objects, e.g. for simulation\n    if (length(y)>0) eval(family$initialize, rho)\n    family$initialize <- NULL     # remove clutter from str output\n    ll <- as.list(rho)\n    ans <- do.call(\"new\", c(list(Class=\"glmResp\", family=family),\n                          ll[setdiff(names(ll), c(\"m\", \"nobs\", \"mustart\"))]))\n    if (length(y)>0) ans$updateMu(if (!is.null(es <- etastart_update)) es else\n                                  family$linkfun(get(\"mustart\", rho)))\n    ans\n}\n\n##' From the right hand side of a formula for a mixed-effects model,\n##' determine the pairs of expressions that are separated by the\n##' vertical bar operator.  Also expand the slash operator in grouping\n##' factor expressions and expand terms with the double vertical bar operator\n##' into separate, independent random effect terms.\n##'\n##' @title Determine random-effects expressions from a formula\n##' @seealso \\code{\\link{formula}}, \\code{\\link{model.frame}}, \\code{\\link{model.matrix}}.\n##' @param term a mixed-model formula\n##' @return pairs of expressions that were separated by vertical bars\n##' @section Note: This function is called recursively on individual\n##' terms in the model, which is why the argument is called \\code{term} and not\n##' a name like \\code{form}, indicating a formula.\n##' @example\n##' findbars(f1 <- Reaction ~ Days + (Days|Subject))\n##' ## => list( Days | Subject )\n##' findbars(y ~ Days + (1|Subject) + (0+Days|Subject))\n##' ## => list of length 2:  list ( 1 | Subject ,  0+Days|Subject)\n##' findbars(~ 1 + (1|batch/cask))\n##' ## => list of length 2:  list ( 1 | cask:batch ,  1 | batch)\n##' identical(findbars(~ 1 + (Days || Subject)),\n##'     findbars(~ 1 + (1|Subject) + (0+Days|Subject)))\n##' \\dontshow{\n##' stopifnot(identical(findbars(f1),\n##'                     list(expression(Days | Subject)[[1]])))\n##' }\n##' @family utilities\n##' @keywords models utilities\n##' @export\nfindbars <- function(term)\n{\n    ## Recursive function applied to individual terms\n    fb <- function(term)\n    {\n\tif (is.name(term) || !is.language(term)) return(NULL)\n\tif (term[[1]] == as.name(\"(\")) return(fb(term[[2]]))\n\tstopifnot(is.call(term))\n\tif (term[[1]] == as.name('|')) return(term)\n\tif (length(term) == 2) return(fb(term[[2]]))\n\tc(fb(term[[2]]), fb(term[[3]]))\n    }\n    ## Expand any slashes in the grouping factors returned by fb\n    expandSlash <- function(bb)\n    {\n\t## Create the interaction terms for nested effects\n\tmakeInteraction <- function(x)\n\t{\n\t    if (length(x) < 2) return(x)\n\t    trm1 <- makeInteraction(x[[1]])\n\t    trm11 <- if(is.list(trm1)) trm1[[1]] else trm1\n\t    list(substitute(foo:bar, list(foo=x[[2]], bar = trm11)), trm1)\n\t}\n\t## Return the list of '/'-separated terms\n\tslashTerms <- function(x)\n\t{\n\t    if (!(\"/\" %in% all.names(x))) return(x)\n\t    if (x[[1]] != as.name(\"/\"))\n\t\tstop(\"unparseable formula for grouping factor\")\n\t    list(slashTerms(x[[2]]), slashTerms(x[[3]]))\n\t}\n\n\tif (!is.list(bb))\n\t    expandSlash(list(bb))\n\telse\n\t    unlist(lapply(bb, function(x) {\n\t\tif (length(x) > 2 && is.list(trms <- slashTerms(x[[3]])))\n\t\t    ## lapply(unlist(...)) - unlist returns a flattened list\n\t\t    lapply(unlist(makeInteraction(trms)),\n\t\t\t   function(trm) substitute(foo|bar, list(foo = x[[2]], bar = trm)))\n\t\telse x\n\t    }))\n    }## {expandSlash}\n\n    modterm <- expandDoubleVerts(\n\tif(is(term, \"formula\")) term[[length(term)]] else term)\n    expandSlash(fb(modterm))\n}\n\n##' From the right hand side of a formula for a mixed-effects model,\n##' expand terms with the double vertical bar operator\n##' into separate, independent random effect terms.\n##'\n##' @title Expand terms with \\code{'||'} notation into separate \\code{'|'} terms\n##' @seealso \\code{\\link{formula}}, \\code{\\link{model.frame}}, \\code{\\link{model.matrix}}.\n##' @param term a mixed-model formula\n##' @return the modified term\n##' @family utilities\n##' @keywords models utilities\n##' @export\nexpandDoubleVerts <- function(term)\n{\n    expandDoubleVert <- function(term) {\n\tfrml <- formula(paste0(\"~\", deparse(term[[2]])))\n\t## need term.labels not all.vars to capture interactions too:\n\tnewtrms <- paste0(\"0+\", attr(terms(frml), \"term.labels\"))\n\tif(attr(terms(frml), \"intercept\")!=0)\n\t    newtrms <- c(\"1\", newtrms)\n\tas.formula(paste(\"~(\",\n\t\t\t paste(vapply(newtrms, function(trm)\n\t\t\t\t      paste0(trm, \"|\", deparse(term[[3]])), \"\"),\n\t\t\t       collapse=\")+(\"), \")\"))[[2]]\n    }\n\n    if (!is.name(term) && is.language(term)) {\n\tif (term[[1]] == as.name(\"(\")) {\n\t    term[[2]] <- expandDoubleVerts(term[[2]])\n\t}\n\tstopifnot(is.call(term))\n\tif (term[[1]] == as.name('||'))\n\t    return( expandDoubleVert(term) )\n\t## else :\n\tterm[[2]] <- expandDoubleVerts(term[[2]])\n\tif (length(term) != 2) {\n\t    if(length(term) == 3)\n\t\tterm[[3]] <- expandDoubleVerts(term[[3]])\n\t}\n    }\n    term\n}\n\n\n\n##' Remove the random-effects terms from a mixed-effects formula,\n##' thereby producing the fixed-effects formula.\n##'\n##' @title Omit terms separated by vertical bars in a formula\n##' @param term the right-hand side of a mixed-model formula\n##' @return the fixed-effects part of the formula\n##' @section Note: This function is called recursively on individual\n##' terms in the model, which is why the argument is called \\code{term} and not\n##' a name like \\code{form}, indicating a formula.\n##' @examples\n##' nobars(Reaction ~ Days + (Days|Subject)) ## => Reaction ~ Days\n##' @seealso \\code{\\link{formula}}, \\code{\\link{model.frame}}, \\code{\\link{model.matrix}}.\n##' @family utilities\n##' @keywords models utilities\n##' @export\nnobars <- function(term)\n{\n    if (!any(c('|','||') %in% all.names(term))) return(term)\n    if (is.call(term) && term[[1]] == as.name('|')) return(NULL)\n    if (is.call(term) && term[[1]] == as.name('||')) return(NULL)\n    if (length(term) == 2) {\n        nb <- nobars(term[[2]])\n        if (is.null(nb)) return(NULL)\n        term[[2]] <- nb\n        return(term)\n    }\n    nb2 <- nobars(term[[2]])\n    nb3 <- nobars(term[[3]])\n    if (is.null(nb2)) return(nb3)\n    if (is.null(nb3)) return(nb2)\n    term[[2]] <- nb2\n    term[[3]] <- nb3\n    term\n}\n\n##' Substitute the '+' function for the '|' and '||' function in a mixed-model\n##' formula.  This provides a formula suitable for the current\n##' model.frame function.\n##'\n##' @title \"Sub[stitute] Bars\"\n##' @param term a mixed-model formula\n##' @return the formula with all |  and || operators replaced by +\n##' @section Note: This function is called recursively on individual\n##' terms in the model, which is why the argument is called \\code{term} and not\n##' a name like \\code{form}, indicating a formula.\n##' @examples\n##' subbars(Reaction ~ Days + (Days|Subject)) ## => Reaction ~ Days + (Days + Subject)\n##' @seealso \\code{\\link{formula}}, \\code{\\link{model.frame}}, \\code{\\link{model.matrix}}.\n##' @family utilities\n##' @keywords models utilities\n##' @export\nsubbars <- function(term)\n{\n    if (is.name(term) || !is.language(term)) return(term)\n    if (length(term) == 2) {\n        term[[2]] <- subbars(term[[2]])\n        return(term)\n    }\n    stopifnot(length(term) >= 3)\n    if (is.call(term) && term[[1]] == as.name('|'))\n        term[[1]] <- as.name('+')\n    if (is.call(term) && term[[1]] == as.name('||'))\n        term[[1]] <- as.name('+')\n    for (j in 2:length(term)) term[[j]] <- subbars(term[[j]])\n    term\n}\n\n##' @param bars result of findbars\nbarnames <- function(bars) {\n    unlist(lapply(bars, function(x) deparse(x[[3]])))\n}\n\n##' Does every level of f1 occur in conjunction with exactly one level\n##' of f2? The function is based on converting a triplet sparse matrix\n##' to a compressed column-oriented form in which the nesting can be\n##' quickly evaluated.\n##'\n##' @title Is f1 nested within f2?\n##'\n##' @param f1 factor 1\n##' @param f2 factor 2\n##'\n##' @return TRUE if factor 1 is nested within factor 2\n##' @examples\n##' with(Pastes, isNested(cask, batch))   ## => FALSE\n##' with(Pastes, isNested(sample, batch))  ## => TRUE\n##' @export\nisNested <- function(f1, f2)\n{\n    f1 <- as.factor(f1)\n    f2 <- as.factor(f2)\n    stopifnot(length(f1) == length(f2))\n    k <- length(levels(f1))\n    sm <- as(new(\"ngTMatrix\",\n                 i = as.integer(f2) - 1L,\n                 j = as.integer(f1) - 1L,\n                 Dim = c(length(levels(f2)), k)),\n             \"CsparseMatrix\")\n    all(sm@p[2:(k+1L)] - sm@p[1:k] <= 1L)\n}\n\nsubnms <- function(form, nms) {\n    ## Recursive function applied to individual terms\n    sbnm <- function(term)\n    {\n        if (is.name(term)) {\n\t    if (any(term == nms)) 0 else term\n\t} else switch(length(term),\n\t       term, ## 1\n\t   {   ## 2\n\t       term[[2]] <- sbnm(term[[2]])\n\t       term\n\t   },\n\t   {   ## 3\n\t       term[[2]] <- sbnm(term[[2]])\n\t       term[[3]] <- sbnm(term[[3]])\n\t       term\n\t   })\n    }\n    sbnm(form)\n}\n\n## Check for a constant term (a literal 1) in an expression\n##\n## In the mixed-effects part of a nonlinear model formula, a constant\n## term is not meaningful because every term must be relative to a\n## nonlinear model parameter.  This function recursively checks the\n## expressions in the formula for a a constant, calling stop() if\n## such a term is encountered.\n## @title Check for constant terms.\n## @param expr an expression\n## @return NULL.  The function is executed for its side effect.\nchck1 <- function(expr) {\n    if ((le <- length(expr)) == 1) {\n        if (is.numeric(expr) && expr == 1)\n            stop(\"1 is not meaningful in a nonlinear model formula\")\n        return()\n    } else\n        for (j in seq_len(le)[-1]) Recall(expr[[j]])\n}\n\n## ---> ../man/nlformula.Rd --- Manipulate a nonlinear model formula\n##' @param mc matched call from the caller, with arguments 'formula','start',...\n##' @return a list with components \"respMod\", \"frame\", \"X\", \"reTrms\"\nnlformula <- function(mc) {\n  start <- eval(mc$start, parent.frame(2L))\n  if (is.numeric(start)) start <- list(nlpars = start)\n  stopifnot(is.numeric(nlpars <- start$nlpars),\n            vapply(nlpars, length, 0L) == 1L,\n            length(pnames <- names(nlpars)) == length(nlpars),\n            length(form <- as.formula(mc$formula)) == 3L,\n            is(nlform <- eval(form[[2]]), \"formula\"),\n            pnames %in%\n                  (av <- all.vars(nlmod <- as.call(nlform[[lnl <- length(nlform)]]))))\n\n  ## MM{FIXME}: fortune(106) even twice in here!\n    nlform[[lnl]] <- parse(text= paste(setdiff(all.vars(form), pnames), collapse=' + '))[[1]]\n    nlform <- eval(nlform)\n    environment(nlform) <- environment(form)\n    m <- match(c(\"data\", \"subset\", \"weights\", \"na.action\", \"offset\"),\n               names(mc), 0)\n    mc <- mc[c(1, m)]\n    mc$drop.unused.levels <- TRUE\n    mc[[1]] <- as.name(\"model.frame\")\n    mc$formula <- nlform\n    fr <- eval(mc, parent.frame(2L))\n    n <- nrow(fr)\n    nlenv <- list2env(fr, parent=parent.frame(2L))\n    lapply(pnames, function(nm) nlenv[[nm]] <- rep.int(nlpars[[nm]], n))\n    respMod <- mkRespMod(fr, nlenv=nlenv, nlmod=nlmod)\n\n    chck1(meform <- form[[3L]])\n    pnameexpr <- parse(text=paste(pnames, collapse='+'))[[1]]\n    nb <- nobars(meform)\n    fe <- eval(substitute(~ 0 + nb + pnameexpr))\n    environment(fe) <- environment(form)\n    frE <- do.call(rbind, lapply(seq_along(nlpars), function(i) fr)) # rbind s copies of the frame\n    for (nm in pnames) # convert these variables in fr to indicators\n        frE[[nm]] <- as.numeric(rep(nm == pnames, each = n))\n    X <- model.matrix(fe, frE)\n    rownames(X) <- NULL\n\n    reTrms <- mkReTrms(lapply(findbars(meform),\n                              function(expr) {\n                                  expr[[2]] <- substitute(0+foo, list(foo=expr[[2]]))\n                                  expr\n                              }), frE)\n    list(respMod=respMod, frame=fr, X=X, reTrms=reTrms, pnames=pnames)\n} ## {nlformula}\n\n##--> ../man/mkMerMod.Rd ---Create a merMod object\n##' @param rho the environment of the objective function\n##' @param opt the value returned by the optimizer\n##' @param reTrms reTrms list from the calling function\nmkMerMod <- function(rho, opt, reTrms, fr, mc, lme4conv=NULL) {\n    if(missing(mc)) mc <- match.call()\n    stopifnot(is.environment(rho),\n              is(pp <- rho$pp, \"merPredD\"),\n              is(resp <- rho$resp, \"lmResp\"),\n              is.list(opt), \"par\" %in% names(opt),\n              c(\"conv\",\"fval\") %in% substr(names(opt),1,4), ## \"conv[ergence]\", \"fval[ues]\"\n              is.list(reTrms), c(\"flist\", \"cnms\", \"Gp\", \"lower\") %in% names(reTrms),\n              length(rcl <- class(resp)) == 1)\n    n    <- nrow(pp$V)\n    p    <- ncol(pp$V)\n    dims <- c(N=nrow(pp$X), n=n, p=p, nmp=n-p,\n              nth=length(pp$theta), q=nrow(pp$Zt),\n              nAGQ=rho$nAGQ,\n              compDev=rho$compDev,\n              ## 'use scale' in the sense of whether dispersion parameter should\n              ##  be reported/used (*not* whether theta should be scaled by sigma)\n              useSc=(rcl != \"glmResp\" ||\n                     !resp$family$family %in% c(\"poisson\",\"binomial\")),\n              reTrms=length(reTrms$cnms),\n              spFe=0L,\n              REML=if (rcl==\"lmerResp\") resp$REML else 0L,\n              GLMM=(rcl==\"glmResp\"),\n              NLMM=(rcl==\"nlsResp\"))\n    storage.mode(dims) <- \"integer\"\n    fac     <- as.numeric(rcl != \"nlsResp\")\n    if (trivial.y <- (length(resp$y)==0)) {\n        ## trivial model\n        sqrLenU <- wrss <- pwrss <- NA\n    } else {\n        sqrLenU <- pp$sqrL(fac)\n        wrss    <- resp$wrss()\n        pwrss   <- wrss + sqrLenU\n    }\n    weights <- resp$weights\n    beta    <- pp$beta(fac)\n    #sigmaML <- pwrss/sum(weights)\n    sigmaML <- pwrss/n\n    if (rcl != \"lmerResp\") {\n        pars <- opt$par\n        if (length(pars) > length(pp$theta)) beta <- pars[-(seq_along(pp$theta))]\n    }\n    cmp <- c(ldL2=pp$ldL2(), ldRX2=pp$ldRX2(), wrss=wrss,\n             ussq=sqrLenU, pwrss=pwrss,\n             drsum=if (rcl==\"glmResp\" && !trivial.y) resp$resDev() else NA,\n             REML=if (rcl==\"lmerResp\" && resp$REML != 0L && !trivial.y)\n                  opt$fval else NA,\n             ## FIXME: construct 'REML deviance' here?\n             dev=if (rcl==\"lmerResp\" && resp$REML != 0L || trivial.y) NA else opt$fval,\n             sigmaML=sqrt(unname(if (!dims[\"useSc\"] || trivial.y) NA else sigmaML)),\n             sigmaREML=sqrt(unname(if (rcl!=\"lmerResp\" || trivial.y) NA else sigmaML*(dims['n']/dims['nmp']))),\n             tolPwrss=rho$tolPwrss)\n    ## TODO:  improve this hack to get something in frame slot (maybe need weights, etc...)\n    if(missing(fr)) fr <- data.frame(resp$y)\n    new(switch(rcl, lmerResp=\"lmerMod\", glmResp=\"glmerMod\", nlsResp=\"nlmerMod\"),\n        call=mc, frame=fr, flist=reTrms$flist, cnms=reTrms$cnms,\n        Gp=reTrms$Gp, theta=pp$theta, beta=beta,\n        u=if (trivial.y) rep(NA_real_,nrow(pp$Zt)) else pp$u(fac),\n        lower=reTrms$lower, devcomp=list(cmp=cmp, dims=dims),\n        pp=pp, resp=resp,\n\toptinfo = list (optimizer= attr(opt,\"optimizer\"),\n\t\t\tcontrol\t = attr(opt,\"control\"),\n\t\t\tderivs\t = attr(opt,\"derivs\"),\n\t\t\tconv  = list(opt=opt$conv, lme4=lme4conv),\n\t\t\tfeval = if (is.null(opt$feval)) NA else opt$feval,\n\t\t\twarnings = attr(opt,\"warnings\"), val = opt$par)\n        )\n}## {mkMerMod}\n\n## generic argument checking\n## 'type': name of calling function (\"glmer\", \"lmer\", \"nlmer\")\n##\ncheckArgs <- function(type,...) {\n    l... <- list(...)\n    if (isTRUE(l...[[\"sparseX\"]])) warning(\"sparseX = TRUE has no effect at present\")\n    ## '...' handling up front, safe-guarding against typos (\"familiy\") :\n    if(length(l... <- list(...))) {\n        if (!is.null(l...[[\"family\"]])) {  # call glmer if family specified\n            ## we will only get here if 'family' is *not* in the arg list\n            warning(\"calling lmer with family() is deprecated: please use glmer() instead\")\n            type <- \"glmer\"\n        }\n        ## Check for method argument which is no longer used\n        ## (different meanings/hints depending on glmer vs lmer)\n        if (!is.null(method <- l...[[\"method\"]])) {\n            msg <- paste(\"Argument\", sQuote(\"method\"), \"is deprecated.\")\n            if (type==\"lmer\") msg <- paste(msg,\"Use the REML argument to specify ML or REML estimation.\")\n            if (type==\"glmer\") msg <- paste(msg,\"Use the nAGQ argument to specify Laplace (nAGQ=1) or adaptive\",\n                \"Gauss-Hermite quadrature (nAGQ>1).  PQL is no longer available.\")\n            warning(msg)\n            l... <- l...[names(l...) != \"method\"]\n        }\n        if(length(l...)) {\n            warning(\"extra argument(s) \",\n                    paste(sQuote(names(l...)), collapse=\", \"),\n                    \" disregarded\")\n        }\n    }\n}\n\n## check formula and data: return an environment suitable for evaluating\n##  the formula.\n## (1) if data is specified, return it\n## (2) otherwise, if formula has an environment, use it\n## (3) otherwise [e.g. if formula was passed as a string], try to use parent.frame(2)\n\n## if #3 is true *and* the user is doing something tricky with nested functions,\n## this may fail ...\n\ncheckFormulaData <- function(formula,data,checkLHS=TRUE,debug=FALSE) {\n    dataName <- deparse(substitute(data))\n    missingData <- inherits(tryCatch(eval(data), error=function(e)e), \"error\")\n    ## data not found (this *should* only happen with garbage input,\n    ## OR when strings used as formulae -> drop1/update/etc.)\n    ##\n    ## alternate attempt (fails)\n    ##\n    ## ff <- sys.frames()\n    ## ex <- substitute(data)\n    ## ii <- rev(seq_along(ff))\n    ## for(i in ii) {\n    ##     ex <- eval(substitute(substitute(x, env=sys.frames()[[n]]),\n    ##                           env = list(x = ex, n=i)))\n    ## }\n    ## origName <- deparse(ex)\n    ## missingData <- !exists(origName)\n    ## (!dataName==\"NULL\" && !exists(dataName))\n    if (missingData) {\n        varex <- function(v,env) exists(v,envir=env,inherits=FALSE)\n        allvars <- all.vars(as.formula(formula))\n        allvarex <- function(vvec=allvars,...) { all(sapply(vvec,varex,...)) }\n        if (allvarex(env=(ee <- environment(formula)))) {\n            stop(\"'data' not found, but variables found in environment of formula: \",\n                 \"try specifying 'formula' as a formula rather \",\n                 \"than a string in the original model\")\n        } else stop(\"'data' not found, and some variables missing from formula environment\")\n    } else {\n        if (is.null(data)) {\n            if (!is.null(ee <- environment(formula))) {\n                ## use environment of formula\n                denv <- ee\n            } else {\n                ## e.g. no environment, e.g. because formula is a character vector\n                ## parent.frame(2L) works because [g]lFormula (our calling environment)\n                ## has been called within [g]lmer with env=parent.frame(1L)\n                ## If you call checkFormulaData in some other bizarre way such that\n                ## parent.frame(2L) is *not* OK, you deserve what you get\n                ## calling checkFormulaData directly from the global\n                ## environment should be OK, since trying to go up beyond the global\n                ## environment keeps bringing you back to the global environment ...\n                denv <- parent.frame(2L)\n            }\n        } else {\n            ## data specified\n            denv <- list2env(data)\n        }\n    }\n    ## FIXME: set enclosing environment of denv to environment(formula), or parent.frame(2L) ?\n    if (debug) {\n        cat(\"Debugging parent frames in checkFormulaData:\\n\")\n        ## find global environment -- could do this with sys.nframe() ?\n        glEnv <- 1\n        while (!identical(parent.frame(glEnv),.GlobalEnv)) {\n            glEnv <- glEnv+1\n        }\n        ## where are vars?\n        for (i in 1:glEnv) {\n            OK <- allvarex(env=parent.frame(i))\n            cat(\"vars exist in parent frame \",i)\n            if (i==glEnv) cat(\" (global)\")\n            cat(\" \",OK,\"\\n\")\n        }\n        cat(\"vars exist in env of formula \",allvarex(env=denv),\"\\n\")\n    } ## if (debug)\n\n    stopifnot(!checkLHS || length(as.formula(formula,env=denv)) == 3)  ## check for two-sided formula\n    return(denv)\n}\n\n## checkFormulaData <- function(formula,data) {\n##     ee <- environment(formula)\n##     if (is.null(ee)) {\n##         ee <- parent.frame(2)\n##     }\n##     if (missing(data)) data <- ee\n##     stopifnot(length(as.formula(formula,env=as.environment(data))) == 3)\n##     return(data)\n## }\n\n\n##' Not exported; for tests (and examples) that can be slow;\n##' Use   if(lme4:::testLevel() >= 1.) .....  see ../README.md\ntestLevel <- function()\n    if(nzchar(s <- Sys.getenv(\"LME4_TEST_LEVEL\")) &&\n       is.finite(s <- as.numeric(s))) s else 1\n\n##' General conditional variance-covariance matrix\n##'\n##' Experimental function for estimating the variance-covariance\n##' matrix of the random effects, conditional on the observed data\n##' and at the (RE)ML estimate of the fixed effects and covariance\n##' parameters.  Applicable for any Lambda matrix, but slower than\n##' other block-by-block methods.\n##' Not exported.\n##'\n##' TODO:\n##' (1) Write up quite note on theory (e.g. Laplace approximation).\n##' (2) Figure out how to convert between full q-by-q matrix, and\n##'     the format currently in the postVar attributes of the\n##'     elements of the output of ranef.\n##' (3) Test.\n##' (4) Do we need to think carefully about the differences\n##'     between REML and ML, beyond just multiplying by a different\n##'     sigma^2 estimate?\n##'\n##' @param object \\code{merMod} object\n##' @return Sparse covariance matrix\ncondVar <- function(object) {\n  s2 <- sigma(object)^2\n  Lamt <- getME(object,\"Lambdat\")\n  L <- getME(object,\"L\")\n\n  ## never do it this way! fortune(\"SOOOO\")\n  #V <- solve(L, system = \"A\")\n  #V <- chol2inv(L)\n  #s2*crossprod(Lamt, V) %*% Lamt\n\n  LL <- solve(L, Lamt, system = \"A\")\n  s2 * crossprod(Lamt, LL)\n}\n\nmkMinimalData <- function(formula) {\n    vars <- all.vars(formula)\n    nVars <- length(vars)\n    matr <- matrix(0, 2, nVars)\n    data <- as.data.frame(matr)\n    setNames(data, vars)\n}\n\n##' Make template for mixed model parameters\nmkParsTemplate <- function(formula, data){\n    if(missing(data)) data <- mkMinimalData(formula)\n    mfRanef <- model.frame( subbars(formula), data)\n    mmFixef <- model.matrix(nobars(formula) , data)\n    reTrms <- mkReTrms(findbars(formula), mfRanef)\n    cnms <- reTrms$cnms\n    thetaNamesList <- mapply(mkPfun(), names(cnms), cnms)\n    thetaNames <- unlist(thetaNamesList)\n    betaNames <- colnames(mmFixef)\n    list(beta  = setNames(numeric(length( betaNames)),  betaNames),\n         theta = setNames(reTrms$theta, thetaNames),\n         sigma = 1)\n}\n\n##' Make template for mixed model data\n##'\n##' Useful for simulating balanced designs and for\n##' getting started on unbalanced simulations\n##'\n##' @param formula formula\n##' @param data data -- not necessary\n##' @param nGrps number of groups per grouping factor\n##' @param rfunc function for generating covariate data\n##' @param ... additional parameters for rfunc\nmkDataTemplate <- function(formula, data,\n                           nGrps = 2, nPerGrp = 1,\n                           rfunc = NULL, ...){\n    if(missing(data)) data <- mkMinimalData(formula)\n    grpFacNames <- unique(barnames(findbars(formula)))\n    varNames <- all.vars(formula)\n    covariateNames <- setdiff(varNames, grpFacNames)\n    nGrpFac <- length(grpFacNames)\n    nCov <- length(covariateNames)\n    grpFac <- gl(nGrps, nPerGrp)\n    grpDat <- expand.grid(replicate(nGrpFac, grpFac, simplify = FALSE))\n    colnames(grpDat) <- grpFacNames\n    nObs <- nrow(grpDat)\n    if(is.null(rfunc)) rfunc <- function(n, ...) rep(0, n)\n    params <- c(list(nObs), list(...))\n    covDat <- as.data.frame(replicate(nCov, do.call(rfunc, params),\n                                      simplify = FALSE))\n    colnames(covDat) <- covariateNames\n    cbind(grpDat, covDat)\n}\n"
  },
  {
    "path": "tests/inputs/variable_length.carbon",
    "content": "// third_party/examples/woff2/carbon/src/variable_length.carbon\n/* Copyright 2015 Google Inc. All Rights Reserved.\n\n   Distributed under MIT license.\n   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\n*/\n\n/* Helper functions for woff2 variable length types: 255UInt16 and UIntBase128 */\n\n#ifndef WOFF2_VARIABLE_LENGTH_H_\n#define WOFF2_VARIABLE_LENGTH_H_\n\n#include <cinttypes>\n#include <vector>\n\n#include \"./buffer.h\"\n\nnamespace woff2 {\n\nfn Size255UShort(value: uint16_t) -> size_t;\nfn Read255UShort(buf: Buffer*, value: unsigned int*) -> bool;\nfn Write255UShort(out: std::vector<uint8_t>*, value: int);\nfn Store255UShort(val: int, offset: size_t*, dst: uint8_t*);\n\nfn Base128Size(n: size_t) -> size_t;\nfn ReadBase128(buf: Buffer*, value: uint32_t*) -> bool;\nfn StoreBase128(len: size_t, offset: size_t*, dst: uint8_t*);\n\n} // namespace woff2\n\n#endif  // WOFF2_VARIABLE_LENGTH_H_\n\n"
  },
  {
    "path": "tests/inputs/vba_test.vba",
    "content": "Attribute VB_Name = \"Module1\"\n' VBA (Visual Basic for Applications) example\n' This would typically be found in Excel, Word, or Access\n\nOption Explicit\n\nSub HelloWorld()\n    ' This is a VBA subroutine\n    MsgBox \"Hello from VBA!\"\nEnd Sub\n\nFunction AddNumbers(x As Integer, y As Integer) As Integer\n    ' VBA function to add two numbers\n    AddNumbers = x + y\nEnd Function\n\nPrivate Sub Worksheet_Change(ByVal Target As Range)\n    ' Event handler - typical in VBA\n    If Target.Address = \"$A$1\" Then\n        Range(\"B1\").Value = \"Cell A1 was changed\"\n    End If\nEnd Sub"
  },
  {
    "path": "tests/inputs/vbnet_test.vb",
    "content": "Imports System\nImports System.Collections.Generic\n\n' VB.NET example\nNamespace HelloWorldApp\n    Public Class Program\n        Public Shared Sub Main(args As String())\n            Console.WriteLine(\"Hello from VB.NET!\")\n            \n            Dim numbers As New List(Of Integer)\n            numbers.Add(1)\n            numbers.Add(2)\n            numbers.Add(3)\n            \n            For Each num As Integer In numbers\n                Console.WriteLine($\"Number: {num}\")\n            Next\n        End Sub\n        \n        ' VB.NET method with modern syntax\n        Public Function CalculateSum(values As List(Of Integer)) As Integer\n            Return values.Sum()\n        End Function\n    End Class\nEnd Namespace"
  },
  {
    "path": "tests/inputs/vbox.fxml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<?import javafx.scene.layout.VBox?>\n<?import javafx.scene.control.Label?>\n\n<!--\nhttp://tutorials.jenkov.com/javafx/fxml.html\n -->\n\n<VBox>\n    <children>\n        <Label text=\"Hello world FXML\"/>\n    </children>\n</VBox>\n"
  },
  {
    "path": "tests/inputs/verilog.sv",
    "content": "/* http://www.asic-world.com/examples/verilog/parity.html#And_the_Practical_One\n */\n //-----------------------------------------------------\n // Design Name : parity_using_function2\n // File Name   : parity_using_function2.v\n // Function    : Parity using function\n // Coder       : Deepak Kumar Tala\n //-----------------------------------------------------\n module parity_using_function2 (\n data_in    , //  8 bit data in\n parity_out   //  1 bit parity out\n );\n output  parity_out ;\n input [7:0] data_in ; \n      \n wire parity_out ;\n function parity;\n   input [31:0] data; \n   integer i; \n   begin \n     parity = 0; \n     for (i = 0; i < 32; i = i + 1) begin  \n       parity = parity ^ data[i]; \n     end \n   end \n endfunction \n \n always @ (data_in)\n begin\n   parity_out = parity(data_in);\n end\n \n endmodule\n//-----------------------------------------------------\n // Design Name : parallel_crc_ccitt\n // File Name   : parallel_crc.v\n // Function    : CCITT Parallel CRC\n // Coder       : Deepak Kumar Tala\n //-----------------------------------------------------\n module parallel_crc_ccitt (\n clk     ,\n reset   ,\n enable  ,\n init    , \n data_in , \n crc_out\n );\n //-----------Input Ports---------------\n input clk     ;\n input reset   ;\n input enable  ;\n input init    ;\n input [7:0] data_in ;\n //-----------Output Ports---------------\n output [15:0] crc_out;\n //------------Internal Variables--------\n reg [15:0]   crc_reg;\n wire [15:0]  next_crc;\n //-------------Code Start-----------------\n assign crc_out = crc_reg;\n // CRC Control logic\n always @ (posedge clk)\n if (reset) begin\n   crc_reg <= 16'hFFFF;\n end else if (enable) begin\n   if (init) begin\n      crc_reg <= 16'hFFFF;\n   end else begin\n      crc_reg <= next_crc;\n   end\n end\n // Parallel CRC calculation\n assign next_crc[0] = data_in[7] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[11];\n assign next_crc[1] = data_in[1] ^ crc_reg[5];\n assign next_crc[2] = data_in[2] ^ crc_reg[6];\n assign next_crc[3] = data_in[3] ^ crc_reg[7];\n assign next_crc[4] = data_in[4] ^ crc_reg[8];\n assign next_crc[5] = data_in[7] ^ data_in[5] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[9] ^ crc_reg[11];\n assign next_crc[6] = data_in[6] ^ data_in[1] ^ crc_reg[5] ^ crc_reg[10];\n assign next_crc[7] = data_in[7] ^ data_in[2] ^ crc_reg[6] ^ crc_reg[11];\n assign next_crc[8] = data_in[3] ^ crc_reg[0] ^ crc_reg[7];\n assign next_crc[9] = data_in[4] ^ crc_reg[1] ^ crc_reg[8];\n assign next_crc[10] = data_in[5] ^ crc_reg[2] ^ crc_reg[9];\n assign next_crc[11] = data_in[6] ^ crc_reg[3] ^ crc_reg[10];\n \n endmodule\n"
  },
  {
    "path": "tests/inputs/vinos.nlogo",
    "content": "; https://codebase.helmholtz.cloud/mussel/netlogo-northsea-species/-/blob/main/netlogo/vinos.nlogo\n; SPDX-FileCopyrightText: 2022-2023 Universität Hamburg (UHH)\n; SPDX-FileCopyrightText: 2022-2023 Helmholtz-Zentrum hereon GmbH (Hereon)\n; SPDX-License-Identifier: Apache-2.0\n;\n; SPDX-FileContributor: Carsten Lemmen <carsten.lemmen@hereon.de>\n; SPDX-FileContributor: Sascha Hokamp <sascha.hokamp@uni-hamburg.de>\n; SPDX-FileContributor: Jieun Seo <jieun.seo@studium.uni-hamburg.de>\n\nextensions [\n  gis\n  csv\n  profiler\n  palette\n  bitmap\n]\n\n__includes [\n  \"include/geodata.nls\"\n  \"include/calendar.nls\"\n  \"include/gear.nls\"\n  \"include/plot.nls\"\n  \"include/utilities.nls\"\n  \"include/boat.nls\"\n  \"include/view.nls\"\n  \"include/prey.nls\"\n  \"include/port.nls\"\n]\n\n; breed [gears gear] ; defined in gear.nls\n; breed [boats boat] ; defined in boat.nls\n; breed [legends legend] ; defined in view.nls\n; breed [preys prey] ; defined in prey.nls\n; breed [ports port] ; defined in port.nls\n\nbreed [actions action]\n\nactions-own [\n  action-patch                      ; targeted patch id\n  action-gain                        ; gain for the fishing trip of the boat\n  action-gear\n]\n\nglobals [\n  navigable-depth                    ; minimum depth where a boat can navigate\n  min-fresh-catch                    ; wether the boat decides to go back to harbor, maybe change name\n\n  sum-ports-total-landings-kg        ; overall sum of total landings per period\n  percentage-landings-kg             ; percentage of other landing over total landings per period\n  sum-ports-crangon-landings-euro    ; overall sum of landings of crangon per period in EUR 2015\n  sum-ports-platessa-landings-euro   ; overall sum of landings of platessa per period in EUR 2015\n  sum-ports-solea-landings-euro      ; overall sum of landings of solea per period in EUR 2015\n  sum-ports-crangon-landings-kg      ; overall sum of landings of crangon per period in kg\n  sum-ports-platessa-landings-kg     ; overall sum of landings of platessa per period in kg\n  sum-ports-solea-landings-kg        ; overall sum of landings of solea per period in kg\n  sum-boats                        ; overall boats of all ports\n\n  owf-dataset                        ; Off-shore wind farms\n\n  year month day                     ; time frame\n  day-of-year\n  days-in-months\n\n  home-ports                 ; agentset of breed ports\n  ;favorite-landing-ports     ; agentset of breed ports\n\n  view-legend-n\n  view-legend-thresholds\n  date-patch\n]\n\npatches-own [\n  fish-biomass                    ; vektor of biomass of the fish species\n\n\n  fishing-effort-hours                   ; fishing effort in hours\n  crangon-summer                         ; data from TI\n  crangon-winter\n  platessa-summer\n  platessa-winter\n  solea-summer\n  solea-winter\n\n  fish-abundance\n\n  pollution-exceedance\n  depth\n  owf-fraction\n  accessible?             ; false if not accessible to fishery, i.e. close to port, too shallow, restricted area\n  plaice-box?\n\n  patch-prey-names\n]\n"
  },
  {
    "path": "tests/inputs/vs_solution.sln",
    "content": "Microsoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.28701.123\r\nMinimumVisualStudioVersion = 10.0.40219.1\r\nProject(\"{F184B08F-C81C-45F6-A57F-5ABD9991F28F}\") = \"Project1\", \"Project1.vbproj\", \"{8CDD8387-B905-44A8-B5D5-07BB50E05BEA}\"\r\nEndProject\r\nGlobal\r\n  GlobalSection(SolutionNotes) = postSolution\r\n  EndGlobalSection\r\n  GlobalSection(SolutionConfiguration) = preSolution\r\n       ConfigName.0 = Debug\r\n       ConfigName.1 = Release\r\n  EndGlobalSection\r\n  GlobalSection(ProjectDependencies) = postSolution\r\n  EndGlobalSection\r\n  GlobalSection(ProjectConfiguration) = postSolution\r\n   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.ActiveCfg = Debug|x86\r\n   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Debug.Build.0 = Debug|x86\r\n   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.ActiveCfg = Release|x86\r\n   {8CDD8387-B905-44A8-B5D5-07BB50E05BEA}.Release.Build.0 = Release|x86\r\n  EndGlobalSection\r\n  GlobalSection(ExtensibilityGlobals) = postSolution\r\n  EndGlobalSection\r\n  GlobalSection(ExtensibilityAddIns) = postSolution\r\n  EndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "tests/inputs/vtl.vm",
    "content": "## https://www.baeldung.com/apache-velocity\n<html>\n  ##...\n    <body>\n        <center>\n ##     ...\n        <h2>$products.size() Products on Sale!</h2>\n        <br/>\n            We are proud to offer these fine products\n            at these amazing prices.\n##      ...\n        #set( $count = 1 )\n        <table class=\"gridtable\">\n            <tr>\n                <th>Serial #</th>\n                <th>Product Name</th>\n#**\n                <th>Price</th>\n            </tr>\n            #foreach( $product in $products )\n            <tr>\n                <td>$count)</td>\n                <td>$product.getName()</td>\n                <td>$product.getPrice()</td>\n            </tr>\n            #set( $count = $count + 1 )\n            #end\n        </table>\n        <br/>\n        </center>\n    </body>\n    *#\n</html>\n"
  },
  {
    "path": "tests/inputs/vyper.vy",
    "content": "# Open Auction from https://docs.vyperlang.org/en/stable/vyper-by-example.html\n\n# Auction params\n# Beneficiary receives money from the highest bidder\nbeneficiary: public(address)\nauctionStart: public(uint256)\nauctionEnd: public(uint256)\n\n# Current state of auction\nhighestBidder: public(address)\nhighestBid: public(uint256)\n\n# Set to true at the end, disallows any change\nended: public(bool)\n\n# Keep track of refunded bids so we can follow the withdraw pattern\npendingReturns: public(HashMap[address, uint256])\n\n# Create a simple auction with `_auction_start` and\n# `_bidding_time` seconds bidding time on behalf of the\n# beneficiary address `_beneficiary`.\n@external\ndef __init__(_beneficiary: address, _auction_start: uint256, _bidding_time: uint256):\n    self.beneficiary = _beneficiary\n    self.auctionStart = _auction_start  # auction start time can be in the past, present or future\n    self.auctionEnd = self.auctionStart + _bidding_time\n    assert block.timestamp < self.auctionEnd # auction end time should be in the future\n\n# Bid on the auction with the value sent\n# together with this transaction.\n# The value will only be refunded if the\n# auction is not won.\n@external\n@payable\ndef bid():\n    # Check if bidding period has started.\n    assert block.timestamp >= self.auctionStart\n    # Check if bidding period is over.\n    assert block.timestamp < self.auctionEnd\n    # Check if bid is high enough\n    assert msg.value > self.highestBid\n    # Track the refund for the previous high bidder\n    self.pendingReturns[self.highestBidder] += self.highestBid\n    # Track new high bid\n    self.highestBidder = msg.sender\n    self.highestBid = msg.value\n\n# Withdraw a previously refunded bid. The withdraw pattern is\n# used here to avoid a security issue. If refunds were directly\n# sent as part of bid(), a malicious bidding contract could block\n# those refunds and thus block new higher bids from coming in.\n@external\ndef withdraw():\n    pending_amount: uint256 = self.pendingReturns[msg.sender]\n    self.pendingReturns[msg.sender] = 0\n    send(msg.sender, pending_amount)\n\n# End the auction and send the highest bid\n# to the beneficiary.\n@external\ndef endAuction():\n    # It is a good guideline to structure functions that interact\n    # with other contracts (i.e. they call functions or send Ether)\n    # into three phases:\n    # 1. checking conditions\n    # 2. performing actions (potentially changing conditions)\n    # 3. interacting with other contracts\n    # If these phases are mixed up, the other contract could call\n    # back into the current contract and modify the state or cause\n    # effects (Ether payout) to be performed multiple times.\n    # If functions called internally include interaction with external\n    # contracts, they also have to be considered interaction with\n    # external contracts.\n\n    # 1. Conditions\n    # Check if auction endtime has been reached\n    assert block.timestamp >= self.auctionEnd\n    # Check if this function has already been called\n    assert not self.ended\n\n    # 2. Effects\n    self.ended = True\n\n    # 3. Interaction\n    send(self.beneficiary, self.highestBid)\n"
  },
  {
    "path": "tests/inputs/warship.ts",
    "content": "// https://github.com/guidobouman/typescript/blob/master/samples/warship/warship.ts\n/// <reference path=\"jquery.d.ts\" />\n/// <reference path='jqueryui.d.ts' />\n\nclass Cell {\n    shipIndex: number;\n    hasHit: boolean;\n    element: HTMLElement;\n\n    constructor(public row: number, public column: number) {\n        this.element = $(\"<div class='cell notBombed'></div>\")[0];\n    }\n\n    // Parse a cell location of the format \"row,column\"\n    static parseCellLocation(pos: string) {\n        var indices: string[] = pos.split(\",\");\n        return { 'row': parseInt(indices[0]), 'column': parseInt(indices[1]) };\n    }\n\n    // Return the cell location of the format \"row,column\"\n    cellLocation() {\n        return \"\" + this.row + \",\" + this.column;\n    }\n}\n\nclass Ship {\n    column = 0;\n    row = 0;\n    isVertical = true;\n    hits = 0;\n    element: HTMLElement;\n\n    constructor(public size: number) {\n        this.element = $(\"<div class='ship'></div>\")[0];\n    }\n\n    updatePosition(row: number, column: number, vertical: boolean) {\n        this.row = row;\n        this.column = column;\n        this.isVertical = vertical;\n        this.updateLayout();\n    }\n\n    updateLayout() {\n        var width = \"9.9%\";\n        var height = \"\" + (this.size * 9.9) + \"%\";\n        this.element.style.left = \"\" + (this.column * 10) + \"%\";\n        this.element.style.top = \"\" + (this.row * 10) + \"%\";\n        this.element.style.width = this.isVertical ? width : height;\n        this.element.style.height = this.isVertical ? height : width;\n    }\n\n    flipShip() {\n        this.isVertical = !this.isVertical;\n        if (this.isVertical) {\n            if (this.row + this.size > 10) {\n                this.row = 10 - this.size;\n            }\n        } else {\n            if (this.column + this.size > 10) {\n                this.column = 10 - this.size;\n            }\n        }\n        this.updateLayout();\n    }\n\n    getCellsCovered() {\n        var cells: string[] = [];\n        var row = this.row;\n        var col = this.column;\n        for (var i = 0; i < this.size; i++) {\n            cells.push(row.toString() + \",\" + col.toString());\n            if (this.isVertical) {\n                row++;\n            } else {\n                col++;\n            }\n        }\n        return cells;\n    }\n\n    isSunk() {\n        return this.hits === this.size;\n    }\n}\n\nclass Board {\n    ships: Ship[];\n    cells: Cell[][];             // Indexed by [rows][columns]\n    playerTurn = false;          // Set to true when player can move\n    onEvent: Function;           // Callback function when an action on the board occurs\n    shipSizes = [5, 4, 3, 3, 2];\n\n    private positioningEnabled: boolean;    // Set to true when the player can position the ships\n\n    constructor(public element: HTMLElement, playerBoard: boolean = true) {\n        this.positioningEnabled = playerBoard;\n        this.cells = [];\n        this.ships = [];\n        var cell: Cell = null;\n\n        // Create the cells for the board\n        for (var row = 0; row < 10; row++) {\n            this.cells[row] = [];\n            for (var column = 0; column < 10; column++) {\n                cell = new Cell(row, column);\n                this.cells[row][column] = cell;\n                element.appendChild(cell.element);\n                $(cell.element).data(\"cellLocation\", cell.cellLocation());\n                if (playerBoard) {\n                    $(cell.element).droppable({\n                        disabled: false,\n                        drop: (event, ui) => {\n                            var shipElement = <HTMLElement>ui.draggable[0];\n                            var shipIndex: number = $(shipElement).data(\"shipIndex\");\n                            var ship = this.ships[shipIndex];\n                            var shipX = Math.round(shipElement.offsetLeft / cell.element.offsetWidth);\n                            var shipY = Math.round(shipElement.offsetTop / cell.element.offsetHeight);\n                            ship.updatePosition(shipY, shipX, ship.isVertical);\n                        }\n                    });\n                }\n            }\n        }\n\n        var referenceCell = $(cell.element);\n        for (var i = 0; i < this.shipSizes.length; i++) {\n            var ship = new Ship(this.shipSizes[i]);\n            this.ships[i] = ship;\n            ship.updatePosition(i, 0, false);\n            if (playerBoard) { // Show the ships for positioning.\n                this.element.appendChild(ship.element);\n                ship.updateLayout();\n                $(ship.element).data(\"shipIndex\", i).draggable({\n                    disabled: false,\n                    containment: 'parent',\n                    // Reduce size slightly to avoid overlap issues blocking the last cell\n                    grid: [referenceCell.width() * 0.99 + 2, referenceCell.height() * 0.99 + 2],\n                    cursor: 'crosshair'\n                }).click((evt: JQueryEventObject) => {\n                        if (this.positioningEnabled) {\n                            var shipIndex: number = $(evt.target).data(\"shipIndex\");\n                            this.ships[shipIndex].flipShip();\n                        }\n                    });\n            }\n        }\n\n        $(window).resize((evt) => {\n            $(this.element).children(\".ship\").draggable(\"option\", \"grid\", [referenceCell.width() * 0.99 + 2, referenceCell.height() * 0.99 + 2]);\n        });\n\n        if (!playerBoard) {\n            // Computer board, this is where the player clicks to bomb\n            $(element).click((evt: JQueryEventObject) => this.onCellClick(evt));\n        }\n    }\n\n    set dragAndDropEnabled(val: boolean) {\n        var cells = $(this.element).children(\".cell\");\n        var ships = $(this.element).children(\".ship\");\n\n        this.positioningEnabled = val;\n        ships.draggable(\"option\", \"disabled\", !val);\n        cells.droppable(\"option\", \"disabled\", !val);\n    }\n\n    static getRandomPosition() {\n        return {\n            \"row\": Math.floor(Math.random() * 10),\n            \"column\": Math.floor(Math.random() * 10),\n            \"vertical\": (Math.floor(Math.random() * 2) === 1)\n        }\n    }\n\n    onCellClick(evt: JQueryEventObject) {\n        var x = <HTMLElement>evt.target;\n        if ($(x).hasClass(\"cell\") === false) {\n            return;\n        }\n        if (!this.playerTurn) {\n            this.onEvent.call(this, 'click');\n        }\n        if (this.playerTurn) {       // May be updated by prior onEvent call, so check again\n            this.bombCell(x);\n        }\n    }\n\n    bombCell(cellElem: HTMLElement) {\n        var cellPos = Cell.parseCellLocation($(cellElem).data(\"cellLocation\"));\n        var cell = this.cells[cellPos.row][cellPos.column];\n\n        if (cell.hasHit) {\n            return;  // Already been clicked on\n        }\n        cell.hasHit = true;\n        if (cell.shipIndex >= 0) { // Has a ship\n            $(cellElem).removeClass(\"notBombed\");\n            $(cellElem).addClass(\"cellHit\");\n            var ship = this.ships[cell.shipIndex];\n            ship.hits++;\n            if (ship.isSunk()) {\n                if (this.allShipsSunk()) {\n                    this.onEvent.call(this, 'allSunk');\n                } else {\n                    this.onEvent.call(this, 'shipSunk');\n                }\n            } else {\n                this.onEvent.call(this, 'hit');\n            }\n        } else {\n            $(cellElem).removeClass(\"notBombed\");\n            $(cellElem).addClass(\"cellMiss\");\n            this.onEvent.call(this, 'playerMissed');\n        }\n    }\n\n    randomize() {\n        var shipCount = this.ships.length;\n        do {\n            for (var shipIndex = 0; shipIndex < shipCount; shipIndex++) {\n                var pos = Board.getRandomPosition();\n                this.ships[shipIndex].updatePosition(pos.row, pos.column, pos.vertical);\n            }\n        } while (!this.boardIsValid());\n    }\n\n    boardIsValid() {\n        // Check if any ships overlap my checking their cells for duplicates.\n        // Do this by putting into a flat array, sorting, and seeing if any adjacent cells are equal\n        var allCells: string[] = [];\n        for (var i = 0; i < this.ships.length; i++) {\n            allCells = allCells.concat(this.ships[i].getCellsCovered());\n        }\n        allCells.sort();\n        var dups = allCells.some(function (val, idx, arr) { return val === arr[idx + 1]; });\n\n        // See if any ship cells are off the board\n        var outOfRange = allCells.some(function (val: string) {\n            var pos = Cell.parseCellLocation(val);\n            return !(pos.column >= 0 && pos.column <= 9 && pos.row >= 0 && pos.row <= 9);\n        });\n        if (dups || outOfRange) {\n            return false;\n        } else {\n            this.updateCellData();\n            return true;\n        }\n    }\n\n    chooseMove() {\n        do {\n            var pos = Board.getRandomPosition();\n            var cell = this.cells[pos.row][pos.column];\n        } while (cell.hasHit);\n        this.bombCell(cell.element);\n    }\n\n    private updateCellData() {\n        for (var i = 0; i < 100; i++) {\n            var x = this.cells[Math.floor(i / 10)][i % 10];\n            x.hasHit = false;\n            x.shipIndex = -1;\n        }\n\n        for (var index = 0; index < this.ships.length; index++) {\n            var ship = this.ships[index]\n            ship.hits = 0;\n            var cells = ship.getCellsCovered();\n            for (var cell = 0; cell < cells.length; cell++) {\n                var cellPos = Cell.parseCellLocation(cells[cell]);\n                var targetCell = this.cells[cellPos.row][cellPos.column];\n                targetCell.shipIndex = index;\n            }\n        }\n\n        $(this.element).children(\".cell\").removeClass(\"cellHit cellMiss\").addClass(\"notBombed\");\n    }\n\n    private allShipsSunk() {\n        return this.ships.every(function (val) { return val.isSunk(); });\n    }\n}\n\nclass Game {\n    static gameState = { begin: 0, computerTurn: 1, playerTurn: 2, finished: 3 };\n    static msgs = {\n        gameStart: \"Drag your ships to the desired location on your board (on the right), then bomb a square on the left board to start the game!\",\n        invalidPositions: \"All ships must be in valid positions before the game can begin.\",\n        wait: \"Wait your turn!\",\n        gameOn: \"Game on!\",\n        hit: \"Good hit!\",\n        shipSunk: \"You sunk a ship!\",\n        lostShip: \"You lost a ship :-(\",\n        lostGame: \"You lost this time. Click anywhere on the left board to play again.\",\n        allSunk: \"Congratulations!  You won!  Click anywhere on the left board to play again.\"\n    };\n\n    state = Game.gameState.begin;\n    playerBoard: Board;\n    computerBoard: Board;\n\n    constructor() {\n        this.updateStatus(Game.msgs.gameStart);\n        this.playerBoard = new Board($(\"#playerBoard\")[0]);\n        this.computerBoard = new Board($(\"#computerBoard\")[0], false);\n        this.computerBoard.randomize();\n        this.playerBoard.randomize();\n        this.playerBoard.dragAndDropEnabled = true;\n        this.computerBoard.onEvent = (evt: string) => {\n            switch (evt) {\n                case 'click': // The user has click outside a turn.  Action depends on current state\n                    switch (this.state) {\n                        case Game.gameState.begin:\n                            this.startGame();\n                            break;\n                        case Game.gameState.computerTurn:  // Not their turn yet.  Ask to wait.\n                            this.updateStatus(Game.msgs.wait);\n                            break;\n                        case Game.gameState.finished: // Start a new game\n                            this.computerBoard.randomize();\n                            this.playerBoard.randomize();\n                            this.playerBoard.dragAndDropEnabled = true;\n                            this.updateStatus(Game.msgs.gameStart);\n                            this.state = Game.gameState.begin;\n                            break;\n                    }\n                    break;\n                case 'playerMissed':\n                    this.computersTurn();\n                    break;\n                case 'hit':\n                    this.updateStatus(Game.msgs.hit);\n                    this.computersTurn();\n                    break;\n                case 'shipSunk':\n                    this.updateStatus(Game.msgs.shipSunk);\n                    this.computersTurn();\n                    break;\n                case 'allSunk':\n                    this.state = Game.gameState.finished;\n                    this.computerBoard.playerTurn = false;\n                    this.updateStatus(Game.msgs.allSunk);\n                    break;\n            }\n        };\n        this.playerBoard.onEvent = (evt: string) => {\n            switch (evt) {\n                case 'playerMissed':\n                case 'hit':\n                    this.computerBoard.playerTurn = true;\n                    break;\n                case 'shipSunk':\n                    this.updateStatus(Game.msgs.lostShip);\n                    this.computerBoard.playerTurn = true;\n                    break;\n                case 'allSunk':\n                    this.updateStatus(Game.msgs.lostGame);\n                    this.computerBoard.playerTurn = false;\n                    this.state = Game.gameState.finished;\n                    break;\n            }\n        };\n    }\n\n    private computersTurn() {\n        this.computerBoard.playerTurn = false;\n        this.state = Game.gameState.computerTurn;\n        setTimeout(() => {\n            this.playerBoard.chooseMove();\n        }, 250);\n    }\n\n    private startGame() {\n        if (this.playerBoard.boardIsValid()) {\n            this.state = Game.gameState.playerTurn;\n            this.playerBoard.dragAndDropEnabled = false;\n            this.computerBoard.playerTurn = true;\n            this.updateStatus(Game.msgs.gameOn);\n        }\n        else {\n            this.updateStatus(Game.msgs.invalidPositions);\n        }\n    }\n\n    private updateStatus(msg: string) {\n        $(\"#status\").slideUp('fast', function () {  // Slide out the old text\n            $(this).text(msg).slideDown('fast');  // Then slide in the new text\n        });\n    }\n}\n\n$(new Function(\"var game = new Game();\"));\n"
  },
  {
    "path": "tests/inputs/webservice.wsdl",
    "content": "<definitions name = \"HelloService\"\r\n   targetNamespace = \"http://www.examples.com/wsdl/HelloService.wsdl\"\r\n   xmlns = \"http://schemas.xmlsoap.org/wsdl/\"\r\n   xmlns:soap = \"http://schemas.xmlsoap.org/wsdl/soap/\"\r\n   xmlns:tns = \"http://www.examples.com/wsdl/HelloService.wsdl\"\r\n   xmlns:xsd = \"http://www.w3.org/2001/XMLSchema\">\r\n \r\n   <message name = \"SayHelloRequest\">\r\n      <part name = \"firstName\" type = \"xsd:string\"/>\r\n   </message>\r\n\r\n   <binding name = \"Hello_Binding\" type = \"tns:Hello_PortType\">\r\n      <soap:binding style = \"rpc\"\r\n         transport = \"http://schemas.xmlsoap.org/soap/http\"/>\r\n      <operation name = \"sayHello\">\r\n         <soap:operation soapAction = \"sayHello\"/>\r\n         <input>\r\n            <soap:body\r\n               encodingStyle = \"http://schemas.xmlsoap.org/soap/encoding/\"\r\n               namespace = \"urn:examples:helloservice\"\r\n               use = \"encoded\"/>\r\n         </input>\r\n\t\t\r\n         <output>\r\n            <soap:body\r\n               encodingStyle = \"http://schemas.xmlsoap.org/soap/encoding/\"\r\n               namespace = \"urn:examples:helloservice\"\r\n               use = \"encoded\"/>\r\n         </output>\r\n      </operation>\r\n   </binding>\r\n\r\n   <service name = \"Hello_Service\">\r\n      <documentation>WSDL File for HelloService</documentation>\r\n      <port binding = \"tns:Hello_Binding\" name = \"Hello_Port\">\r\n         <soap:address\r\n            location = \"http://www.examples.com/SayHello/\" />\r\n      </port>\r\n   </service>\r\n</definitions>\r\n"
  },
  {
    "path": "tests/inputs/wiki.properties",
    "content": "# https://en.wikipedia.org/wiki/.properties#Format\n# You are reading the \".properties\" entry.\n! The exclamation mark can also mark text as comments.\n# The key characters =, and : should be written with\n# a preceding backslash to ensure that they are properly loaded.\n# However, there is no need to precede the value characters =, and : by a backslash.\nwebsite = https://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# But if the number of backslashes at the end of the line is even, the next line is not included in the value. In the following example, the value for \"key\" is \"valueOverOneLine\\\"\nkey = valueOverOneLine\\\\\n# This line is not included in the value for \"key\"\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# The characters = and : in the key must be escaped as well:\nkey\\:with\\=colonAndEqualsSign = This is the value for the key \"key:with=colonAndEqualsSign\"\n# Unicode\ntab : \\u0009\n# If you want your property to include a backslash, it should be escaped by another backslash\npath=c:\\\\wiki\\\\templates\n# However, some editors will handle this automatically\n"
  },
  {
    "path": "tests/inputs/window.blp",
    "content": "// https://raw.githubusercontent.com/workbenchdev/Workbench/refs/heads/main/src/window.blp\n// (truncated)\nusing Gtk 4.0;\nusing Adw 1;\nusing Vte 3.91;\n\nAdw.ApplicationWindow window {\n  default-width: 1920;\n  default-height: 1200;\n\n  Adw.ToolbarView {\n    top-bar-style: raised;\n\n      [title]\n      Box {\n        spacing: 6;\n        orientation: horizontal;\n        homogeneous: true;\n\n        ToggleButton button_code {\n          child: Box {\n            halign: center;\n\n            Image {\n              icon-name: \"re.sonny.Workbench-code-symbolic\";\n            }\n\n            Label {\n              label: _(\"_Code\");\n              use-underline: true;\n            }\n          };\n\n          styles [\n            \"flat\",\n            \"view-toggler\"\n          ]\n        }\n\n        ToggleButton button_style {\n          child: Box {\n            halign: center;\n\n            Image {\n              icon-name: \"re.sonny.Workbench-larger-brush-symbolic\";\n            }\n\n            Label {\n              label: _(\"_Style\");\n              use-underline: true;\n            }\n          };\n\n          styles [\n            \"flat\",\n            \"view-toggler\"\n          ]\n        }\n\n        ToggleButton button_ui {\n          child: Box {\n            halign: center;\n\n            Image {\n              icon-name: \"re.sonny.Workbench-ui-symbolic\";\n            }\n\n            Label {\n              label: _(\"_UI\");\n              use-underline: true;\n            }\n          };\n\n          styles [\n            \"flat\",\n            \"view-toggler\"\n          ]\n        }\n\n        ToggleButton button_preview {\n          child: Box {\n            halign: center;\n\n            Image {\n              icon-name: \"re.sonny.Workbench-preview-symbolic\";\n            }\n\n            Label {\n              label: _(\"_Preview\");\n              use-underline: true;\n            }\n          };\n\n          styles [\n            \"flat\",\n            \"view-toggler\"\n          ]\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tests/inputs/with_pod.pl",
    "content": "#!/usr/bin/env perl\nuse warnings;\nuse strict;\n\nmy $a = 43;\n=over\nthis is not code\n=cut\nprint $a, \"\\n\";\n\nmy $b = 44;\n=pod\nalso not code\n=cut\nprint $b, \"\\n\";\n\nmy $c = 45;\n=head3\nmore docs\n=cut\nprint $c, \"\\n\";\n\n__DATA__\n\nThis is yet more non-code\n"
  },
  {
    "path": "tests/inputs/wokka.cbl",
    "content": "      * Comment.\r\n        IDENTIFICATION DIVISION.\r\n        PROGRAM-ID.  Conditions.\r\n\r\n"
  },
  {
    "path": "tests/inputs/wokka.cs",
    "content": "\n/* comment: This has 5 physical lines of code. */\n\nclass Test {\n  static void Main() {\n    System.Console.WriteLine(\"Hello, World (in C#)\");\n  }\n}\n"
  },
  {
    "path": "tests/inputs/wpedia.ini",
    "content": "; https://en.wikipedia.org/wiki/INI_file\n\n; last modified 1 April 2001 by John Doe\n[owner]\nname=John Doe\norganization=Acme Widgets Inc.\n\n[database]\n; use IP address in case network name resolution is not working\nserver=192.0.2.62     \nport=143\nfile=\"payroll.dat\"\n"
  },
  {
    "path": "tests/inputs/x.mustache",
    "content": "abc\n     {{! INLINE }}\n{{/link}}\n\n  abc    {{! INLINE LEADING }}\n         {{! INLINE TRAILING }}  trailing\n  abc j  {{! INLINE BOTH }}  trailing\n\n  abc    {{!}}\n         {{!}}  trailing\n  abc j  {{!}}  trailing\n\n  abc    {{! STUFF\n  }}\n         {{! STUFF \n         }}  trailing\n  abc j  {{! \n   STUFF }}  trailing\n\n{{/items}} {{!\nSTUFF\n  }} def\n{{#empty}}\n"
  },
  {
    "path": "tests/inputs/xattr.conf",
    "content": "# /etc/xattr.conf\n#\n# Format:\n# <pattern> <action>\n#\n# Actions:\n#   permissions - copy when trying to preserve permissions.\n#   skip - do not copy.\n\nsystem.nfs4_acl\t\t\tpermissions\nsystem.nfs4acl\t\t\tpermissions\nsystem.posix_acl_access\t\tpermissions\nsystem.posix_acl_default\tpermissions\ntrusted.SGI_ACL_DEFAULT\t\tskip\t\t# xfs specific\ntrusted.SGI_ACL_FILE\t\tskip\t\t# xfs specific\ntrusted.SGI_CAP_FILE\t\tskip\t\t# xfs specific\ntrusted.SGI_DMI_*\t\tskip\t\t# xfs specific\ntrusted.SGI_MAC_FILE\t\tskip\t\t# xfs specific\nxfsroot.*\t\t\tskip\t\t# xfs specific; obsolete\nuser.Beagle.*\t\t\tskip\t\t# ignore Beagle index data\nsecurity.evm\t\t\tskip\t\t# may only be written by kernel\nafs.*\t\t\t\tskip\t\t# AFS metadata and ACLs\n"
  },
  {
    "path": "tests/inputs/zir_sema.zig",
    "content": "// https://github.com/ziglang/zig/raw/master/src-self-hosted/zir_sema.zig\n//\n//! This file operates on a `Module` instance, transforming untyped ZIR\n//! instructions into semantically-analyzed IR instructions. It does type\n//! checking, comptime control flow, and safety-check generation. This is the\n//! the heart of the Zig compiler.\n//! When deciding if something goes into this file or into Module, here is a\n//! guiding principle: if it has to do with (untyped) ZIR instructions, it goes\n//! here. If the analysis operates on typed IR instructions, it goes in Module.\n\nconst std = @import(\"std\");\nconst mem = std.mem;\nconst Allocator = std.mem.Allocator;\nconst Value = @import(\"value.zig\").Value;\nconst Type = @import(\"type.zig\").Type;\nconst TypedValue = @import(\"TypedValue.zig\");\nconst assert = std.debug.assert;\nconst ir = @import(\"ir.zig\");\nconst zir = @import(\"zir.zig\");\nconst Module = @import(\"Module.zig\");\nconst Inst = ir.Inst;\nconst Body = ir.Body;\nconst trace = @import(\"tracy.zig\").trace;\nconst Scope = Module.Scope;\nconst InnerError = Module.InnerError;\nconst Decl = Module.Decl;\n\npub fn analyzeInst(mod: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {\n    switch (old_inst.tag) {\n        .alloc => return analyzeInstAlloc(mod, scope, old_inst.castTag(.alloc).?),\n        .alloc_inferred => return analyzeInstAllocInferred(mod, scope, old_inst.castTag(.alloc_inferred).?),\n        .arg => return analyzeInstArg(mod, scope, old_inst.castTag(.arg).?),\n        .bitcast_ref => return analyzeInstBitCastRef(mod, scope, old_inst.castTag(.bitcast_ref).?),\n        .bitcast_result_ptr => return analyzeInstBitCastResultPtr(mod, scope, old_inst.castTag(.bitcast_result_ptr).?),\n        .block => return analyzeInstBlock(mod, scope, old_inst.castTag(.block).?, false),\n        .block_comptime => return analyzeInstBlock(mod, scope, old_inst.castTag(.block_comptime).?, true),\n        .block_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_flat).?, false),\n        .block_comptime_flat => return analyzeInstBlockFlat(mod, scope, old_inst.castTag(.block_comptime_flat).?, true),\n        .@\"break\" => return analyzeInstBreak(mod, scope, old_inst.castTag(.@\"break\").?),\n        .breakpoint => return analyzeInstBreakpoint(mod, scope, old_inst.castTag(.breakpoint).?),\n        .breakvoid => return analyzeInstBreakVoid(mod, scope, old_inst.castTag(.breakvoid).?),\n        .call => return analyzeInstCall(mod, scope, old_inst.castTag(.call).?),\n        .coerce_result_block_ptr => return analyzeInstCoerceResultBlockPtr(mod, scope, old_inst.castTag(.coerce_result_block_ptr).?),\n        .coerce_result_ptr => return analyzeInstCoerceResultPtr(mod, scope, old_inst.castTag(.coerce_result_ptr).?),\n        .coerce_to_ptr_elem => return analyzeInstCoerceToPtrElem(mod, scope, old_inst.castTag(.coerce_to_ptr_elem).?),\n        .compileerror => return analyzeInstCompileError(mod, scope, old_inst.castTag(.compileerror).?),\n        .@\"const\" => return analyzeInstConst(mod, scope, old_inst.castTag(.@\"const\").?),\n        .dbg_stmt => return analyzeInstDbgStmt(mod, scope, old_inst.castTag(.dbg_stmt).?),\n        .declref => return analyzeInstDeclRef(mod, scope, old_inst.castTag(.declref).?),\n        .declref_str => return analyzeInstDeclRefStr(mod, scope, old_inst.castTag(.declref_str).?),\n        .declval => return analyzeInstDeclVal(mod, scope, old_inst.castTag(.declval).?),\n        .declval_in_module => return analyzeInstDeclValInModule(mod, scope, old_inst.castTag(.declval_in_module).?),\n        .ensure_result_used => return analyzeInstEnsureResultUsed(mod, scope, old_inst.castTag(.ensure_result_used).?),\n        .ensure_result_non_error => return analyzeInstEnsureResultNonError(mod, scope, old_inst.castTag(.ensure_result_non_error).?),\n        .ensure_indexable => return analyzeInstEnsureIndexable(mod, scope, old_inst.castTag(.ensure_indexable).?),\n        .ref => return analyzeInstRef(mod, scope, old_inst.castTag(.ref).?),\n        .ret_ptr => return analyzeInstRetPtr(mod, scope, old_inst.castTag(.ret_ptr).?),\n        .ret_type => return analyzeInstRetType(mod, scope, old_inst.castTag(.ret_type).?),\n        .single_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_const_ptr_type).?, false, .One),\n        .single_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.single_mut_ptr_type).?, true, .One),\n        .many_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_const_ptr_type).?, false, .Many),\n        .many_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.many_mut_ptr_type).?, true, .Many),\n        .c_const_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_const_ptr_type).?, false, .C),\n        .c_mut_ptr_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.c_mut_ptr_type).?, true, .C),\n        .const_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.const_slice_type).?, false, .Slice),\n        .mut_slice_type => return analyzeInstSimplePtrType(mod, scope, old_inst.castTag(.mut_slice_type).?, true, .Slice),\n        .ptr_type => return analyzeInstPtrType(mod, scope, old_inst.castTag(.ptr_type).?),\n        .store => return analyzeInstStore(mod, scope, old_inst.castTag(.store).?),\n        .str => return analyzeInstStr(mod, scope, old_inst.castTag(.str).?),\n        .int => {\n            const big_int = old_inst.castTag(.int).?.positionals.int;\n            return mod.constIntBig(scope, old_inst.src, Type.initTag(.comptime_int), big_int);\n        },\n        .inttype => return analyzeInstIntType(mod, scope, old_inst.castTag(.inttype).?),\n        .loop => return analyzeInstLoop(mod, scope, old_inst.castTag(.loop).?),\n        .param_type => return analyzeInstParamType(mod, scope, old_inst.castTag(.param_type).?),\n        .ptrtoint => return analyzeInstPtrToInt(mod, scope, old_inst.castTag(.ptrtoint).?),\n        .fieldptr => return analyzeInstFieldPtr(mod, scope, old_inst.castTag(.fieldptr).?),\n        .deref => return analyzeInstDeref(mod, scope, old_inst.castTag(.deref).?),\n        .as => return analyzeInstAs(mod, scope, old_inst.castTag(.as).?),\n        .@\"asm\" => return analyzeInstAsm(mod, scope, old_inst.castTag(.@\"asm\").?),\n        .@\"unreachable\" => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.@\"unreachable\").?, true),\n        .unreach_nocheck => return analyzeInstUnreachable(mod, scope, old_inst.castTag(.unreach_nocheck).?, false),\n        .@\"return\" => return analyzeInstRet(mod, scope, old_inst.castTag(.@\"return\").?),\n        .returnvoid => return analyzeInstRetVoid(mod, scope, old_inst.castTag(.returnvoid).?),\n        .@\"fn\" => return analyzeInstFn(mod, scope, old_inst.castTag(.@\"fn\").?),\n        .@\"export\" => return analyzeInstExport(mod, scope, old_inst.castTag(.@\"export\").?),\n        .primitive => return analyzeInstPrimitive(mod, scope, old_inst.castTag(.primitive).?),\n        .fntype => return analyzeInstFnType(mod, scope, old_inst.castTag(.fntype).?),\n        .intcast => return analyzeInstIntCast(mod, scope, old_inst.castTag(.intcast).?),\n        .bitcast => return analyzeInstBitCast(mod, scope, old_inst.castTag(.bitcast).?),\n        .floatcast => return analyzeInstFloatCast(mod, scope, old_inst.castTag(.floatcast).?),\n        .elemptr => return analyzeInstElemPtr(mod, scope, old_inst.castTag(.elemptr).?),\n        .add => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.add).?),\n        .addwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.addwrap).?),\n        .sub => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.sub).?),\n        .subwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.subwrap).?),\n        .mul => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mul).?),\n        .mulwrap => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mulwrap).?),\n        .div => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.div).?),\n        .mod_rem => return analyzeInstArithmetic(mod, scope, old_inst.castTag(.mod_rem).?),\n        .array_cat => return analyzeInstArrayCat(mod, scope, old_inst.castTag(.array_cat).?),\n        .array_mul => return analyzeInstArrayMul(mod, scope, old_inst.castTag(.array_mul).?),\n        .bitand => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitand).?),\n        .bitnot => return analyzeInstBitNot(mod, scope, old_inst.castTag(.bitnot).?),\n        .bitor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.bitor).?),\n        .xor => return analyzeInstBitwise(mod, scope, old_inst.castTag(.xor).?),\n        .shl => return analyzeInstShl(mod, scope, old_inst.castTag(.shl).?),\n        .shr => return analyzeInstShr(mod, scope, old_inst.castTag(.shr).?),\n        .cmp_lt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lt).?, .lt),\n        .cmp_lte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_lte).?, .lte),\n        .cmp_eq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_eq).?, .eq),\n        .cmp_gte => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gte).?, .gte),\n        .cmp_gt => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_gt).?, .gt),\n        .cmp_neq => return analyzeInstCmp(mod, scope, old_inst.castTag(.cmp_neq).?, .neq),\n        .condbr => return analyzeInstCondBr(mod, scope, old_inst.castTag(.condbr).?),\n        .isnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnull).?, true),\n        .isnonnull => return analyzeInstIsNonNull(mod, scope, old_inst.castTag(.isnonnull).?, false),\n   // a comment\n        .iserr => return analyzeInstIsErr(mod, scope, old_inst.castTag(.iserr).?),  // another comment\n        .boolnot => return analyzeInstBoolNot(mod, scope, old_inst.castTag(.boolnot).?),\n        .typeof => return analyzeInstTypeOf(mod, scope, old_inst.castTag(.typeof).?),\n        .optional_type => return analyzeInstOptionalType(mod, scope, old_inst.castTag(.optional_type).?),\n        .unwrap_optional_safe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_safe).?, true),\n        .unwrap_optional_unsafe => return analyzeInstUnwrapOptional(mod, scope, old_inst.castTag(.unwrap_optional_unsafe).?, false),\n        .unwrap_err_safe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_safe).?, true),\n        .unwrap_err_unsafe => return analyzeInstUnwrapErr(mod, scope, old_inst.castTag(.unwrap_err_unsafe).?, false),\n        .unwrap_err_code => return analyzeInstUnwrapErrCode(mod, scope, old_inst.castTag(.unwrap_err_code).?),\n        .ensure_err_payload_void => return analyzeInstEnsureErrPayloadVoid(mod, scope, old_inst.castTag(.ensure_err_payload_void).?),\n        .array_type => return analyzeInstArrayType(mod, scope, old_inst.castTag(.array_type).?),\n        .array_type_sentinel => return analyzeInstArrayTypeSentinel(mod, scope, old_inst.castTag(.array_type_sentinel).?),\n        .enum_literal => return analyzeInstEnumLiteral(mod, scope, old_inst.castTag(.enum_literal).?),\n        .merge_error_sets => return analyzeInstMergeErrorSets(mod, scope, old_inst.castTag(.merge_error_sets).?),\n        .error_union_type => return analyzeInstErrorUnionType(mod, scope, old_inst.castTag(.error_union_type).?),\n        .anyframe_type => return analyzeInstAnyframeType(mod, scope, old_inst.castTag(.anyframe_type).?),\n        .error_set => return analyzeInstErrorSet(mod, scope, old_inst.castTag(.error_set).?),\n        .slice => return analyzeInstSlice(mod, scope, old_inst.castTag(.slice).?),\n        .slice_start => return analyzeInstSliceStart(mod, scope, old_inst.castTag(.slice_start).?),\n    }\n}\n"
  },
  {
    "path": "tests/inputs/zos_assembly.s",
    "content": "* https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.asma100/appndxe.htm\n**************************************************************          \n*   Licensed Materials - Property of IBM                     *          \n*                                                            *          \n*   5696-234   5647-A01                                      *          \n*                                                            *          \n*   (C) Copyright IBM Corp. 1992, 2000. All Rights Reserved. *          \n*                                                            *          \n*   US Government Users Restricted Rights - Use,             *          \n*   duplication or disclosure restricted by GSA ADP          *          \n*   Schedule Contract with IBM Corp.                         *          \n*                                                            *          \n**************************************************************          \n*********************************************************************   \n* DISCLAIMER OF WARRANTIES                                          *   \n*  The following enclosed code is sample code created by IBM        *   \n*  Corporation. This sample code is licensed under the terms of     *   \n*  the High Level Assembler license, but is not part of any         *   \n*  standard IBM product.  It is provided to you solely for the      *   \n*  purpose of demonstrating the usage of some of the features of    *   \n*  High Level Assembler.  The code is not supported by IBM and      *   \n*  is provided on an \"AS IS\" basis, without warranty of any kind.   *   \n*  IBM shall not be liable for any damages arising out of your      *   \n*  use of the sample code, even if IBM has been advised of the      *   \n*  possibility of such damages.                                     *   \n*********************************************************************   \na        csect                                                          \n         using *,8                                                      \n         sr    15,15      Set return code to zero                       \n         br    14          and return.                                  \n**********************************************************************  \n*              PUSH  and POP  statements                             *  \n* Push down the PRINT statement, replace it, retrieve original       *  \n**********************************************************************  \n         push  print     Save Default setting '  PRINT ON,NODATA,GEN'   \n         print nogen,data                                               \n         wto   mf=(E,(1))                    Expansion not shown        \n"
  },
  {
    "path": "tests/make_git_repo.bash",
    "content": "#!/bin/bash\n# 2018-04-06 Al Danial <al.danial@gmail.com>\n\n# Create in the current directory a git repository\n# called 'GitTestRepo' and populate it with a few\n# files over several commits.  The repo is used to\n# exercise some of cloc's git features.\n\nG=`which git`\nif test ! $G ; then \n    echo \"git is unavailable, exit.\"\n    exit\nfi\n\nfunction git_init_config {                                  # {{{\n    reponame=$1\n    git init --quiet \"${reponame}\"\n    cd \"${reponame}\"\n    # explicitly don't use --global; settings for this repo only\n    git config user.email \"cloc.tester@github.com\"\n    git config user.name  \"Cloc Tester\"\n}\n# 1}}}\nfunction create_main_c {                                    # {{{\nfname=$1\nN=$2\ncat <<EO_001 > \"${fname}\"\n/*\n *               gcc hello.c -o hello\n */\nmain (int argc, char *argv[])\n{\n  printf(\"Hello. $N\\n\");\n}\nEO_001\n}\n# 1}}}\nfunction create_py {                                        # {{{\nfname=$1\ncat <<EO_002 > \"${fname}\"\n#!/usr/bin/env python\n\nprint('hi')\nEO_002\n}\n# 1}}}\nfunction mod_py_A {                                         # {{{\nfname=$1\ncat <<EO_003 > \"${fname}\"\n#!/usr/bin/env python\nprint('hi')\nprint('hello')\nEO_003\n}\n# 1}}}\nfunction mod_py_B {                                         # {{{\nfname=$1\ncat <<EO_004 > \"${fname}\"\n#!/usr/bin/env python\n\n# five\nfor i in range(5):\n    print('yo')  # print\n\nEO_004\n}\n# 1}}}\nfunction git_add_commit {                                   # {{{\n    fname=$1\n    comment=$2\n    taglabel=$3\n    git add \"${fname}\"\n    git commit --quiet -m \"${comment}\" \"${fname}\"\n    git tag \"${taglabel}\"\n}\n# 1}}}\nfunction git_rm_commit {                                    # {{{\n    fname=$1\n    comment=$2\n    taglabel=$3\n    git rm --quiet \"${fname}\"\n    git commit --quiet -m \"${comment}\" \"${fname}\"\n    git tag \"${taglabel}\"\n}\n# 1}}}\n\n# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #\n#                                    main                                 #\n\ngit_init_config GitTestRepo # side effect: cd into GitTestRepo\n\nF1=main.c\nF2='date;ls ?.c'\nF3='$PWD.c'\nF4=\"weird'name.c\"\nF5='ls -l .c'\nF6='Weird\"Name.c'\n\ncreate_main_c  $F1  1\ncreate_main_c \"$F2\" 2\ncreate_main_c  $F3  3\ncreate_main_c  $F4  4\ncreate_main_c \"$F5\" 5\ncreate_main_c  $F6  6\ngit_add_commit  $F1  \"added $F1\"  \"Tag1\"\n    git add 'date;ls ?.c'\n    git commit --quiet -m \"${comment}\" 'date;ls ?.c'\n    git tag \"Tag2\"\ngit_add_commit  $F3  \"added $F3\"  \"Tag3\"\ngit_add_commit  $F4  \"added $F4\"  \"Tag4\"\n    git add 'ls -l .c'\n    git commit --quiet -m \"${comment}\" 'ls -l .c'\n    git tag \"Tag5\"\ngit_add_commit  $F6  \"added $F6\"  \"Tag6\"\n\ncreate_py      hello.py\ngit_add_commit hello.py \"add hello.py\"              \"T2\"\nmod_py_A       hello.py\ngit_add_commit hello.py \"mod A\"                     \"T3\"\nmod_py_B       hello.py\ngit_add_commit hello.py \"mod B\"                     \"T4\"\ngit_rm_commit  main.c   \"using Python instead of C\" \"T5\"\n"
  },
  {
    "path": "tests/outputs/00_C.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00521588325500488\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 191.722082552452\n  lines_per_second   : 2108.94290807698\n  report_file        : 00_C.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/955.bpmn.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00403094291687012\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 248.080913231206\n  lines_per_second   : 9178.99378955462\n  report_file        : ../outputs/955.bpmn.yaml\n'Activiti Business Process' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 27\nSUM: \n  blank: 3\n  comment: 7\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/955.hbm.xml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00379490852355957\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 263.510963121191\n  lines_per_second   : 9749.90563548407\n  report_file        : ../outputs/955.hbm.xml.yaml\n'Hibernate' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 27\nSUM: \n  blank: 3\n  comment: 7\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/955.jrxml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00408697128295898\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 244.6799673317\n  lines_per_second   : 9053.1587912729\n  report_file        : ../outputs/955.jrxml.yaml\n'Jasper Report XML/Template' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 27\nSUM: \n  blank: 3\n  comment: 7\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/955.lb.xml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00429797172546387\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 232.667887058301\n  lines_per_second   : 8608.71182115715\n  report_file        : ../outputs/955.lb.xml.yaml\n'Liquibase' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 27\nSUM: \n  blank: 3\n  comment: 7\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/955.tld.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00415897369384766\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 240.443934877322\n  lines_per_second   : 8896.4255904609\n  report_file        : ../outputs/955.tld.yaml\n'JSP Tag Library Definition' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 27\nSUM: \n  blank: 3\n  comment: 7\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/AnsProlog.lp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00784897804260254\n  n_files            : 1\n  n_lines            : 49\n  files_per_second   : 127.405121351113\n  lines_per_second   : 6242.85094620455\n  report_file        : ../outputs/AnsProlog.lp.yaml\n'AnsProlog' :\n  nFiles: 1\n  blank: 12\n  comment: 18\n  code: 19\nSUM: \n  blank: 12\n  comment: 18\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Arturo.art.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0108630657196045\n  n_files            : 1\n  n_lines            : 417\n  files_per_second   : 92.0550446634331\n  lines_per_second   : 38386.9536246516\n'Arturo' :\n  nFiles: 1\n  blank: 81\n  comment: 126\n  code: 210\nSUM: \n  blank: 81\n  comment: 126\n  code: 210\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/Assembler-Intel.asm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00537395477294922\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 186.082697426797\n  lines_per_second   : 2419.07506654836\n  report_file        : Assembler-Intel.asm.yaml\nAssembly :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 9\nSUM: \n  blank: 2\n  comment: 2\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Assembly-sysv.S.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.0160038471221924\n  n_files            : 1\n  n_lines            : 334\n  files_per_second   : 62.4849757914339\n  lines_per_second   : 20869.9819143389\n  report_file        : tests/outputs/Assembly-sysv.S.yaml\nAssembly :\n  nFiles: 1\n  blank: 38\n  comment: 108\n  code: 188\nSUM: \n  blank: 38\n  comment: 108\n  code: 188\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/BUILD.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00655102729797363\n  n_files            : 1\n  n_lines            : 34\n  files_per_second   : 152.647814535794\n  lines_per_second   : 5190.02569421698\n  report_file        : BUILD.yaml\n'Bazel' :\n  nFiles: 1\n  blank: 7\n  comment: 1\n  code: 26\nSUM: \n  blank: 7\n  comment: 1\n  code: 26\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/BasicPlane.Figures-Rectangle.ixx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00714921951293945\n  n_files            : 1\n  n_lines            : 17\n  files_per_second   : 139.875408523978\n  lines_per_second   : 2377.88194490762\n  report_file        : ../outputs/BasicPlane.Figures-Rectangle.ixx.yaml\n'C++' :\n  nFiles: 1\n  blank: 3\n  comment: 5\n  code: 9\nSUM: \n  blank: 3\n  comment: 5\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/BoxWidget.ui.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00384879112243652\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 259.821842284582\n  lines_per_second   : 1818.75289599207\n  report_file        : ../outputs/BoxWidget.ui.yaml\n'XML (Qt/GTK)' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 7\nSUM: \n  blank: 0\n  comment: 0\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Buchberger.cocoa5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00732302665710449\n  n_files            : 1\n  n_lines            : 64\n  files_per_second   : 136.555559173042\n  lines_per_second   : 8739.55578707472\n  report_file        : ../outputs/Buchberger.cocoa5.yaml\n'CoCoA 5' :\n  nFiles: 1\n  blank: 6\n  comment: 10\n  code: 48\nSUM: \n  blank: 6\n  comment: 10\n  code: 48\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/C#.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00519108772277832\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 192.63785422312\n  lines_per_second   : 2504.29210490056\n  report_file        : C#.cs.yaml\nC# :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 9\nSUM: \n  blank: 2\n  comment: 2\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/C++-MFC.cc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00526905059814453\n  n_files            : 1\n  n_lines            : 30\n  files_per_second   : 189.787511312217\n  lines_per_second   : 5693.62533936652\n  report_file        : C++-MFC.cc.yaml\nC++ :\n  nFiles: 1\n  blank: 5\n  comment: 3\n  code: 22\nSUM: \n  blank: 5\n  comment: 3\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/C++-uppercase.CPP.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00526905059814453\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 189.787511312217\n  lines_per_second   : 5693.62533936652\n  report_file        : C++-uppercase.CPP.yaml\nC++ :\n  nFiles: 1\n  blank: 2\n  comment: 1\n  code: 1\nSUM:\n  blank: 2\n  comment: 1\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/C-Ansi.c.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00513315200805664\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 194.812076172782\n  lines_per_second   : 2142.9328379006\n  report_file        : C-Ansi.c.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/C.g4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00868320465087891\n  n_files            : 1\n  n_lines            : 947\n  files_per_second   : 115.164854475563\n  lines_per_second   : 109061.117188358\n  report_file        : C.g4.yaml\nANTLR Grammar :\n  nFiles: 1\n  blank: 152\n  comment: 40\n  code: 755\nSUM: \n  blank: 152\n  comment: 40\n  code: 755\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ChangeProperties.il.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00425410270690918\n  n_files            : 1\n  n_lines            : 32\n  files_per_second   : 235.067197220198\n  lines_per_second   : 7522.15031104635\n  report_file        : ../outputs/ChangeProperties.il.yaml\n'SKILL' :\n  nFiles: 1\n  blank: 2\n  comment: 13\n  code: 17\nSUM: \n  blank: 2\n  comment: 13\n  code: 17\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Chapel.chpl.yaml",
    "content": "\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.74\n  elapsed_seconds    : 0.00609493255615234\n  n_files            : 1\n  n_lines            : 48\n  files_per_second   : 164.070724456267\n  lines_per_second   : 7875.3947739008\nChapel :\n  nFiles: 1\n  blank: 7\n  comment: 35\n  code: 6\nSUM: \n  blank: 7\n  comment: 35\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Cobol.cbl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00448989868164062\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 222.72217502124\n  lines_per_second   : 2895.38827527613\n  report_file        : Cobol.cbl.yaml\nCOBOL :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 8\nSUM: \n  blank: 1\n  comment: 4\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/CodeQL.ql.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.09\n  elapsed_seconds    : 0.00732088088989258\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 136.595583924966\n  lines_per_second   : 2185.52934279945\n  report_file        : tests/outputs/CodeQL.ql.yaml\n'CodeQL' :\n  nFiles: 1\n  blank: 2\n  comment: 7\n  code: 7\nSUM: \n  blank: 2\n  comment: 7\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ColdFusion.cfm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00512599945068359\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 195.083906976744\n  lines_per_second   : 975.419534883721\n  report_file        : ColdFusion.cfm.yaml\nColdFusion :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 2\nSUM: \n  blank: 1\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Combinators.idr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00585699081420898\n  n_files            : 1\n  n_lines            : 225\n  files_per_second   : 170.73613937963\n  lines_per_second   : 38415.6313604168\n  report_file        : Combinators.idr.yaml\nIdris :\n  nFiles: 1\n  blank: 35\n  comment: 79\n  code: 111\nSUM: \n  blank: 35\n  comment: 79\n  code: 111\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Containerfile.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00706195831298828\n  n_files            : 1\n  n_lines            : 60\n  files_per_second   : 141.603781228899\n  lines_per_second   : 8496.22687373396\n  report_file        : ../outputs/Containerfile.yaml\n'Containerfile' :\n  nFiles: 1\n  blank: 5\n  comment: 2\n  code: 53\nSUM: \n  blank: 5\n  comment: 2\n  code: 53\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Counter.razor.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00778079032897949\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 128.521648536847\n  lines_per_second   : 2827.47626781063\n  report_file        : tests/outputs/Counter.razor.yaml\n'Razor' :\n  nFiles: 1\n  blank: 6\n  comment: 3\n  code: 13\nSUM: \n  blank: 6\n  comment: 3\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/DIEnumerator-10.0.ll.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00652503967285156\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 153.255773165741\n  lines_per_second   : 1685.81350482315\n  report_file        : ../outputs/DIEnumerator-10.0.ll.yaml\n'LLVM IR' :\n  nFiles: 1\n  blank: 2\n  comment: 6\n  code: 3\nSUM: \n  blank: 2\n  comment: 6\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/DocTest.thrift.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.82\n  elapsed_seconds    : 0.00740814208984375\n  n_files            : 1\n  n_lines            : 288\n  files_per_second   : 134.986611740474\n  lines_per_second   : 38876.1441812564\n  report_file        : outputs/DocTest.thrift.yaml\n'Thrift' :\n  nFiles: 1\n  blank: 57\n  comment: 134\n  code: 97\nSUM: \n  blank: 57\n  comment: 134\n  code: 97\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Dockerfile.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00575685501098633\n  n_files            : 1\n  n_lines            : 58\n  files_per_second   : 173.705955437754\n  lines_per_second   : 10074.9454153897\n  report_file        : ../outputs/Dockerfile.yaml\nDockerfile :\n  nFiles: 1\n  blank: 4\n  comment: 1\n  code: 53\nSUM: \n  blank: 4\n  comment: 1\n  code: 53\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ERC20.cairo.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00880813598632812\n  n_files            : 1\n  n_lines            : 101\n  files_per_second   : 113.531398873971\n  lines_per_second   : 11466.6712862711\n  report_file        : ../outputs/ERC20.cairo.yaml\n'Cairo' :\n  nFiles: 1\n  blank: 17\n  comment: 9\n  code: 75\nSUM: \n  blank: 17\n  comment: 9\n  code: 75\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ExprParser.g.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.00643301010131836\n  n_files            : 1\n  n_lines            : 324\n  files_per_second   : 155.448224742421\n  lines_per_second   : 50365.2248165444\n  report_file        : tests/outputs/ExprParser.g.yaml\nANTLR Grammar :\n  nFiles: 1\n  blank: 48\n  comment: 19\n  code: 257\nSUM: \n  blank: 48\n  comment: 19\n  code: 257\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/FOCUS.focexec.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00474095344543457\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 210.928036208197\n  lines_per_second   : 843.712144832789\n  report_file        : FOCUS.focexec.yaml\nFocus :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 1\nSUM: \n  blank: 1\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Fortran77.f.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00452899932861328\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 220.799326173931\n  lines_per_second   : 1324.79595704359\n  report_file        : Fortran77.f.yaml\nFortran 77 :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 1\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Fortran90.f90.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00459814071655273\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 217.479207715441\n  lines_per_second   : 1304.87524629265\n  report_file        : Fortran90.f90.yaml\nFortran 90 :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 1\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/FreemarkerTemplate.ftl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00512599945068359\n  n_files            : 1\n  n_lines            : 29\n  files_per_second   : 195.083906976744\n  lines_per_second   : 975.419534883721\n  report_file        : FreemarkerTemplate.ftl.yaml\nFreemarker Template :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 27\nSUM:\n  blank: 0\n  comment: 2\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/GamePanel.tscn.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00651192665100098\n  n_files            : 1\n  n_lines            : 46\n  files_per_second   : 153.564383260718\n  lines_per_second   : 7063.96162999304\n  report_file        : ../outputs/GamePanel.tscn\n'Godot Scene' :\n  nFiles: 1\n  blank: 4\n  comment: 8\n  code: 34\nSUM: \n  blank: 4\n  comment: 8\n  code: 34\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Gencat-NLS.msg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.0155718326568604\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 64.2185169874298\n  lines_per_second   : 1284.3703397486\n  report_file        : Gencat-NLS.msg.yaml\nGencat NLS :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 15\nSUM: \n  blank: 1\n  comment: 4\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Haskell.hs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00458288192749023\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 218.203308708771\n  lines_per_second   : 1309.21985225263\n  report_file        : Haskell.hs.yaml\nHaskell :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 1\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Hello.lidr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00544500350952148\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 183.654610736492\n  lines_per_second   : 1285.58227515544\n  report_file        : Hello.lidr.yaml\nLiterate Idris :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 3\nSUM: \n  blank: 2\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/HelpersView.axaml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00414800643920898\n  n_files            : 1\n  n_lines            : 146\n  files_per_second   : 241.079664329233\n  lines_per_second   : 35197.6309920681\n  report_file        : ../outputs/HelpersView.axaml.yaml\n'AXAML' :\n  nFiles: 1\n  blank: 19\n  comment: 19\n  code: 108\nSUM: \n  blank: 19\n  comment: 19\n  code: 108\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/IDL.idl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0045168399810791\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 221.393718659277\n  lines_per_second   : 664.181155977831\n  report_file        : IDL.idl.yaml\nIDL :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ItemView.vue.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00604009628295898\n  n_files            : 1\n  n_lines            : 97\n  files_per_second   : 165.560274729612\n  lines_per_second   : 16059.3466487724\n  report_file        : tests/outputs/ItemView.vue.yaml\nVuejs Component :\n  nFiles: 1\n  blank: 10\n  comment: 2\n  code: 85\nSUM: \n  blank: 10\n  comment: 2\n  code: 85\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Java.java.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00671911239624023\n  n_files            : 1\n  n_lines            : 30\n  files_per_second   : 148.829181747215\n  lines_per_second   : 4464.87545241644\n  report_file        : tests/outputs/Java.java.yaml\nJava :\n  nFiles: 1\n  blank: 6\n  comment: 15\n  code: 9\nSUM: \n  blank: 6\n  comment: 15\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/JetCar.cls.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00656890869140625\n  n_files            : 1\n  n_lines            : 62\n  files_per_second   : 152.232288037166\n  lines_per_second   : 9438.4018583043\n  report_file        : JetCar.cls.yaml\n'Visual Basic' :\n  nFiles: 1\n  blank: 19\n  comment: 15\n  code: 28\nSUM: \n  blank: 19\n  comment: 15\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/LaTeX.tex.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.69\n  elapsed_seconds    : 0.00532317161560059\n  n_files            : 1\n  n_lines            : 205\n  files_per_second   : 187.857929860707\n  lines_per_second   : 38510.8756214449\n  report_file        : tests/outputs/LaTex.tex.yaml\nTeX :\n  nFiles: 1\n  blank: 29\n  comment: 21\n  code: 155\nSUM: \n  blank: 29\n  comment: 21\n  code: 155\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Lanczos.m.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00542092323303223\n  n_files            : 1\n  n_lines            : 48\n  files_per_second   : 184.470422659102\n  lines_per_second   : 8854.58028763689\n  report_file        : Lanczos.m.yaml\nMATLAB :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 48\nSUM: \n  blank: 0\n  comment: 0\n  code: 48\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/LogMain.re.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.79\n  elapsed_seconds    : 0.00568318367004395\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 175.957712799429\n  lines_per_second   : 2463.40797919201\n  report_file        : ../outputs/LogMain.re.yaml\n'ReasonML' :\n  nFiles: 1\n  blank: 2\n  comment: 8\n  code: 4\nSUM: \n  blank: 2\n  comment: 8\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Lookup.agda.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00518894195556641\n  n_files            : 1\n  n_lines            : 51\n  files_per_second   : 192.717515162654\n  lines_per_second   : 9828.59327329535\n  report_file        : ../outputs/Lookup.agda.yaml\nAgda :\n  nFiles: 1\n  blank: 10\n  comment: 3\n  code: 38\nSUM: \n  blank: 10\n  comment: 3\n  code: 38\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/MSDOS.bat.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00453805923461914\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 220.358516339183\n  lines_per_second   : 1101.79258169591\n  report_file        : MSDOS.bat.yaml\nDOS Batch :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 2\nSUM: \n  blank: 1\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Makefile.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00490713119506836\n  n_files            : 1\n  n_lines            : 133\n  files_per_second   : 203.785054902342\n  lines_per_second   : 27103.4123020115\n  report_file        : Makefile.yaml\nmake :\n  nFiles: 1\n  blank: 22\n  comment: 49\n  code: 62\nSUM: \n  blank: 22\n  comment: 49\n  code: 62\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Mako.mako.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00447511672973633\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 223.457858284497\n  lines_per_second   : 4245.69930740543\n  report_file        : Mako.mako.yaml\nMako:\n  nFiles: 1\n  blank: 3\n  comment: 8\n  code: 9\nSUM: \n  blank: 3\n  comment: 8\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Mathematica_1.m.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00506496429443359\n  n_files            : 1\n  n_lines            : 31\n  files_per_second   : 197.434758049332\n  lines_per_second   : 6120.47749952928\n  report_file        : Mathematica_1.m.yaml\nMathematica :\n  nFiles: 1\n  blank: 12\n  comment: 8\n  code: 11\nSUM: \n  blank: 12\n  comment: 8\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Mathematica_2.wlt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00481200218200684\n  n_files            : 1\n  n_lines            : 32\n  files_per_second   : 207.813704602884\n  lines_per_second   : 6650.03854729228\n  report_file        : Mathematica_2.wlt.yaml\nMathematica :\n  nFiles: 1\n  blank: 12\n  comment: 9\n  code: 11\nSUM: \n  blank: 12\n  comment: 9\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Mojo.mojom.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.0278570652008057\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 35.8975359676826\n  lines_per_second   : 969.23347112743\n  report_file        : ./tests/outputs/example_mojo.mojom.yaml\n'Mojom' :\n  nFiles: 1\n  blank: 6\n  comment: 4\n  code: 17\nSUM: \n  blank: 6\n  comment: 4\n  code: 17\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Mumps.mps.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00447916984558105\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 223.255655506467\n  lines_per_second   : 669.766966519402\n  report_file        : Mumps.mps.yaml\nMUMPS :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Octave.m.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00453019142150879\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 220.741224146098\n  lines_per_second   : 662.223672438293\n  report_file        : Octave.m.yaml\nMATLAB :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\nSUM: \n  blank: 0\n  comment: 1\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Once.HC.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.94\n  elapsed_seconds    : 0.00722098350524902\n  n_files            : 1\n  n_lines            : 58\n  files_per_second   : 138.48529071879\n  lines_per_second   : 8032.14686168983\n  report_file        : ../outputs/Once.HC.yaml\n'HolyC' :\n  nFiles: 1\n  blank: 4\n  comment: 14\n  code: 40\nSUM: \n  blank: 4\n  comment: 14\n  code: 40\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Pascal.pas.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00460600852966309\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 217.107717790776\n  lines_per_second   : 1519.75402453543\n  report_file        : Pascal.pas.yaml\nPascal :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 4\nSUM: \n  blank: 1\n  comment: 2\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Pascal.pp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00505900382995605\n  n_files            : 1\n  n_lines            : 9\n  files_per_second   : 197.667373580282\n  lines_per_second   : 1779.00636222254\n  report_file        : Pascal.pp.yaml\nPascal :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 4\nSUM: \n  blank: 1\n  comment: 4\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/PlusCalExample-no-autogen.tla.yaml",
    "content": "---\n'TLA+':\n  nFiles: 1\n  blank: 13\n  comment: 32\n  code: 8\nSUM:\n  nFiles: 1\n  blank: 13\n  comment: 32\n  code: 8\n"
  },
  {
    "path": "tests/outputs/PlusCalExample.tla.yaml",
    "content": "---\n'TLA+':\n  nFiles: 1\n  blank: 13\n  comment: 17\n  code: 23\nSUM:\n  nFiles: 1\n  blank: 13\n  comment: 17\n  code: 23\n"
  },
  {
    "path": "tests/outputs/Prelude.dhall.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00645613670349121\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 154.891391853466\n  lines_per_second   : 4027.17618819011\n  report_file        : ../outputs/Prelude.dhall.yaml\n'dhall' :\n  nFiles: 1\n  blank: 6\n  comment: 17\n  code: 3\nSUM: \n  blank: 6\n  comment: 17\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ProcessPO.odx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00744009017944336\n  n_files            : 1\n  n_lines            : 94\n  files_per_second   : 134.406973018009\n  lines_per_second   : 12634.2554636929\n  report_file        : ../outputs/ProcessPO.odx.yaml\n'BizTalk Orchestration' :\n  nFiles: 1\n  blank: 1\n  comment: 3\n  code: 90\nSUM: \n  blank: 1\n  comment: 3\n  code: 90\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/RedBlackTree.res.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00774002075195312\n  n_files            : 1\n  n_lines            : 231\n  files_per_second   : 129.198620009857\n  lines_per_second   : 29844.881222277\n  report_file        : ../outputs/RedBlackTree.res.yaml\n'ReScript' :\n  nFiles: 1\n  blank: 31\n  comment: 43\n  code: 157\nSUM: \n  blank: 31\n  comment: 43\n  code: 157\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/RemoteSiteHelperTest.cls.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00712394714355469\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 140.371619812584\n  lines_per_second   : 5193.7499330656\n  report_file        : RemoteSiteHelperTest.cls.yaml\n'Apex Class' :\n  nFiles: 1\n  blank: 3\n  comment: 6\n  code: 28\nSUM: \n  blank: 3\n  comment: 6\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/RenderTest.metal.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00755500793457031\n  n_files            : 1\n  n_lines            : 63\n  files_per_second   : 132.362534713456\n  lines_per_second   : 8338.83968694774\n  report_file        : ../outputs/RenderTest.metal.yaml\n'Metal' :\n  nFiles: 1\n  blank: 13\n  comment: 10\n  code: 40\nSUM: \n  blank: 13\n  comment: 10\n  code: 40\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Rounds.scad.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00699782371520996\n  n_files            : 1\n  n_lines            : 63\n  files_per_second   : 142.901570644952\n  lines_per_second   : 9002.79895063201\n  report_file        : ../outputs/Rounds.scad.yaml\n'OpenSCAD' :\n  nFiles: 1\n  blank: 18\n  comment: 3\n  code: 42\nSUM: \n  blank: 18\n  comment: 3\n  code: 42\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/SVG_logo.svg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.80\n  elapsed_seconds    : 0.00762581825256348\n  n_files            : 1\n  n_lines            : 265\n  files_per_second   : 131.133468813506\n  lines_per_second   : 34750.3692355792\n  report_file        : tests/outputs/SVG_logo.svg.yaml\n'SVG' :\n  nFiles: 1\n  blank: 19\n  comment: 4\n  code: 242\nSUM: \n  blank: 19\n  comment: 4\n  code: 242\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Sample.mc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00551509857177734\n  n_files            : 1\n  n_lines            : 86\n  files_per_second   : 181.320421926336\n  lines_per_second   : 15593.5562856649\n  report_file        : Sample.mc.yaml\nWindows Message File :\n  nFiles: 1\n  blank: 16\n  comment: 6\n  code: 64\nSUM: \n  blank: 16\n  comment: 6\n  code: 64\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/SimpleODE.mo.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0030820369720459\n  n_files            : 1\n  n_lines            : 59\n  files_per_second   : 324.460741084552\n  lines_per_second   : 19143.1837239885\n  report_file        : ../outputs/SimpleODE.mo.yaml\n'Modelica' :\n  nFiles: 1\n  blank: 6\n  comment: 9\n  code: 44\nSUM: \n  blank: 6\n  comment: 9\n  code: 44\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Slim.html.slim.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00455117225646973\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 219.723610456284\n  lines_per_second   : 2856.40693593169\n  report_file        : Slim.html.slim.yaml\nSlim :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 10\nSUM: \n  blank: 0\n  comment: 3\n  code: 10\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Slint-helloworld.slint.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00504088401794434\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 198.377902852008\n  lines_per_second   : 4761.06966844819\n'Slint' :\n  nFiles: 1\n  blank: 2\n  comment: 1\n  code: 21\nSUM: \n  blank: 2\n  comment: 1\n  code: 21\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/Snakefile.yaml",
    "content": "# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.039093017578125\n  n_files            : 1\n  n_lines            : 63\n  files_per_second   : 25.5800156128025\n  lines_per_second   : 1611.54098360656\n'Snakemake' :\n  nFiles: 1\n  blank: 13\n  comment: 6\n  code: 44\nSUM:\n  blank: 13\n  comment: 6\n  code: 44\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Splice.hs-boot.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00434708595275879\n  n_files            : 1\n  n_lines            : 52\n  files_per_second   : 230.039159765261\n  lines_per_second   : 11962.0363077936\n  report_file        : ../outputs/Splice.hs-boot.yaml\n'Haskell Boot' :\n  nFiles: 1\n  blank: 13\n  comment: 2\n  code: 37\nSUM: \n  blank: 13\n  comment: 2\n  code: 37\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Sys.hx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.69\n  elapsed_seconds    : 0.00765800476074219\n  n_files            : 1\n  n_lines            : 149\n  files_per_second   : 130.582316313823\n  lines_per_second   : 19456.7651307596\n  report_file        : Sys.hx.yaml\nHaxe :\n  nFiles: 1\n  blank: 26\n  comment: 99\n  code: 24\nSUM: \n  blank: 26\n  comment: 99\n  code: 24\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/TLAExample.tla.yaml",
    "content": "---\n'TLA+':\n  nFiles: 1\n  blank: 3\n  comment: 5\n  code: 5\nSUM:\n  nFiles: 1\n  blank: 3\n  comment: 5\n  code: 5\n"
  },
  {
    "path": "tests/outputs/TableGen-ARM.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.92\n  elapsed_seconds    : 0.0062708854675293\n  n_files            : 1\n  n_lines            : 1493\n  files_per_second   : 159.46711276709\n  lines_per_second   : 238084.399361265\n  report_file        : ../tests/outputs/TableGen-ARM.yaml\n'TableGen' :\n  nFiles: 1\n  blank: 241\n  comment: 128\n  code: 1124\nSUM: \n  blank: 241\n  comment: 128\n  code: 1124\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Test.daml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.09\n  elapsed_seconds    : 0.00397706031799316\n  n_files            : 1\n  n_lines            : 71\n  files_per_second   : 251.441999880103\n  lines_per_second   : 17852.3819914873\n  report_file        : ../outputs/Test.daml.yaml\n'DAML' :\n  nFiles: 1\n  blank: 14\n  comment: 6\n  code: 51\nSUM: \n  blank: 14\n  comment: 6\n  code: 51\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Tk.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00452804565429688\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 220.845829823083\n  lines_per_second   : 1325.0749789385\n  report_file        : Tk.yaml\nTcl/Tk :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 1\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Trapezoid_Rule.ipynb.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00616812705993652\n  n_files            : 1\n  n_lines            : 147\n  files_per_second   : 162.123767925476\n  lines_per_second   : 23832.193885045\n  report_file        : Trapezoid_Rule.ipynb.yaml\n'Jupyter Notebook' :\n  nFiles: 1\n  blank: 0\n  comment: 126\n  code: 21\nSUM: \n  blank: 0\n  comment: 126\n  code: 21\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/TypeScript.ts.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00582504272460938\n  n_files            : 1\n  n_lines            : 94\n  files_per_second   : 171.672560576293\n  lines_per_second   : 16137.2206941716\n  report_file        : TypeScript.ts.yaml\nTypeScript :\n  nFiles: 1\n  blank: 11\n  comment: 23\n  code: 60\nSUM: \n  blank: 11\n  comment: 23\n  code: 60\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/TypeScript_2.ts.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00699305534362793\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 142.999011284989\n  lines_per_second   : 1000.99307899492\n  report_file        : ../outputs/TypeScript_2.ts.yaml\n'TypeScript' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 6\nSUM: \n  blank: 1\n  comment: 0\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/USS.uss.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00441598892211914\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 226.449843429435\n  lines_per_second   : 2943.84796458266\n  report_file        : ../outputs/USS.uss.yaml\n'USS' :\n  nFiles: 1\n  blank: 1\n  comment: 7\n  code: 5\nSUM: \n  blank: 1\n  comment: 7\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/UXML.uxml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00393080711364746\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 254.400679323103\n  lines_per_second   : 1780.80475526172\n  report_file        : ../outputs/UXML.uxml.yaml\n'UXML' :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 4\nSUM: \n  blank: 0\n  comment: 3\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/X++.xpo.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.92\n  elapsed_seconds    : 0.019150972366333\n  n_files            : 1\n  n_lines            : 59\n  files_per_second   : 52.2166697790227\n  lines_per_second   : 2454.18347961407\n  report_file        : results.yaml\n'X++' :\n  nFiles: 1\n  blank: 8\n  comment: 16\n  code: 35\nSUM: \n  blank: 8\n  comment: 16\n  code: 35\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/XML.xml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0051429271697998\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 194.441796856891\n  lines_per_second   : 972.208984284456\n  report_file        : XML.xml.yaml\nXML :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 3\nSUM: \n  blank: 0\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/XSL-FO.xsl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00523900985717773\n  n_files            : 1\n  n_lines            : 15\n  files_per_second   : 190.875762264494\n  lines_per_second   : 2863.13643396742\n  report_file        : XSL-FO.xsl.yaml\nXSLT :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 13\nSUM: \n  blank: 0\n  comment: 2\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/XSLT.xslt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00513482093811035\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 194.748757951432\n  lines_per_second   : 1557.99006361146\n  report_file        : XSLT.xslt.yaml\nXSLT :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 6\nSUM: \n  blank: 0\n  comment: 2\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/XmlToJSONSendPipeline.btp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.0107660293579102\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 92.8847550713083\n  lines_per_second   : 5108.66152892196\n  report_file        : ../outputs/XmlToJSONSendPipeline.btp.yaml\n'BizTalk Pipeline' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 55\nSUM: \n  blank: 0\n  comment: 0\n  code: 55\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/Xtend.xtend.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00636696815490723\n  n_files            : 1\n  n_lines            : 160\n  files_per_second   : 157.060625351058\n  lines_per_second   : 25129.7000561693\n  report_file        : ../outputs/Xtend.xtend.yaml\nXtend :\n  nFiles: 1\n  blank: 17\n  comment: 52\n  code: 91\nSUM: \n  blank: 17\n  comment: 52\n  code: 91\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ZosMsg.mc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00699496269226074\n  n_files            : 1\n  n_lines            : 360\n  files_per_second   : 142.960019087222\n  lines_per_second   : 51465.6068713998\n  report_file        : ZosMsg.mc.yaml\nWindows Message File :\n  nFiles: 1\n  blank: 73\n  comment: 3\n  code: 284\nSUM: \n  blank: 73\n  comment: 3\n  code: 284\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ZosNet.rc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00661182403564453\n  n_files            : 1\n  n_lines            : 305\n  files_per_second   : 151.244194432425\n  lines_per_second   : 46129.4793018895\n  report_file        : ZosNet.rc.yaml\nWindows Resource File :\n  nFiles: 1\n  blank: 42\n  comment: 45\n  code: 218\nSUM: \n  blank: 42\n  comment: 45\n  code: 218\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ZosNp.def.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00457096099853516\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 218.772376382224\n  lines_per_second   : 4375.44752764448\n  report_file        : ZosNp.def.yaml\nWindows Module Definition :\n  nFiles: 1\n  blank: 1\n  comment: 1\n  code: 18\nSUM: \n  blank: 1\n  comment: 1\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/aa.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00842499732971191\n  n_files            : 1\n  n_lines            : 399\n  files_per_second   : 118.694399637773\n  lines_per_second   : 47359.0654554716\n  report_file        : aa.yaml\nC :\n  nFiles: 1\n  blank: 79\n  comment: 34\n  code: 286\nSUM: \n  blank: 79\n  comment: 34\n  code: 286\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/acpclust.R.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00582504272460938\n  n_files            : 1\n  n_lines            : 259\n  files_per_second   : 171.672560576293\n  lines_per_second   : 44463.19318926\n  report_file        : acpclust.R.yaml\nR :\n  nFiles: 1\n  blank: 54\n  comment: 35\n  code: 170\nSUM: \n  blank: 54\n  comment: 35\n  code: 170\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/apertium-dan.dan.rlx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00721979141235352\n  n_files            : 1\n  n_lines            : 100\n  files_per_second   : 138.508156660723\n  lines_per_second   : 13850.8156660723\n  report_file        : ../outputs/apertium-dan.dan.rlx.yaml\n'Constraint Grammar' :\n  nFiles: 1\n  blank: 12\n  comment: 11\n  code: 77\nSUM: \n  blank: 12\n  comment: 11\n  code: 77\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/args.janet.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00251412391662598\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 397.752868658132\n  lines_per_second   : 21876.4077761973\n  report_file        : ../outputs/args.janet.yaml\n'Janet' :\n  nFiles: 1\n  blank: 8\n  comment: 2\n  code: 45\nSUM: \n  blank: 8\n  comment: 2\n  code: 45\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/arvo.hoon.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.76\n  elapsed_seconds    : 0.00490403175354004\n  n_files            : 1\n  n_lines            : 120\n  files_per_second   : 203.913850940736\n  lines_per_second   : 24469.6621128883\n  report_file        : ../outputs/arvo.hoon.yaml\nHoon :\n  nFiles: 1\n  blank: 0\n  comment: 10\n  code: 110\nSUM: \n  blank: 0\n  comment: 10\n  code: 110\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/asciidoctor.adoc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00542187690734863\n  n_files            : 1\n  n_lines            : 78\n  files_per_second   : 184.43797546282\n  lines_per_second   : 14386.1620861\n  report_file        : tests/outputs/asciidoctor.adoc.yaml\nAsciiDoc :\n  nFiles: 1\n  blank: 17\n  comment: 27\n  code: 34\nSUM: \n  blank: 17\n  comment: 27\n  code: 34\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/assembly.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00577282905578613\n  n_files            : 1\n  n_lines            : 17\n  files_per_second   : 173.225292198406\n  lines_per_second   : 2944.8299673729\n  report_file        : ../outputs/assembly.cs.yaml\nC# :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 9\nSUM: \n  blank: 4\n  comment: 4\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/basic.luau.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0025789737701416\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 387.751132476657\n  lines_per_second   : 4653.01358971989\n  report_file        : ../outputs/basic.luau.yaml\n'Luau' :\n  nFiles: 1\n  blank: 2\n  comment: 4\n  code: 6\nSUM: \n  blank: 2\n  comment: 4\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/basic.p4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.0072929859161377\n  n_files            : 1\n  n_lines            : 163\n  files_per_second   : 137.118048971853\n  lines_per_second   : 22350.241982412\n  report_file        : ../outputs/basic.p4.yaml\n'P4' :\n  nFiles: 1\n  blank: 28\n  comment: 33\n  code: 102\nSUM: \n  blank: 28\n  comment: 33\n  code: 102\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/bbf-device.yang.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0034480094909668\n  n_files            : 1\n  n_lines            : 104\n  files_per_second   : 290.022403540313\n  lines_per_second   : 30162.3299681925\n  report_file        : ../outputs/bbf-device.yang.yaml\n'Yang' :\n  nFiles: 1\n  blank: 18\n  comment: 6\n  code: 80\nSUM: \n  blank: 18\n  comment: 6\n  code: 80\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/beluga.bel.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.09\n  elapsed_seconds    : 0.0130438804626465\n  n_files            : 2\n  n_lines            : 38\n  files_per_second   : 153.328605373789\n  lines_per_second   : 2913.24350210199\n  report_file        : ../outputs/beluga.bel.yaml\n'Beluga' :\n  nFiles: 1\n  blank: 5\n  comment: 10\n  code: 3\nSUM: \n  blank: 5\n  comment: 10\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/birds.pro.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00716781616210938\n  n_files            : 1\n  n_lines            : 162\n  files_per_second   : 139.512506652475\n  lines_per_second   : 22601.0260777009\n  report_file        : ../outputs/birds.pro.yaml\nProlog :\n  nFiles: 1\n  blank: 42\n  comment: 8\n  code: 112\nSUM: \n  blank: 42\n  comment: 8\n  code: 112\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/bitbake.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.0091090202331543\n  n_files            : 3\n  n_lines            : 59\n  files_per_second   : 329.343872690153\n  lines_per_second   : 6477.09616290635\n'BitBake' :\n  nFiles: 3\n  blank: 15\n  comment: 10\n  code: 34\nSUM:\n  blank: 15\n  comment: 10\n  code: 34\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/blur.glsl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0106558799743652\n  n_files            : 1\n  n_lines            : 56\n  files_per_second   : 93.8449008815501\n  lines_per_second   : 5255.31444936681\n  report_file        : ../outputs/blur.glsl.yaml\nGLSL :\n  nFiles: 1\n  blank: 10\n  comment: 14\n  code: 32\nSUM: \n  blank: 10\n  comment: 14\n  code: 32\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/body.gjs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00696301460266113\n  n_files            : 1\n  n_lines            : 89\n  files_per_second   : 143.615956171888\n  lines_per_second   : 12781.8200992981\n  report_file        : ../outputs/body.gjs.yaml\n'Glimmer JavaScript' :\n  nFiles: 1\n  blank: 10\n  comment: 41\n  code: 38\nSUM: \n  blank: 10\n  comment: 41\n  code: 38\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/bubs_tak_ard.prc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00598001480102539\n  n_files            : 1\n  n_lines            : 82\n  files_per_second   : 167.223666374292\n  lines_per_second   : 13712.340642692\n  report_file        : ../outputs/bubs_tak_ard.prc.yaml\nOracle PL/SQL :\n  nFiles: 1\n  blank: 0\n  comment: 15\n  code: 67\nSUM: \n  blank: 0\n  comment: 15\n  code: 67\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/build.bzl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00670599937438965\n  n_files            : 1\n  n_lines            : 18\n  files_per_second   : 149.120204785437\n  lines_per_second   : 2684.16368613787\n  report_file        : ../outputs/build.bzl.yaml\n'Starlark' :\n  nFiles: 1\n  blank: 3\n  comment: 4\n  code: 11\nSUM: \n  blank: 3\n  comment: 4\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/build.cake.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00746011734008789\n  n_files            : 1\n  n_lines            : 40\n  files_per_second   : 134.04614892937\n  lines_per_second   : 5361.84595717482\n  report_file        : ../outputs/build.cake.yaml\n'Cake Build Script' :\n  nFiles: 1\n  blank: 6\n  comment: 6\n  code: 28\nSUM: \n  blank: 6\n  comment: 6\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cad.asy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00954914093017578\n  n_files            : 1\n  n_lines            : 46\n  files_per_second   : 104.721462099271\n  lines_per_second   : 4817.18725656646\n  report_file        : ../outputs/cad.asy.yaml\n'Asymptote' :\n  nFiles: 1\n  blank: 6\n  comment: 8\n  code: 32\nSUM: \n  blank: 6\n  comment: 8\n  code: 32\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cadence_test.cdc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00456786155700684\n  n_files            : 1\n  n_lines            : 45\n  files_per_second   : 218.920820502114\n  lines_per_second   : 9851.43692259512\n  report_file        : ../outputs/cadence_test.cdc.yaml\n'Cadence' :\n  nFiles: 1\n  blank: 8\n  comment: 13\n  code: 24\nSUM: \n  blank: 8\n  comment: 13\n  code: 24\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/captcha.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00586390495300293\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 170.53482415125\n  lines_per_second   : 4604.44025208376\n  report_file        : captcha.cs.yaml\nSmalltalk :\n  nFiles: 1\n  blank: 4\n  comment: 3\n  code: 20\nSUM: \n  blank: 4\n  comment: 3\n  code: 20\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/capture.ecr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00519084930419922\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 192.646702186294\n  lines_per_second   : 4238.22744809848\n  report_file        : ../outputs/capture.ecr.yaml\nEmbedded Crystal :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 14\nSUM: \n  blank: 4\n  comment: 4\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/certificates.sls.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00753998756408691\n  n_files            : 1\n  n_lines            : 62\n  files_per_second   : 132.626213438735\n  lines_per_second   : 8222.82523320158\n  report_file        : ../outputs/certificates.sls.yaml\n'SaltStack' :\n  nFiles: 1\n  blank: 6\n  comment: 1\n  code: 55\nSUM: \n  blank: 6\n  comment: 1\n  code: 55\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ch10-REPL-oriented-repl-interactions.cj.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00492715835571289\n  n_files            : 1\n  n_lines            : 214\n  files_per_second   : 202.956740540017\n  lines_per_second   : 43432.7424755637\n  report_file        : ../outputs/ch10-REPL-oriented-repl-interactions.cj.yaml\n'Clojure' :\n  nFiles: 1\n  blank: 44\n  comment: 82\n  code: 88\nSUM: \n  blank: 44\n  comment: 82\n  code: 88\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/chat.st.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00579404830932617\n  n_files            : 1\n  n_lines            : 82\n  files_per_second   : 172.590897868488\n  lines_per_second   : 14152.453625216\n  report_file        : chat.st.yaml\nSmalltalk :\n  nFiles: 1\n  blank: 15\n  comment: 2\n  code: 65\nSUM: \n  blank: 15\n  comment: 2\n  code: 65\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/child_template.jinja2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00688791275024414\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 145.181862236068\n  lines_per_second   : 2322.90979577709\n  report_file        : ../outputs/child_template.jinja2.yaml\n'Jinja Template' :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 10\nSUM: \n  blank: 0\n  comment: 6\n  code: 10\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/child_template.njk.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00661802291870117\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 151.102529000648\n  lines_per_second   : 2417.64046401038\n  report_file        : ../outputs/child_template.njk.yaml\n'Nunjucks' :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 10\nSUM: \n  blank: 0\n  comment: 6\n  code: 10\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/clarityfiles.clar.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00625514984130859\n  n_files            : 1\n  n_lines            : 31\n  files_per_second   : 159.868272602531\n  lines_per_second   : 4955.91645067846\n'Clarity' :\n  nFiles: 1\n  blank: 8\n  comment: 8\n  code: 15\nSUM: \n  blank: 8\n  comment: 8\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/class.imba.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.0073249340057373\n  n_files            : 1\n  n_lines            : 209\n  files_per_second   : 136.520001301956\n  lines_per_second   : 28532.6802721088\n  report_file        : tests/outputs/class.imba.yaml\n'Imba' :\n  nFiles: 1\n  blank: 71\n  comment: 30\n  code: 108\nSUM: \n  blank: 71\n  comment: 30\n  code: 108\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cli-args.nf.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00423502922058105\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 236.125879637449\n  lines_per_second   : 5667.02111129877\n  report_file        : ../outputs/cli-args.nf.yaml\n'Nextflow' :\n  nFiles: 1\n  blank: 1\n  comment: 16\n  code: 7\nSUM: \n  blank: 1\n  comment: 16\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cloc-dev.code-workspace.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00441718101501465\n  n_files            : 1\n  n_lines            : 19\n  files_per_second   : 226.388729961678\n  lines_per_second   : 4301.38586927187\n  report_file        : ../outputs/cloc-dev.code-workspace.yaml\n'VSCode Workspace' :\n  nFiles: 1\n  blank: 0\n  comment: 5\n  code: 14\nSUM: \n  blank: 0\n  comment: 5\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cloc_counts.csv.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00732684135437012\n  n_files            : 1\n  n_lines            : 158\n  files_per_second   : 136.484461943965\n  lines_per_second   : 21564.5449871465\n  report_file        : ../outputs/cloc_counts.csv.yaml\n'CSV' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 158\nSUM: \n  blank: 0\n  comment: 0\n  code: 158\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/clusterConf.ttcn.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00589418411254883\n  n_files            : 1\n  n_lines            : 46\n  files_per_second   : 169.658765472049\n  lines_per_second   : 7804.30321171426\n  report_file        : tests/outputs/clusterConf.ttcn.yaml\nTTCN :\n  nFiles: 1\n  blank: 11\n  comment: 16\n  code: 19\nSUM: \n  blank: 11\n  comment: 16\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/comments.rhai.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.08\n  elapsed_seconds    : 0.00410795211791992\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 243.430295995357\n  lines_per_second   : 3894.88473592571\n  report_file        : ../outputs/comments.rhai.yaml\n'Rhai' :\n  nFiles: 1\n  blank: 7\n  comment: 6\n  code: 3\nSUM: \n  blank: 7\n  comment: 6\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/comments_in_str.svelte.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00450420379638672\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 222.014821088291\n  lines_per_second   : 1776.11856870633\n  report_file        : ../outputs/comments_in_str.svelte.yaml\n'Svelte' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 7\nSUM: \n  blank: 1\n  comment: 0\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/comp.ecpp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00635004043579102\n  n_files            : 1\n  n_lines            : 176\n  files_per_second   : 157.479312157393\n  lines_per_second   : 27716.3589397011\n  report_file        : comp.ecpp.yaml\nECPP :\n  nFiles: 1\n  blank: 26\n  comment: 34\n  code: 116\nSUM: \n  blank: 26\n  comment: 34\n  code: 116\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/complex_union.derw.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00703787803649902\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 142.088282123378\n  lines_per_second   : 2841.76564246756\n  report_file        : ../outputs/complex_union.derw.yaml\n'Derw' :\n  nFiles: 1\n  blank: 2\n  comment: 5\n  code: 13\nSUM: \n  blank: 2\n  comment: 5\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/conditions.CBL.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00464391708374023\n  n_files            : 1\n  n_lines            : 31\n  files_per_second   : 215.335455385563\n  lines_per_second   : 6675.39911695246\n  report_file        : conditions.CBL.yaml\nCOBOL :\n  nFiles: 1\n  blank: 3\n  comment: 3\n  code: 25\nSUM: \n  blank: 3\n  comment: 3\n  code: 25\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/config.junos.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.0077509880065918\n  n_files            : 1\n  n_lines            : 137\n  files_per_second   : 129.01581051984\n  lines_per_second   : 17675.1660412181\n  report_file        : ../outputs/config.junos.yaml\n'Juniper Junos' :\n  nFiles: 1\n  blank: 0\n  comment: 8\n  code: 129\nSUM: \n  blank: 0\n  comment: 8\n  code: 129\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cross-platform.just.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.06\n  elapsed_seconds    : 0.00395989418029785\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 252.5320007225\n  lines_per_second   : 6818.3640195075\n  report_file        : ../outputs/cross-platform.just.yaml\n'Justfile' :\n  nFiles: 1\n  blank: 5\n  comment: 9\n  code: 13\nSUM: \n  blank: 5\n  comment: 9\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/csharp-designer.designer.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00700807571411133\n  n_files            : 1\n  n_lines            : 58\n  files_per_second   : 142.692522283459\n  lines_per_second   : 8276.16629244063\n  report_file        : ../outputs/csharp-designer.designer.cs.yaml\n'C# Designer' :\n  nFiles: 1\n  blank: 8\n  comment: 22\n  code: 28\nSUM: \n  blank: 8\n  comment: 22\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/cucumber.feature.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00510287284851074\n  n_files            : 1\n  n_lines            : 33\n  files_per_second   : 195.96804186329\n  lines_per_second   : 6466.94538148858\n  report_file        : ../outputs/cucumber.feature.yaml\nCucumber :\n  nFiles: 1\n  blank: 3\n  comment: 2\n  code: 28\nSUM: \n  blank: 3\n  comment: 2\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/custom.triple.extension.js.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00475001335144043\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 210.525724037545\n  lines_per_second   : 4631.56592882598\n  report_file        : glossary.json.yaml\nCustom Triple JS :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM:\n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/darwin-configuration.nix.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00613999366760254\n  n_files            : 1\n  n_lines            : 73\n  files_per_second   : 162.866617481458\n  lines_per_second   : 11889.2630761465\n  report_file        : ../outputs/darwin-configuration.nix.yaml\nNix :\n  nFiles: 1\n  blank: 15\n  comment: 15\n  code: 43\nSUM: \n  blank: 15\n  comment: 15\n  code: 43\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/dd.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0172619819641113\n  n_files            : 3\n  n_lines            : 929\n  files_per_second   : 173.792326178835\n  lines_per_second   : 53817.6903400459\n  report_file        : dd.yaml\nC++ :\n  nFiles: 2\n  blank: 125\n  comment: 169\n  code: 547\nC :\n  nFiles: 1\n  blank: 22\n  comment: 22\n  code: 44\nSUM: \n  blank: 147\n  comment: 191\n  code: 591\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/demo.odin.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00814199447631836\n  n_files            : 1\n  n_lines            : 178\n  files_per_second   : 122.820029282577\n  lines_per_second   : 21861.9652122987\n  report_file        : ../outputs/demo.odin.yaml\n'Odin' :\n  nFiles: 1\n  blank: 32\n  comment: 56\n  code: 90\nSUM: \n  blank: 32\n  comment: 56\n  code: 90\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/dev.exs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00414299964904785\n  n_files            : 1\n  n_lines            : 86\n  files_per_second   : 241.371007653795\n  lines_per_second   : 20757.9066582264\n  report_file        : ../outputs/dev.exs.yaml\n'Elixir Script' :\n  nFiles: 1\n  blank: 8\n  comment: 38\n  code: 40\nSUM: \n  blank: 8\n  comment: 38\n  code: 40\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/dlist.lean.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00614404678344727\n  n_files            : 1\n  n_lines            : 146\n  files_per_second   : 162.75917733799\n  lines_per_second   : 23762.8398913465\n  report_file        : ../outputs/dlist.lean.yaml\nLean :\n  nFiles: 1\n  blank: 36\n  comment: 20\n  code: 90\nSUM: \n  blank: 36\n  comment: 20\n  code: 90\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/door.tres.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00702595710754395\n  n_files            : 1\n  n_lines            : 30\n  files_per_second   : 142.329363059486\n  lines_per_second   : 4269.88089178459\n  report_file        : ../outputs/door.tres.yaml\n'Godot Resource' :\n  nFiles: 1\n  blank: 2\n  comment: 8\n  code: 20\nSUM: \n  blank: 2\n  comment: 8\n  code: 20\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/dotNET_intermediate.il.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00411295890808105\n  n_files            : 1\n  n_lines            : 47\n  files_per_second   : 243.133963248507\n  lines_per_second   : 11427.2962726798\n  report_file        : ../outputs/dotNET_intermediate.il.yaml\n'.NET IL' :\n  nFiles: 1\n  blank: 3\n  comment: 6\n  code: 38\nSUM: \n  blank: 3\n  comment: 6\n  code: 38\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/double_doors.dsc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.92\n  elapsed_seconds    : 0.00667405128479004\n  n_files            : 1\n  n_lines            : 21\n  files_per_second   : 149.834029936055\n  lines_per_second   : 3146.51462865716\n  report_file        : ../outputs/double_doors.dsc.yaml\n'DenizenScript' :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 15\nSUM: \n  blank: 0\n  comment: 6\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/drools.drl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00578093528747559\n  n_files            : 1\n  n_lines            : 51\n  files_per_second   : 172.982389573968\n  lines_per_second   : 8822.10186827236\n  report_file        : tests/outputs/drools.drl.yaml\nDrools :\n  nFiles: 1\n  blank: 7\n  comment: 16\n  code: 28\nSUM: \n  blank: 7\n  comment: 16\n  code: 28\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/drupal.mxml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00597906112670898\n  n_files            : 1\n  n_lines            : 102\n  files_per_second   : 167.250338942499\n  lines_per_second   : 17059.5345721349\n  report_file        : drupal.mxml.yaml\nMXML :\n  nFiles: 1\n  blank: 23\n  comment: 5\n  code: 74\nSUM: \n  blank: 23\n  comment: 5\n  code: 74\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/eddsa.circom.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00864696502685547\n  n_files            : 1\n  n_lines            : 140\n  files_per_second   : 115.647512959082\n  lines_per_second   : 16190.6518142715\n  report_file        : ../outputs/eddsa.circom.yaml\n'Circom' :\n  nFiles: 1\n  blank: 34\n  comment: 26\n  code: 80\nSUM: \n  blank: 34\n  comment: 26\n  code: 80\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/elixir.ex.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00999093055725098\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 100.09077675695\n  lines_per_second   : 2001.815535139\n  report_file        : elixir.ex.yaml\nElixir :\n  nFiles: 1\n  blank: 3\n  comment: 10\n  code: 7\nSUM: \n  blank: 3\n  comment: 10\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/en_AU.po.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.00470113754272461\n  n_files            : 1\n  n_lines            : 60\n  files_per_second   : 212.714474084593\n  lines_per_second   : 12762.8684450756\n  report_file        : ../outputs/en_AU.po.yaml\nPO File :\n  nFiles: 1\n  blank: 9\n  comment: 18\n  code: 33\nSUM: \n  blank: 9\n  comment: 18\n  code: 33\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/example_2d.gdshader.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00944209098815918\n  n_files            : 1\n  n_lines            : 15\n  files_per_second   : 105.908744287049\n  lines_per_second   : 1588.63116430573\n  report_file        : ../outputs/example_2d.gdshader.yaml\n'Godot Shaders' :\n  nFiles: 1\n  blank: 3\n  comment: 3\n  code: 9\nSUM: \n  blank: 3\n  comment: 3\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/exclude_dir_1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0140111446380615\n  n_files            : 2\n  n_lines            : 374\n  files_per_second   : 142.743512515527\n  lines_per_second   : 26693.0368404036\n  report_file        : ../tests/outputs/exclude_dir_1.yaml\nC++ :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\nC :\n  nFiles: 1\n  blank: 22\n  comment: 22\n  code: 44\nSUM: \n  blank: 71\n  comment: 77\n  code: 226\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/fib.dfy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00714278221130371\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 140.001468673854\n  lines_per_second   : 3780.03965419407\n  report_file        : ../outputs/fib.dfy.yaml\n'Dafny' :\n  nFiles: 1\n  blank: 0\n  comment: 5\n  code: 22\nSUM: \n  blank: 0\n  comment: 5\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/fib_class.pkl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00434088706970215\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 230.367660789806\n  lines_per_second   : 5759.19151974515\n  report_file        : ../outputs/fib_class.pkl.yaml\n'Pkl' :\n  nFiles: 1\n  blank: 3\n  comment: 18\n  code: 4\nSUM: \n  blank: 3\n  comment: 18\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/fibonacci.ncl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00243306159973145\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 411.004801567859\n  lines_per_second   : 5754.06722195002\n  report_file        : ../outputs/fibonacci.ncl.yaml\n'Nickel' :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 9\nSUM: \n  blank: 1\n  comment: 4\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/find.plm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00586414337158203\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 170.527890713937\n  lines_per_second   : 4263.19726784843\n  report_file        : ../outputs/find.plm.yaml\nPL/M :\n  nFiles: 1\n  blank: 1\n  comment: 5\n  code: 19\nSUM: \n  blank: 1\n  comment: 5\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/flatbuffers.fbs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00527405738830566\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 189.60734144026\n  lines_per_second   : 4360.96885312599\n  report_file        : flatbuffers.fbs.yaml\nFlatbuffers :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 1\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/fmt.ha.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00677204132080078\n  n_files            : 1\n  n_lines            : 34\n  files_per_second   : 147.665962540487\n  lines_per_second   : 5020.64272637657\n  report_file        : tests/outputs/fmt.ha.yaml\n'Hare' :\n  nFiles: 1\n  blank: 4\n  comment: 14\n  code: 16\nSUM: \n  blank: 4\n  comment: 14\n  code: 16\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/foo_bar.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.014286994934082\n  n_files            : 2\n  n_lines            : 2\n  files_per_second   : 139.987450770977\n  lines_per_second   : 139.987450770977\n  report_file        : foo_bar.yaml\nBourne Shell :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/fractal.um.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00748491287231445\n  n_files            : 1\n  n_lines            : 38\n  files_per_second   : 133.602089571256\n  lines_per_second   : 5076.87940370772\n  report_file        : ../outputs/fractal.um.yaml\n'Umka' :\n  nFiles: 1\n  blank: 7\n  comment: 5\n  code: 26\nSUM: \n  blank: 7\n  comment: 5\n  code: 26\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/fsharp.fs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00527405738830566\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 189.60734144026\n  lines_per_second   : 4360.96885312599\n  report_file        : fsharp.fs.yaml\nF# :\n  nFiles: 1\n  blank: 3\n  comment: 6\n  code: 14\nSUM: \n  blank: 3\n  comment: 6\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/fsharp_script.fsx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00549101829528809\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 182.115583344188\n  lines_per_second   : 2003.27141678607\n  report_file        : fsharp_script.fsx.yaml\nF# Script :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 8\nSUM: \n  blank: 1\n  comment: 2\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/functional.cj.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00456094741821289\n  n_files            : 1\n  n_lines            : 60\n  files_per_second   : 219.252692106639\n  lines_per_second   : 13155.1615263983\n  report_file        : ../outputs/functional.cj.yaml\n'Cangjie' :\n  nFiles: 1\n  blank: 6\n  comment: 6\n  code: 48\nSUM: \n  blank: 6\n  comment: 6\n  code: 48\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/futhark.fut.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00682711601257324\n  n_files            : 1\n  n_lines            : 58\n  files_per_second   : 146.474733717479\n  lines_per_second   : 8495.53455561376\n  report_file        : futhark.fut.yaml\n'Futhark' :\n  nFiles: 1\n  blank: 7\n  comment: 35\n  code: 16\nSUM: \n  blank: 7\n  comment: 35\n  code: 16\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/generate.fnl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00580787658691406\n  n_files            : 1\n  n_lines            : 53\n  files_per_second   : 172.179967159278\n  lines_per_second   : 9125.53825944171\n  report_file        : ../outputs/generate.fnl.yaml\n'Fennel' :\n  nFiles: 1\n  blank: 6\n  comment: 3\n  code: 44\nSUM: \n  blank: 6\n  comment: 3\n  code: 44\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/git_helpers.fish.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00541305541992188\n  n_files            : 1\n  n_lines            : 123\n  files_per_second   : 184.738548273432\n  lines_per_second   : 22722.8414376321\n  report_file        : ../outputs/git_helpers.fish.yaml\nFish Shell :\n  nFiles: 1\n  blank: 14\n  comment: 47\n  code: 62\nSUM: \n  blank: 14\n  comment: 47\n  code: 62\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/git_tests/04179b6_ae0d26e.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.123239994049072\n  n_files            : 1\n  n_lines            : 555\n  files_per_second   : 8.11424901239297\n  lines_per_second   : 4503.4082018781\n  report_file        : 04179b6_ae0d26e.yaml\nadded :\n  'C++' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nsame :\n  'C++' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nmodified :\n  'C++' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nremoved :\n  'C++' :\n    comment : 114\n    code : 365\n    blank : 76\n    nFiles : 1\nSUM :\n  added :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  same :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  modified :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  removed :\n    nFiles : 1\n    blank : 76\n    comment : 114\n    code : 365\n"
  },
  {
    "path": "tests/outputs/git_tests/contents_f647093e8.tar.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.80\n  elapsed_seconds    : 0.0191028118133545\n  n_files            : 6\n  n_lines            : 655\n  files_per_second   : 314.089886799046\n  lines_per_second   : 34288.1459755626\n  report_file        : ../tests/outputs/git_tests/contents_f647093e8.tar.yaml\n'C' :\n  nFiles: 2\n  blank: 70\n  comment: 46\n  code: 231\n'C++' :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 123\n  comment: 113\n  code: 419\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/git_tests/count_and_diff.yaml.HEAD",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0785520076751709\n  n_files            : 6\n  n_lines            : 655\n  files_per_second   : 76.3825162153877\n  lines_per_second   : 8338.42468684649\n  report_file        : results.yaml.HEAD\n'C' :\n  nFiles: 2\n  blank: 70\n  comment: 46\n  code: 231\n'C++' :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 123\n  comment: 113\n  code: 419\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/git_tests/count_and_diff.yaml.HEAD~1",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0514130592346191\n  n_files            : 7\n  n_lines            : 661\n  files_per_second   : 136.152178147114\n  lines_per_second   : 12856.6556793204\n  report_file        : results.yaml.HEAD~1\n'C' :\n  nFiles: 2\n  blank: 70\n  comment: 46\n  code: 231\n'C++' :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\n'Fortran 90' :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 124\n  comment: 115\n  code: 422\n  nFiles: 7\n"
  },
  {
    "path": "tests/outputs/git_tests/count_and_diff.yaml.diff.HEAD~1.HEAD",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.112855911254883\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 8.86085619158681\n  lines_per_second   : 53.1651371495209\n  report_file        : results.yaml.diff.HEAD~1.HEAD\nadded :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nsame :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nmodified :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nremoved :\n  'Fortran 90' :\n    blank : 1\n    nFiles : 1\n    code : 3\n    comment : 2\nSUM :\n  added :\n    code : 0\n    comment : 0\n    nFiles : 0\n    blank : 0\n  same :\n    code : 0\n    comment : 0\n    nFiles : 0\n    blank : 0\n  modified :\n    code : 0\n    comment : 0\n    nFiles : 0\n    blank : 0\n  removed :\n    code : 3\n    comment : 2\n    nFiles : 1\n    blank : 1\n"
  },
  {
    "path": "tests/outputs/git_tests/d9b672643d.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.79\n  elapsed_seconds    : 0.0288271903991699\n  n_files            : 8\n  n_lines            : 1356\n  files_per_second   : 277.515772061864\n  lines_per_second   : 47038.923364486\n  report_file        : ../../tests/outputs/d9b672643d.yaml\n'C++' :\n  nFiles: 2\n  blank: 125\n  comment: 169\n  code: 547\n'C' :\n  nFiles: 2\n  blank: 101\n  comment: 56\n  code: 330\n'Fortran 90' :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 231\n  comment: 239\n  code: 886\n  nFiles: 8\n"
  },
  {
    "path": "tests/outputs/git_tests/diff_contents_f647093e8.tar.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.80\n  elapsed_seconds    : 0.0364840030670166\n  n_files            : 6\n  n_lines            : 655\n  files_per_second   : 164.455637967652\n  lines_per_second   : 17953.0738114687\n  report_file        : ../../tests/outputs/git_tests/diff_contents_f647093e8.tar.yaml\nadded :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Markdown' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'C' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\nsame :\n  'C++' :\n    nFiles : 1\n    blank : 49\n    comment : 55\n    code : 182\n  'Markdown' :\n    blank : 0\n    nFiles : 1\n    code : 2\n    comment : 0\n  'MATLAB' :\n    nFiles : 1\n    blank : 0\n    comment : 1\n    code : 2\n  'Python' :\n    nFiles : 1\n    blank : 4\n    comment : 11\n    code : 2\n  'C' :\n    nFiles : 2\n    blank : 70\n    comment : 46\n    code : 231\nmodified :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Markdown' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'C' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\nremoved :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Markdown' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'C' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\nSUM :\n  added :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\n  same :\n    comment : 113\n    code : 419\n    nFiles : 6\n    blank : 123\n  modified :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\n  removed :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\n"
  },
  {
    "path": "tests/outputs/git_tests/diff_f15bf042b_f647093e8b.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.79\n  elapsed_seconds    : 0.0542740821838379\n  n_files            : 5\n  n_lines            : 986\n  files_per_second   : 92.1250032946469\n  lines_per_second   : 18167.0506497044\n  report_file        : ../../tests/outputs/git_tests/diff_f15bf042b_f647093e8b.yaml\nadded :\n  'C' :\n    nFiles : 0\n    code : 3\n    blank : 1\n    comment : 0\n  'C++' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 1\n    code : 2\n    blank : 0\n    comment : 1\n  'Fortran 90' :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\nsame :\n  'C' :\n    nFiles : 0\n    code : 228\n    blank : 0\n    comment : 46\n  'C++' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\n  'Fortran 90' :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\nmodified :\n  'C' :\n    nFiles : 2\n    code : 0\n    blank : 0\n    comment : 0\n  'C++' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 0\n  'MATLAB' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\n  'Fortran 90' :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\nremoved :\n  'C' :\n    nFiles : 0\n    code : 102\n    blank : 32\n    comment : 10\n  'C++' :\n    code : 365\n    nFiles : 1\n    blank : 76\n    comment : 114\n  'MATLAB' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\n  'Fortran 90' :\n    code : 3\n    nFiles : 1\n    comment : 2\n    blank : 1\nSUM :\n  added :\n    comment : 1\n    blank : 1\n    nFiles : 1\n    code : 5\n  same :\n    comment : 46\n    blank : 0\n    nFiles : 0\n    code : 228\n  modified :\n    comment : 0\n    blank : 0\n    nFiles : 2\n    code : 0\n  removed :\n    comment : 126\n    blank : 109\n    nFiles : 2\n    code : 470\n"
  },
  {
    "path": "tests/outputs/git_tests/f15bf04_d9b6726.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.122870922088623\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 8.13862208406583\n  lines_per_second   : 24.4158662521975\n  report_file        : f15bf04_d9b6726.yaml\nadded :\n  'MATLAB' :\n    code : 2\n    blank : 0\n    nFiles : 1\n    comment : 1\nsame :\n  'MATLAB' :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\nmodified :\n  'MATLAB' :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\nremoved :\n  'MATLAB' :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\nSUM :\n  added :\n    code : 2\n    blank : 0\n    nFiles : 1\n    comment : 1\n  same :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\n  modified :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\n  removed :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\n"
  },
  {
    "path": "tests/outputs/git_tests/f647093e8be3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.79\n  elapsed_seconds    : 0.0260219573974609\n  n_files            : 6\n  n_lines            : 655\n  files_per_second   : 230.574507073224\n  lines_per_second   : 25171.0503554937\n  report_file        : ../../tests/outputs/git_tests/f647093e8be3.yaml\n'C' :\n  nFiles: 2\n  blank: 70\n  comment: 46\n  code: 231\n'C++' :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 123\n  comment: 113\n  code: 419\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/github_user.aria.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00420713424682617\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 237.691488155956\n  lines_per_second   : 4753.82976311912\n  report_file        : ../outputs/github_user.aria.yaml\n'Aria' :\n  nFiles: 1\n  blank: 4\n  comment: 2\n  code: 14\nSUM: \n  blank: 4\n  comment: 2\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/glade-search-popover.ui.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.00665783882141113\n  n_files            : 1\n  n_lines            : 254\n  files_per_second   : 150.198889883617\n  lines_per_second   : 38150.5180304387\n  report_file        : ../outputs/glade-search-popover.ui.yaml\nGlade :\n  nFiles: 1\n  blank: 0\n  comment: 22\n  code: 232\nSUM: \n  blank: 0\n  comment: 22\n  code: 232\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/glossary.json.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00475001335144043\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 210.525724037545\n  lines_per_second   : 4631.56592882598\n  report_file        : glossary.json.yaml\nJSON :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 22\nSUM: \n  blank: 0\n  comment: 0\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/glossary.json5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00584006309509277\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 171.231026740151\n  lines_per_second   : 4452.00669524393\n  report_file        : ../outputs/glossary.json5.yaml\nJSON5 :\n  nFiles: 1\n  blank: 0\n  comment: 4\n  code: 22\nSUM: \n  blank: 0\n  comment: 4\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/gnureadline.vala.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00732588768005371\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 136.502229309728\n  lines_per_second   : 1911.03121033619\n  report_file        : gnureadline.vala.yaml\n'Vala' :\n  nFiles: 1\n  blank: 0\n  comment: 5\n  code: 9\nSUM: \n  blank: 0\n  comment: 5\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/graphql.gql.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00529694557189941\n  n_files            : 1\n  n_lines            : 17\n  files_per_second   : 188.78804519062\n  lines_per_second   : 3209.39676824054\n  report_file        : ../outputs/graphql.gql.yaml\nGraphQL :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 14\nSUM: \n  blank: 1\n  comment: 2\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/greeter.tsx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00571799278259277\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 174.886544635784\n  lines_per_second   : 2448.41162490097\n  report_file        : ../outputs/greeter.tsx.yaml\nTypeScript :\n  nFiles: 1\n  blank: 2\n  comment: 5\n  code: 7\nSUM: \n  blank: 2\n  comment: 5\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/guard_talking.yarn.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00369501113891602\n  n_files            : 1\n  n_lines            : 32\n  files_per_second   : 270.63517873274\n  lines_per_second   : 8660.32571944767\n  report_file        : ../outputs/guard_talking.yarn.yaml\n'Yarn' :\n  nFiles: 1\n  blank: 2\n  comment: 3\n  code: 27\nSUM: \n  blank: 2\n  comment: 3\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/guestbook.tpl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00787687301635742\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 126.953931836068\n  lines_per_second   : 2919.94043222955\n  report_file        : ../outputs/guestbook.tpl.yaml\n'Smarty' :\n  nFiles: 1\n  blank: 1\n  comment: 1\n  code: 21\nSUM: \n  blank: 1\n  comment: 1\n  code: 21\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/harbour_xbase.prg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00532102584838867\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 187.933685814141\n  lines_per_second   : 1879.33685814141\n  report_file        : harbour_xbase.prg.yaml\nxBase :\n  nFiles: 1\n  blank: 0\n  comment: 9\n  code: 1\nSUM: \n  blank: 0\n  comment: 9\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.bf.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00564002990722656\n  n_files            : 1\n  n_lines            : 28\n  files_per_second   : 177.304024349002\n  lines_per_second   : 4964.51268177207\n  report_file        : tests/output/bf.yaml\nBrainfuck :\n  nFiles: 1\n  blank: 1\n  comment: 3\n  code: 24\nSUM: \n  blank: 1\n  comment: 3\n  code: 24\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.f.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00486397743225098\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 205.593059163766\n  lines_per_second   : 2055.93059163766\n  report_file        : hello.f.yaml\nFortran 77 :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 4\nSUM: \n  blank: 0\n  comment: 6\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.f90.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00467109680175781\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 214.082482645978\n  lines_per_second   : 1498.57737852185\n  report_file        : hello.f90.yaml\nFortran 90 :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 4\nSUM: \n  blank: 0\n  comment: 3\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.kt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00518703460693359\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 192.788380216952\n  lines_per_second   : 2313.46056260342\n  report_file        : hello.kt.yaml\nKotlin :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 9\nSUM: \n  blank: 0\n  comment: 3\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.lua.yaml",
    "content": "       1 text file.\n       1 unique file.                              \n       0 files ignored.\n\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.00693893432617188\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 144.114348543156\n  lines_per_second   : 2017.60087960418\nLua :\n  nFiles: 1\n  blank: 3\n  comment: 9\n  code: 2\nSUM: \n  blank: 3\n  comment: 9\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.pas.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00459885597229004\n  n_files            : 1\n  n_lines            : 9\n  files_per_second   : 217.445383379128\n  lines_per_second   : 1957.00845041215\n  report_file        : hello.pas.yaml\nPascal :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 4\nSUM: \n  blank: 1\n  comment: 4\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.pl1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00530290603637695\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 188.575847495729\n  lines_per_second   : 2262.91016994875\n  report_file        : hello.pl1.yaml\nPL/I :\n  nFiles: 1\n  blank: 0\n  comment: 7\n  code: 5\nSUM: \n  blank: 0\n  comment: 7\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello.sp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.0046238899230957\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 216.268124162112\n  lines_per_second   : 4757.89873156646\n  report_file        : ../outputs/hello.sp.yaml\nSparForte :\n  nFiles: 1\n  blank: 6\n  comment: 8\n  code: 8\nSUM: \n  blank: 6\n  comment: 8\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello1.pas.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0048980712890625\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 204.16199376947\n  lines_per_second   : 2449.94392523364\n  report_file        : hello1.pas.yaml\nPascal :\n  nFiles: 1\n  blank: 1\n  comment: 5\n  code: 6\nSUM: \n  blank: 1\n  comment: 5\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hello_app.go-1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00630497932434082\n  n_files            : 2\n  n_lines            : 69\n  files_per_second   : 317.209604840234\n  lines_per_second   : 10943.7313669881\n  report_file        : ../outputs/hello_app.go-1.yaml\nGo :\n  nFiles: 2\n  blank: 10\n  comment: 37\n  code: 22\nSUM: \n  blank: 10\n  comment: 37\n  code: 22\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/hello_app.go-2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00606894493103027\n  n_files            : 1\n  n_lines            : 34\n  files_per_second   : 164.773286191318\n  lines_per_second   : 5602.29173050481\n  report_file        : ../outputs/hello_app.go-2.yaml\nGo :\n  nFiles: 1\n  blank: 5\n  comment: 18\n  code: 11\nSUM: \n  blank: 5\n  comment: 18\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/helloworld.raml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00540709495544434\n  n_files            : 1\n  n_lines            : 70\n  files_per_second   : 184.942193218396\n  lines_per_second   : 12945.9535252877\n  report_file        : ../outputs/helloworld.raml.yaml\nRAML :\n  nFiles: 1\n  blank: 5\n  comment: 3\n  code: 62\nSUM: \n  blank: 5\n  comment: 3\n  code: 62\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hi.mojo.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0048980712890625\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 204.16199376947\n  lines_per_second   : 2449.94392523364\n  report_file        : hi.mojo.yaml\nMojo :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 3\nSUM: \n  blank: 4\n  comment: 11\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/hi.py.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0048980712890625\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 204.16199376947\n  lines_per_second   : 2449.94392523364\n  report_file        : hi.py.yaml\nPython :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 4\n  comment: 11\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/htlc.teal.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.94\n  elapsed_seconds    : 0.0102791786193848\n  n_files            : 1\n  n_lines            : 70\n  files_per_second   : 97.284037667579\n  lines_per_second   : 6809.88263673053\n  report_file        : ../outputs/htlc.teal.yaml\n'TEAL' :\n  nFiles: 1\n  blank: 16\n  comment: 37\n  code: 17\nSUM: \n  blank: 16\n  comment: 37\n  code: 17\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/html_heex_example.heex.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00759506225585938\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 131.664490205927\n  lines_per_second   : 1316.64490205927\n  report_file        : ../outputs/html_heex_example.heex.yaml\n'HTML EEx' :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 5\nSUM: \n  blank: 1\n  comment: 4\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/i18n_de.ts.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00563406944274902\n  n_files            : 1\n  n_lines            : 61\n  files_per_second   : 177.491600016927\n  lines_per_second   : 10826.9876010325\n  report_file        : i18n_de.ts.yaml\nQt Linguist :\n  nFiles: 1\n  blank: 0\n  comment: 4\n  code: 57\nSUM: \n  blank: 0\n  comment: 4\n  code: 57\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/iclean.icl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0087277889251709\n  n_files            : 1\n  n_lines            : 98\n  files_per_second   : 114.576556396318\n  lines_per_second   : 11228.5025268391\n  report_file        : iclean.icl.yaml\nClean :\n  nFiles: 1\n  blank: 10\n  comment: 30\n  code: 58\nSUM: \n  blank: 10\n  comment: 30\n  code: 58\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/idris_block_comments.idr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00631189346313477\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 158.431064440583\n  lines_per_second   : 3168.62128881166\n  report_file        : idris_block_comments.idr.yaml\nIdris :\n  nFiles: 1\n  blank: 3\n  comment: 11\n  code: 6\nSUM:\n  blank: 3\n  comment: 11\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/igorpro.ipf.yaml",
    "content": "       1 text file.\n       1 unique file.                              \n       0 files ignored.\n\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00516295433044434\n  n_files            : 1\n  n_lines            : 29\n  files_per_second   : 193.68755483722\n  lines_per_second   : 5616.93909027938\nIgor Pro :\n  nFiles: 1\n  blank: 4\n  comment: 6\n  code: 19\nSUM: \n  blank: 4\n  comment: 6\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/includes_demo.mustache.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00461196899414062\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 216.827129859388\n  lines_per_second   : 4336.54259718776\n  report_file        : includes_demo.mustache.yaml\nMustache :\n  nFiles: 1\n  blank: 1\n  comment: 3\n  code: 16\nSUM: \n  blank: 1\n  comment: 3\n  code: 16\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/inner_ref.jsonnet.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00428891181945801\n  n_files            : 1\n  n_lines            : 19\n  files_per_second   : 233.159375173717\n  lines_per_second   : 4430.02812830063\n  report_file        : ../outputs/inner_ref.jsonnet.yaml\n'Jsonnet' :\n  nFiles: 1\n  blank: 0\n  comment: 5\n  code: 14\nSUM: \n  blank: 0\n  comment: 5\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/input.gts.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00317215919494629\n  n_files            : 1\n  n_lines            : 150\n  files_per_second   : 315.242690717775\n  lines_per_second   : 47286.4036076663\n  report_file        : ../outputs/input.gts.yaml\n'Glimmer TypeScript' :\n  nFiles: 1\n  blank: 17\n  comment: 24\n  code: 109\nSUM: \n  blank: 17\n  comment: 24\n  code: 109\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/insertJournalEntry.ipl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00725007057189941\n  n_files            : 1\n  n_lines            : 54\n  files_per_second   : 137.929691867539\n  lines_per_second   : 7448.20336084712\n  report_file        : insertJournalEntry.ipl.yaml\n'IPL' :\n  nFiles: 1\n  blank: 6\n  comment: 15\n  code: 33\nSUM: \n  blank: 6\n  comment: 15\n  code: 33\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/invoices.prql.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.0065009593963623\n  n_files            : 1\n  n_lines            : 17\n  files_per_second   : 153.823449591081\n  lines_per_second   : 2614.99864304837\n  report_file        : ../outputs/invoices.prql.yaml\n'PRQL' :\n  nFiles: 1\n  blank: 2\n  comment: 1\n  code: 14\nSUM: \n  blank: 2\n  comment: 1\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/io.c3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.09\n  elapsed_seconds    : 0.00584793090820312\n  n_files            : 1\n  n_lines            : 163\n  files_per_second   : 171.000652315721\n  lines_per_second   : 27873.1063274625\n  report_file        : ../outputs/io.c3.yaml\n'C3' :\n  nFiles: 1\n  blank: 13\n  comment: 36\n  code: 114\nSUM: \n  blank: 13\n  comment: 36\n  code: 114\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issue_875.bdy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00424885749816895\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 235.357387352\n  lines_per_second   : 6119.29207115201\n  report_file        : ../outputs/issue_875.bdy.yaml\n'Oracle PL/SQL' :\n  nFiles: 1\n  blank: 0\n  comment: 4\n  code: 22\nSUM: \n  blank: 0\n  comment: 4\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issue_876.vue.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00376987457275391\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 265.260814571212\n  lines_per_second   : 4244.17303313939\n  report_file        : ../tests/outputs/issue_876.vue.yaml\n'Vuejs Component' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 15\nSUM: \n  blank: 0\n  comment: 1\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/114/T1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0196640491485596\n  n_files            : 3\n  n_lines            : 3\n  files_per_second   : 152.56267807995\n  lines_per_second   : 152.56267807995\n  report_file        : outputs/issues/114/T1.yaml\nissues/114/bar/bee/inner_most.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nissues/114/bar/under_Bar.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nissues/114/foo/under_foo.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/114/T2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00754880905151367\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 132.471227338766\n  lines_per_second   : 132.471227338766\n  report_file        : ../outputs/issues/114/T2.yaml\n'issues/114/foo/under_foo.js' :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/114/T3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0176558494567871\n  n_files            : 2\n  n_lines            : 2\n  files_per_second   : 113.276906041537\n  lines_per_second   : 113.276906041537\n  report_file        : outputs/issues/114/T3.yaml\nissues/114/bar/under_Bar.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nissues/114/foo/under_foo.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/114/T4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00816798210144043\n  n_files            : 2\n  n_lines            : 2\n  files_per_second   : 244.858518929332\n  lines_per_second   : 244.858518929332\n  report_file        : ../outputs/issues/114/T4.yaml\n'issues/114/bar/under_Bar.js' :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\n'issues/114/foo/under_foo.js' :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/114/T5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0129168033599854\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 77.4185355409122\n  lines_per_second   : 77.4185355409122\n  report_file        : outputs/issues/114/T5.yaml\nissues/114/foo/under_foo.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/114/T6.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0154697895050049\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 64.6421206750405\n  lines_per_second   : 64.6421206750405\n  report_file        : outputs/issues/114/T6.yaml\nissues/114/foo/under_foo.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/114/T7.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.0181760787963867\n  n_files            : 2\n  n_lines            : 2\n  files_per_second   : 110.034734246288\n  lines_per_second   : 110.034734246288\n  report_file        : outputs/issues/114/T7.yaml\nissues/114/foo/under_foo.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nissues/114/bar/under_Bar.js :\n  blank: 0\n  comment: 0\n  code: 1\n  language: JavaScript\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/131/T1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.0114109516143799\n  n_files            : 2\n  n_lines            : 14\n  files_per_second   : 175.270220012118\n  lines_per_second   : 1226.89154008483\n  report_file        : ../outputs/issues/131/T1.yaml\nPython :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 2\nMarkdown :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 3\n  comment: 7\n  code: 4\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/131/T2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.0349979400634766\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 28.5731102512399\n  lines_per_second   : 342.877323014878\n  report_file        : ../outputs/issues/131/T2.yaml\nPython :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 2\nSUM: \n  blank: 3\n  comment: 7\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/132/T1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.0163099765777588\n  n_files            : 3\n  n_lines            : 34\n  files_per_second   : 183.936499583388\n  lines_per_second   : 2084.61366194507\n  report_file        : ../outputs/issues/132/T1.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nFortran 77 :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nPython :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 7\n  comment: 15\n  code: 12\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/132/T2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00781106948852539\n  n_files            : 2\n  n_lines            : 17\n  files_per_second   : 256.046883584641\n  lines_per_second   : 2176.39851046945\n  report_file        : ../outputs/issues/132/T2.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nFortran 77 :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 3\nSUM: \n  blank: 3\n  comment: 4\n  code: 10\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/132/T3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.007781982421875\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 128.501960784314\n  lines_per_second   : 1413.52156862745\n  report_file        : ../../../outputs/issues/132/T3.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/132/T4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00798988342285156\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 125.158271663882\n  lines_per_second   : 1376.7409883027\n  report_file        : ../outputs/issues/132/T4.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/132/T5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00879096984863281\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 113.753091776958\n  lines_per_second   : 1251.28400954654\n  report_file        : ../outputs/issues/132/T5.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/132/T6.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00894808769226074\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 111.755721936532\n  lines_per_second   : 1229.31294130186\n  report_file        : ../outputs/issues/132/T.6\nC :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/147/T1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.0291268825531006\n  n_files            : 2\n  n_lines            : 2\n  files_per_second   : 68.6650895904786\n  lines_per_second   : 68.6650895904786\n  report_file        : ../outputs/issues/147/T1.yaml\nBourne Shell :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/166/fake.thy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00702595710754395\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 142.329363059486\n  lines_per_second   : 711.646815297431\n  report_file        : /home/al/git-cloc/tests/outputs/issues/166/fake.thy.yaml\nIsabelle :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 2\nSUM: \n  blank: 1\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/183/eval1957.SACunidir.fr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.0095360279083252\n  n_files            : 1\n  n_lines            : 469\n  files_per_second   : 104.865464909868\n  lines_per_second   : 49181.9030427282\n  report_file        : /home/al/git-cloc/tests/outputs/issues/183/eval1957.SACunidir.fr.yaml\nForth :\n  nFiles: 1\n  blank: 0\n  comment: 46\n  code: 423\nSUM: \n  blank: 0\n  comment: 46\n  code: 423\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/183/file.fth.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.0075380802154541\n  n_files            : 1\n  n_lines            : 161\n  files_per_second   : 132.659771641838\n  lines_per_second   : 21358.223234336\n  report_file        : /home/al/git-cloc/tests/outputs/issues/183/file.fth.yaml\nForth :\n  nFiles: 1\n  blank: 17\n  comment: 38\n  code: 106\nSUM: \n  blank: 17\n  comment: 38\n  code: 106\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/245/CRS.scala.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00722098350524902\n  n_files            : 1\n  n_lines            : 41\n  files_per_second   : 138.48529071879\n  lines_per_second   : 5677.8969194704\n  report_file        : ../tests/outputs/issues/245/CRS.scala.yaml\n'Scala' :\n  nFiles: 1\n  blank: 8\n  comment: 8\n  code: 25\nSUM: \n  blank: 8\n  comment: 8\n  code: 25\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/280/280.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.0126500129699707\n  n_files            : 3\n  n_lines            : 1608\n  files_per_second   : 237.15390704512\n  lines_per_second   : 127114.494176185\n  report_file        : 280.yaml\nadded :\n  C/C++ Header :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n  C :\n    nFiles : 1\n    comment : 2\n    blank : 2\n    code : 7\nsame :\n  C/C++ Header :\n    blank : 191\n    code : 617\n    comment : 780\n    nFiles : 1\n  C :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nmodified :\n  C/C++ Header :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n  C :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nremoved :\n  C/C++ Header :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n  C :\n    nFiles : 1\n    comment : 1\n    blank : 2\n    code : 6\nSUM :\n  added :\n    code : 7\n    blank : 2\n    nFiles : 1\n    comment : 2\n  same :\n    code : 617\n    blank : 191\n    nFiles : 1\n    comment : 780\n  modified :\n    code : 0\n    blank : 0\n    nFiles : 0\n    comment : 0\n  removed :\n    code : 6\n    blank : 2\n    nFiles : 1\n    comment : 1\n"
  },
  {
    "path": "tests/outputs/issues/280/280_by_file.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.0132617950439453\n  n_files            : 0\n  n_lines            : 1608\n  files_per_second   : 0\n  lines_per_second   : 121250.554293111\n  report_file        : 280_by_file.yaml\nadded :\n  L/locale_facets.h :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  L/hello_1.c :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  R/hello_2.c :\n    comment : 2\n    code : 7\n    blank : 2\n    nFiles : 0\nsame :\n  L/locale_facets.h :\n    nFiles : 0\n    blank : 191\n    code : 617\n    comment : 780\n  L/hello_1.c :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  R/hello_2.c :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nmodified :\n  L/locale_facets.h :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  L/hello_1.c :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\n  R/hello_2.c :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nremoved :\n  L/locale_facets.h :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  L/hello_1.c :\n    blank : 2\n    nFiles : 0\n    code : 6\n    comment : 1\n  R/hello_2.c :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nSUM :\n  added :\n    comment : 2\n    nFiles : 0\n    blank : 2\n    code : 7\n  same :\n    comment : 780\n    nFiles : 0\n    blank : 191\n    code : 617\n  modified :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  removed :\n    comment : 1\n    nFiles : 0\n    blank : 2\n    code : 6\n"
  },
  {
    "path": "tests/outputs/issues/286/1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00780487060546875\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 128.125122189638\n  lines_per_second   : 512.500488758553\n  report_file        : tests/outputs/issues/286/1.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nSUM: \n  blank: 0\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/286/2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00678896903991699\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 147.297769973661\n  lines_per_second   : 589.191079894644\n  report_file        : tests/outputs/issues/286/2.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nSUM: \n  blank: 0\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/286/3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00693893432617188\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 144.114348543156\n  lines_per_second   : 576.457394172622\n  report_file        : tests/outputs/issues/286/3.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nSUM: \n  blank: 0\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/286/4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00791406631469727\n  n_files            : 2\n  n_lines            : 5\n  files_per_second   : 252.714586973549\n  lines_per_second   : 631.786467433874\n  report_file        : tests/outputs/issues/286/4.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nPython :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 3\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/286/5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00767397880554199\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 130.310498027154\n  lines_per_second   : 521.241992108615\n  report_file        : tests/outputs/issues/286/5.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nSUM: \n  blank: 0\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/286/6.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.0067901611328125\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 147.27191011236\n  lines_per_second   : 589.087640449438\n  report_file        : tests/outputs/issues/286/6.yaml\nC :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 2\nSUM: \n  blank: 0\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/296/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.0279321670532227\n  n_files            : 6\n  n_lines            : 172\n  files_per_second   : 214.806104680938\n  lines_per_second   : 6157.77500085356\n  report_file        : ../outputs/issues/296/results.yaml\n'MATLAB' :\n  nFiles: 2\n  blank: 0\n  comment: 1\n  code: 50\n'Objective-C' :\n  nFiles: 1\n  blank: 11\n  comment: 11\n  code: 25\n'Mathematica' :\n  nFiles: 1\n  blank: 12\n  comment: 8\n  code: 11\n'Lua' :\n  nFiles: 2\n  blank: 7\n  comment: 32\n  code: 4\nSUM: \n  blank: 30\n  comment: 52\n  code: 90\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/issues/312/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00709319114685059\n  n_files            : 1\n  n_lines            : 2\n  files_per_second   : 140.980269570771\n  lines_per_second   : 281.960539141541\n  report_file        : ../../../outputs/issues/312/results.yaml\n'./sam #ple.py' :\n  blank: 0\n  comment: 0\n  code: 2\n  language: Python\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/327/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.79\n  elapsed_seconds    : 0.00521588325500488\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 191.722082552452\n  lines_per_second   : 191.722082552452\n  report_file        : ../../../outputs/issues/327/results.yaml\n'Smarty' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/341/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00841999053955078\n  n_files            : 2\n  n_lines            : 263\n  files_per_second   : 237.529958092649\n  lines_per_second   : 31235.1894891834\n  report_file        : results.yaml\n'TeX' :\n  nFiles: 1\n  blank: 7\n  comment: 43\n  code: 110\n'Visual Basic' :\n  nFiles: 1\n  blank: 25\n  comment: 40\n  code: 38\nSUM: \n  blank: 32\n  comment: 83\n  code: 148\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/350/fs.go.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00793290138244629\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 126.057283683467\n  lines_per_second   : 3277.48937577014\n  report_file        : ../../../outputs/issues/350/fs.go.yaml\n'Go' :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 18\nSUM: \n  blank: 4\n  comment: 4\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/365/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00717306137084961\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 139.410489928871\n  lines_per_second   : 5158.18812736821\n  report_file        : /home/al/git-cloc/tests/outputs/issues/365/results.yaml\n'Java' :\n  nFiles: 1\n  blank: 2\n  comment: 3\n  code: 32\nSUM: \n  blank: 2\n  comment: 3\n  code: 32\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/370/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00791311264038086\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 126.372521843929\n  lines_per_second   : 1263.72521843929\n  report_file        : /home/al/git-cloc/tests/outputs/issues/370/results.yaml\n'Arduino Sketch' :\n  nFiles: 1\n  blank: 1\n  comment: 5\n  code: 4\nSUM: \n  blank: 1\n  comment: 5\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/375/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00719809532165527\n  n_files            : 1\n  n_lines            : 35\n  files_per_second   : 138.925640091418\n  lines_per_second   : 4862.39740319963\n  report_file        : results.yaml\n'Python' :\n  nFiles: 1\n  blank: 3\n  comment: 0\n  code: 32\nSUM: \n  blank: 3\n  comment: 0\n  code: 32\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/380/wrapper.pl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00648021697998047\n  n_files            : 1\n  n_lines            : 187\n  files_per_second   : 154.315820456218\n  lines_per_second   : 28857.0584253127\n  report_file        : /home/al/git-cloc/tests/outputs/issues/380/wrapper.pl.yaml\n'Perl' :\n  nFiles: 1\n  blank: 44\n  comment: 72\n  code: 71\nSUM: \n  blank: 44\n  comment: 72\n  code: 71\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/381/issue381.c.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00760793685913086\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 131.441679724224\n  lines_per_second   : 2628.83359448449\n  report_file        : ../../../outputs/issues/381/issue381.c.yaml\n'C' :\n  nFiles: 1\n  blank: 3\n  comment: 1\n  code: 16\nSUM: \n  blank: 3\n  comment: 1\n  code: 16\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/381/issue381.java.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00729489326477051\n  n_files            : 1\n  n_lines            : 35\n  files_per_second   : 137.082197601072\n  lines_per_second   : 4797.87691603752\n  report_file        : ../../../outputs/issues/381/issue381.java.yaml\n'Java' :\n  nFiles: 1\n  blank: 5\n  comment: 3\n  code: 27\nSUM: \n  blank: 5\n  comment: 3\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/396/excl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00886392593383789\n  n_files            : 2\n  n_lines            : 264\n  files_per_second   : 225.63365431169\n  lines_per_second   : 29783.642369143\n  report_file        : excl.yaml\n'R' :\n  nFiles: 2\n  blank: 54\n  comment: 36\n  code: 174\nSUM: \n  blank: 54\n  comment: 36\n  code: 174\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/396/excl_diff.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.0111479759216309\n  n_files            : 1\n  n_lines            : 9\n  files_per_second   : 89.7023824800034\n  lines_per_second   : 807.321442320031\n  report_file        : ../../../outputs/issues/396/excl_diff.yaml\nadded :\n  'C' :\n    blank : 0\n    code : 1\n    comment : 1\n    nFiles : 0\nsame :\n  'C' :\n    blank : 0\n    code : 6\n    comment : 1\n    nFiles : 0\nmodified :\n  'C' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 1\nremoved :\n  'C' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nSUM :\n  added :\n    code : 1\n    comment : 1\n    blank : 0\n    nFiles : 0\n  same :\n    code : 6\n    comment : 1\n    blank : 0\n    nFiles : 0\n  modified :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 1\n  removed :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n"
  },
  {
    "path": "tests/outputs/issues/405/globs.py.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00863099098205566\n  n_files            : 1\n  n_lines            : 16\n  files_per_second   : 115.86155078589\n  lines_per_second   : 1853.78481257424\n  report_file        : globs.py.yaml\n'Python' :\n  nFiles: 1\n  blank: 2\n  comment: 7\n  code: 7\nSUM: \n  blank: 2\n  comment: 7\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/407/results1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00797700881958008\n  n_files            : 2\n  n_lines            : 21\n  files_per_second   : 250.720545161098\n  lines_per_second   : 2632.56572419152\n  report_file        : 407.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\n'Fortran 77' :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 4\nSUM: \n  blank: 2\n  comment: 8\n  code: 11\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/407/results2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.0085301399230957\n  n_files            : 1\n  n_lines            : 30\n  files_per_second   : 117.231371233719\n  lines_per_second   : 3516.94113701157\n  report_file        : results2.yaml\n'Java' :\n  nFiles: 1\n  blank: 6\n  comment: 15\n  code: 9\nSUM: \n  blank: 6\n  comment: 15\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/407/results3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00864291191101074\n  n_files            : 1\n  n_lines            : 30\n  files_per_second   : 115.701746158727\n  lines_per_second   : 3471.0523847618\n  report_file        : results3.yaml\n'Java' :\n  nFiles: 1\n  blank: 6\n  comment: 15\n  code: 9\nSUM: \n  blank: 6\n  comment: 15\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/408/badly_named_ruby.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00796198844909668\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 125.596765982932\n  lines_per_second   : 376.790297948795\n  report_file        : badly_named_ruby.yaml\n'Prolog' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 2\nSUM: \n  blank: 1\n  comment: 0\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/420/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.84\n  elapsed_seconds    : 0.00705695152282715\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 141.704246765093\n  lines_per_second   : 2834.08493530187\n  report_file        : ../../../outputs/issues/420/results.yaml\n'Perl' :\n  nFiles: 1\n  blank: 5\n  comment: 1\n  code: 14\nSUM: \n  blank: 5\n  comment: 1\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/433/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00985193252563477\n  n_files            : 0\n  n_lines            : 20\n  files_per_second   : 0\n  lines_per_second   : 2030.05856444509\n  report_file        : /home/al/git-cloc/tests/outputs/issues/433/results.yaml\nadded :\n  'L/hello_1.c' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  'R/hello_2.c' :\n    nFiles : 0\n    comment : 2\n    blank : 2\n    code : 7\nsame :\n  'L/hello_1.c' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  'R/hello_2.c' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nmodified :\n  'L/hello_1.c' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  'R/hello_2.c' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nremoved :\n  'L/hello_1.c' :\n    nFiles : 0\n    blank : 2\n    code : 6\n    comment : 1\n  'R/hello_2.c' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nSUM :\n  added :\n    nFiles : 0\n    code : 7\n    blank : 2\n    comment : 2\n  same :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\n  modified :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\n  removed :\n    nFiles : 0\n    code : 6\n    blank : 2\n    comment : 1\n"
  },
  {
    "path": "tests/outputs/issues/454/createServer.js.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0077979564666748\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 128.238725655059\n  lines_per_second   : 1795.34215917082\n  report_file        : ../../../outputs/issues/454/createServer.js.yaml\n'JavaScript' :\n  nFiles: 1\n  blank: 3\n  comment: 0\n  code: 11\nSUM: \n  blank: 3\n  comment: 0\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/455/list.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0106370449066162\n  n_files            : 3\n  n_lines            : 34\n  files_per_second   : 282.033217527737\n  lines_per_second   : 3196.37646531436\n  report_file        : /home/al/git-cloc/tests/outputs/issues/455/list.yaml\nadded :\n  'C++' :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  'Fortran 90' :\n    comment : 1\n    blank : 0\n    nFiles : 0\n    code : 0\n  'Python' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nsame :\n  'C++' :\n    blank : 0\n    comment : 1\n    nFiles : 0\n    code : 6\n  'Fortran 90' :\n    comment : 3\n    blank : 0\n    nFiles : 0\n    code : 4\n  'Python' :\n    comment : 10\n    blank : 4\n    nFiles : 1\n    code : 3\nmodified :\n  'C++' :\n    blank : 0\n    comment : 1\n    nFiles : 1\n    code : 0\n  'Fortran 90' :\n    comment : 0\n    blank : 0\n    nFiles : 1\n    code : 0\n  'Python' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nremoved :\n  'C++' :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  'Fortran 90' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 1\n  'Python' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nSUM :\n  added :\n    comment : 1\n    blank : 0\n    nFiles : 0\n    code : 0\n  same :\n    comment : 14\n    blank : 4\n    nFiles : 1\n    code : 13\n  modified :\n    comment : 1\n    blank : 0\n    nFiles : 2\n    code : 0\n  removed :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 1\n"
  },
  {
    "path": "tests/outputs/issues/455/list_align.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0118508338928223\n  n_files            : 5\n  n_lines            : 47\n  files_per_second   : 421.91123807991\n  lines_per_second   : 3965.96563795115\n  report_file        : /home/al/git-cloc/tests/outputs/issues/455/list_align.yaml\nadded :\n  'C++' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 0\n  'Java' :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  'Perl' :\n    nFiles : 1\n    blank : 0\n    comment : 0\n    code : 2\n  'Python' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'Fortran 90' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 1\nsame :\n  'C++' :\n    code : 6\n    nFiles : 0\n    blank : 0\n    comment : 1\n  'Java' :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  'Perl' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    code : 3\n    comment : 10\n    blank : 4\n    nFiles : 1\n  'Fortran 90' :\n    code : 4\n    nFiles : 0\n    blank : 0\n    comment : 3\nmodified :\n  'C++' :\n    code : 0\n    nFiles : 1\n    blank : 0\n    comment : 1\n  'Java' :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  'Perl' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'Fortran 90' :\n    code : 0\n    nFiles : 1\n    blank : 0\n    comment : 0\nremoved :\n  'C++' :\n    code : 0\n    nFiles : 0\n    blank : 0\n    comment : 0\n  'Java' :\n    blank : 0\n    comment : 4\n    nFiles : 1\n    code : 7\n  'Perl' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  'Python' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'Fortran 90' :\n    code : 1\n    nFiles : 0\n    blank : 0\n    comment : 0\nSUM :\n  added :\n    comment : 1\n    blank : 0\n    nFiles : 1\n    code : 2\n  same :\n    comment : 14\n    blank : 4\n    nFiles : 1\n    code : 13\n  modified :\n    comment : 1\n    blank : 0\n    nFiles : 2\n    code : 0\n  removed :\n    comment : 4\n    blank : 0\n    nFiles : 1\n    code : 8\n"
  },
  {
    "path": "tests/outputs/issues/456/XML_no_ext.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00800895690917969\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 124.860204810669\n  lines_per_second   : 624.301024053346\n  report_file        : /home/al/git-cloc/tests/outputs/issues/456/XML_no_ext.yaml\n'XML' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 3\nSUM: \n  blank: 0\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/456/XML_weird_ext.profile.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00759005546569824\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 131.75134286163\n  lines_per_second   : 527.005371446521\n  report_file        : /home/al/git-cloc/tests/outputs/issues/456/XML_weird_ext.profile.yaml\n'XML' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 3\nSUM: \n  blank: 0\n  comment: 1\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/463/diff.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0103778839111328\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 96.358757581327\n  lines_per_second   : 578.152545487962\n  report_file        : /home/al/git-cloc/tests/outputs/issues/463/diff.yaml\nadded :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\nsame :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 2\n    comment : 0\nmodified :\n  'C++' :\n    nFiles : 1\n    blank : 0\n    code : 0\n    comment : 0\nremoved :\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 1\n    comment : 3\nSUM :\n  added :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 0\n  same :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 2\n  modified :\n    nFiles : 1\n    blank : 0\n    comment : 0\n    code : 0\n  removed :\n    nFiles : 0\n    blank : 0\n    comment : 3\n    code : 1\n"
  },
  {
    "path": "tests/outputs/issues/472/not_really.lua.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00434207916259766\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 230.304414671645\n  lines_per_second   : 1381.82648802987\n  report_file        : not_really.lua.yaml\n'Lua' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 2\nSUM: \n  blank: 2\n  comment: 2\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/476/all.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.0108919143676758\n  n_files            : 5\n  n_lines            : 35\n  files_per_second   : 459.056124682602\n  lines_per_second   : 3213.39287277822\n  report_file        : all.yaml\nadded :\n  'Fortran 90' :\n    comment : 0\n    nFiles : 0\n    code : 0\n    blank : 0\n  'C++' :\n    comment : 1\n    code : 6\n    blank : 0\n    nFiles : 1\nsame :\n  'Fortran 90' :\n    comment : 5\n    nFiles : 1\n    code : 7\n    blank : 0\n  'C++' :\n    comment : 1\n    code : 5\n    blank : 0\n    nFiles : 0\nmodified :\n  'Fortran 90' :\n    comment : 1\n    nFiles : 1\n    code : 1\n    blank : 0\n  'C++' :\n    comment : 1\n    code : 0\n    blank : 0\n    nFiles : 1\nremoved :\n  'Fortran 90' :\n    comment : 0\n    nFiles : 0\n    code : 0\n    blank : 0\n  'C++' :\n    comment : 2\n    code : 5\n    blank : 0\n    nFiles : 1\nSUM :\n  added :\n    comment : 1\n    code : 6\n    blank : 0\n    nFiles : 1\n  same :\n    comment : 6\n    code : 12\n    blank : 0\n    nFiles : 1\n  modified :\n    comment : 2\n    code : 1\n    blank : 0\n    nFiles : 2\n  removed :\n    comment : 2\n    code : 5\n    blank : 0\n    nFiles : 1\n"
  },
  {
    "path": "tests/outputs/issues/476/no_cpp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00912594795227051\n  n_files            : 2\n  n_lines            : 14\n  files_per_second   : 219.155315202341\n  lines_per_second   : 1534.08720641639\n  report_file        : no_cpp.yaml\nadded :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nsame :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 1\n    code : 7\n    comment : 5\nmodified :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 1\n    code : 1\n    comment : 1\nremoved :\n  'Fortran 90' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nSUM :\n  added :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  same :\n    nFiles : 1\n    blank : 0\n    code : 7\n    comment : 5\n  modified :\n    nFiles : 1\n    blank : 0\n    code : 1\n    comment : 1\n  removed :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n"
  },
  {
    "path": "tests/outputs/issues/476/no_fortran.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00994992256164551\n  n_files            : 3\n  n_lines            : 21\n  files_per_second   : 301.509884264251\n  lines_per_second   : 2110.56918984976\n  report_file        : no_fortran.yaml\nadded :\n  'C++' :\n    code : 6\n    blank : 0\n    comment : 1\n    nFiles : 1\nsame :\n  'C++' :\n    code : 5\n    blank : 0\n    comment : 1\n    nFiles : 0\nmodified :\n  'C++' :\n    code : 0\n    blank : 0\n    comment : 1\n    nFiles : 1\nremoved :\n  'C++' :\n    code : 5\n    blank : 0\n    comment : 2\n    nFiles : 1\nSUM :\n  added :\n    nFiles : 1\n    comment : 1\n    blank : 0\n    code : 6\n  same :\n    nFiles : 0\n    comment : 1\n    blank : 0\n    code : 5\n  modified :\n    nFiles : 1\n    comment : 1\n    blank : 0\n    code : 0\n  removed :\n    nFiles : 1\n    comment : 2\n    blank : 0\n    code : 5\n"
  },
  {
    "path": "tests/outputs/issues/482/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00847101211547852\n  n_files            : 2\n  n_lines            : 16\n  files_per_second   : 236.099296369265\n  lines_per_second   : 1888.79437095412\n  report_file        : ../../../outputs/issues/482/results.yaml\nadded :\n  'C' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nsame :\n  'C' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nmodified :\n  'C' :\n    blank : 0\n    nFiles : 0\n    code : 0\n    comment : 0\nremoved :\n  'C' :\n    blank : 4\n    nFiles : 2\n    code : 10\n    comment : 2\nSUM :\n  added :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\n  same :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\n  modified :\n    code : 0\n    nFiles : 0\n    comment : 0\n    blank : 0\n  removed :\n    code : 10\n    nFiles : 2\n    comment : 2\n    blank : 4\n"
  },
  {
    "path": "tests/outputs/issues/494/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.0113317966461182\n  n_files            : 2\n  n_lines            : 166\n  files_per_second   : 176.494519135686\n  lines_per_second   : 14649.0450882619\n  report_file        : ../../../outputs/issues/494/results.yaml\n'P_EDI_Book.sql' :\n  blank: 24\n  comment: 36\n  code: 23\n  language: SQL\n'P_EDI_BookF8.sql' :\n  blank: 24\n  comment: 36\n  code: 23\n  language: SQL\nSUM: \n  blank: 48\n  comment: 72\n  code: 46\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/502/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00855422019958496\n  n_files            : 1\n  n_lines            : 83\n  files_per_second   : 116.90136291424\n  lines_per_second   : 9702.81312188188\n  report_file        : ../../../outputs/issues/502/results.yaml\n'SQL' :\n  nFiles: 1\n  blank: 24\n  comment: 36\n  code: 23\nSUM: \n  blank: 24\n  comment: 36\n  code: 23\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/513/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.0145459175109863\n  n_files            : 3\n  n_lines            : 1608\n  files_per_second   : 206.243435502377\n  lines_per_second   : 110546.481429274\n  report_file        : ../../../outputs/issues/513/results.yaml\nadded :\n  'C/C++ Header' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    comment : 2\n    nFiles : 1\n    blank : 2\n    code : 7\nsame :\n  'C/C++ Header' :\n    comment : 780\n    code : 617\n    blank : 191\n    nFiles : 1\n  'C' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nmodified :\n  'C/C++ Header' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nremoved :\n  'C/C++ Header' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    comment : 1\n    nFiles : 1\n    blank : 2\n    code : 6\nSUM :\n  added :\n    comment : 2\n    blank : 2\n    code : 7\n    nFiles : 1\n  same :\n    comment : 780\n    blank : 191\n    code : 617\n    nFiles : 1\n  modified :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  removed :\n    comment : 1\n    blank : 2\n    code : 6\n    nFiles : 1\n"
  },
  {
    "path": "tests/outputs/issues/520/doc_as_code.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.88\n  elapsed_seconds    : 0.00802803039550781\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 124.56355428843\n  lines_per_second   : 747.381325730577\n  report_file        : ../../../outputs/issues/520/doc_as_code.yaml\n'Julia' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 5\nSUM: \n  blank: 1\n  comment: 0\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/520/doc_as_comment.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.88\n  elapsed_seconds    : 0.00936198234558105\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 106.814984592661\n  lines_per_second   : 640.889907555963\n  report_file        : ../../../outputs/issues/520/doc_as_comment.yaml\n'Julia' :\n  nFiles: 1\n  blank: 1\n  comment: 4\n  code: 1\nSUM: \n  blank: 1\n  comment: 4\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/521/skip_uniq.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.0129001140594482\n  n_files            : 2\n  n_lines            : 20\n  files_per_second   : 155.037388877594\n  lines_per_second   : 1550.37388877594\n  report_file        : ../../../outputs/issues/521/skip_uniq.yaml\nadded :\n  'SQL' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nsame :\n  'SQL' :\n    comment : 0\n    blank : 0\n    nFiles : 1\n    code : 16\nmodified :\n  'SQL' :\n    comment : 0\n    blank : 0\n    nFiles : 1\n    code : 0\nremoved :\n  'SQL' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 4\nSUM :\n  added :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 0\n  same :\n    blank : 0\n    comment : 0\n    nFiles : 1\n    code : 16\n  modified :\n    blank : 0\n    comment : 0\n    nFiles : 1\n    code : 0\n  removed :\n    blank : 0\n    comment : 0\n    nFiles : 0\n    code : 4\n"
  },
  {
    "path": "tests/outputs/issues/521/uniq.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00958991050720215\n  n_files            : 2\n  n_lines            : 16\n  files_per_second   : 208.552519702658\n  lines_per_second   : 1668.42015762126\n  report_file        : ../../../outputs/issues/521/uniq.yaml\nadded :\n  'SQL' :\n    comment : 0\n    nFiles : 1\n    blank : 0\n    code : 6\nsame :\n  'SQL' :\n    comment : 0\n    nFiles : 1\n    blank : 0\n    code : 10\nmodified :\n  'SQL' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nremoved :\n  'SQL' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nSUM :\n  added :\n    nFiles : 1\n    blank : 0\n    code : 6\n    comment : 0\n  same :\n    nFiles : 1\n    blank : 0\n    code : 10\n    comment : 0\n  modified :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  removed :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n"
  },
  {
    "path": "tests/outputs/issues/528/cutoff_code_10.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.014768123626709\n  n_files            : 8\n  n_lines            : 184\n  files_per_second   : 541.707274547157\n  lines_per_second   : 12459.2673145846\n  report_file        : /home/al/git-cloc/tests/outputs/issues/528/cutoff_code_10.yaml\n'MATLAB' :\n  nFiles: 3\n  blank: 3\n  comment: 11\n  code: 68\n'Objective-C' :\n  nFiles: 1\n  blank: 11\n  comment: 11\n  code: 25\n'Other' :\n  nFiles: 3\n  blank: 1\n  comment: 10\n  code: 13\n'Mathematica' :\n  nFiles: 1\n  blank: 12\n  comment: 8\n  code: 11\nSUM: \n  blank: 27\n  comment: 40\n  code: 117\n  nFiles: 8\n"
  },
  {
    "path": "tests/outputs/issues/528/cutoff_code_50pct.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.0111649036407471\n  n_files            : 8\n  n_lines            : 184\n  files_per_second   : 716.531038459074\n  lines_per_second   : 16480.2138845587\n  report_file        : /home/al/git-cloc/tests/outputs/issues/528/cutoff_code_50pct.yaml\n'MATLAB' :\n  nFiles: 3\n  blank: 3\n  comment: 11\n  code: 68\n'Other' :\n  nFiles: 5\n  blank: 24\n  comment: 29\n  code: 49\nSUM: \n  blank: 27\n  comment: 40\n  code: 117\n  nFiles: 8\n"
  },
  {
    "path": "tests/outputs/issues/528/cutoff_files_1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.0106549263000488\n  n_files            : 8\n  n_lines            : 184\n  files_per_second   : 750.826404117252\n  lines_per_second   : 17269.0072946968\n  report_file        : /home/al/git-cloc/tests/outputs/issues/528/cutoff_files_1.yaml\n'MATLAB' :\n  nFiles: 3\n  blank: 3\n  comment: 11\n  code: 68\n'Other' :\n  nFiles: 3\n  blank: 23\n  comment: 21\n  code: 42\n'Fortran 77' :\n  nFiles: 2\n  blank: 1\n  comment: 8\n  code: 7\nSUM: \n  blank: 27\n  comment: 40\n  code: 117\n  nFiles: 8\n"
  },
  {
    "path": "tests/outputs/issues/530/case_1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00850200653076172\n  n_files            : 1\n  n_lines            : 9\n  files_per_second   : 117.619293325855\n  lines_per_second   : 1058.5736399327\n  report_file        : case_1.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 0\n  code: 7\nSUM: \n  blank: 2\n  comment: 0\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/530/case_2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00734210014343262\n  n_files            : 1\n  n_lines            : 0\n  files_per_second   : 136.200811820101\n  lines_per_second   : 0\n  report_file        : case_2.yaml\n'C' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 0\nSUM: \n  blank: 0\n  comment: 0\n  code: 0\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/530/case_3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00851607322692871\n  n_files            : 1\n  n_lines            : 9\n  files_per_second   : 117.425011898429\n  lines_per_second   : 1056.82510708586\n  report_file        : case_3.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 0\n  code: 7\nSUM: \n  blank: 2\n  comment: 0\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/530/case_4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00853896141052246\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 117.1102610638\n  lines_per_second   : 1288.2128717018\n  report_file        : case_4.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/530/tests.sh",
    "content": "# nominal; skip first two\ncloc --yaml --out case_1.yaml --skip-leading 2 ../../../inputs/issues/530\n\n# more lines than in the file; null return\ncloc --yaml --out case_2.yaml --skip-leading 100 ../../../inputs/issues/530\n\n# in extension list; skip first two\ncloc --yaml --out case_3.yaml --skip-leading 2,c,h ../../../inputs/issues/530\n\n# not in extension list; skip nothing\ncloc --yaml --out case_4.yaml --skip-leading 2,C,H ../../../inputs/issues/530\n"
  },
  {
    "path": "tests/outputs/issues/537/results_force.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00471711158752441\n  n_files            : 1\n  n_lines            : 36\n  files_per_second   : 211.994136972454\n  lines_per_second   : 7631.78893100834\n  report_file        : ../../../outputs/issues/results_force.yaml\n'VERTICA_SQL' :\n  nFiles: 1\n  blank: 9\n  comment: 14\n  code: 13\nSUM: \n  blank: 9\n  comment: 14\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/537/results_read.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00664687156677246\n  n_files            : 1\n  n_lines            : 36\n  files_per_second   : 150.44671616629\n  lines_per_second   : 5416.08178198644\n  report_file        : ../../../outputs/issues/results_read.yaml\n'VERTICA_SQL' :\n  nFiles: 1\n  blank: 9\n  comment: 14\n  code: 13\nSUM: \n  blank: 9\n  comment: 14\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/538/add.elm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00626897811889648\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 159.51563094242\n  lines_per_second   : 478.546892827261\n  report_file        : ../../../outputs/issues/538/add.elm.yaml\n'Elm' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/539/nested_comments.elm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00657892227172852\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 152.000579836196\n  lines_per_second   : 760.002899180981\n  report_file        : ../../../outputs/issues/539/nested_comments.elm.yaml\n'Elm' :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 2\nSUM: \n  blank: 0\n  comment: 3\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/540/Hello.f.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00683403015136719\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 146.326542003907\n  lines_per_second   : 1463.26542003907\n  report_file        : ../../../outputs/issues/540/Hello.f.yaml\n'Hello.f' :\n  blank: 0\n  comment: 6\n  code: 4\n  language: Fortran 77\nSUM: \n  blank: 0\n  comment: 6\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/542/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00708508491516113\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 141.141568799004\n  lines_per_second   : 564.566275196016\n  report_file        : ../../../outputs/issues/542/results.yaml\n'Text File' :\n  nFiles: 1\n  blank: 0\n  comment: 4\n  code: 0\nSUM: \n  blank: 0\n  comment: 4\n  code: 0\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/577/diff_list.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00794696807861328\n  n_files            : 1\n  n_lines            : 101\n  files_per_second   : 125.834153366135\n  lines_per_second   : 12709.2494899796\n  report_file        : ../../../outputs/issues/577/diff_list.yaml\nadded :\n  'Swift' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nsame :\n  'Swift' :\n    nFiles : 1\n    comment : 13\n    blank : 23\n    code : 65\nmodified :\n  'Swift' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nremoved :\n  'Swift' :\n    nFiles : 0\n    comment : 0\n    blank : 0\n    code : 0\nSUM :\n  added :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n  same :\n    blank : 23\n    code : 65\n    comment : 13\n    nFiles : 1\n  modified :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n  removed :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\n"
  },
  {
    "path": "tests/outputs/issues/579/csharp-autogen.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00695490837097168\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 143.783346474238\n  lines_per_second   : 3594.58366185595\n  report_file        : ../../../outputs/issues/579/csharp-autogen.cs.yaml\n'C# Generated' :\n  nFiles: 1\n  blank: 2\n  comment: 16\n  code: 7\nSUM: \n  blank: 2\n  comment: 16\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/580/encodingtest.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00690698623657227\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 144.780945806006\n  lines_per_second   : 434.342837418019\n  report_file        : ../../../outputs/issues/580/encodingtest.cs.yaml\n'C#' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 3\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/596/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.90\n  elapsed_seconds    : 0.00493121147155762\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 202.78992409225\n  lines_per_second   : 608.369772276749\n  report_file        : ../../../outputs/issues/596/results.yaml\n'Yarn' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\nSUM: \n  blank: 0\n  comment: 1\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/597/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.90\n  elapsed_seconds    : 0.00784587860107422\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 127.45545156193\n  lines_per_second   : 1019.64361249544\n  report_file        : ../../../outputs/issues/597/results.yaml\n'C++' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 6\nSUM: \n  blank: 0\n  comment: 2\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/599/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00736308097839355\n  n_files            : 1\n  n_lines            : 2\n  files_per_second   : 135.812712495548\n  lines_per_second   : 271.625424991095\n  report_file        : ../tests/outputs/issues/599/results.yaml\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/606/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.0093681812286377\n  n_files            : 1\n  n_lines            : 93\n  files_per_second   : 106.744305601507\n  lines_per_second   : 9927.22042094012\n  report_file        : /home/al/git-cloc/tests/outputs/issues/606/results.yaml\n'HCL' :\n  nFiles: 1\n  blank: 14\n  comment: 36\n  code: 43\nSUM: \n  blank: 14\n  comment: 36\n  code: 43\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/611/cmakelists.txt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00787496566772461\n  n_files            : 1\n  n_lines            : 337\n  files_per_second   : 126.9846805934\n  lines_per_second   : 42793.8373599758\n  report_file        : ../../../outputs/issues/611/cmakelists.txt.yaml\n'CMake' :\n  nFiles: 1\n  blank: 36\n  comment: 40\n  code: 261\nSUM: \n  blank: 36\n  comment: 40\n  code: 261\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/613/nav.scss.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00863790512084961\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 115.76881037814\n  lines_per_second   : 3009.98906983163\n  report_file        : ../../../outputs/issues/613/nav.scss.yaml\n'SCSS' :\n  nFiles: 1\n  blank: 2\n  comment: 4\n  code: 20\nSUM: \n  blank: 2\n  comment: 4\n  code: 20\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/619/RA.s.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00762414932250977\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 131.162173994621\n  lines_per_second   : 393.486521983864\n  report_file        : ../../../outputs/issues/619/RA.s.yaml\n'Assembly' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/625/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00797080993652344\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 125.457765015554\n  lines_per_second   : 1003.66212012443\n  report_file        : /home/al/git-cloc/tests/outputs/issues/625/results.yaml\nadded :\n  'C++' :\n    blank : 0\n    code : 6\n    comment : 2\n    nFiles : 1\nsame :\n  'C++' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nmodified :\n  'C++' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nremoved :\n  'C++' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nSUM :\n  added :\n    comment : 2\n    blank : 0\n    code : 6\n    nFiles : 1\n  same :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  modified :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  removed :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n"
  },
  {
    "path": "tests/outputs/issues/628/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00743508338928223\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 134.497482764149\n  lines_per_second   : 1882.96475869809\n  report_file        : ../../../outputs/issues/628/results.yaml\n'GraphQL' :\n  nFiles: 1\n  blank: 2\n  comment: 4\n  code: 8\nSUM: \n  blank: 2\n  comment: 4\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/637/diff_incl_lang.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00929498672485352\n  n_files            : 2\n  n_lines            : 19\n  files_per_second   : 215.169753244755\n  lines_per_second   : 2044.11265582517\n  report_file        : ../../../outputs/issues/637/diff_incl_lang.yaml\nadded :\n  'Python' :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  'Perl' :\n    nFiles : 1\n    code : 2\n    blank : 0\n    comment : 0\nsame :\n  'Python' :\n    comment : 10\n    blank : 4\n    code : 3\n    nFiles : 1\n  'Perl' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\nmodified :\n  'Python' :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  'Perl' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\nremoved :\n  'Python' :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  'Perl' :\n    nFiles : 0\n    code : 0\n    blank : 0\n    comment : 0\nSUM :\n  added :\n    comment : 0\n    blank : 0\n    code : 2\n    nFiles : 1\n  same :\n    comment : 10\n    blank : 4\n    code : 3\n    nFiles : 1\n  modified :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n  removed :\n    comment : 0\n    blank : 0\n    code : 0\n    nFiles : 0\n"
  },
  {
    "path": "tests/outputs/issues/637/straight_incl_lang.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00884604454040527\n  n_files            : 2\n  n_lines            : 19\n  files_per_second   : 226.089750154974\n  lines_per_second   : 2147.85262647225\n  report_file        : ../../../outputs/issues/637/straight_incl_lang.yaml\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 10\n  code: 3\n'Perl' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 4\n  comment: 10\n  code: 5\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/644/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.0103890895843506\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 96.2548250143431\n  lines_per_second   : 96.2548250143431\n  report_file        : ../../../outputs/issues/644/results.yaml\n'C#' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 0\nSUM: \n  blank: 1\n  comment: 0\n  code: 0\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/657/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00711417198181152\n  n_files            : 2\n  n_lines            : 21\n  files_per_second   : 281.128992258454\n  lines_per_second   : 2951.85441871376\n  report_file        : ../../../outputs/issues/657/results.yaml\n'C' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 7\n'Fortran 77' :\n  nFiles: 1\n  blank: 0\n  comment: 6\n  code: 4\nSUM: \n  blank: 2\n  comment: 8\n  code: 11\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/670/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00746417045593262\n  n_files            : 2\n  n_lines            : 25\n  files_per_second   : 267.946721180567\n  lines_per_second   : 3349.33401475708\n  report_file        : /home/al/git-cloc/tests/outputs/issues/670/results.yaml\nfiles|language|blank|comment|code|\"github.com/AlDanial/cloc v 1.95  T=0.01 s (267.9 files/s, 3349.3 lines/s)\"\n'C++' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 6\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 4\n  comment: 13\n  code: 8\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/692/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.0124430656433105\n  n_files            : 5\n  n_lines            : 47\n  files_per_second   : 401.830235677333\n  lines_per_second   : 3777.20421536693\n  report_file        : ../../../outputs/issues/692/results.yaml\nadded :\n  'Fortran 90' :\n    nFiles : 0\n    blank : 0\n    comment : 1\n    code : 0\n  'Perl' :\n    code : 2\n    comment : 0\n    blank : 0\n    nFiles : 1\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  'Java' :\n    code : 0\n    blank : 0\n    comment : 0\n    nFiles : 0\n  'Python' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nsame :\n  'Fortran 90' :\n    nFiles : 0\n    blank : 0\n    comment : 3\n    code : 4\n  'Perl' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 6\n    comment : 1\n  'Java' :\n    code : 0\n    blank : 0\n    comment : 0\n    nFiles : 0\n  'Python' :\n    blank : 4\n    code : 3\n    comment : 10\n    nFiles : 1\nmodified :\n  'Fortran 90' :\n    nFiles : 1\n    blank : 0\n    comment : 0\n    code : 0\n  'Perl' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C++' :\n    nFiles : 1\n    blank : 0\n    code : 0\n    comment : 1\n  'Java' :\n    code : 0\n    blank : 0\n    comment : 0\n    nFiles : 0\n  'Python' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nremoved :\n  'Fortran 90' :\n    nFiles : 0\n    blank : 0\n    comment : 0\n    code : 1\n  'Perl' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C++' :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  'Java' :\n    code : 7\n    blank : 0\n    comment : 4\n    nFiles : 1\n  'Python' :\n    blank : 0\n    code : 0\n    comment : 0\n    nFiles : 0\nSUM :\n  added :\n    nFiles : 1\n    blank : 0\n    code : 2\n    comment : 1\n  same :\n    nFiles : 1\n    blank : 4\n    code : 13\n    comment : 14\n  modified :\n    nFiles : 2\n    blank : 0\n    code : 0\n    comment : 1\n  removed :\n    nFiles : 1\n    blank : 0\n    code : 8\n    comment : 4\n"
  },
  {
    "path": "tests/outputs/issues/701/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00726699829101562\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 137.608398950131\n  lines_per_second   : 1100.86719160105\n  report_file        : ../../../outputs/issues/701/results.yaml\n'OCaml' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 8\nSUM: \n  blank: 0\n  comment: 0\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/708/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00759720802307129\n  n_files            : 3\n  n_lines            : 0\n  files_per_second   : 394.881908049584\n  lines_per_second   : 0\n  report_file        : ../tests/outputs/issues/708/results.yaml\n'C' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 0\n'C++' :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 0\nSUM: \n  blank: 0\n  comment: 0\n  code: 0\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/710/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00808811187744141\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 123.638250206344\n  lines_per_second   : 989.106001650749\n  report_file        : /home/al/git-cloc/tests/outputs/issues/710/results.txt\nadded :\n  'C++' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nsame :\n  'C++' :\n    comment : 2\n    blank : 0\n    nFiles : 1\n    code : 6\nmodified :\n  'C++' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nremoved :\n  'C++' :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\nSUM :\n  added :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  same :\n    nFiles : 1\n    blank : 0\n    code : 6\n    comment : 2\n  modified :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n  removed :\n    nFiles : 0\n    blank : 0\n    code : 0\n    comment : 0\n"
  },
  {
    "path": "tests/outputs/issues/712/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00920295715332031\n  n_files            : 0\n  n_lines            : 6\n  files_per_second   : 0\n  lines_per_second   : 651.964352331606\n  report_file        : /home/al/git-cloc/tests/outputs/issues/712/results.yaml\nadded :\n  'dir1/main.c' :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\nsame :\n  'dir1/main.c' :\n    comment : 0\n    code : 5\n    nFiles : 0\n    blank : 1\nmodified :\n  'dir1/main.c' :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\nremoved :\n  'dir1/main.c' :\n    comment : 0\n    code : 0\n    nFiles : 0\n    blank : 0\nSUM :\n  added :\n    blank : 0\n    comment : 0\n    code : 0\n    nFiles : 0\n  same :\n    blank : 1\n    comment : 0\n    code : 5\n    nFiles : 0\n  modified :\n    blank : 0\n    comment : 0\n    code : 0\n    nFiles : 0\n  removed :\n    blank : 0\n    comment : 0\n    code : 0\n    nFiles : 0\n"
  },
  {
    "path": "tests/outputs/issues/713/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  n_files            : 1\n  n_lines            : 8\n  report_file        : /home/al/git-cloc/tests/outputs/issues/713/results.yaml\n'C++' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 6\nSUM: \n  blank: 0\n  comment: 2\n  code: 6\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/720/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.0102310180664062\n  n_files            : 3\n  n_lines            : 126\n  files_per_second   : 293.225950782998\n  lines_per_second   : 12315.4899328859\n  report_file        : ../../../outputs/issues/720/results.yaml\n'../../Lanczos.m' :\n  blank: 0\n  comment: 0\n  code: 48\n  language: MATLAB\n'../../qsort_demo.m' :\n  blank: 11\n  comment: 11\n  code: 25\n  language: Objective-C\n'../../matlab_line_colors.m' :\n  blank: 3\n  comment: 10\n  code: 18\n  language: MATLAB\nSUM: \n  blank: 14\n  comment: 21\n  code: 91\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/722/results_1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00737595558166504\n  n_files            : 1\n  n_lines            : 7\n  files_per_second   : 135.575653747939\n  lines_per_second   : 949.029576235576\n  report_file        : /home/al/git-cloc/tests/outputs/issues/722/results_1.yaml\n'./hello.f90' :\n  blank: 0\n  comment: 3\n  code: 4\n  language: Fortran 90\nSUM: \n  blank: 0\n  comment: 3\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/735/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.0950539112091064\n  n_files            : 3\n  n_lines            : 425\n  files_per_second   : 31.5610369088378\n  lines_per_second   : 4471.14689541869\n  report_file        : ../../tests/outputs/issues/735/results.yaml\nadded :\n  'MATLAB' :\n    code : 2\n    comment : 1\n    blank : 0\n    nFiles : 1\n  'C' :\n    blank : 1\n    nFiles : 0\n    code : 3\n    comment : 0\nsame :\n  'MATLAB' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    blank : 0\n    nFiles : 0\n    code : 228\n    comment : 46\nmodified :\n  'MATLAB' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    blank : 0\n    nFiles : 2\n    code : 0\n    comment : 0\nremoved :\n  'MATLAB' :\n    code : 0\n    comment : 0\n    blank : 0\n    nFiles : 0\n  'C' :\n    blank : 32\n    nFiles : 0\n    code : 102\n    comment : 10\nSUM :\n  added :\n    comment : 1\n    code : 5\n    nFiles : 1\n    blank : 1\n  same :\n    comment : 46\n    code : 228\n    nFiles : 0\n    blank : 0\n  modified :\n    comment : 0\n    code : 0\n    nFiles : 2\n    blank : 0\n  removed :\n    comment : 10\n    code : 102\n    nFiles : 0\n    blank : 32\n"
  },
  {
    "path": "tests/outputs/issues/753/all.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00866103172302246\n  n_files            : 3\n  n_lines            : 105\n  files_per_second   : 346.379056899827\n  lines_per_second   : 12123.2669914939\n  report_file        : /home/al/git-cloc/tests/outputs/issues/753/all.yaml\n'C# Designer' :\n  nFiles: 1\n  blank: 8\n  comment: 22\n  code: 28\n'C# Generated' :\n  nFiles: 1\n  blank: 2\n  comment: 11\n  code: 17\n'C#' :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 9\nSUM: \n  blank: 14\n  comment: 37\n  code: 54\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/753/no_autogen.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00845623016357422\n  n_files            : 2\n  n_lines            : 75\n  files_per_second   : 236.512010826661\n  lines_per_second   : 8869.20040599977\n  report_file        : /home/al/git-cloc/tests/outputs/issues/753/no_autogen.yaml\n'C# Designer' :\n  nFiles: 1\n  blank: 8\n  comment: 22\n  code: 28\n'C#' :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 9\nSUM: \n  blank: 12\n  comment: 26\n  code: 37\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/772/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.0455169677734375\n  n_files            : 6\n  n_lines            : 655\n  files_per_second   : 131.81897418706\n  lines_per_second   : 14390.2380154207\n  report_file        : ../tests/outputs/issues/772/results.yaml\n'C' :\n  nFiles: 2\n  blank: 70\n  comment: 46\n  code: 231\n'C++' :\n  nFiles: 1\n  blank: 49\n  comment: 55\n  code: 182\n'MATLAB' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 2\n'Markdown' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'Python' :\n  nFiles: 1\n  blank: 4\n  comment: 11\n  code: 2\nSUM: \n  blank: 123\n  comment: 113\n  code: 419\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/issues/781/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.0100669860839844\n  n_files            : 3\n  n_lines            : 64\n  files_per_second   : 298.003789314134\n  lines_per_second   : 6357.41417203486\n  report_file        : /home/al/git-cloc/tests/outputs/issues/781/results.yaml\n'./fortran.inc' :\n  blank: 4\n  comment: 4\n  code: 20\n  language: Fortran 90\n'./test1.inc' :\n  blank: 5\n  comment: 7\n  code: 11\n  language: PHP\n'./pascal.inc' :\n  blank: 1\n  comment: 2\n  code: 10\n  language: Pascal\nSUM: \n  blank: 10\n  comment: 13\n  code: 41\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/784/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.0088798999786377\n  n_files            : 1\n  n_lines            : 17\n  files_per_second   : 112.61388105786\n  lines_per_second   : 1914.43597798362\n  report_file        : ../../../../tests/outputs/issues/results.yaml\n'./src/net/companies/assembly.cs' :\n  blank: 4\n  comment: 4\n  code: 9\n  language: C#\nSUM: \n  blank: 4\n  comment: 4\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/785/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00858902931213379\n  n_files            : 1\n  n_lines            : 2\n  files_per_second   : 116.427591950035\n  lines_per_second   : 232.855183900069\n  report_file        : tests/outputs/issues/785/results.yaml\n'Bourne Shell' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\nSUM: \n  blank: 0\n  comment: 0\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/804/infoSQL.java.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00276994705200195\n  n_files            : 1\n  n_lines            : 41\n  files_per_second   : 361.017731106903\n  lines_per_second   : 14801.726975383\n  report_file        : ../../../outputs/issues/804/infoSQL.java.yaml\n'Java' :\n  nFiles: 1\n  blank: 1\n  comment: 11\n  code: 29\nSUM: \n  blank: 1\n  comment: 11\n  code: 29\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/805/text_block.java.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00261998176574707\n  n_files            : 1\n  n_lines            : 21\n  files_per_second   : 381.682045682046\n  lines_per_second   : 8015.32295932296\n  report_file        : ../../../outputs/issues/805/text_block.java.yaml\n'Java' :\n  nFiles: 1\n  blank: 2\n  comment: 1\n  code: 18\nSUM: \n  blank: 2\n  comment: 1\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/806/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00264716148376465\n  n_files            : 1\n  n_lines            : 11\n  files_per_second   : 377.76312708277\n  lines_per_second   : 4155.39439791047\n  report_file        : ../../../outputs/issues/806/results.yaml\n'Java' :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 8\nSUM: \n  blank: 0\n  comment: 3\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/811/inline_comment.xml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00256609916687012\n  n_files            : 1\n  n_lines            : 6\n  files_per_second   : 389.696553005668\n  lines_per_second   : 2338.17931803401\n  report_file        : ../../../outputs/issues/811/inline_comment.xml.yaml\n'XML' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 4\nSUM: \n  blank: 0\n  comment: 2\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/816/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00281190872192383\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 355.63032050195\n  lines_per_second   : 4623.19416652535\n  report_file        : ../../../outputs/issues/816/results.yaml\n'Go' :\n  nFiles: 1\n  blank: 2\n  comment: 3\n  code: 8\nSUM: \n  blank: 2\n  comment: 3\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/822/T1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00448489189147949\n  n_files            : 2\n  n_lines            : 3\n  files_per_second   : 445.9416298974\n  lines_per_second   : 668.912444846101\n  report_file        : ../outputs/issues/822/T1.yaml\n'CSV' :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 3\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/822/T2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0277459621429443\n  n_files            : 2\n  n_lines            : 3\n  files_per_second   : 72.0825606874329\n  lines_per_second   : 108.123841031149\n  report_file        : ../outputs/issues/822/T2.yaml\n'CSV' :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 3\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/822/T3.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00403499603271484\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 247.831718269913\n  lines_per_second   : 247.831718269913\n  report_file        : ../outputs/issues/822/T3.yaml\n'CSV' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/822/T4.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0277609825134277\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 36.0217798313265\n  lines_per_second   : 36.0217798313265\n  report_file        : ../outputs/issues/822/T4.yaml\n'CSV' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/822/T5.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00425601005554199\n  n_files            : 2\n  n_lines            : 3\n  files_per_second   : 469.923701753403\n  lines_per_second   : 704.885552630105\n  report_file        : ../outputs/issues/822/T5.yaml\n'CSV' :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 3\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/822/T6.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0273749828338623\n  n_files            : 2\n  n_lines            : 3\n  files_per_second   : 73.0594065442131\n  lines_per_second   : 109.58910981632\n  report_file        : ../outputs/issues/822/T6.yaml\n'CSV' :\n  nFiles: 2\n  blank: 0\n  comment: 0\n  code: 3\nSUM: \n  blank: 0\n  comment: 0\n  code: 3\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/822/T7.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00388598442077637\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 257.335051230137\n  lines_per_second   : 257.335051230137\n  report_file        : ../outputs/issues/822/T7.yaml\n'CSV' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/822/T8.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0281188488006592\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 35.5633335877021\n  lines_per_second   : 35.5633335877021\n  report_file        : ../outputs/issues/822/T8.yaml\n'CSV' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/833/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00325608253479004\n  n_files            : 1\n  n_lines            : 1\n  files_per_second   : 307.117522149813\n  lines_per_second   : 307.117522149813\n  report_file        : ../../../outputs/issues/833/results.yaml\n'Text' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 1\nSUM: \n  blank: 0\n  comment: 0\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/851/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.02\n  elapsed_seconds    : 0.00290799140930176\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 343.879970484545\n  lines_per_second   : 4814.31958678364\n  report_file        : /home/al/git-cloc/tests/outputs/issues/851/results.yaml\n'Lua' :\n  nFiles: 1\n  blank: 3\n  comment: 9\n  code: 2\nSUM: \n  blank: 3\n  comment: 9\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/issues/862/diff_results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00476408004760742\n  n_files            : 1\n  n_lines            : 15\n  files_per_second   : 209.904113702332\n  lines_per_second   : 3148.56170553498\n  report_file        : ../../../outputs/issues/862/diff_results.yaml\nadded :\n  'Python' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nsame :\n  'Python' :\n    comment : 1\n    code : 13\n    blank : 0\n    nFiles : 0\nmodified :\n  'Python' :\n    comment : 0\n    code : 1\n    blank : 0\n    nFiles : 1\nremoved :\n  'Python' :\n    comment : 0\n    code : 0\n    blank : 0\n    nFiles : 0\nSUM :\n  added :\n    nFiles : 0\n    comment : 0\n    code : 0\n    blank : 0\n  same :\n    nFiles : 0\n    comment : 1\n    code : 13\n    blank : 0\n  modified :\n    nFiles : 1\n    comment : 0\n    code : 1\n    blank : 0\n  removed :\n    nFiles : 0\n    comment : 0\n    code : 0\n    blank : 0\n"
  },
  {
    "path": "tests/outputs/issues/862/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00425577163696289\n  n_files            : 2\n  n_lines            : 11\n  files_per_second   : 469.950028011204\n  lines_per_second   : 2584.72515406162\n  report_file        : results.yaml\n'C' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 5\n'Fortran 77' :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 2\nSUM: \n  blank: 2\n  comment: 2\n  code: 7\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/issues/886/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00586795806884766\n  n_files            : 3\n  n_lines            : 929\n  files_per_second   : 511.251097025841\n  lines_per_second   : 158317.423045669\n  report_file        : ../../outputs/issues/886/results.yaml\n'C++' :\n  nFiles: 2\n  blank_pct: 85.03\n  comment_pct: 88.48\n  code_pct: 92.55\n'C' :\n  nFiles: 1\n  blank_pct: 14.97\n  comment_pct: 11.52\n  code_pct: 7.45\nSUM: \n  blank: 100.00\n  comment: 100.00\n  code: 100.00\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/886/results_by_file.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00641512870788574\n  n_files            : 3\n  n_lines            : 929\n  files_per_second   : 467.644553461924\n  lines_per_second   : 144813.930055376\n  report_file        : ../../outputs/issues/886/results_by_file.yaml\n'./bb/cc/MoreTeapotsRenderer.cpp' :\n  blank_pct: 51.70\n  comment_pct: 59.69\n  code_pct: 61.76\n  language: C++\n'./bb/ee/TeapotRenderer.cpp' :\n  blank_pct: 33.33\n  comment_pct: 28.80\n  code_pct: 30.80\n  language: C++\n'./bb/config.c' :\n  blank_pct: 14.97\n  comment_pct: 11.52\n  code_pct: 7.45\n  language: C\nSUM: \n  blank: 100.00\n  comment: 100.00\n  code: 100.00\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/898/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00424814224243164\n  n_files            : 3\n  n_lines            : 36\n  files_per_second   : 706.191042765743\n  lines_per_second   : 8474.29251318891\n  report_file        : ../../../outputs/issues/898/results.yaml\n'./irregular\"file2.md' :\n  blank: 3\n  comment: 0\n  code: 9\n  language: Markdown\n'./irregular0x27file.md' :\n  blank: 3\n  comment: 0\n  code: 9\n  language: Markdown\n'./regular.md' :\n  blank: 3\n  comment: 0\n  code: 9\n  language: Markdown\nSUM: \n  blank: 9\n  comment: 0\n  code: 27\n  nFiles: 3\n"
  },
  {
    "path": "tests/outputs/issues/906/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.0101969242095947\n  n_files            : 1\n  n_lines            : 332\n  files_per_second   : 98.0687881409432\n  lines_per_second   : 32558.8376627931\n  report_file        : /home/al/git-cloc/tests/outputs/issues/906/results.yaml\nadded :\n  'Python' :\n    code : 7\n    blank : 1\n    comment : 4\n    nFiles : 0\nsame :\n  'Python' :\n    code : 251\n    blank : 0\n    comment : 69\n    nFiles : 0\nmodified :\n  'Python' :\n    code : 0\n    blank : 0\n    comment : 0\n    nFiles : 1\nremoved :\n  'Python' :\n    code : 0\n    blank : 0\n    comment : 0\n    nFiles : 0\nSUM :\n  added :\n    comment : 4\n    nFiles : 0\n    code : 7\n    blank : 1\n  same :\n    comment : 69\n    nFiles : 0\n    code : 251\n    blank : 0\n  modified :\n    comment : 0\n    nFiles : 1\n    code : 0\n    blank : 0\n  removed :\n    comment : 0\n    nFiles : 0\n    code : 0\n    blank : 0\n"
  },
  {
    "path": "tests/outputs/issues/917/results.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.127105951309204\n  n_files            : 4\n  n_lines            : 308\n  files_per_second   : 31.4698089176754\n  lines_per_second   : 2423.175286661\nadded :\n  'Markdown' :\n    comment : 0\n    nFiles : 1\n    blank : 0\n    code : 2\n  'Python' :\n    comment : 11\n    nFiles : 1\n    blank : 4\n    code : 2\n  'C++' :\n    comment : 55\n    nFiles : 1\n    blank : 49\n    code : 182\n  'MATLAB' :\n    comment : 1\n    nFiles : 1\n    blank : 0\n    code : 2\nsame :\n  'Markdown' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'Python' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'C++' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'MATLAB' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nmodified :\n  'Markdown' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'Python' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'C++' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'MATLAB' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nremoved :\n  'Markdown' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'Python' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'C++' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\n  'MATLAB' :\n    comment : 0\n    nFiles : 0\n    blank : 0\n    code : 0\nSUM :\n  added :\n    comment : 67\n    blank : 53\n    nFiles : 4\n    code : 188\n  same :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\n  modified :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\n  removed :\n    comment : 0\n    blank : 0\n    nFiles : 0\n    code : 0\n"
  },
  {
    "path": "tests/outputs/julia.jl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00499296188354492\n  n_files            : 1\n  n_lines            : 18\n  files_per_second   : 200.281921497469\n  lines_per_second   : 3605.07458695445\n  report_file        : ../outputs/julia.jl.yaml\nJulia :\n  nFiles: 1\n  blank: 3\n  comment: 11\n  code: 4\nSUM: \n  blank: 3\n  comment: 11\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/just_stuff.haml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00527405738830566\n  n_files            : 1\n  n_lines            : 87\n  files_per_second   : 189.60734144026\n  lines_per_second   : 16495.8387053027\n  report_file        : just_stuff.haml.yaml\nHaml :\n  nFiles: 1\n  blank: 5\n  comment: 16\n  code: 66\nSUM: \n  blank: 5\n  comment: 16\n  code: 66\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/kvlang.kv.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.94\n  elapsed_seconds    : 0.00590109825134277\n  n_files            : 1\n  n_lines            : 101\n  files_per_second   : 169.459981414892\n  lines_per_second   : 17115.4581229041\n'kvlang' :\n  nFiles: 1\n  blank: 13\n  comment: 2\n  code: 86\nSUM: \n  blank: 13\n  comment: 2\n  code: 86\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/layout.dt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00719904899597168\n  n_files            : 1\n  n_lines            : 244\n  files_per_second   : 138.9072362974\n  lines_per_second   : 33893.3656565657\n  report_file        : ../outputs/layout.dt.yaml\n'DIET' :\n  nFiles: 1\n  blank: 10\n  comment: 4\n  code: 230\nSUM: \n  blank: 10\n  comment: 4\n  code: 230\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/linker.ld.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00527691841125488\n  n_files            : 1\n  n_lines            : 260\n  files_per_second   : 189.504540731035\n  lines_per_second   : 49271.1805900691\n  report_file        : results.yaml\n'Linker Script' :\n  nFiles: 1\n  blank: 3\n  comment: 60\n  code: 197\nSUM: \n  blank: 3\n  comment: 60\n  code: 197\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/locale_facets.h.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0107300281524658\n  n_files            : 1\n  n_lines            : 1588\n  files_per_second   : 93.1964003999556\n  lines_per_second   : 147995.883835129\n  report_file        : locale_facets.h.yaml\nC/C++ Header :\n  nFiles: 1\n  blank: 191\n  comment: 780\n  code: 617\nSUM: \n  blank: 191\n  comment: 780\n  code: 617\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/logos.x.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00698399543762207\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 143.18451507186\n  lines_per_second   : 1718.21418086232\n  report_file        : ../outputs/logos.x.yaml\n'Logos' :\n  nFiles: 1\n  blank: 3\n  comment: 1\n  code: 8\nSUM: \n  blank: 3\n  comment: 1\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/logos.xm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00635313987731934\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 157.402484332195\n  lines_per_second   : 2046.23229631853\n  report_file        : ../outputs/logos.xm.yaml\n'Logos' :\n  nFiles: 1\n  blank: 3\n  comment: 2\n  code: 8\nSUM: \n  blank: 3\n  comment: 2\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/logtalk.lgt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00737118721008301\n  n_files            : 1\n  n_lines            : 484\n  files_per_second   : 135.663356729308\n  lines_per_second   : 65661.0646569848\n  report_file        : logtalk.lgt.yaml\nLogtalk :\n  nFiles: 1\n  blank: 59\n  comment: 57\n  code: 368\nSUM: \n  blank: 59\n  comment: 57\n  code: 368\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/machineDefFreshIds.lem.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.92\n  elapsed_seconds    : 0.00672507286071777\n  n_files            : 1\n  n_lines            : 50\n  files_per_second   : 148.69727372638\n  lines_per_second   : 7434.863686319\n  report_file        : ../outputs/machineDefFreshIds.lem.yaml\n'Lem' :\n  nFiles: 1\n  blank: 11\n  comment: 24\n  code: 15\nSUM: \n  blank: 11\n  comment: 24\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/magikfile.magik.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.0126919746398926\n  n_files            : 1\n  n_lines            : 41\n  files_per_second   : 78.7899462749371\n  lines_per_second   : 3230.38779727242\n'Magik' :\n  nFiles: 1\n  blank: 7\n  comment: 8\n  code: 26\nSUM:\n  blank: 7\n  comment: 8\n  code: 26\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/main.f03.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00438594818115234\n  n_files            : 1\n  n_lines            : 359\n  files_per_second   : 228.000869754294\n  lines_per_second   : 81852.3122417917\n  report_file        : ../outputs/main.f03.yaml\n'Fortran 2003' :\n  nFiles: 1\n  blank: 56\n  comment: 13\n  code: 290\nSUM: \n  blank: 56\n  comment: 13\n  code: 290\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/master.blade.php.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00471401214599609\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 212.133522152539\n  lines_per_second   : 7848.94031964394\n  report_file        : master.blade.php.yaml\nBlade :\n  nFiles: 1\n  blank: 10\n  comment: 5\n  code: 22\nSUM: \n  blank: 10\n  comment: 5\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/matlab_line_colors.m.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00687313079833984\n  n_files            : 1\n  n_lines            : 31\n  files_per_second   : 145.49410295546\n  lines_per_second   : 4510.31719161926\n  report_file        : ../outputs/matlab_line_colors.m.yaml\n'MATLAB' :\n  nFiles: 1\n  blank: 3\n  comment: 10\n  code: 18\nSUM: \n  blank: 3\n  comment: 10\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/md5.rkt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00575590133666992\n  n_files            : 1\n  n_lines            : 438\n  files_per_second   : 173.734736144478\n  lines_per_second   : 76095.8144312816\n  report_file        : md5.rkt.yaml\nRacket :\n  nFiles: 1\n  blank: 32\n  comment: 159\n  code: 247\nSUM: \n  blank: 32\n  comment: 159\n  code: 247\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/meson.build.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00704503059387207\n  n_files            : 1\n  n_lines            : 70\n  files_per_second   : 141.944025178517\n  lines_per_second   : 9936.08176249619\n  report_file        : tests/inputs/meson.build.yaml\n'Meson' :\n  nFiles: 1\n  blank: 13\n  comment: 9\n  code: 48\nSUM: \n  blank: 13\n  comment: 9\n  code: 48\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/messages.rb.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00532007217407227\n  n_files            : 1\n  n_lines            : 152\n  files_per_second   : 187.967374742314\n  lines_per_second   : 28571.0409608318\n  report_file        : messages.rb.yaml\nRuby :\n  nFiles: 1\n  blank: 11\n  comment: 30\n  code: 111\nSUM: \n  blank: 11\n  comment: 30\n  code: 111\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/mfile.mk.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00570511817932129\n  n_files            : 1\n  n_lines            : 140\n  files_per_second   : 175.281206903757\n  lines_per_second   : 24539.368966526\n  report_file        : ../tests/outputs/mfile.mk.yaml\nmake :\n  nFiles: 1\n  blank: 27\n  comment: 36\n  code: 77\nSUM: \n  blank: 27\n  comment: 36\n  code: 77\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/modules1-func1.pp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.90\n  elapsed_seconds    : 0.00691103935241699\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 144.696036154138\n  lines_per_second   : 723.48018077069\n  report_file        : tests/outputs/modules1-func1.pp.yaml\n'Puppet' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 3\nSUM: \n  blank: 0\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/modules1-func2.pp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.90\n  elapsed_seconds    : 0.00696206092834473\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 143.635628916818\n  lines_per_second   : 718.17814458409\n  report_file        : tests/outputs/modules1-func2.pp.yaml\n'Puppet' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 3\nSUM: \n  blank: 0\n  comment: 2\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/modules1-ntp1.pp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00547695159912109\n  n_files            : 1\n  n_lines            : 31\n  files_per_second   : 182.583318822915\n  lines_per_second   : 5660.08288351036\n  report_file        : modules1-ntp1.pp.yaml\nPuppet :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 27\nSUM: \n  blank: 2\n  comment: 2\n  code: 27\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/modules1-typealias.pp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.90\n  elapsed_seconds    : 0.00902009010314941\n  n_files            : 1\n  n_lines            : 3\n  files_per_second   : 110.863637565089\n  lines_per_second   : 332.590912695266\n'Puppet' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 1\nSUM: \n  blank: 0\n  comment: 2\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/moonbit.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.02\n  elapsed_seconds    : 0.0278570652008057\n  n_files            : 2\n  n_lines            : 27\n  files_per_second   : 35.8975359676826\n  lines_per_second   : 969.23347112743\n  report_file        : ./tests/outputs/moonbit.yaml\n'MoonBit' :\n  nFiles: 2\n  blank: 12\n  comment: 21\n  code: 35\nSUM: \n  blank: 12\n  comment: 21\n  code: 35\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/nested.lua.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00621604919433594\n  n_files            : 1\n  n_lines            : 29\n  files_per_second   : 160.873887695612\n  lines_per_second   : 4665.34274317275\n  report_file        : ../outputs/nested.lua.yaml\n'Lua' :\n  nFiles: 1\n  blank: 4\n  comment: 23\n  code: 2\nSUM: \n  blank: 4\n  comment: 23\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/nomad_job.hcl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00662708282470703\n  n_files            : 1\n  n_lines            : 93\n  files_per_second   : 150.895956252698\n  lines_per_second   : 14033.3239315009\n  report_file        : ../outputs/nomad_job.hcl.yaml\nHCL :\n  nFiles: 1\n  blank: 14\n  comment: 36\n  code: 43\nSUM: \n  blank: 14\n  comment: 36\n  code: 43\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/notes.typ.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00755405426025391\n  n_files            : 1\n  n_lines            : 187\n  files_per_second   : 132.379245044818\n  lines_per_second   : 24754.9188233809\n  report_file        : ../outputs/notes.typ.yaml\n'Typst' :\n  nFiles: 1\n  blank: 32\n  comment: 38\n  code: 117\nSUM: \n  blank: 32\n  comment: 38\n  code: 117\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/nu-example.nu.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.04\n  elapsed_seconds    : 0.00595688819885254\n  n_files            : 1\n  n_lines            : 268\n  files_per_second   : 167.872883730238\n  lines_per_second   : 44989.9328397038\n  report_file        : ../tests/outputs/nu-example.nu.yaml\n'Nushell' :\n  nFiles: 1\n  blank: 29\n  comment: 24\n  code: 215\nSUM: \n  blank: 29\n  comment: 24\n  code: 215\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/nuon-example.nuon.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.04\n  elapsed_seconds    : 0.00592303276062012\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 168.832427645614\n  lines_per_second   : 4051.97826349475\n  report_file        : ../tests/outputs/nuon-example.nuon.yaml\n'Nushell Object Notation' :\n  nFiles: 1\n  blank: 1\n  comment: 3\n  code: 20\nSUM: \n  blank: 1\n  comment: 3\n  code: 20\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/offline.jcl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00634098052978516\n  n_files            : 1\n  n_lines            : 62\n  files_per_second   : 157.704316438562\n  lines_per_second   : 9777.66761919086\n  report_file        : ../outputs/offline.jcl.yaml\nJCL :\n  nFiles: 1\n  blank: 0\n  comment: 18\n  code: 44\nSUM: \n  blank: 0\n  comment: 18\n  code: 44\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/openharmony.ets.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00846600532531738\n  n_files            : 1\n  n_lines            : 21\n  files_per_second   : 118.119462671435\n  lines_per_second   : 2480.50871610014\n  report_file        : ../outputs/openharmony.ets.yaml\n'ArkTs' :\n  nFiles: 1\n  blank: 1\n  comment: 10\n  code: 10\nSUM: \n  blank: 1\n  comment: 10\n  code: 10\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/orgmode.org.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00671911239624023\n  n_files            : 1\n  n_lines            : 21\n  files_per_second   : 204.4\n  lines_per_second   : 3883.0\n  report_file        : tests/outputs/orgmode.org.yaml\nOrg Mode :\n  nFiles: 1\n  blank: 7\n  comment: 6\n  code: 8\nSUM:\n  blank: 7\n  comment: 6\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/page_layout.aspx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00802087783813477\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 124.674632899352\n  lines_per_second   : 4612.96141727602\n  report_file        : ../outputs/page_layout.aspx.yaml\n'ASP.NET' :\n  nFiles: 1\n  blank: 8\n  comment: 6\n  code: 23\nSUM: \n  blank: 8\n  comment: 6\n  code: 23\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/pages.wxml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00750613212585449\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 133.22440682273\n  lines_per_second   : 1731.91728869549\n  report_file        : ../outputs/pages.wxml.yaml\n'WXML' :\n  nFiles: 1\n  blank: 3\n  comment: 2\n  code: 8\nSUM: \n  blank: 3\n  comment: 2\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/pages.wxss.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00998592376708984\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 100.140960748735\n  lines_per_second   : 400.563842994938\n  report_file        : ../outputs/pages.wxss.yaml\n'WXSS' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 4\nSUM: \n  blank: 0\n  comment: 0\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/parser_1.civet.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00380301475524902\n  n_files            : 1\n  n_lines            : 76\n  files_per_second   : 262.949282176666\n  lines_per_second   : 19984.1454454266\n  report_file        : tests/outputs/parser_1.civet.yaml\n'Civet' :\n  nFiles: 1\n  blank: 6\n  comment: 9\n  code: 61\nSUM: \n  blank: 6\n  comment: 9\n  code: 61\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/parser_2.civet.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00392413139343262\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 254.833464973571\n  lines_per_second   : 9428.83820402211\n  report_file        : tests/outputs/parser_2.civet.yaml\n'Civet' :\n  nFiles: 1\n  blank: 4\n  comment: 10\n  code: 23\nSUM: \n  blank: 4\n  comment: 10\n  code: 23\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/pawn.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00428891181945801\n  n_files            : 6\n  n_lines            : 165\n  files_per_second   : 1398.9562510423\n  lines_per_second   : 38471.2969036634\n  report_file        : ../outputs/pawn.yaml\n'Pawn' :\n  nFiles: 2\n  blank: 16\n  comment: 14\n  code: 64\n'Fortran 90' :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 20\n'Pascal' :\n  nFiles: 2\n  blank: 2\n  comment: 4\n  code: 14\n'PHP' :\n  nFiles: 1\n  blank: 5\n  comment: 7\n  code: 11\nSUM: \n  blank: 27\n  comment: 29\n  code: 109\n  nFiles: 6\n"
  },
  {
    "path": "tests/outputs/pek_example.pek.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00303912162780762\n  n_files            : 1\n  n_lines            : 15\n  files_per_second   : 329.042441358751\n  lines_per_second   : 4935.63662038127\n  report_file        : tests/outputs/pek_example.pek.yaml\n'Pek' :\n  nFiles: 1\n  blank: 1\n  comment: 2\n  code: 12\nSUM: \n  blank: 1\n  comment: 2\n  code: 12\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ping_pong.lfe.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.71\n  elapsed_seconds    : 0.00490498542785645\n  n_files            : 1\n  n_lines            : 61\n  files_per_second   : 203.874204053857\n  lines_per_second   : 12436.3264472853\n  report_file        : ../outputs/ping_pong.lfe.yaml\nLFE :\n  nFiles: 1\n  blank: 15\n  comment: 21\n  code: 25\nSUM: \n  blank: 15\n  comment: 21\n  code: 25\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/plain_text.txt.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00678491592407227\n  n_files            : 1\n  n_lines            : 33\n  files_per_second   : 147.385761473048\n  lines_per_second   : 4863.73012861058\n  report_file        : ../outputs/plain_text.txt.yaml\n'Text' :\n  nFiles: 1\n  blank: 4\n  comment: 0\n  code: 29\nSUM: \n  blank: 4\n  comment: 0\n  code: 29\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/plantuml.puml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00668501853942871\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 149.588216412854\n  lines_per_second   : 1795.05859695424\n  report_file        : ../outputs/plantuml.puml.yaml\n'PlantUML' :\n  nFiles: 1\n  blank: 2\n  comment: 5\n  code: 5\nSUM: \n  blank: 2\n  comment: 5\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/pointillism.pde.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.00258994102478027\n  n_files            : 1\n  n_lines            : 32\n  files_per_second   : 386.109177943478\n  lines_per_second   : 12355.4936941913\n  report_file        : ../outputs/pointillism.pde.yaml\n'Processing' :\n  nFiles: 1\n  blank: 4\n  comment: 9\n  code: 19\nSUM: \n  blank: 4\n  comment: 9\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/poly_constructor.jai.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00720787048339844\n  n_files            : 1\n  n_lines            : 29\n  files_per_second   : 138.737232071977\n  lines_per_second   : 4023.37973008732\n  report_file        : ../outputs/poly_constructor.jai.yaml\n'Jai' :\n  nFiles: 1\n  blank: 4\n  comment: 7\n  code: 18\nSUM: \n  blank: 4\n  comment: 7\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/pop_by_country.xq.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00459504127502441\n  n_files            : 1\n  n_lines            : 2\n  files_per_second   : 217.625901520261\n  lines_per_second   : 435.251803040523\n  report_file        : pop_by_country.xq.yaml\nXQuery :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 1\nSUM: \n  blank: 0\n  comment: 1\n  code: 1\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/prob060-andreoss.p6.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.87\n  elapsed_seconds    : 0.00777983665466309\n  n_files            : 1\n  n_lines            : 70\n  files_per_second   : 128.537403082958\n  lines_per_second   : 8997.61821580706\n  report_file        : ../outputs/prob060-andreoss.p6.yaml\n'Raku' :\n  nFiles: 1\n  blank: 19\n  comment: 12\n  code: 39\nSUM: \n  blank: 19\n  comment: 12\n  code: 39\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/proguard-project-app.pro.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00521683692932129\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 191.687034413418\n  lines_per_second   : 4600.48882592203\n  report_file        : ../outputs/proguard-project-app.pro.yaml\nProGuard :\n  nFiles: 1\n  blank: 7\n  comment: 14\n  code: 3\nSUM: \n  blank: 7\n  comment: 14\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/qsort_demo.m.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00562095642089844\n  n_files            : 1\n  n_lines            : 47\n  files_per_second   : 177.905666779776\n  lines_per_second   : 8361.56633864947\n  report_file        : qsort_demo.m.yaml\nObjective-C :\n  nFiles: 1\n  blank: 11\n  comment: 11\n  code: 25\nSUM: \n  blank: 11\n  comment: 11\n  code: 25\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/rand.apl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00633096694946289\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 157.953754613241\n  lines_per_second   : 2053.39880997213\n  report_file        : ../outputs/rand.apl.yaml\n'APL' :\n  nFiles: 1\n  blank: 3\n  comment: 6\n  code: 4\nSUM: \n  blank: 3\n  comment: 6\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ranges.surql.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.0037388801574707\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 267.459762785359\n  lines_per_second   : 3476.97691620967\n  report_file        : ../outputs/ranges.surql.yaml\n'SurrealQL' :\n  nFiles: 1\n  blank: 0\n  comment: 8\n  code: 5\nSUM: \n  blank: 0\n  comment: 8\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/razor.cshtml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00537896156311035\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 185.909489827579\n  lines_per_second   : 1487.27591862063\n  report_file        : razor.cshtml.yaml\nRazor :\n  nFiles: 1\n  blank: 0\n  comment: 4\n  code: 4\nSUM: \n  blank: 0\n  comment: 4\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/reStructuredText.rst.yaml",
    "content": "       1 text file.\n       1 unique file.                              \n       0 files ignored.\n\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 1.04324388504028\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 0.958548633104508\n  lines_per_second   : 19.1709726620902\n'reStructuredText' :\n  nFiles: 1\n  blank: 6\n  comment: 4\n  code: 10\nSUM: \n  blank: 6\n  comment: 4\n  code: 10\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/reactive.svelte.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00773501396179199\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 129.282248867244\n  lines_per_second   : 1680.66923527417\n  report_file        : ../outputs/reactive.svelte.yaml\n'Svelte' :\n  nFiles: 1\n  blank: 2\n  comment: 2\n  code: 9\nSUM: \n  blank: 2\n  comment: 2\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/regex_limit.gradle.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00709295272827148\n  n_files            : 1\n  n_lines            : 19\n  files_per_second   : 140.985008403361\n  lines_per_second   : 2678.71515966387\n  report_file        : regex_limit.gradle.yaml\n'Gradle' :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 17\nSUM: \n  blank: 0\n  comment: 2\n  code: 17\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ring.pony.1.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00724482536315918\n  n_files            : 1\n  n_lines            : 132\n  files_per_second   : 138.0295521111\n  lines_per_second   : 18219.9008786652\n  report_file        : ../outputs/ring.pony.1.yaml\n'Pony' :\n  nFiles: 1\n  blank: 23\n  comment: 4\n  code: 105\nSUM: \n  blank: 23\n  comment: 4\n  code: 105\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/ring.pony.2.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00731205940246582\n  n_files            : 1\n  n_lines            : 132\n  files_per_second   : 136.760376927842\n  lines_per_second   : 18052.3697544752\n  report_file        : ../outputs/ring.pony.2.yaml\n'Pony' :\n  nFiles: 1\n  blank: 23\n  comment: 43\n  code: 66\nSUM: \n  blank: 23\n  comment: 43\n  code: 66\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/robotframework.robot.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0049128532409668\n  n_files            : 1\n  n_lines            : 49\n  files_per_second   : 203.547704552072\n  lines_per_second   : 9973.83752305154\n  report_file        : robotframework.tsv.yaml\nRobotFramework :\n  nFiles: 1\n  blank: 9\n  comment: 5\n  code: 35\nSUM: \n  blank: 9\n  comment: 5\n  code: 35\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/robotframework.tsv.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0049128532409668\n  n_files            : 1\n  n_lines            : 49\n  files_per_second   : 203.547704552072\n  lines_per_second   : 9973.83752305154\n  report_file        : robotframework.tsv.yaml\nRobotFramework :\n  nFiles: 1\n  blank: 9\n  comment: 5\n  code: 35\nSUM: \n  blank: 9\n  comment: 5\n  code: 35\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/roku.brs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00533485412597656\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 187.446549874866\n  lines_per_second   : 4123.82409724705\n  report_file        : ../outputs/roku.brs.yaml\nBrightScript :\n  nFiles: 1\n  blank: 0\n  comment: 3\n  code: 19\nSUM: \n  blank: 0\n  comment: 3\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/rules.sss.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00715804100036621\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 139.70302767878\n  lines_per_second   : 3073.46660893315\n  report_file        : ../outputs/rules.sss.yaml\n'SugarSS' :\n  nFiles: 1\n  blank: 5\n  comment: 4\n  code: 13\nSUM: \n  blank: 5\n  comment: 4\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sample.R.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0048220157623291\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 207.382150803461\n  lines_per_second   : 1036.91075401731\n  report_file        : sample.R.yaml\nR :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 4\nSUM: \n  blank: 0\n  comment: 1\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sample.bicep.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00441193580627441\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 226.657876249662\n  lines_per_second   : 8386.3414212375\n  report_file        : ../outputs/sample.bicep.yaml\n'Bicep' :\n  nFiles: 1\n  blank: 5\n  comment: 6\n  code: 26\nSUM: \n  blank: 5\n  comment: 6\n  code: 26\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sample.ejs.yaml",
    "content": "﻿       1 text file.\n       1 unique file.                              \n       0 files ignored.\n\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.0163509845733643\n  n_files            : 1\n  n_lines            : 45\n  files_per_second   : 61.1583966404689\n  lines_per_second   : 2752.1278488211\nEJS :\n  nFiles: 1\n  blank: 0\n  comment: 11\n  code: 34\nSUM: \n  blank: 0\n  comment: 11\n  code: 34\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/schema.prisma.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00669693946838379\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 149.321940973335\n  lines_per_second   : 4031.69240628004\n  report_file        : ../outputs/schema.prisma.yaml\n'Prisma Schema' :\n  nFiles: 1\n  blank: 5\n  comment: 1\n  code: 21\nSUM: \n  blank: 5\n  comment: 1\n  code: 21\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/scheme.sls.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.83\n  elapsed_seconds    : 0.00698304176330566\n  n_files            : 1\n  n_lines            : 106\n  files_per_second   : 143.204069787292\n  lines_per_second   : 15179.631397453\n  report_file        : ../outputs/scheme.sls.yaml\n'Scheme' :\n  nFiles: 1\n  blank: 10\n  comment: 18\n  code: 78\nSUM: \n  blank: 10\n  comment: 18\n  code: 78\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/script1-hadoop.pig.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00578999519348145\n  n_files            : 1\n  n_lines            : 74\n  files_per_second   : 172.711715050443\n  lines_per_second   : 12780.6669137328\n  report_file        : script1-hadoop.pig.yaml\nPig Latin :\n  nFiles: 1\n  blank: 19\n  comment: 40\n  code: 15\nSUM: \n  blank: 19\n  comment: 40\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sdp_parser.jspeg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00704693794250488\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 141.905606116994\n  lines_per_second   : 7804.80833643469\n  report_file        : ../outputs/sdp_parser.jspeg.yaml\n'tspeg' :\n  nFiles: 1\n  blank: 16\n  comment: 5\n  code: 34\nSUM: \n  blank: 16\n  comment: 5\n  code: 34\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sdp_parser.peg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00700283050537109\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 142.799400789868\n  lines_per_second   : 7853.96704344273\n  report_file        : ../outputs/sdp_parser.peg.yaml\n'PEG' :\n  nFiles: 1\n  blank: 24\n  comment: 9\n  code: 22\nSUM: \n  blank: 24\n  comment: 9\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sdp_parser.peggy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00702095031738281\n  n_files            : 1\n  n_lines            : 51\n  files_per_second   : 142.430861179027\n  lines_per_second   : 7263.9739201304\n  report_file        : ../outputs/sdp_parser.peggy.yaml\n'peggy' :\n  nFiles: 1\n  blank: 25\n  comment: 7\n  code: 19\nSUM: \n  blank: 25\n  comment: 7\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sdp_parser.pegjs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00680398941040039\n  n_files            : 1\n  n_lines            : 50\n  files_per_second   : 146.972597939589\n  lines_per_second   : 7348.62989697947\n  report_file        : ../outputs/sdp_parser.pegjs.yaml\n'peg.js' :\n  nFiles: 1\n  blank: 18\n  comment: 9\n  code: 23\nSUM: \n  blank: 18\n  comment: 9\n  code: 23\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sdp_parser.tspeg.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.0070347785949707\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 142.150884565851\n  lines_per_second   : 7818.29865112181\n  report_file        : ../outputs/sdp_parser.tspeg.yaml\n'tspeg' :\n  nFiles: 1\n  blank: 10\n  comment: 26\n  code: 19\nSUM: \n  blank: 10\n  comment: 26\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/send_msg.applescript.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00740313529968262\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 135.077904093266\n  lines_per_second   : 3241.86969823838\n  report_file        : ../outputs/send_msg.applescript.yaml\n'AppleScript' :\n  nFiles: 1\n  blank: 5\n  comment: 8\n  code: 11\nSUM: \n  blank: 5\n  comment: 8\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/server_side.aspx.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00776505470275879\n  n_files            : 1\n  n_lines            : 39\n  files_per_second   : 128.782093401701\n  lines_per_second   : 5022.50164266634\n  report_file        : ../outputs/server_side.aspx.yaml\n'ASP.NET' :\n  nFiles: 1\n  blank: 8\n  comment: 15\n  code: 16\nSUM: \n  blank: 8\n  comment: 15\n  code: 16\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/sharpsign.cl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00552105903625488\n  n_files            : 1\n  n_lines            : 55\n  files_per_second   : 181.124670725914\n  lines_per_second   : 9961.85688992529\n  report_file        : sharpsign.cl.yaml\nLisp :\n  nFiles: 1\n  blank: 5\n  comment: 26\n  code: 24\nSUM: \n  blank: 5\n  comment: 26\n  code: 24\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/slug.astro.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00802516937255859\n  n_files            : 1\n  n_lines            : 102\n  files_per_second   : 124.607961972668\n  lines_per_second   : 12710.0121212121\n  report_file        : ../outputs/slug.astro.yaml\n'Astro' :\n  nFiles: 1\n  blank: 2\n  comment: 28\n  code: 72\nSUM: \n  blank: 2\n  comment: 28\n  code: 72\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/solidity.sol.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.0056149959564209\n  n_files            : 1\n  n_lines            : 21\n  files_per_second   : 178.094518279479\n  lines_per_second   : 3739.98488386905\n  report_file        : ../outputs/solidity.sol.yaml\nSolidity :\n  nFiles: 1\n  blank: 0\n  comment: 2\n  code: 19\nSUM: \n  blank: 0\n  comment: 2\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/specman_e.e.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00639891624450684\n  n_files            : 1\n  n_lines            : 28\n  files_per_second   : 156.276463355565\n  lines_per_second   : 4375.74097395581\n  report_file        : tests/outputs/specman_e.e.yaml\nSpecman e :\n  nFiles: 1\n  blank: 1\n  comment: 8\n  code: 19\nSUM: \n  blank: 1\n  comment: 8\n  code: 19\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/specman_e2.e.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00627398490905762\n  n_files            : 1\n  n_lines            : 19\n  files_per_second   : 159.38833365001\n  lines_per_second   : 3028.37833935018\n  report_file        : tests/outputs/specman_e2.e.yaml\nSpecman e :\n  nFiles: 1\n  blank: 3\n  comment: 4\n  code: 12\nSUM: \n  blank: 3\n  comment: 4\n  code: 12\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/squirrel_table.nut.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.85\n  elapsed_seconds    : 0.00813984870910645\n  n_files            : 1\n  n_lines            : 41\n  files_per_second   : 122.852406197827\n  lines_per_second   : 5036.94865411089\n  report_file        : squirrel_table.nut.yaml\n'Squirrel' :\n  nFiles: 1\n  blank: 6\n  comment: 4\n  code: 31\nSUM: \n  blank: 6\n  comment: 4\n  code: 31\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/stata.do.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00582790374755859\n  n_files            : 1\n  n_lines            : 36\n  files_per_second   : 171.588283423335\n  lines_per_second   : 6177.17820324006\n  report_file        : tests/outputs/stata.do.yaml\nStata :\n  nFiles: 1\n  blank: 7\n  comment: 7\n  code: 22\nSUM: \n  blank: 7\n  comment: 7\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/statcsv.nim.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.70\n  elapsed_seconds    : 0.00490713119506836\n  n_files            : 1\n  n_lines            : 61\n  files_per_second   : 203.785054902342\n  lines_per_second   : 12430.8883490429\n  report_file        : ../tests/outputs/statcsv.nim.yaml\nNim :\n  nFiles: 1\n  blank: 5\n  comment: 13\n  code: 43\nSUM: \n  blank: 5\n  comment: 13\n  code: 43\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/streamlines.pro.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.0055849552154541\n  n_files            : 1\n  n_lines            : 43\n  files_per_second   : 179.052465314835\n  lines_per_second   : 7699.25600853789\n  report_file        : ../outputs/streamlines.pro.yaml\nIDL :\n  nFiles: 1\n  blank: 25\n  comment: 5\n  code: 13\nSUM: \n  blank: 25\n  comment: 5\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/string.gleam.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00691604614257812\n  n_files            : 1\n  n_lines            : 68\n  files_per_second   : 144.591285162714\n  lines_per_second   : 9832.20739106453\n  report_file        : string.gleam.yaml\n'Gleam' :\n  nFiles: 1\n  blank: 6\n  comment: 41\n  code: 21\nSUM: \n  blank: 6\n  comment: 41\n  code: 21\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/style.scss.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.00746607780456543\n  n_files            : 1\n  n_lines            : 57\n  files_per_second   : 133.939134600032\n  lines_per_second   : 7634.53067220182\n  report_file        : outputs/style.scss.yaml\n'SCSS' :\n  nFiles: 1\n  blank: 14\n  comment: 4\n  code: 39\nSUM: \n  blank: 14\n  comment: 4\n  code: 39\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/swig_example.i.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.75\n  elapsed_seconds    : 0.00647306442260742\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 154.486335174954\n  lines_per_second   : 3553.18570902394\n  report_file        : ../outputs/swig_example.i.yaml\nSWIG :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 15\nSUM: \n  blank: 4\n  comment: 4\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/temp.c.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00521707534790039\n  n_files            : 1\n  n_lines            : 5\n  files_per_second   : 191.67827438077\n  lines_per_second   : 958.391371903848\n  report_file        : temp.c.yaml\nC :\n  nFiles: 1\n  blank: 2\n  comment: 0\n  code: 3\nSUM: \n  blank: 2\n  comment: 0\n  code: 3\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/templ_example.templ.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.01\n  elapsed_seconds    : 0.0374619960784912\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 26.6937190934722\n  lines_per_second   : 667.342977336804\n'Templ' :\n  nFiles: 1\n  blank: 5\n  comment: 12\n  code: 8\nSUM:\n  blank: 5\n  comment: 12\n  code: 8\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/test-1.0-py2.py3-none-win32.whl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.0141270160675049\n  n_files            : 2\n  n_lines            : 5\n  files_per_second   : 141.572713617876\n  lines_per_second   : 353.93178404469\n  report_file        : test-1.0-py2.py3-none-win32.whl.yaml\n'Python' :\n  nFiles: 1\n  blank: 0\n  comment: 0\n  code: 2\n'Bourne Shell' :\n  nFiles: 1\n  blank: 1\n  comment: 0\n  code: 2\nSUM: \n  blank: 1\n  comment: 0\n  code: 4\n  nFiles: 2\n"
  },
  {
    "path": "tests/outputs/test.Dsr.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00898003578186035\n  n_files            : 1\n  n_lines            : 20\n  files_per_second   : 111.358130890747\n  lines_per_second   : 2227.16261781495\n  report_file        : tests/outputs/test.Dsr.yaml\n'Visual Basic' :\n  nFiles: 1\n  blank: 2\n  comment: 12\n  code: 6\nSUM: \n  blank: 2\n  comment: 12\n  code: 6\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/test.Rmd.yaml",
    "content": "       1 text file.\n       1 unique file.                              \n       0 files ignored.\n\n---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00812411308288574\n  n_files            : 1\n  n_lines            : 33\n  files_per_second   : 123.090359501101\n  lines_per_second   : 4061.98186353632\nRmd :\n  nFiles: 1\n  blank: 10\n  comment: 19\n  code: 4\nSUM: \n  blank: 10\n  comment: 19\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test.hs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00447511672973633\n  n_files            : 1\n  n_lines            : 19\n  files_per_second   : 223.457858284497\n  lines_per_second   : 4245.69930740543\n  report_file        : test.hs.yaml\nHaskell :\n  nFiles: 1\n  blank: 5\n  comment: 5\n  code: 9\nSUM: \n  blank: 5\n  comment: 5\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test.rego.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00916504859924316\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 109.110168830155\n  lines_per_second   : 2727.75422075388\n  report_file        : results.yaml\n'Rego' :\n  nFiles: 1\n  blank: 5\n  comment: 2\n  code: 18\nSUM: \n  blank: 5\n  comment: 2\n  code: 18\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test.vbhtml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.0128321647644043\n  n_files            : 1\n  n_lines            : 18\n  files_per_second   : 77.9291739437405\n  lines_per_second   : 1402.72513098733\n  report_file        : tests/outputs/test.vbhtml.yaml\n'Visual Basic .NET' :\n  nFiles: 1\n  blank: 1\n  comment: 1\n  code: 16\nSUM: \n  blank: 1\n  comment: 1\n  code: 16\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/test.vbs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00967001914978027\n  n_files            : 1\n  n_lines            : 10\n  files_per_second   : 103.412411548608\n  lines_per_second   : 1034.12411548608\n  report_file        : tests/outputs/test.vbs.yaml\n'VBScript' :\n  nFiles: 1\n  blank: 1\n  comment: 3\n  code: 6\nSUM: \n  blank: 1\n  comment: 3\n  code: 6\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/test1.inc.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00563192367553711\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 177.559224451782\n  lines_per_second   : 4083.86216239099\n  report_file        : test1.inc.yaml\nPHP :\n  nFiles: 1\n  blank: 5\n  comment: 7\n  code: 11\nSUM: \n  blank: 5\n  comment: 7\n  code: 11\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test1.lhs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0046699047088623\n  n_files            : 1\n  n_lines            : 15\n  files_per_second   : 214.137131771073\n  lines_per_second   : 3212.05697656609\n  report_file        : test1.lhs.yaml\nHaskell :\n  nFiles: 1\n  blank: 5\n  comment: 8\n  code: 2\nSUM: \n  blank: 5\n  comment: 8\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test1.php.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0059359073638916\n  n_files            : 1\n  n_lines            : 27\n  files_per_second   : 168.46624091256\n  lines_per_second   : 4548.58850463911\n  report_file        : test1.php.yaml\nPHP :\n  nFiles: 1\n  blank: 6\n  comment: 6\n  code: 15\nSUM: \n  blank: 6\n  comment: 6\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test2.lhs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0049288272857666\n  n_files            : 1\n  n_lines            : 44\n  files_per_second   : 202.888018187975\n  lines_per_second   : 8927.07280027089\n  report_file        : test2.lhs.yaml\nHaskell :\n  nFiles: 1\n  blank: 12\n  comment: 11\n  code: 21\nSUM: \n  blank: 12\n  comment: 11\n  code: 21\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/test_w_cpp_comments.svelte.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.05\n  elapsed_seconds    : 0.00441312789916992\n  n_files            : 1\n  n_lines            : 14\n  files_per_second   : 226.596650459211\n  lines_per_second   : 3172.35310642896\n  report_file        : ../outputs/test_w_cpp_comments.svelte.yaml\n'Svelte' :\n  nFiles: 1\n  blank: 3\n  comment: 7\n  code: 4\nSUM: \n  blank: 3\n  comment: 7\n  code: 4\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/tictactoe3d.ring.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00797295570373535\n  n_files            : 1\n  n_lines            : 60\n  files_per_second   : 125.424000478455\n  lines_per_second   : 7525.44002870728\n  report_file        : ../outputs/tictactoe3d.ring.yaml\n'Ring' :\n  nFiles: 1\n  blank: 11\n  comment: 11\n  code: 38\nSUM: \n  blank: 11\n  comment: 11\n  code: 38\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/tnsdl.sdl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader:\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.84\n  elapsed_seconds    : 0.0125899314880371\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 79.4285497860092\n  lines_per_second   : 1826.85664507821\nTNSDL:\n  nFiles: 1\n  blank: 5\n  comment: 3\n  code: 15\nSUM:\n  blank: 5\n  comment: 3\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/toml.pest.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader :\n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00414586067199707\n  n_files            : 1\n  n_lines            : 76\n  files_per_second   : 241.204439588245\n  lines_per_second   : 18331.5374087067\n'Pest' :\n  nFiles: 1\n  blank: 16\n  comment: 9\n  code: 51\nSUM:\n  blank: 16\n  comment: 9\n  code: 51\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/toml_example.toml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.73\n  elapsed_seconds    : 0.00557589530944824\n  n_files            : 1\n  n_lines            : 34\n  files_per_second   : 179.343395903707\n  lines_per_second   : 6097.67546072604\n  report_file        : ../outputs/toml_example.toml.yaml\nTOML :\n  nFiles: 1\n  blank: 8\n  comment: 4\n  code: 22\nSUM: \n  blank: 8\n  comment: 4\n  code: 22\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/tour.swift.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00580596923828125\n  n_files            : 1\n  n_lines            : 101\n  files_per_second   : 172.236530880421\n  lines_per_second   : 17395.8896189225\n  report_file        : tour.swift.yaml\nSwift :\n  nFiles: 1\n  blank: 23\n  comment: 13\n  code: 65\nSUM: \n  blank: 23\n  comment: 13\n  code: 65\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/traffic_light.fsl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.93\n  elapsed_seconds    : 0.00660109519958496\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 151.490013363672\n  lines_per_second   : 3635.76032072814\n  report_file        : ../outputs/traffic_light.fsl.yaml\n'Finite State Language' :\n  nFiles: 1\n  blank: 7\n  comment: 3\n  code: 14\nSUM: \n  blank: 7\n  comment: 3\n  code: 14\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/type.wast.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00589084625244141\n  n_files            : 1\n  n_lines            : 60\n  files_per_second   : 169.754897199288\n  lines_per_second   : 10185.2938319573\n  report_file        : ../outputs/type.wast.yaml\n'WebAssembly' :\n  nFiles: 1\n  blank: 8\n  comment: 20\n  code: 32\nSUM: \n  blank: 8\n  comment: 20\n  code: 32\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/updateSprites.wgsl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.95\n  elapsed_seconds    : 0.00713205337524414\n  n_files            : 1\n  n_lines            : 89\n  files_per_second   : 140.212074613893\n  lines_per_second   : 12478.8746406365\n  report_file        : ../outputs/updateSprites.wgsl.yaml\n'WGSL' :\n  nFiles: 1\n  blank: 5\n  comment: 8\n  code: 76\nSUM: \n  blank: 5\n  comment: 8\n  code: 76\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/utilities.R.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00746488571166992\n  n_files            : 1\n  n_lines            : 841\n  files_per_second   : 133.960523794315\n  lines_per_second   : 112660.800511019\n  report_file        : utilities.R.yaml\nR :\n  nFiles: 1\n  blank: 41\n  comment: 276\n  code: 524\nSUM: \n  blank: 41\n  comment: 276\n  code: 524\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/variable_length.carbon.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.94\n  elapsed_seconds    : 0.0084228515625\n  n_files            : 1\n  n_lines            : 32\n  files_per_second   : 118.724637681159\n  lines_per_second   : 3799.1884057971\n  report_file        : ../outputs/variable_length.carbon.yaml\n'Carbon' :\n  nFiles: 1\n  blank: 11\n  comment: 6\n  code: 15\nSUM: \n  blank: 11\n  comment: 6\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/vba_test.vba.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00922179222106934\n  n_files            : 1\n  n_lines            : 22\n  files_per_second   : 108.43879107526\n  lines_per_second   : 2385.65340365573\n'VBA' :\n  nFiles: 1\n  blank: 4\n  comment: 6\n  code: 12\nSUM: \n  blank: 4\n  comment: 6\n  code: 12\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/vbnet_test.vb.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.0076439380645752\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 130.822619381803\n  lines_per_second   : 3270.56548454509\n'Visual Basic .NET' :\n  nFiles: 1\n  blank: 4\n  comment: 2\n  code: 19\nSUM: \n  blank: 4\n  comment: 2\n  code: 19\n  nFiles: 1"
  },
  {
    "path": "tests/outputs/vbox.fxml.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.0251579284667969\n  n_files            : 1\n  n_lines            : 13\n  files_per_second   : 39.7489006823351\n  lines_per_second   : 516.735708870356\n  report_file        : ../outputs/vbox.fxml.yaml\n'FXML' :\n  nFiles: 1\n  blank: 2\n  comment: 3\n  code: 8\nSUM: \n  blank: 2\n  comment: 3\n  code: 8\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/verilog.sv.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00602293014526367\n  n_files            : 1\n  n_lines            : 86\n  files_per_second   : 166.032143139894\n  lines_per_second   : 14278.7643100309\n  report_file        : verilog.sv.yaml\nVerilog-SystemVerilog :\n  nFiles: 1\n  blank: 4\n  comment: 20\n  code: 62\nSUM: \n  blank: 4\n  comment: 20\n  code: 62\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/vinos.nlogo.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.97\n  elapsed_seconds    : 0.00728893280029297\n  n_files            : 1\n  n_lines            : 93\n  files_per_second   : 137.19429543373\n  lines_per_second   : 12759.0694753369\n  report_file        : ../outputs/vinos.nlogo.yaml\n'NetLogo' :\n  nFiles: 1\n  blank: 17\n  comment: 14\n  code: 62\nSUM: \n  blank: 17\n  comment: 14\n  code: 62\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/vs_solution.sln.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00731205940246582\n  n_files            : 1\n  n_lines            : 26\n  files_per_second   : 136.760376927842\n  lines_per_second   : 3555.7698001239\n  report_file        : ../outputs/vs_solution.sln.yaml\n'Visual Studio Solution' :\n  nFiles: 1\n  blank: 0\n  comment: 1\n  code: 25\nSUM: \n  blank: 0\n  comment: 1\n  code: 25\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/vtl.vm.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.81\n  elapsed_seconds    : 0.00817298889160156\n  n_files            : 1\n  n_lines            : 33\n  files_per_second   : 122.354259043174\n  lines_per_second   : 4037.69054842474\n  report_file        : ../outputs/vtl.vm.yaml\n'Velocity Template Language' :\n  nFiles: 1\n  blank: 0\n  comment: 20\n  code: 13\nSUM: \n  blank: 0\n  comment: 20\n  code: 13\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/vyper.vy.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.99\n  elapsed_seconds    : 0.00448417663574219\n  n_files            : 1\n  n_lines            : 85\n  files_per_second   : 223.006380263718\n  lines_per_second   : 18955.542322416\n  report_file        : vyper.vy.yaml\n'Vyper' :\n  nFiles: 1\n  blank: 11\n  comment: 41\n  code: 33\nSUM: \n  blank: 11\n  comment: 41\n  code: 33\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/warship.ts.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0075831413269043\n  n_files            : 1\n  n_lines            : 393\n  files_per_second   : 131.871470791675\n  lines_per_second   : 51825.4880211281\n  report_file        : warship.ts.yaml\nTypeScript :\n  nFiles: 1\n  blank: 39\n  comment: 11\n  code: 343\nSUM: \n  blank: 39\n  comment: 11\n  code: 343\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/webservice.wsdl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00689792633056641\n  n_files            : 1\n  n_lines            : 40\n  files_per_second   : 144.971104659201\n  lines_per_second   : 5798.84418636804\n  report_file        : ../outputs/webservice.wsdl.yaml\n'Web Services Description' :\n  nFiles: 1\n  blank: 4\n  comment: 0\n  code: 36\nSUM: \n  blank: 4\n  comment: 0\n  code: 36\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/wiki.properties.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.91\n  elapsed_seconds    : 0.0072939395904541\n  n_files            : 1\n  n_lines            : 24\n  files_per_second   : 137.100120942699\n  lines_per_second   : 3290.40290262478\n  report_file        : ../outputs/wiki.properties.yaml\n'Properties' :\n  nFiles: 1\n  blank: 0\n  comment: 15\n  code: 9\nSUM: \n  blank: 0\n  comment: 15\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/window.blp.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.03\n  elapsed_seconds    : 0.00471806526184082\n  n_files            : 1\n  n_lines            : 101\n  files_per_second   : 211.951286068018\n  lines_per_second   : 21407.0798928698\n  report_file        : ../outputs/window.blp.yaml\n'Blueprint' :\n  nFiles: 1\n  blank: 19\n  comment: 2\n  code: 80\nSUM: \n  blank: 19\n  comment: 2\n  code: 80\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/with_pod.pl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 2.07\n  elapsed_seconds    : 0.00382208824157715\n  n_files            : 1\n  n_lines            : 25\n  files_per_second   : 261.637078161063\n  lines_per_second   : 6540.92695402657\n  report_file        : ../outputs/with_pod.pl.yaml\n'Perl' :\n  nFiles: 1\n  blank: 5\n  comment: 11\n  code: 9\nSUM: \n  blank: 5\n  comment: 11\n  code: 9\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/wokka.cbl.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.0047309398651123\n  n_files            : 1\n  n_lines            : 4\n  files_per_second   : 211.374489744494\n  lines_per_second   : 845.497958977977\n  report_file        : wokka.cbl.yaml\nCOBOL :\n  nFiles: 1\n  blank: 1\n  comment: 1\n  code: 2\nSUM: \n  blank: 1\n  comment: 1\n  code: 2\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/wokka.cs.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00531911849975586\n  n_files            : 1\n  n_lines            : 8\n  files_per_second   : 188.001075750784\n  lines_per_second   : 1504.00860600628\n  report_file        : wokka.cs.yaml\nC# :\n  nFiles: 1\n  blank: 2\n  comment: 1\n  code: 5\nSUM: \n  blank: 2\n  comment: 1\n  code: 5\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/wpedia.ini.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00518488883972168\n  n_files            : 1\n  n_lines            : 12\n  files_per_second   : 192.868165724008\n  lines_per_second   : 2314.41798868809\n  report_file        : tests/outputs/wpedia.ini.yaml\nINI :\n  nFiles: 1\n  blank: 2\n  comment: 3\n  code: 7\nSUM: \n  blank: 2\n  comment: 3\n  code: 7\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/x.mustache.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.67\n  elapsed_seconds    : 0.00459003448486328\n  n_files            : 1\n  n_lines            : 23\n  files_per_second   : 217.863286931228\n  lines_per_second   : 5010.85559941824\n  report_file        : x.mustache.yaml\nMustache :\n  nFiles: 1\n  blank: 4\n  comment: 4\n  code: 15\nSUM: \n  blank: 4\n  comment: 4\n  code: 15\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/zir_sema.zig.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.89\n  elapsed_seconds    : 0.00783014297485352\n  n_files            : 1\n  n_lines            : 140\n  files_per_second   : 127.711588819195\n  lines_per_second   : 17879.6224346873\n  report_file        : ../outputs/zir_sema.zig.yaml\n'Zig' :\n  nFiles: 1\n  blank: 2\n  comment: 10\n  code: 128\nSUM: \n  blank: 2\n  comment: 10\n  code: 128\n  nFiles: 1\n"
  },
  {
    "path": "tests/outputs/zos_assembly.s.yaml",
    "content": "---\n# github.com/AlDanial/cloc\nheader : \n  cloc_url           : github.com/AlDanial/cloc\n  cloc_version       : 1.77\n  elapsed_seconds    : 0.00715398788452148\n  n_files            : 1\n  n_lines            : 37\n  files_per_second   : 139.782176897954\n  lines_per_second   : 5171.94054522429\n  report_file        : ../outputs/zos_assembly.s.yaml\nAssembly :\n  nFiles: 1\n  blank: 0\n  comment: 30\n  code: 7\nSUM: \n  blank: 0\n  comment: 30\n  code: 7\n  nFiles: 1\n"
  }
]