Full Code of ned14/pcpp for AI

master 988cc2f5eab4 cached
210 files
861.8 KB
240.8k tokens
371 symbols
1 requests
Download .txt
Showing preview only (915K chars total). Download the full file or copy to clipboard to get everything.
Repository: ned14/pcpp
Branch: master
Commit: 988cc2f5eab4
Files: 210
Total size: 861.8 KB

Directory structure:
gitextract_sih0q66g/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .gitmodules
├── AGENTS.md
├── LICENSE.txt
├── README.rst
├── doc/
│   ├── evaluator.html
│   ├── index.html
│   ├── lextab.html
│   ├── parser.html
│   ├── parsetab.html
│   ├── pcmd.html
│   └── preprocessor.html
├── pcpp/
│   ├── __init__.py
│   ├── evaluator.py
│   ├── lextab.py
│   ├── parser.py
│   ├── parsetab.py
│   ├── pcmd.py
│   └── preprocessor.py
├── pyproject.toml
├── requirements.txt
├── setup.py
└── tests/
    ├── Readme.md
    ├── __init__.py
    ├── alternate_input_encodings.py
    ├── alternate_input_encodings1_ucs16le.c
    ├── alternate_input_encodings2_ucs16le.c
    ├── cstd.py
    ├── doctests.py
    ├── embedded.py
    ├── eval.py
    ├── issue0017/
    │   ├── inc.h
    │   └── issue0017.c
    ├── issue0017-ref.i
    ├── issue0017.py
    ├── issue0025/
    │   ├── inc.h
    │   └── main.c
    ├── issue0025-ref.i
    ├── issue0025.py
    ├── issue0027.py
    ├── issue0030/
    │   ├── source1.c
    │   ├── source2.c
    │   └── source3.c
    ├── issue0030.py
    ├── issue0032.py
    ├── issue0037/
    │   └── inc.h
    ├── issue0037.py
    ├── issue0044.h
    ├── issue0044.py
    ├── issue0051.c
    ├── issue0051.h
    ├── issue0051.py
    ├── issue0057.h
    ├── issue0057.py
    ├── issue0059.py
    ├── issue0059a.h
    ├── issue0059b.h
    ├── issue0063.c
    ├── issue0063.h
    ├── issue0063.py
    ├── issue0079.py
    ├── issue0098/
    │   ├── dir1/
    │   │   └── header.h
    │   ├── dir2/
    │   │   └── header.h
    │   ├── dir3/
    │   │   └── header.h
    │   └── dir4/
    │       └── header.h
    ├── issue0098.py
    ├── issue0103.py
    ├── n_std-clang.i
    ├── n_std-gcc.i
    ├── n_std-pcpp.i
    ├── n_std.i
    ├── n_std.py
    ├── passthru.py
    └── test-c/
        ├── LICENSE
        ├── defs.h
        ├── e_12_8.c
        ├── e_14.c
        ├── e_14_10.c
        ├── e_14_7.c
        ├── e_14_9.c
        ├── e_15_3.c
        ├── e_16.c
        ├── e_17.c
        ├── e_18_4.c
        ├── e_19_3.c
        ├── e_23_3.c
        ├── e_24_6.c
        ├── e_25_6.c
        ├── e_27_7.c
        ├── e_29_3.c
        ├── e_31.c
        ├── e_31_3.c
        ├── e_32_5.c
        ├── e_33_2.c
        ├── e_35_2.c
        ├── e_4_3.c
        ├── e_7_4.c
        ├── e_std.c
        ├── header.h
        ├── i_32_3.c
        ├── i_35.c
        ├── i_35_3.c
        ├── ifdef15.h
        ├── line.h
        ├── m1024.h
        ├── m_33_big5.c
        ├── m_33_eucjp.c
        ├── m_33_gb.c
        ├── m_33_jis.c
        ├── m_33_ksc.c
        ├── m_33_sjis.c
        ├── m_33_utf8.c
        ├── m_34_big5.c
        ├── m_34_eucjp.c
        ├── m_34_gb.c
        ├── m_34_jis.c
        ├── m_34_ksc.c
        ├── m_34_sjis.c
        ├── m_34_utf8.c
        ├── m_36_big5.c
        ├── m_36_jis.c
        ├── m_36_sjis.c
        ├── n_1.c
        ├── n_10.c
        ├── n_11.c
        ├── n_12.c
        ├── n_13.c
        ├── n_13_13.c
        ├── n_13_5.c
        ├── n_13_7.c
        ├── n_13_8.c
        ├── n_15.c
        ├── n_18.c
        ├── n_19.c
        ├── n_2.c
        ├── n_20.c
        ├── n_21.c
        ├── n_22.c
        ├── n_23.c
        ├── n_24.c
        ├── n_25.c
        ├── n_26.c
        ├── n_27.c
        ├── n_28.c
        ├── n_29.c
        ├── n_3.c
        ├── n_30.c
        ├── n_32.c
        ├── n_37.c
        ├── n_3_4.c
        ├── n_4.c
        ├── n_5.c
        ├── n_6.c
        ├── n_7.c
        ├── n_8.c
        ├── n_8_2.c
        ├── n_9.c
        ├── n_i_.lst
        ├── n_std.c
        ├── nest1.h
        ├── nest10.h
        ├── nest11.h
        ├── nest12.h
        ├── nest13.h
        ├── nest14.h
        ├── nest15.h
        ├── nest2.h
        ├── nest3.h
        ├── nest4.h
        ├── nest5.h
        ├── nest6.h
        ├── nest7.h
        ├── nest8.h
        ├── nest9.h
        ├── side_cpp
        ├── u_1_1.c
        ├── u_1_11.c
        ├── u_1_12.c
        ├── u_1_13.c
        ├── u_1_14.c
        ├── u_1_17.c
        ├── u_1_19.c
        ├── u_1_22.c
        ├── u_1_23.c
        ├── u_1_24.c
        ├── u_1_25.c
        ├── u_1_27.c
        ├── u_1_28.c
        ├── u_1_5.c
        ├── u_1_7_big5.c
        ├── u_1_7_eucjp.c
        ├── u_1_7_gb.c
        ├── u_1_7_jis.c
        ├── u_1_7_ksc.c
        ├── u_1_7_sjis.c
        ├── u_1_7_utf8.c
        ├── u_1_8.c
        ├── u_2.c
        ├── unbal1.h
        ├── unbal2.h
        ├── unbal3.h
        ├── unbal4.h
        ├── unbal5.h
        ├── unbal6.h
        ├── undefs.c
        ├── unspcs.c
        └── warns.c

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

================================================
FILE: .gitattributes
================================================
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain

# Scriptish formats
*.bat        text svneol=native#text/plain
*.bsh        text svneol=native#text/x-beanshell
*.cgi        text svneol=native#text/plain
*.cmd        text svneol=native#text/plain
*.js         text svneol=native#text/javascript
*.php        text svneol=native#text/x-php
*.pl         text svneol=native#text/x-perl
*.pm         text svneol=native#text/x-perl
*.py         text svneol=native#text/x-python
*.sh         eol=lf svneol=LF#text/x-sh
configure    eol=lf svneol=LF#text/x-sh

# Image formats
*.bmp        binary svneol=unset#image/bmp
*.gif        binary svneol=unset#image/gif
*.ico        binary svneol=unset#image/ico
*.jpeg       binary svneol=unset#image/jpeg
*.jpg        binary svneol=unset#image/jpeg
*.png        binary svneol=unset#image/png
*.tif        binary svneol=unset#image/tiff
*.tiff       binary svneol=unset#image/tiff
*.svg        text svneol=native#image/svg%2Bxml

# Data formats
*.pdf        binary svneol=unset#application/pdf
*.avi        binary svneol=unset#video/avi
*.doc        binary svneol=unset#application/msword
*.dsp        text svneol=crlf#text/plain
*.dsw        text svneol=crlf#text/plain
*.eps        binary svneol=unset#application/postscript
*.json       text svneol=native#application/json
*.gz         binary svneol=unset#application/gzip
*.mov        binary svneol=unset#video/quicktime
*.mp3        binary svneol=unset#audio/mpeg
*.ppt        binary svneol=unset#application/vnd.ms-powerpoint
*.ps         binary svneol=unset#application/postscript
*.psd        binary svneol=unset#application/photoshop
*.rdf        binary svneol=unset#text/rdf
*.rss        text svneol=unset#text/xml
*.rtf        binary svneol=unset#text/rtf
*.sln        text svneol=native#text/plain
*.swf        binary svneol=unset#application/x-shockwave-flash
*.tgz        binary svneol=unset#application/gzip
*.vcproj     text svneol=native#text/xml
*.vcxproj    text svneol=native#text/xml
*.vsprops    text svneol=native#text/xml
*.wav        binary svneol=unset#audio/wav
*.xls        binary svneol=unset#application/vnd.ms-excel
*.zip        binary svneol=unset#application/zip

# Text formats
.htaccess    text svneol=native#text/plain
*.bbk        text svneol=native#text/xml
*.cmake      text svneol=native#text/plain
*.css        text svneol=native#text/css
*.dtd        text svneol=native#text/xml
*.htm        text svneol=native#text/html
*.html       text svneol=native#text/html
*.ini        text svneol=native#text/plain
*.log        text svneol=native#text/plain
*.mak        text svneol=native#text/plain
*.qbk        text svneol=native#text/plain
*.rst        text svneol=native#text/plain
*.sql        text svneol=native#text/x-sql
*.txt        text svneol=native#text/plain
*.xhtml      text svneol=native#text/xhtml%2Bxml
*.xml        text svneol=native#text/xml
*.xsd        text svneol=native#text/xml
*.xsl        text svneol=native#text/xml
*.xslt       text svneol=native#text/xml
*.xul        text svneol=native#text/xul
*.yml        text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES      text svneol=native#text/plain
COPYING      text svneol=native#text/plain
INSTALL      text svneol=native#text/plain
Jamfile      text svneol=native#text/plain
Jamroot      text svneol=native#text/plain
Jamfile.v2   text svneol=native#text/plain
Jamrules     text svneol=native#text/plain
Makefile*    text svneol=native#text/plain
README       text svneol=native#text/plain
TODO         text svneol=native#text/plain

# Code formats
*.c          text svneol=native#text/plain
*.cpp        text svneol=native#text/plain
*.h          text svneol=native#text/plain
*.hpp        text svneol=native#text/plain
*.ipp        text svneol=native#text/plain
*.tpp        text svneol=native#text/plain
*.jam        text svneol=native#text/plain
*.java       text svneol=native#text/plain


================================================
FILE: .github/FUNDING.yml
================================================
github: ned14


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  Build:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ['3.x', 'pypy3.11']
        
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
  
    - shell: bash
      run: |
        pip install -r requirements.txt
        git submodule update --init --recursive

    - name: Build
      shell: bash
      run: |
        python setup.py build

  Test:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ['3.x', 'pypy3.11']
        
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    
    - shell: bash
      run: |
        pip install -r requirements.txt
        git submodule update --init --recursive

    - name: Test
      shell: bash
      run: |
        pip install pytest
        python -m pytest tests/ -v

  Install-Pip:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ['3.x', 'pypy3.11']
        
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    
    - shell: bash
      run: |
        pip install -r requirements.txt
        git submodule update --init --recursive

    - name: Install with pip
      shell: bash
      run: |
        python setup.py install
        pcpp --version

  Install-Uv:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ['3.x', 'pypy3.11']
        
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    
    - name: Install uv
      shell: bash
      run: |
        curl -LsSf https://astral.sh/uv/install.sh | sh
        echo "$HOME/.cargo/bin" >> $GITHUB_PATH
    
    - shell: bash
      run: |
        git submodule update --init --recursive

    - name: Install with uv
      shell: bash
      run: |
        uv venv test_env
        source test_env/bin/activate
        uv pip install -e .
        pcpp --version

  Test-Uv:
    runs-on: ubuntu-24.04
    strategy:
      matrix:
        python-version: ['3.x', 'pypy3.11']
        
    steps:
    - uses: actions/checkout@v5
    - uses: actions/setup-python@v6
      with:
        python-version: ${{ matrix.python-version }}
    
    - name: Install uv
      shell: bash
      run: |
        curl -LsSf https://astral.sh/uv/install.sh | sh
        echo "$HOME/.cargo/bin" >> $GITHUB_PATH
    
    - shell: bash
      run: |
        git submodule update --init --recursive
        
    - name: Install dependencies and pcpp with uv
      shell: bash
      run: |
        uv venv test_env
        source test_env/bin/activate
        uv pip install -e .
        uv pip install pytest
        python -m pytest tests/ -v


================================================
FILE: .gitignore
================================================
*.pyc
build/*
dist/*
pcpp.egg-info/*


================================================
FILE: .gitmodules
================================================
[submodule "pcpp/ply"]
	path = pcpp/ply
	url = https://github.com/ned14/ply.git
	branch = master
	ignore = untracked


================================================
FILE: AGENTS.md
================================================
# Agent Overview for pcpp (Pure Python C Preprocessor)

## How to build
- `python setup.py build`

## How to test
- `python setup.py test`

## Instructions
1. Ignore everything within the `ply` submodule.
2. Run tests before making a change.
3. Run tests after making a change.
4. If writing a unit test, always use the `unittest` framework.



================================================
FILE: LICENSE.txt
================================================
(C) 2018-2026 Niall Douglas http://www.nedproductions.biz/
and (C) 2007-2019 David Beazley http://www.dabeaz.com/

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.  
* Redistributions in binary form must reproduce the above copyright notice, 
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.  
* Neither the name of the David Beazley or Dabeaz LLC may be used to
  endorse or promote products derived from this software without
  specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.rst
================================================
A C99 preprocessor written in pure Python
=========================================
.. role:: c(code)
   :language: c

.. |travis| image:: https://github.com/ned14/pcpp/actions/workflows/ci.yml/badge.svg?branch=master
     :align: middle
     :target: https://github.com/ned14/pcpp/actions

\(C) 2018-2026 Niall Douglas http://www.nedproductions.biz/ and (C) 2007-2020 David Beazley http://www.dabeaz.com/

PyPI: https://pypi.python.org/pypi/pcpp Github: https://github.com/ned14/pcpp API reference docs: https://ned14.github.io/pcpp/

Travis master branch all tests passing for Python 3 and PyPy3: |travis|

A pure universal Python C (pre-)preprocessor implementation very useful for pre-preprocessing header only
C++ libraries into single file includes and other such build or packaging stage malarky.
The implementation can be used as a Python module (`see API reference <https://ned14.github.io/pcpp/>`_)
or as a command line tool ``pcpp`` which
can stand in for a conventional C preprocessor (i.e. it'll accept similar arguments).
Works great under PyPy, and you can expect performance gains of between 0.84x and 2.62x
(average = 2.2x, median = 2.31x).

To install pcpp, you can use either pip or uv:

Using pip:
::

    pip install pcpp

Using uv (faster installation):
::

    uv install pcpp


Your includes can be benchmarked for heft in order to improve your build times! See
the ``--times`` and ``--filetimes`` options, and you can see graphs from pcpp for the
C++ STLs at https://github.com/ned14/stl-header-heft.

A very unique facility of this C preprocessor is *partial* preprocessing so you can
programmatically control how much preprocessing is done by ``pcpp`` and how much is
done by the C or C++ compiler's preprocessor. The ultimate control is by subclassing
the :c:`Preprocessor` class in Python from which you can do anything you like, however
for your convenience the ``pcpp`` command line tool comes with the following canned
partial preprocessing algorithms:

**passthru-defines**
  Pass through but still execute #defines and #undefs if not always removed by
  preprocessor logic. This ensures that including the output sets exactly the same
  macros as if you included the original, plus include guards work.

**passthru-unfound-includes**
  If an :c:`#include` is not found, pass it through unmodified. This is very useful
  for passing through includes of system headers.

**passthru-undefined-exprs**
  This is one of the most powerful pass through algorithms. If an expression passed to
  :c:`#if` (or its brethern) contains an unknown macro, expand the expression with
  known macros and pass through *unexecuted*, and then pass through the remaining block.
  Each :c:`#elif` is evaluated in turn and if it does not contain unknown macros, it will be
  executed immediately. Finally, any :c:`#else` clause is always passed through *unexecuted*.
  Note that include guards normally defeat this algorithm, so those are specially detected and
  ignored.

**passthru-comments**
  A major use case for ``pcpp`` is as a preprocessor for the `doxygen <http://www.stack.nl/~dimitri/doxygen/>`_
  reference documentation tool whose preprocessor is unable to handle any preprocessing
  of any complexity. ``pcpp`` can partially execute the preprocessing which doxygen
  is incapable of, thus generating output which produces good results with doxygen.
  Hence the ability to pass through comments containing doxygen markup is very useful.

**passthru-magic-macros**
  Don't expand ``__DATE__``, ``__TIME__``, ``__FILE__``, ``__LINE__`` nor ``__COUNTER__``.

**passthru-includes**
  Don't expand those ``#include`` whose arguments match the supplied regular expression
  into the output, however still execute those includes. This lets you generate output
  with macros from nested includes expanded, however those ``#include`` matching
  the regular expression are passed through into the output.


Standards (non-)compliance
--------------------------
``pcpp`` passes a very slightly modified edition of the `mcpp <http://mcpp.sourceforge.net/>`_
unit test suite. The only modifications done were to disable the digraph and trigraphs tests.
It also passes the list of "preprocessor torture" expansion fragments
in the C11 standard, correctly expanding some very complex recursive macro expansions
where expansions cause new macro expansions to be formed. In this, it handily beats
the MSVC preprocessor and ought to handle most C99 preprocessor metaprogramming.
If you compare its output side-by-side to that of GCC or clang's preprocessor, results
are extremely close indeed with blank line collapsing being the only difference.

As of v1.30 (Oct 2020), a proper yacc based expression evaluator for :c:`#if`
expressions is used which is standards conforming, and fixes a large number of
problems found in the previous Python :c:`eval()` based expression evaluator.

A full, detailed list of known non-conformance with the C99 standard is below.
Pull requests with bug fixes and new unit tests for the fix are welcome.

On Python 3, input and output files can have your choice of encoding, and you can
hook file open to inspect the encoding using ``chardet``.

Note that most of this preprocessor was written originally by David Beazley to show
off his excellent Python Lex-Yacc library PLY (http://www.dabeaz.com/ply/) and is
hidden in there without being at all obvious given the number of Stack Overflow
questions which have asked for a pure Python C preprocessor implementation. This
implementation fixes a lot of conformance bugs (the original was never intended to
rigidly adhere to the C standard) and adds in a test suite based on the C11 preprocessor
torture samples plus the mcpp preprocessor test suite. Still, this project would
not be possible without David's work, so please take off your hat and give a bow towards him.

Command line tool ``pcpp``:
---------------------------
The help from the command line tool ``pcpp``::

    usage: pcpp [-h] [-o [path]] [-D macro[=val]] [-U macro] [-N macro] [-I path]
                [--passthru-defines] [--passthru-unfound-includes]
                [--passthru-unknown-exprs] [--passthru-comments]
                [--passthru-magic-macros] [--passthru-includes <regex>]
                [--disable-auto-pragma-once] [--line-directive [form]] [--debug]
                [--time] [--filetimes [path]] [--compress]
                [--assume-input-encoding <encoding>]
                [--output-encoding <encoding>] [--write-bom] [--version]
                [input [input ...]]

    A pure universal Python C (pre-)preprocessor implementation very useful for
    pre-preprocessing header only C++ libraries into single file includes and
    other such build or packaging stage malarky.

    positional arguments:
      input                 Files to preprocess (use '-' for stdin)

    optional arguments:
      -h, --help            show this help message and exit
      -o [path]             Output to a file instead of stdout
      -D macro[=val]        Predefine name as a macro [with value]
      -U macro              Pre-undefine name as a macro
      -N macro              Never define name as a macro, even if defined during
                            the preprocessing.
      -I path               Path to search for unfound #include's
      --passthru-defines    Pass through but still execute #defines and #undefs if
                            not always removed by preprocessor logic
      --passthru-unfound-includes
                            Pass through #includes not found without execution
      --passthru-unknown-exprs
                            Unknown macros in expressions cause preprocessor logic
                            to be passed through instead of executed by treating
                            unknown macros as 0L
      --passthru-comments   Pass through comments unmodified
      --passthru-magic-macros
                            Pass through double underscore magic macros unmodified
      --passthru-includes <regex>
                            Regular expression for which #includes to not expand.
                            #includes, if found, are always executed
      --disable-auto-pragma-once
                            Disable the heuristics which auto apply #pragma once
                            to #include files wholly wrapped in an obvious include
                            guard macro
      --line-directive [form]
                            Form of line directive to use, defaults to #line,
                            specify nothing to disable output of line directives
      --debug               Generate a pcpp_debug.log file logging execution
      --time                Print the time it took to #include each file
      --filetimes [path]    Write CSV file with time spent inside each included
                            file, inclusive and exclusive
      --compress            Make output as small as possible
      --assume-input-encoding <encoding>
                            The text encoding to assume inputs are in
      --output-encoding <encoding>
                            The text encoding to use when writing files
      --write-bom           Prefix any output with a Unicode BOM
      --version             show program's version number and exit

    Note that so pcpp can stand in for other preprocessor tooling, it ignores any
    arguments it does not understand.

Quick demo of pass through mode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let us look at an example for pass through mode. Here is the original:

.. code-block:: c

    #if !defined(__cpp_constexpr)
    #if __cplusplus >= 201402L
    #define __cpp_constexpr 201304  // relaxed constexpr
    #else
    #define __cpp_constexpr 190000
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #if __cpp_constexpr >= 201304
    #define BOOSTLITE_CONSTEXPR constexpr
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

``pcpp test.h --passthru-defines --passthru-unknown-exprs`` will output:

.. code-block:: c

    #if !defined(__cpp_constexpr)
    #if __cplusplus >= 201402
    #define __cpp_constexpr 201304
    #else
    #define __cpp_constexpr 190000
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #if __cpp_constexpr >= 201304
    #define BOOSTLITE_CONSTEXPR constexpr
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

This is because ``__cpp_constexpr`` was not defined, so because of the ``--passthru-unknown-exprs`` flag
we pass through everything inside that if block **unexecuted** i.e. defines and undefs are NOT executed by
``pcpp``. Let's define ``__cpp_constexpr``:

``pcpp test.h --passthru-defines --passthru-unknown-exprs -D __cpp_constexpr``

.. code-block:: c

    #line 8 "test.h"
    #ifndef BOOSTLITE_CONSTEXPR



    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

So, big difference now. We execute the entire first if block as ``__cpp_constexpr`` is now defined, thus
leaving whitespace. Let's try setting ``__cpp_constexpr`` a bit higher:

``pcpp test.h --passthru-defines --passthru-unknown-exprs -D __cpp_constexpr=201304``

.. code-block:: c

    #line 8 "test.h"
    #ifndef BOOSTLITE_CONSTEXPR

    #define BOOSTLITE_CONSTEXPR constexpr

    #endif

As you can see, the lines related to the known ``__cpp_constexpr`` are executed and removed, passing through
any if blocks with unknown macros in the expression.

What if you want a macro to be known but undefined? The -U (to undefine) flag has an obvious meaning in pass
through mode in that it makes a macro no longer unknown, but known to be undefined.

``pcpp test.h --passthru-defines --passthru-unknown-exprs -U __cpp_constexpr``

.. code-block:: c

    #if __cplusplus >= 201402
    #define __cpp_constexpr 201304
    #else
    #define __cpp_constexpr 190000
    #endif

    #ifndef BOOSTLITE_CONSTEXPR



    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

Here ``__cpp_constexpr`` is known to be undefined so the first clause executes, but ``__cplusplus`` is
unknown so that entire block is passed through unexecuted. In the next test comparing ``__cpp_constexpr``
to 201304 it is still known to be undefined, and so 0 >= 201304 is the expressions tested which is false,
hence the following stanza is removed entirely.

Helping ``pcpp`` using source code annotation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can achieve a great deal using -D (define), -U (undefine) and -N (never define) on the command line,
but for more complex preprocessing it gets hard to pass through the correct logic without some source code
annotation.

``pcpp`` lets you annotate which part of an if block being passed through due to use of unknown macros
to also be executed in addition to the pass through. For this use ``__PCPP_ALWAYS_FALSE__`` or
``__PCPP_ALWAYS_TRUE__`` which tells ``pcpp`` to temporarily start executing the passed through
preprocessor commands e.g.

.. code-block:: c

    #if !defined(__cpp_constexpr)
    #if __cplusplus >= 201402L
    #define __cpp_constexpr 201304
    #elif !__PCPP_ALWAYS_FALSE__     // pcpp please execute this next block
    #define __cpp_constexpr 190000
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #if __cpp_constexpr >= 201304
    #define BOOSTLITE_CONSTEXPR constexpr
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

Note that ``__PCPP_ALWAYS_FALSE__`` will always be false in any other preprocessor, and it is also
false in ``pcpp``. However, it causes ``pcpp`` to execute the define of ``__cpp_constexpr`` to 190000:

``pcpp test.h --passthru-defines --passthru-unknown-exprs``

.. code-block:: c

    #if !defined(__cpp_constexpr)
    #if __cplusplus >= 201402
    #define __cpp_constexpr 201304
    #elif 1
    #define __cpp_constexpr 190000
    #endif
    #endif
    #ifndef BOOSTLITE_CONSTEXPR



    #endif
    #ifndef BOOSTLITE_CONSTEXPR
    #define BOOSTLITE_CONSTEXPR
    #endif

This is one way of marking up ``#else`` clauses so they always execute in a normal preprocessor
and also pass through with execution with ``pcpp``. You can, of course, also place ``|| __PCPP_ALWAYS_FALSE__``
in any ``#if`` stanza to cause it to be passed through with execution, but not affect the
preprocessing logic otherwise.

What's implemented by the ``Preprocessor`` class:
=================================================
- Digraphs and Trigraphs
- line continuation operator '``\``'
- C99 correct elimination of comments and maintenance of whitespace in output.
- :c:`__DATE__`, :c:`__TIME__`, :c:`__FILE__`, :c:`__LINE__`. Note that :c:`__STDC__` et al are NOT defined by
  default, you need to define those manually before starting preprocessing.
- :c:`__COUNTER__`, a very common extension
- Object :c:`#define`
- Function :c:`#define macro(...)`

  - Retokenisation and reexpansion after expansion is C99 compliant.

- :c:`#undef`
- :c:`#include "path"`, :c:`<path>` and :c:`PATH`
- :c:`defined` operator
- C operators:

  - :c:`+, -, !, ~`
  - :c:`*, /, %`
  - :c:`+, -`
  - :c:`<<, >>`
  - :c:`<, <=, >, >=`
  - :c:`==, !=`
  - :c:`&`
  - :c:`^`
  - :c:`|`
  - :c:`&&`
  - :c:`||`
  - :c:`x ? y : z` (partial support, see known bugs)

- :c:`#if`, :c:`#ifdef`, :c:`#ifndef`, :c:`#elif`, :c:`#else`, :c:`#endif`
- Stringizing operator #
- Token pasting operator ##
- :c:`#pragma once`, a very common extension

Additionally implemented by ``pcpp`` command line tool:
-------------------------------------------------------
- :c:`#error` (default implementation prints to stderr and increments the exit code)
- :c:`#warning` (default implementation prints to stderr)

Not implemented yet (donations of code welcome):
------------------------------------------------
- :c:`#pragma` anything other than :c:`once`.
- :c:`_Pragma` used to emit preprocessor calculated #pragma.
- :c:`#line num`, :c:`num "file"` and :c:`NUMBER FILE`.

Known bugs (ordered from worst to least worst):
-----------------------------------------------
None presently known.

Customising your own preprocessor:
==================================
See the API reference docs at https://ned14.github.io/pcpp/

You can find an example of overriding the ``on_*()`` processing hooks at https://github.com/ned14/pcpp/blob/master/pcpp/pcmd.py

Running Tests
=============
To run the test suite for ``pcpp``, you can use either of these methods:

1. Using pytest directly (recommended):
   ::

       python -m pytest tests/ -v

2. Using the setup.py test command (deprecated but still functional):
   ::

       python setup.py test

The test suite includes various test cases covering C99 preprocessor functionality,
edge cases, and compatibility with the C11 standard preprocessor torture samples.


History:
========
v1.31 (?):
----------
- Remove Python 2 support completely; pcpp is now Python 3 only
  (issue #87).
- Replace setuptools test suite with pytest as the test runner.
- Add ``uv`` support for faster dependency installation.
- Rearrange ``main()`` function logic to avoid code duplication and make the
  entry point cleaner (PR #73). Thanks to assarbad for this improvement.
- Fix issue #79 by replacing ``CPP_INTEGER`` and ``CPP_FLOAT`` tokens with a
  ``PP_NUMBER`` token for better preprocessing compliance. Update ``PP_NUMBER``
  regex definition to properly handle digit separators in numeric literals.
  Add new test file for issue0079. Thanks to willwray for the PR implementing
  these features.
- Add support for ``#include_next``, though note it is gated behind the
``--enable-include-next`` command line option. Thanks to Dudeldu for the original
PR #98.
- Multi line and unicode character literals were not working by pure oversight.
Fixed and thanks to geky for showing the issue in PR #103.
- Add support for ``__has_include``, a long requested and oft requested
feature (#53, #77, #97).
- Disable the processing of trigraphs by default to match other C preprocessors.
Now pass ``--trigraphs`` to enable them. Thanks to pmp-p for suggesting this #100.
- Believe it or not, until now this caused an infinite loop:

```
#define FOO(x) x
#define BAR FOO(BAR)
BAR
```

This is fixed, which closes #72, #101 and possibly quite a few more open issues.
Thanks to MatthewShao for originally reporting this.

v1.30 (29th October 2021):
--------------------------
- Thanks to a 5km limit covid lockdown in my country, a public holiday where we were
  supposed to be away meant I was stuck at home instead. I took the full day to finish
  the https://github.com/ned14/pcpp/tree/yacc_expression_evaluator branch which is a
  proper C preprocessor expression evaluator based on http://www.dabeaz.com/ply/ 's
  yacc module. This was a very long outstanding piece of work which had been in
  progress for nearly two years. It just needed a full day of my time to get it done,
  and now it is indeed done at long last.
- BREAKING CHANGE: Thanks to the new expression evaluator, fix a long standing bug
  where unknown function macros in expressions were parsed as ``0(0)`` which obviously
  enough does not work. Fixing this changes how the ``on_unknown_macro_in_expr()``
  hook works, and there is now an added ``on_unknown_macro_function_in_expr()`` hook.
- Add a new passthru option ``--passthru-includes`` which enables selected ``#include``
  to be passed through, in addition to being executed. Thanks to schra for suggesting
  this, including a PR. The original implementation had some subtle corner case bugs,
  thanks to trelau for reporting those.
- Fix a token expansion ordering bug whereby if a function macro used the same
  macro in more than one argument, expansion in one argument evaluation caused overly
  eager expansion in later argument evaluations. This fix ought to fix pcpp's ability
  to parse Boost (untested). Thanks to joaquintides for reporting this.
- Now that pcpp no longer ever calls ``eval()``, pcpp is PyPy compatible and is
  probably also compatible with Pyston (untested). Typical speedup is about 2.2x-2.3x,
  though it can also be slower occasionally for some inputs. PyPy compatibility is now
  being tested by CI to ensure it remains working going forth.
- Fix internal preprocessor error and failure to insert newlines before ``#include``
  caused by certain sequence of line continuations in a macro. Thanks to dslijepcevic
  for reporting this.

v1.22 (19th October 2020):
--------------------------
- Fix bug where outputting to stdout did not combine with anything which
  printed to stdout. Thanks to Fondesa for reporting this.
- Fix extra newlines being inserted after a multiline comment. Thanks to virtuald
  for sending a PR fixing this.
- Fix not being able to actually specify an empty line directive. Thanks to kuri65536
  for sending a PR fixing this.
- Update ply submodule to latest from trunk.
- Emit line continuations as tokens, rather than collapsing lines during parsing.
  Thanks to MathieuDuponchelle for the pull request implementing this.
- Enable parsing and emission of files in arbitrary text encodings. This is supported
  in Python 3 or later only. Thanks to MathieuDuponchelle for the suggestion.
- Fix bad regex for parsing floats, so now floats are correctly tokenised. Thanks
  to LynnKirby for reporting this.
- BREAKING CHANGE: Passthrough for ``#include MACRO`` was not supported. This was not
  intentional, and to fix it required modifying the ``on_include_not_found()``
  customisation point which is a source breaking change. Thanks to schra for reporting this.

v1.21 (30th September 2019):
----------------------------
- Fix bug where token pasting two numeric tokens did not yield a numeric token. Thanks
  to Sei-Lisa for reporting this.
- BREAKING CHANGE: Paths emitted by pcpp into ``#line`` directives now are relative to the
  working directory of the process when ``Preprocessor`` is initialised. This includes
  added search paths - files included from those locations will be emitted with a sequence
  of ``../`` to relativise the path emitted. If no path exists between the working
  directory and the path of the file being emitted, an absolute path is emitted instead.

  If you wish to disable this new behaviour, or use different behaviour, you can
  customise the new `rewrite_paths` member variable of ``Preprocessor``.
- Fix bug where ``__LINE__`` was expanding into the line number of its definition instead
  of its use. Thanks to Sei-Lisa for reporting this.
- Add ``--passthru-magic-macros`` command line option.
- BREAKING CHANGE: The ``PreprocessorHooks`` and ``OutputDirective`` interface has
  changed. One now must specify the kind of ``OutputDirective`` abort one wants, and one
  can now both ignore AND remove directives. ``on_directive_handle()`` and
  ``on_directive_unknown()`` now take an extra parameter ``precedingtoks``, these are the
  tokens from the ``#`` up to the directive.
- Fix a corner case where ``FUNC(void)foo()`` expanded to ``voidfoo()`` and not
  ``void foo()`` which is a very common non-conforming extension of the C preprocessor.
  Thanks to OmegaDoom for reporting this.
- Add tokens for all the C operators, to help implementation of an expression evaluator.
- Updated embedded ply to HEAD (2019-04-25)
- Fix ``#include`` not working if no ``-I`` parameters were supplied. Thanks to csm10495
  for reporting this.

v1.20 (7th January 2019):
-------------------------
- Now supports character literals in expressions. Thanks to untaugh for the pull request
  adding this.
- Stopped the default collapsing of whitespace in output, and made it optional via a
  new command line option ``--compress``.
- Fixed extraneous whitespace in ``--passthru-comments`` caused by multiline comments.
  Thanks to p2k for reporting this.
- Fixed bug where defining a macro via string did not set the source attribute in the
  token. Thanks to ZedThree for reporting this.
- Stop triggering an exception when no arguments are supplied to pcpp. Thanks to
  virtuald for reporting this.
- Rebase onto PLY latest from Dec 28th 2018 (https://github.com/dabeaz/ply/commit/a37e0839583d683d95e70ce1445c0063c7d4bd21). Latest
  PLY no longer works using pypi packaging, David wants people to include the source of
  PLY directly. pcpp does this via a git submodule, and has setuptools bundle the submodule.
- Add a formal LICENSE.txt file, as requested by Sei-Lisa.
- Fix failure to issue ``#line`` directive for first include file in a file. Thanks to
  Sei-Lisa for reporting this.

v1.1 (19th June 2018):
----------------------
- Added the ``--times`` and ``--filetimes`` features.
- Fix bug where macros containing operator `defined` were not being expanded properly.
- Added the ability to accept multiple inputs, they are concatenated into the output.
- Fix bug where lines beginning with `#` and no contents caused an internal preprocessor error.
- Fix bug where the macro expansion ``par par##ext`` was expanding into ``parext parext``.

v1.01 (21st Feb 2018):
----------------------
- Fix bug where in pass through mode, an #elif in an #if block inside an #if block in ifpassthru was failing to be passed through.
- Downgraded failure to evaluate an expression to a warning.
- Fix missing Readme.rst in pypi package.

v1.00 (13th Mar 2017):
----------------------
First release


================================================
FILE: doc/evaluator.html
================================================
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
    <meta name="generator" content="pdoc 0.5.3" />
    <title>pcpp.evaluator API documentation</title>
    <meta name="description" content="" />
    <link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
    <link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
    <style>
        .flex {
            display: flex !important
        }

        body {
            line-height: 1.5em
        }

        #content {
            padding: 20px
        }

        #sidebar {
            padding: 30px;
            overflow: hidden
        }

        .http-server-breadcrumbs {
            font-size: 130%;
            margin: 0 0 15px 0
        }

        #footer {
            font-size: .75em;
            padding: 5px 30px;
            border-top: 1px solid #ddd;
            text-align: right
        }

        #footer p {
            margin: 0 0 0 1em;
            display: inline-block
        }

        #footer p:last-child {
            margin-right: 30px
        }

        h1,
        h2,
        h3,
        h4,
        h5 {
            font-weight: 300
        }

        h1 {
            font-size: 2.5em;
            line-height: 1.1em
        }

        h2 {
            font-size: 1.75em;
            margin: 1em 0 .50em 0
        }

        h3 {
            font-size: 1.4em;
            margin: 25px 0 10px 0
        }

        h4 {
            margin: 0;
            font-size: 105%
        }

        a {
            color: #058;
            text-decoration: none;
            transition: color .3s ease-in-out
        }

        a:hover {
            color: #e82
        }

        .title code {
            font-weight: bold
        }

        h2[id^="header-"] {
            margin-top: 2em
        }

        .ident {
            color: #900
        }

        pre code {
            background: #f8f8f8;
            font-size: .8em;
            line-height: 1.4em
        }

        code {
            background: #f2f2f1;
            padding: 1px 4px;
            overflow-wrap: break-word
        }

        h1 code {
            background: transparent
        }

        pre {
            background: #f8f8f8;
            border: 0;
            border-top: 1px solid #ccc;
            border-bottom: 1px solid #ccc;
            margin: 1em 0;
            padding: 1ex
        }

        #http-server-module-list {
            display: flex;
            flex-flow: column
        }

        #http-server-module-list div {
            display: flex
        }

        #http-server-module-list dt {
            min-width: 10%
        }

        #http-server-module-list p {
            margin-top: 0
        }

        .toc ul,
        #index {
            list-style-type: none;
            margin: 0;
            padding: 0
        }

        #index code {
            background: transparent
        }

        #index h3 {
            border-bottom: 1px solid #ddd
        }

        #index ul {
            padding: 0
        }

        #index h4 {
            font-weight: bold
        }

        #index h4+ul {
            margin-bottom: .6em
        }

        @media (min-width:200ex) {
            #index .two-column {
                column-count: 2
            }
        }

        @media (min-width:300ex) {
            #index .two-column {
                column-count: 3
            }
        }

        dl {
            margin-bottom: 2em
        }

        dl dl:last-child {
            margin-bottom: 4em
        }

        dd {
            margin: 0 0 1em 3em
        }

        #header-classes+dl>dd {
            margin-bottom: 3em
        }

        dd dd {
            margin-left: 2em
        }

        dd p {
            margin: 10px 0
        }

        .name {
            background: #eee;
            font-weight: bold;
            font-size: .85em;
            padding: 5px 10px;
            display: inline-block;
            min-width: 40%
        }

        .name:hover {
            background: #e0e0e0
        }

        .name>span:first-child {
            white-space: nowrap
        }

        .name.class>span:nth-child(2) {
            margin-left: .4em
        }

        .name small {
            font-weight: normal
        }

        .inherited {
            color: #999;
            border-left: 5px solid #eee;
            padding-left: 1em
        }

        .inheritance em {
            font-style: normal;
            font-weight: bold
        }

        .desc h2 {
            font-weight: 400;
            font-size: 1.25em
        }

        .desc h3 {
            font-size: 1em
        }

        .desc dt code {
            background: inherit
        }

        .source summary {
            color: #666;
            text-align: right;
            font-weight: 400;
            font-size: .8em;
            text-transform: uppercase;
            cursor: pointer
        }

        .source pre {
            max-height: 500px;
            overflow: auto;
            margin: 0
        }

        .source pre code {
            font-size: 12px;
            overflow: visible
        }

        .hlist {
            list-style: none
        }

        .hlist li {
            display: inline
        }

        .hlist li:after {
            content: ',\2002'
        }

        .hlist li:last-child:after {
            content: none
        }

        .hlist .hlist {
            display: inline;
            padding-left: 1em
        }

        img {
            max-width: 100%
        }

        .admonition {
            padding: .1em .5em
        }

        .admonition-title {
            font-weight: bold
        }

        .admonition.note,
        .admonition.info,
        .admonition.important {
            background: #aef
        }

        .admonition.todo,
        .admonition.versionadded,
        .admonition.tip,
        .admonition.hint {
            background: #dfd
        }

        .admonition.warning,
        .admonition.versionchanged,
        .admonition.deprecated {
            background: #fd4
        }

        .admonition.error,
        .admonition.danger,
        .admonition.caution {
            background: lightpink
        }
    </style>
    <style media="screen and (min-width: 700px)">
        @media screen and (min-width:700px) {
            #sidebar {
                width: 30%
            }

            #content {
                width: 70%;
                max-width: 100ch;
                padding: 3em 4em;
                border-left: 1px solid #ddd
            }

            pre code {
                font-size: 1em
            }

            .item .name {
                font-size: 1em
            }

            main {
                display: flex;
                flex-direction: row-reverse;
                justify-content: flex-end
            }

            .toc ul ul,
            #index ul {
                padding-left: 1.5em
            }

            .toc>ul>li {
                margin-top: .5em
            }
        }
    </style>
    <style media="print">
        @media print {
            #sidebar h1 {
                page-break-before: always
            }

            .source {
                display: none
            }
        }

        @media print {
            * {
                background: transparent !important;
                color: #000 !important;
                box-shadow: none !important;
                text-shadow: none !important
            }

            a[href]:after {
                content: " (" attr(href) ")";
                font-size: 90%
            }

            a[href][title]:after {
                content: none
            }

            abbr[title]:after {
                content: " (" attr(title) ")"
            }

            .ir a:after,
            a[href^="javascript:"]:after,
            a[href^="#"]:after {
                content: ""
            }

            pre,
            blockquote {
                border: 1px solid #999;
                page-break-inside: avoid
            }

            thead {
                display: table-header-group
            }

            tr,
            img {
                page-break-inside: avoid
            }

            img {
                max-width: 100% !important
            }

            @page {
                margin: 0.5cm
            }

            p,
            h2,
            h3 {
                orphans: 3;
                widows: 3
            }

            h1,
            h2,
            h3,
            h4,
            h5,
            h6 {
                page-break-after: avoid
            }
        }
    </style>
</head>

<body>
    <main>
        <article id="content">
            <header>
                <h1 class="title"><code>pcpp.evaluator</code> module</h1>
            </header>
            <section id="section-intro">
                <details class="source">
                    <summary>Source code</summary>
                    <pre><code class="python">#!/usr/bin/python
# Python C99 conforming preprocessor expression evaluator
# (C) 2019-2026 Niall Douglas http://www.nedproductions.biz/
# Started: Apr 2019

from __future__ import generators, print_function, absolute_import, division

import sys, os, re, codecs, copy
if __name__ == &#39;__main__&#39; and __package__ is None:
    sys.path.append( os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) ) )
from pcpp.parser import STRING_TYPES, yacc, default_lexer, in_production

# The width of signed integer which this evaluator will use
INTMAXBITS = 64

# Some Python 3 compatibility shims
if sys.version_info.major &lt; 3:
    INTBASETYPE = long
else:
    INTBASETYPE = int

# Precompile the regular expression for correctly expanding unicode escape
# sequences in Python 2 and 3. See https://stackoverflow.com/questions/4020539/process-escape-sequences-in-a-string-in-python
# for more information.
_expand_escape_sequences_pat = re.compile(r&#39;&#39;&#39;
    ( \\U........      # 8-digit hex escapes
    | \\u....          # 4-digit hex escapes
    | \\x..            # 2-digit hex escapes
    | \\[0-7]{1,3}     # Octal escapes
    | \\N\{[^}]+\}     # Unicode characters by name
    | \\[\\&#39;&#34;abfnrtv]  # Single-character escapes
)&#39;&#39;&#39;, re.UNICODE | re.VERBOSE)

class Value(INTBASETYPE):
    &#34;&#34;&#34;A signed or unsigned integer within a preprocessor expression, bounded
    to within INT_MIN and INT_MAX, or 0 and UINT_MAX. Signed overflow is handled
    like a two&#39;s complement CPU, despite being UB, as that&#39;s what GCC and clang do.
    
    &gt;&gt;&gt; Value(5)
    Value(5)
    &gt;&gt;&gt; Value(&#39;5L&#39;)
    Value(5)
    &gt;&gt;&gt; Value(&#39;5U&#39;)
    Value(5U)
    &gt;&gt;&gt; Value(&#39;0&#39;)
    Value(0)
    &gt;&gt;&gt; Value(&#39;0U&#39;)
    Value(0U)
    &gt;&gt;&gt; Value(&#39;-1U&#39;)
    Value(18446744073709551615U)
    &gt;&gt;&gt; Value(5) * Value(2)
    Value(10)
    &gt;&gt;&gt; Value(5) + Value(&#39;2u&#39;)
    Value(7U)
    &gt;&gt;&gt; Value(5) * 2
    Value(10)
    &gt;&gt;&gt; Value(5) / 2   # Must return integer
    Value(2)
    &gt;&gt;&gt; Value(50) % 8
    Value(2)
    &gt;&gt;&gt; -Value(5)
    Value(-5)
    &gt;&gt;&gt; +Value(-5)
    Value(-5)
    &gt;&gt;&gt; ~Value(5)
    Value(-6)
    &gt;&gt;&gt; Value(6) &amp; 2
    Value(2)
    &gt;&gt;&gt; Value(4) | 2
    Value(6)
    &gt;&gt;&gt; Value(6) ^ 2
    Value(4)
    &gt;&gt;&gt; Value(2) &lt;&lt; 2
    Value(8)
    &gt;&gt;&gt; Value(8) &gt;&gt; 2
    Value(2)
    &gt;&gt;&gt; Value(9223372036854775808)
    Value(-9223372036854775808)
    &gt;&gt;&gt; Value(-9223372036854775809)
    Value(9223372036854775807)
    &gt;&gt;&gt; Value(18446744073709551615)
    Value(-1)
    &gt;&gt;&gt; Value(False)
    Value(0)
    &gt;&gt;&gt; Value(True)
    Value(1)
    &gt;&gt;&gt; Value(5) == Value(6)
    Value(0)
    &gt;&gt;&gt; Value(5) == Value(5)
    Value(1)
    &gt;&gt;&gt; not Value(2)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(4) and Value(2)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(5) and not Value(6)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(&#39;0x3f&#39;)
    Value(63)
    &gt;&gt;&gt; Value(&#39;077&#39;)
    Value(63)
    &gt;&gt;&gt; Value(&#34;&#39;N&#39;&#34;)
    Value(78)
    &gt;&gt;&gt; Value(&#34;L&#39;N&#39;&#34;)
    Value(78)
    &gt;&gt;&gt; Value(&#34;&#39;\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; Value(&#34;&#39;\\\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; Value(&#34;&#39;\\\\&#39;&#34;)
    Value(92)
    &gt;&gt;&gt; Value(&#34;&#39;\\&#39;&#34;)
    Traceback (most recent call last):
    ...
    SyntaxError: Empty character escape sequence
    &#34;&#34;&#34;
    INT_MIN = -(1 &lt;&lt; (INTMAXBITS - 1))
    INT_MAX = (1 &lt;&lt; (INTMAXBITS - 1)) - 1
    INT_MASK = (1 &lt;&lt; INTMAXBITS) - 1
    UINT_MIN = 0
    UINT_MAX = (1 &lt;&lt; INTMAXBITS) - 1
    @classmethod
    def __sclamp(cls, value):
        value = INTBASETYPE(value)
        return ((value - cls.INT_MIN) &amp; cls.INT_MASK) + cls.INT_MIN
    @classmethod
    def __uclamp(cls, value):
        value = INTBASETYPE(value)
        return value &amp; cls.UINT_MAX
    def __new__(cls, value, unsigned = False, exception = None):
        if isinstance(value, Value):
            unsigned = value.unsigned
            exception = value.exception
        elif isinstance(value, INTBASETYPE) or isinstance(value, int) or isinstance(value, float):
            value = cls.__uclamp(value) if unsigned else cls.__sclamp(value)
        elif isinstance(value, STRING_TYPES):
            if (value.startswith(&#34;L&#39;&#34;) or value[0] == &#34;&#39;&#34;) and value[-1] == &#34;&#39;&#34;:
                startidx = 2 if value.startswith(&#34;L&#39;&#34;) else 1
                #print(&#34;1. ***&#34;, value, file = sys.stderr)
                value = value[startidx:-1]
                if len(value) == 0:
                    raise SyntaxError(&#39;Empty character escape sequence&#39;)
                #print(&#34;2. ***&#34;, value, file = sys.stderr)
                value = _expand_escape_sequences_pat.sub(lambda x: codecs.decode(x.group(0), &#39;unicode-escape&#39;), value)
                #print(&#34;3. ***&#34;, value, file = sys.stderr)
                x = INTBASETYPE(ord(value))
                #print(&#34;4. ***&#34;, x, file = sys.stderr)
            elif value.startswith(&#39;0x&#39;) or value.startswith(&#39;0X&#39;):
                # Strip any terminators
                while not ((value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;9&#39;) or (value[-1] &gt;= &#39;a&#39; and value[-1] &lt;= &#39;f&#39;) or (value[-1] &gt;= &#39;A&#39; and value[-1] &lt;= &#39;F&#39;)):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value, base = 16)
            elif value.startswith(&#39;0&#39;):
                # Strip any terminators
                while not (value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;7&#39;):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value, base = 8)
            else:
                # Strip any terminators
                while not (value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;9&#39;):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value)
            value = cls.__uclamp(x) if unsigned else cls.__sclamp(x)
            #assert x == value
        else:
            print(&#39;Unknown value type: %s&#39; % repr(type(value)), file = sys.stderr)
            assert False  # Input is an unrecognised type
        inst = super(Value, cls).__new__(cls, value)
        inst.unsigned = unsigned
        inst.exception = exception
        return inst
    def value(self):
        if self.exception is not None:
            raise self.exception
        return INTBASETYPE(self)
    def __add__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) + self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__add__(other))
    def __sub__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) - self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__sub__(other))
    def __mul__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) * self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__mul__(other))
    def __div__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) / self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__div__(other))
    def __truediv__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) / self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__truediv__(other))
    def __mod__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) % self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__mod__(other))
    def __neg__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__neg__(), self.unsigned)
    def __invert__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__invert__(), self.unsigned)
    def __and__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &amp; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__and__(other))
    def __or__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) | self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__or__(other))
    def __pos__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__pos__())
    def __pow__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) ** self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__pow__(other))
    def __lshift__(self, other):
        if self.exception is not None:
            return self
        # Ignore other signedness
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt;&lt; self.__uclamp(other), True) if (self.unsigned) else Value(super(Value, self).__lshift__(other))
    def __rshift__(self, other):
        if self.exception is not None:
            return self
        # Ignore other signedness
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt;&gt; self.__uclamp(other), True) if (self.unsigned) else Value(super(Value, self).__rshift__(other))
    def __xor__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) ^ self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__xor__(other))
    def __repr__(self):
        if self.exception is not None:
            return &#34;Exception(%s)&#34; % repr(self.exception)
        elif self.unsigned:
            return &#34;Value(%dU)&#34; % INTBASETYPE(self)
        else:
            return &#34;Value(%d)&#34; % INTBASETYPE(self)
    def __bool__(self):
        assert False  # Do not use Python logical operations
    def __nonzero__(self):
        assert False  # Do not use Python logical operations
    def __cmp__(self, other):
        assert False
    def __lt__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &lt; self.__sclamp(other), False)
    def __le__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt;= self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &lt;= self.__sclamp(other), False)
    def __eq__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) == self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) == self.__sclamp(other), False)
    def __ne__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) != self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) != self.__sclamp(other), False)
    def __ge__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt;= self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &gt;= self.__sclamp(other), False)
    def __gt__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &gt; self.__sclamp(other), False)

        
# PLY yacc specification
# Valid C preprocessor expression items:
#   - Integer constants
#   - Character constants
#   - Addition, subtraction, multiplication, division, bitwise and-or-xor, shifts,
#     comparisons, logical and-or-not
#   - defined()
#
# The C preprocessor does not support:
#   - assignment
#   - increment and decrement
#   - array indexing, indirection
#   - casting
#   - sizeof, alignof

# The subset of tokens from Preprocessor used in preprocessor expressions
tokens = (
   &#39;CPP_ID&#39;, &#39;CPP_INTEGER&#39;, &#39;CPP_CHAR&#39;, &#39;CPP_STRING&#39;,
   &#39;CPP_PLUS&#39;, &#39;CPP_MINUS&#39;, &#39;CPP_STAR&#39;, &#39;CPP_FSLASH&#39;, &#39;CPP_PERCENT&#39;, &#39;CPP_BAR&#39;,
   &#39;CPP_AMPERSAND&#39;, &#39;CPP_TILDE&#39;, &#39;CPP_HAT&#39;, &#39;CPP_LESS&#39;, &#39;CPP_GREATER&#39;, &#39;CPP_EXCLAMATION&#39;,
   &#39;CPP_QUESTION&#39;, &#39;CPP_LPAREN&#39;, &#39;CPP_RPAREN&#39;,
   &#39;CPP_COMMA&#39;, &#39;CPP_COLON&#39;,

   &#39;CPP_LSHIFT&#39;, &#39;CPP_LESSEQUAL&#39;, &#39;CPP_RSHIFT&#39;,
   &#39;CPP_GREATEREQUAL&#39;, &#39;CPP_LOGICALOR&#39;, &#39;CPP_LOGICALAND&#39;, &#39;CPP_EQUALITY&#39;,
   &#39;CPP_INEQUALITY&#39;
)
# &#39;CPP_WS&#39;, &#39;CPP_EQUAL&#39;,  &#39;CPP_BSLASH&#39;, &#39;CPP_SQUOTE&#39;,

precedence = (
    (&#39;left&#39;, &#39;CPP_COMMA&#39;),                                                     # 15
                                                                               # 14 (assignments, unused)
    (&#39;left&#39;, &#39;CPP_QUESTION&#39;, &#39;CPP_COLON&#39;),                                     # 13
    (&#39;left&#39;, &#39;CPP_LOGICALOR&#39;),                                                 # 12
    (&#39;left&#39;, &#39;CPP_LOGICALAND&#39;),                                                # 11
    (&#39;left&#39;, &#39;CPP_BAR&#39;),                                                       # 10
    (&#39;left&#39;, &#39;CPP_HAT&#39;),                                                       # 9
    (&#39;left&#39;, &#39;CPP_AMPERSAND&#39;),                                                 # 8
    (&#39;left&#39;, &#39;CPP_EQUALITY&#39;, &#39;CPP_INEQUALITY&#39;),                                # 7
    (&#39;left&#39;, &#39;CPP_LESS&#39;, &#39;CPP_LESSEQUAL&#39;, &#39;CPP_GREATER&#39;, &#39;CPP_GREATEREQUAL&#39;),  # 6
    (&#39;left&#39;, &#39;CPP_LSHIFT&#39;, &#39;CPP_RSHIFT&#39;),                                      # 5
    (&#39;left&#39;, &#39;CPP_PLUS&#39;, &#39;CPP_MINUS&#39;),                                         # 4
    (&#39;left&#39;, &#39;CPP_STAR&#39;, &#39;CPP_FSLASH&#39;, &#39;CPP_PERCENT&#39;),                         # 3
    (&#39;right&#39;, &#39;UPLUS&#39;, &#39;UMINUS&#39;, &#39;CPP_EXCLAMATION&#39;, &#39;CPP_TILDE&#39;),              # 2
                                                                               # 1 (unused in the C preprocessor)
)

def p_error(p):
    if p:
        raise SyntaxError(&#34;around token &#39;%s&#39; type %s&#34; % (p.value, p.type))
    else:
        raise SyntaxError(&#34;at EOF&#34;)

def p_expression_number(p):
    &#39;expression : CPP_INTEGER&#39;
    p[0] = Value(p[1])

def p_expression_character(p):
    &#39;expression : CPP_CHAR&#39;
    p[0] = Value(p[1])

def p_expression_string(p):
    &#34;&#34;&#34;
    expression : CPP_STRING
              | CPP_LESS expression CPP_GREATER
    &#34;&#34;&#34;
    p[0] = p[1]

def p_expression_group(t):
    &#39;expression : CPP_LPAREN expression CPP_RPAREN&#39;
    t[0] = t[2]

def p_expression_uplus(p):
    &#39;expression : CPP_PLUS expression %prec UPLUS&#39;
    p[0] = +Value(p[2])

def p_expression_uminus(p):
    &#39;expression : CPP_MINUS expression %prec UMINUS&#39;
    p[0] = -Value(p[2])

def p_expression_unop(p):
    &#34;&#34;&#34;
    expression : CPP_EXCLAMATION expression
              | CPP_TILDE expression
    &#34;&#34;&#34;
    try:
        if p[1] == &#39;!&#39;:
            p[0] = Value(0) if (Value(p[2]).value()!=0) else Value(1)
        elif p[1] == &#39;~&#39;:
            p[0] = ~Value(p[2])
    except Exception as e:
        p[0] = Value(0, exception = e)

def p_expression_binop(p):
    &#34;&#34;&#34;
    expression : expression CPP_STAR expression
              | expression CPP_FSLASH expression
              | expression CPP_PERCENT expression
              | expression CPP_PLUS expression
              | expression CPP_MINUS expression
              | expression CPP_LSHIFT expression
              | expression CPP_RSHIFT expression
              | expression CPP_LESS expression
              | expression CPP_LESSEQUAL expression
              | expression CPP_GREATER expression
              | expression CPP_GREATEREQUAL expression
              | expression CPP_EQUALITY expression
              | expression CPP_INEQUALITY expression
              | expression CPP_AMPERSAND expression
              | expression CPP_HAT expression
              | expression CPP_BAR expression
              | expression CPP_LOGICALAND expression
              | expression CPP_LOGICALOR expression
              | expression CPP_COMMA expression
    &#34;&#34;&#34;
    # print [repr(p[i]) for i in range(0,4)]
    try:
        if p[2] == &#39;*&#39;:
            p[0] = Value(p[1]) * Value(p[3])
        elif p[2] == &#39;/&#39;:
            p[0] = Value(p[1]) / Value(p[3])
        elif p[2] == &#39;%&#39;:
            p[0] = Value(p[1]) % Value(p[3])
        elif p[2] == &#39;+&#39;:
            p[0] = Value(p[1]) + Value(p[3])
        elif p[2] == &#39;-&#39;:
            p[0] = Value(p[1]) - Value(p[3])
        elif p[2] == &#39;&lt;&lt;&#39;:
            p[0] = Value(p[1]) &lt;&lt; Value(p[3])
        elif p[2] == &#39;&gt;&gt;&#39;:
            p[0] = Value(p[1]) &gt;&gt; Value(p[3])
        elif p[2] == &#39;&lt;&#39;:
            p[0] = Value(p[1]) &lt; Value(p[3])
        elif p[2] == &#39;&lt;=&#39;:
            p[0] = Value(p[1]) &lt;= Value(p[3])
        elif p[2] == &#39;&gt;&#39;:
            p[0] = Value(p[1]) &gt; Value(p[3])
        elif p[2] == &#39;&gt;=&#39;:
            p[0] = Value(p[1]) &gt;= Value(p[3])
        elif p[2] == &#39;==&#39;:
            p[0] = Value(p[1]) == Value(p[3])
        elif p[2] == &#39;!=&#39;:
            p[0] = Value(p[1]) != Value(p[3])
        elif p[2] == &#39;&amp;&#39;:
            p[0] = Value(p[1]) &amp; Value(p[3])
        elif p[2] == &#39;^&#39;:
            p[0] = Value(p[1]) ^ Value(p[3])
        elif p[2] == &#39;|&#39;:
            p[0] = Value(p[1]) | Value(p[3])
        elif p[2] == &#39;&amp;&amp;&#39;:
            p[0] = Value(1) if (Value(p[1]).value()!=0 and Value(p[3]).value()!=0) else Value(0)
        elif p[2] == &#39;||&#39;:
            p[0] = Value(1) if (Value(p[1]).value()!=0 or Value(p[3]).value()!=0) else Value(0)
        elif p[2] == &#39;,&#39;:
            p[0] = Value(p[3])
    except Exception as e:
        p[0] = Value(0, exception = e)

def p_expression_conditional(p):
    &#39;expression : expression CPP_QUESTION expression CPP_COLON expression&#39;
    try:
        # Output type must cast up to unsigned if either input is unsigned
        p[0] = Value(p[3]) if (Value(p[1]).value()!=0) else Value(p[5])
        try:
            p[0] = Value(p[0].value(), unsigned = Value(p[3]).unsigned or Value(p[5]).unsigned)
        except:
            pass
    except Exception as e:
        p[0] = Value(0, exception = e)

def p_expression_function_call(p):
    &#34;expression : CPP_ID CPP_LPAREN expression CPP_RPAREN&#34;
    try:
        p.lexer.on_function_call(p)
    except Exception as e:
        p[0] = Value(0, exception = e)

def p_expression_identifier(p):
    &#34;expression : CPP_ID&#34;
    try:
        p.lexer.on_identifier(p)
    except Exception as e:
        p[0] = Value(0, exception = e)


class Evaluator(object):
    &#34;&#34;&#34;Evaluator of #if C preprocessor expressions.
    
    &gt;&gt;&gt; e = Evaluator()
    &gt;&gt;&gt; e(&#39;5&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5+6&#39;)
    Value(11)
    &gt;&gt;&gt; e(&#39;5+6*2&#39;)
    Value(17)
    &gt;&gt;&gt; e(&#39;5/2+6*2&#39;)
    Value(14)
    &gt;&gt;&gt; e(&#39;5 &lt; 6 &lt;= 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;5 &lt; 6 &amp;&amp; 8 &gt; 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;18446744073709551615 == -1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-9223372036854775809 == 9223372036854775807&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-1 &lt; 0U&#39;)
    Value(0U)
    &gt;&gt;&gt; e(&#39;(( 0L &amp;&amp; 0) || (!0L &amp;&amp; !0 ))&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(1)?2:3&#39;)
    Value(2)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0) &lt;= 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0U)&#39;)       # Output type of ? must be common between both choices
    Value(18446744073709551615U)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0U) &lt;= 0&#39;)
    Value(0U)
    &gt;&gt;&gt; e(&#39;1 &amp;&amp; 10 / 0&#39;)         # doctest: +ELLIPSIS
    Exception(ZeroDivisionError(&#39;division by zero&#39;...
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0&#39;)         # &amp;&amp; must shortcut
    Value(0)
    &gt;&gt;&gt; e(&#39;1 ? 10 / 0 : 0&#39;)      # doctest: +ELLIPSIS
    Exception(ZeroDivisionError(&#39;division by zero&#39;...
    &gt;&gt;&gt; e(&#39;0 ? 10 / 0 : 0&#39;)      # ? must shortcut
    Value(0)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 != 4&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(2 || 3) != 1 || (2 &amp;&amp; 3) != 1 || (0 || 4) != 1 || (0 &amp;&amp; 5) != 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;-1 &lt;&lt; 3U &gt; 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#34;&#39;N&#39; == 78&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0x3f == 63&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\\\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; e(&#34;&#39;\\\\\\\\&#39;&#34;)
    Value(92)
    &gt;&gt;&gt; e(&#34;&#39;\\\\n&#39; == 0xA&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\\\\\\\\&#39; == 0x5c&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#34;L&#39;\\\\0&#39; == 0&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#39;12 == 12&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;12L == 12&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-1 &gt;= 0U&#39;)
    Value(1U)
    &gt;&gt;&gt; e(&#39;(1&lt;&lt;2) == 4&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(-!+!9) == -1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(2 || 3) == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;1L * 3 != 3&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(!1L != 0) || (-1L != -1)&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0177777 == 65535&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0Xffff != 65535 || 0XFfFf == 65535&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0L != 0 || 0l != 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1U != 1 || 1u == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0 &lt;= -1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 == 4&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) == 6&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 | 5) == 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 &amp; 5) == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(0 ? 1 : 2) != 2&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;-1 &lt;&lt; 3U &gt; 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;not_defined &amp;&amp; 10 / not_defined&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown identifier not_defined&#39;...
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0 &gt; 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(0) ? 10 / 0 : 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 == 0 || 10 / 0 &gt; 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(15 &gt;&gt; 2 &gt;&gt; 1 != 1) || (3 &lt;&lt; 2 &lt;&lt; 1 != 24)&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(1 | 2) == 3 &amp;&amp; 4 != 5 || 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;1  &gt;  0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\123&#39; != 83&#34;)
    Value(0)
    &gt;&gt;&gt; e(&#34;&#39;\x1b&#39; != &#39;\033&#39;&#34;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 + (1 - (2 + (3 - (4 + (5 - (6 + (7 - (8 + (9 - (10 + (11 - (12 +          (13 - (14 + (15 - (16 + (17 - (18 + (19 - (20 + (21 - (22 + (23 -           (24 + (25 - (26 + (27 - (28 + (29 - (30 + (31 - (32 + 0))))))))))           )))))))))))))))))))))) == 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;test_function(X)&#39;, functions={&#39;test_function&#39;:lambda x: 55})
    Value(55)
    &gt;&gt;&gt; e(&#39;test_identifier&#39;, identifiers={&#39;test_identifier&#39;:11})
    Value(11)
    &gt;&gt;&gt; e(&#39;defined(X)&#39;, functions={&#39;defined&#39;:lambda x: 55})
    Value(55)
    &gt;&gt;&gt; e(&#39;defined(X)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function defined&#39;...
    &gt;&gt;&gt; e(&#39;__has_include(&#34;variant&#34;)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function __has_include&#39;...
    &gt;&gt;&gt; e(&#39;__has_include(&lt;variant&gt;)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function __has_include&#39;...
    &gt;&gt;&gt; e(&#39;5  // comment&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  /* comment */&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  /* comment // more */&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  // /* comment */&#39;)
    Value(5)
    &#34;&#34;&#34;
#    &gt;&gt;&gt; e(&#39;defined X&#39;, functions={&#39;defined&#39;:lambda x: 55})
#    Value(55)

    def __init__(self, lexer = None):
        self.lexer = lexer if lexer is not None else default_lexer()
        self.parser = yacc.yacc(optimize=in_production,debug=not in_production,write_tables=not in_production)

    class __lexer(object):

        def __init__(self, functions, identifiers):
            self.__toks = []
            self.__functions = functions
            self.__identifiers = identifiers

        def input(self, toks):
            self.__toks = [tok for tok in toks if tok.type != &#39;CPP_WS&#39; and tok.type != &#39;CPP_LINECONT&#39; and tok.type != &#39;CPP_COMMENT1&#39; and tok.type != &#39;CPP_COMMENT2&#39;]
            self.__idx = 0

        def token(self):
            if self.__idx &gt;= len(self.__toks):
                return None
            self.__idx = self.__idx + 1
            return self.__toks[self.__idx - 1]

        def on_function_call(self, p):
            if p[1] not in self.__functions:
                raise SyntaxError(&#39;Unknown function %s&#39; % p[1])
            p[0] = Value(self.__functions[p[1]](p[3]))

        def on_identifier(self, p):
            if p[1] not in self.__identifiers:
                raise SyntaxError(&#39;Unknown identifier %s&#39; % p[1])
            p[0] = Value(self.__identifiers[p[1]])
            
    def __call__(self, input, functions = {}, identifiers = {}):
        &#34;&#34;&#34;Execute a fully macro expanded set of tokens representing an expression,
        returning the result of the evaluation.
        &#34;&#34;&#34;
        if not isinstance(input,list):
            self.lexer.input(input)
            input = []
            while True:
                tok = self.lexer.token()
                if not tok:
                    break
                input.append(tok)
        return self.parser.parse(input, lexer = self.__lexer(functions, identifiers))


if __name__ == &#34;__main__&#34;:
    import doctest
    doctest.testmod()</code></pre>
                </details>
            </section>
            <section>
            </section>
            <section>
            </section>
            <section>
                <h2 class="section-title" id="header-functions">Functions</h2>
                <dl>
                    <dt id="pcpp.evaluator.p_error"><code class="name flex">
<span>def <span class="ident">p_error</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc"></section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_error(p):
    if p:
        raise SyntaxError(&#34;around token &#39;%s&#39; type %s&#34; % (p.value, p.type))
    else:
        raise SyntaxError(&#34;at EOF&#34;)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_binop"><code class="name flex">
<span>def <span class="ident">p_expression_binop</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>expression</code>
                                    <code>CPP_STAR</code> <code>expression</code></dt>
                                <dd>| expression CPP_FSLASH expression
                                    | expression CPP_PERCENT expression
                                    | expression CPP_PLUS expression
                                    | expression CPP_MINUS expression
                                    | expression CPP_LSHIFT expression
                                    | expression CPP_RSHIFT expression
                                    | expression CPP_LESS expression
                                    | expression CPP_LESSEQUAL expression
                                    | expression CPP_GREATER expression
                                    | expression CPP_GREATEREQUAL expression
                                    | expression CPP_EQUALITY expression
                                    | expression CPP_INEQUALITY expression
                                    | expression CPP_AMPERSAND expression
                                    | expression CPP_HAT expression
                                    | expression CPP_BAR expression
                                    | expression CPP_LOGICALAND expression
                                    | expression CPP_LOGICALOR expression
                                    | expression CPP_COMMA expression</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_binop(p):
    &#34;&#34;&#34;
    expression : expression CPP_STAR expression
              | expression CPP_FSLASH expression
              | expression CPP_PERCENT expression
              | expression CPP_PLUS expression
              | expression CPP_MINUS expression
              | expression CPP_LSHIFT expression
              | expression CPP_RSHIFT expression
              | expression CPP_LESS expression
              | expression CPP_LESSEQUAL expression
              | expression CPP_GREATER expression
              | expression CPP_GREATEREQUAL expression
              | expression CPP_EQUALITY expression
              | expression CPP_INEQUALITY expression
              | expression CPP_AMPERSAND expression
              | expression CPP_HAT expression
              | expression CPP_BAR expression
              | expression CPP_LOGICALAND expression
              | expression CPP_LOGICALOR expression
              | expression CPP_COMMA expression
    &#34;&#34;&#34;
    # print [repr(p[i]) for i in range(0,4)]
    try:
        if p[2] == &#39;*&#39;:
            p[0] = Value(p[1]) * Value(p[3])
        elif p[2] == &#39;/&#39;:
            p[0] = Value(p[1]) / Value(p[3])
        elif p[2] == &#39;%&#39;:
            p[0] = Value(p[1]) % Value(p[3])
        elif p[2] == &#39;+&#39;:
            p[0] = Value(p[1]) + Value(p[3])
        elif p[2] == &#39;-&#39;:
            p[0] = Value(p[1]) - Value(p[3])
        elif p[2] == &#39;&lt;&lt;&#39;:
            p[0] = Value(p[1]) &lt;&lt; Value(p[3])
        elif p[2] == &#39;&gt;&gt;&#39;:
            p[0] = Value(p[1]) &gt;&gt; Value(p[3])
        elif p[2] == &#39;&lt;&#39;:
            p[0] = Value(p[1]) &lt; Value(p[3])
        elif p[2] == &#39;&lt;=&#39;:
            p[0] = Value(p[1]) &lt;= Value(p[3])
        elif p[2] == &#39;&gt;&#39;:
            p[0] = Value(p[1]) &gt; Value(p[3])
        elif p[2] == &#39;&gt;=&#39;:
            p[0] = Value(p[1]) &gt;= Value(p[3])
        elif p[2] == &#39;==&#39;:
            p[0] = Value(p[1]) == Value(p[3])
        elif p[2] == &#39;!=&#39;:
            p[0] = Value(p[1]) != Value(p[3])
        elif p[2] == &#39;&amp;&#39;:
            p[0] = Value(p[1]) &amp; Value(p[3])
        elif p[2] == &#39;^&#39;:
            p[0] = Value(p[1]) ^ Value(p[3])
        elif p[2] == &#39;|&#39;:
            p[0] = Value(p[1]) | Value(p[3])
        elif p[2] == &#39;&amp;&amp;&#39;:
            p[0] = Value(1) if (Value(p[1]).value()!=0 and Value(p[3]).value()!=0) else Value(0)
        elif p[2] == &#39;||&#39;:
            p[0] = Value(1) if (Value(p[1]).value()!=0 or Value(p[3]).value()!=0) else Value(0)
        elif p[2] == &#39;,&#39;:
            p[0] = Value(p[3])
    except Exception as e:
        p[0] = Value(0, exception = e)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_character"><code class="name flex">
<span>def <span class="ident">p_expression_character</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_CHAR</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_character(p):
    &#39;expression : CPP_CHAR&#39;
    p[0] = Value(p[1])</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_conditional"><code class="name flex">
<span>def <span class="ident">p_expression_conditional</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>expression</code>
                                    <code>CPP_QUESTION</code> <code>expression</code> <code>CPP_COLON</code>
                                    <code>expression</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_conditional(p):
    &#39;expression : expression CPP_QUESTION expression CPP_COLON expression&#39;
    try:
        # Output type must cast up to unsigned if either input is unsigned
        p[0] = Value(p[3]) if (Value(p[1]).value()!=0) else Value(p[5])
        try:
            p[0] = Value(p[0].value(), unsigned = Value(p[3]).unsigned or Value(p[5]).unsigned)
        except:
            pass
    except Exception as e:
        p[0] = Value(0, exception = e)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_function_call"><code class="name flex">
<span>def <span class="ident">p_expression_function_call</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_ID</code>
                                    <code>CPP_LPAREN</code> <code>expression</code> <code>CPP_RPAREN</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_function_call(p):
    &#34;expression : CPP_ID CPP_LPAREN expression CPP_RPAREN&#34;
    try:
        p.lexer.on_function_call(p)
    except Exception as e:
        p[0] = Value(0, exception = e)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_group"><code class="name flex">
<span>def <span class="ident">p_expression_group</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_LPAREN</code>
                                    <code>expression</code> <code>CPP_RPAREN</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_group(t):
    &#39;expression : CPP_LPAREN expression CPP_RPAREN&#39;
    t[0] = t[2]</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_identifier"><code class="name flex">
<span>def <span class="ident">p_expression_identifier</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_ID</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_identifier(p):
    &#34;expression : CPP_ID&#34;
    try:
        p.lexer.on_identifier(p)
    except Exception as e:
        p[0] = Value(0, exception = e)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_number"><code class="name flex">
<span>def <span class="ident">p_expression_number</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_INTEGER</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_number(p):
    &#39;expression : CPP_INTEGER&#39;
    p[0] = Value(p[1])</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_string"><code class="name flex">
<span>def <span class="ident">p_expression_string</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_STRING</code></dt>
                                <dd>| CPP_LESS expression CPP_GREATER</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_string(p):
    &#34;&#34;&#34;
    expression : CPP_STRING
              | CPP_LESS expression CPP_GREATER
    &#34;&#34;&#34;
    p[0] = p[1]</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_uminus"><code class="name flex">
<span>def <span class="ident">p_expression_uminus</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_MINUS</code>
                                    <code>expression</code> %<code>prec</code> <code>UMINUS</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_uminus(p):
    &#39;expression : CPP_MINUS expression %prec UMINUS&#39;
    p[0] = -Value(p[2])</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_unop"><code class="name flex">
<span>def <span class="ident">p_expression_unop</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_EXCLAMATION</code>
                                    <code>expression</code></dt>
                                <dd>| CPP_TILDE expression</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_unop(p):
    &#34;&#34;&#34;
    expression : CPP_EXCLAMATION expression
              | CPP_TILDE expression
    &#34;&#34;&#34;
    try:
        if p[1] == &#39;!&#39;:
            p[0] = Value(0) if (Value(p[2]).value()!=0) else Value(1)
        elif p[1] == &#39;~&#39;:
            p[0] = ~Value(p[2])
    except Exception as e:
        p[0] = Value(0, exception = e)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.evaluator.p_expression_uplus"><code class="name flex">
<span>def <span class="ident">p_expression_uplus</span></span>(<span>p)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <dl>
                                <dt><strong><code>expression</code></strong> :&ensp;<code>CPP_PLUS</code>
                                    <code>expression</code> %<code>prec</code> <code>UPLUS</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def p_expression_uplus(p):
    &#39;expression : CPP_PLUS expression %prec UPLUS&#39;
    p[0] = +Value(p[2])</code></pre>
                        </details>
                    </dd>
                </dl>
            </section>
            <section>
                <h2 class="section-title" id="header-classes">Classes</h2>
                <dl>
                    <dt id="pcpp.evaluator.Evaluator"><code class="flex name class">
<span>class <span class="ident">Evaluator</span></span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>Evaluator of #if C preprocessor expressions.</p>
                            <pre><code>&gt;&gt;&gt; e = Evaluator()
&gt;&gt;&gt; e('5')
Value(5)
&gt;&gt;&gt; e('5+6')
Value(11)
&gt;&gt;&gt; e('5+6*2')
Value(17)
&gt;&gt;&gt; e('5/2+6*2')
Value(14)
&gt;&gt;&gt; e('5 &lt; 6 &lt;= 7')
Value(1)
&gt;&gt;&gt; e('5 &lt; 6 &amp;&amp; 8 &gt; 7')
Value(1)
&gt;&gt;&gt; e('18446744073709551615 == -1')
Value(1)
&gt;&gt;&gt; e('-9223372036854775809 == 9223372036854775807')
Value(1)
&gt;&gt;&gt; e('-1 &lt; 0U')
Value(0U)
&gt;&gt;&gt; e('(( 0L &amp;&amp; 0) || (!0L &amp;&amp; !0 ))')
Value(1)
&gt;&gt;&gt; e('(1)?2:3')
Value(2)
&gt;&gt;&gt; e('(1 ? -1 : 0) &lt;= 0')
Value(1)
&gt;&gt;&gt; e('(1 ? -1 : 0U)')       # Output type of ? must be common between both choices
Value(18446744073709551615U)
&gt;&gt;&gt; e('(1 ? -1 : 0U) &lt;= 0')
Value(0U)
&gt;&gt;&gt; e('1 &amp;&amp; 10 / 0')         # doctest: +ELLIPSIS
Exception(ZeroDivisionError('division by zero'...
&gt;&gt;&gt; e('0 &amp;&amp; 10 / 0')         # &amp;&amp; must shortcut
Value(0)
&gt;&gt;&gt; e('1 ? 10 / 0 : 0')      # doctest: +ELLIPSIS
Exception(ZeroDivisionError('division by zero'...
&gt;&gt;&gt; e('0 ? 10 / 0 : 0')      # ? must shortcut
Value(0)
&gt;&gt;&gt; e('(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1')
Value(0)
&gt;&gt;&gt; e('1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 != 4')
Value(0)
&gt;&gt;&gt; e('(2 || 3) != 1 || (2 &amp;&amp; 3) != 1 || (0 || 4) != 1 || (0 &amp;&amp; 5) != 0')
Value(0)
&gt;&gt;&gt; e('-1 &lt;&lt; 3U &gt; 0')
Value(0)
&gt;&gt;&gt; e("'N' == 78")
Value(1)
&gt;&gt;&gt; e('0x3f == 63')
Value(1)
&gt;&gt;&gt; e("'\\n'")
Value(10)
&gt;&gt;&gt; e("'\\\\'")
Value(92)
&gt;&gt;&gt; e("'\\n' == 0xA")
Value(1)
&gt;&gt;&gt; e("'\\\\' == 0x5c")
Value(1)
&gt;&gt;&gt; e("L'\\0' == 0")
Value(1)
&gt;&gt;&gt; e('12 == 12')
Value(1)
&gt;&gt;&gt; e('12L == 12')
Value(1)
&gt;&gt;&gt; e('-1 &gt;= 0U')
Value(1U)
&gt;&gt;&gt; e('(1&lt;&lt;2) == 4')
Value(1)
&gt;&gt;&gt; e('(-!+!9) == -1')
Value(1)
&gt;&gt;&gt; e('(2 || 3) == 1')
Value(1)
&gt;&gt;&gt; e('1L * 3 != 3')
Value(0)
&gt;&gt;&gt; e('(!1L != 0) || (-1L != -1)')
Value(0)
&gt;&gt;&gt; e('0177777 == 65535')
Value(1)
&gt;&gt;&gt; e('0Xffff != 65535 || 0XFfFf == 65535')
Value(1)
&gt;&gt;&gt; e('0L != 0 || 0l != 0')
Value(0)
&gt;&gt;&gt; e('1U != 1 || 1u == 1')
Value(1)
&gt;&gt;&gt; e('0 &lt;= -1')
Value(0)
&gt;&gt;&gt; e('1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 == 4')
Value(1)
&gt;&gt;&gt; e('(3 ^ 5) == 6')
Value(1)
&gt;&gt;&gt; e('(3 | 5) == 7')
Value(1)
&gt;&gt;&gt; e('(3 &amp; 5) == 1')
Value(1)
&gt;&gt;&gt; e('(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1')
Value(0)
&gt;&gt;&gt; e('(0 ? 1 : 2) != 2')
Value(0)
&gt;&gt;&gt; e('-1 &lt;&lt; 3U &gt; 0')
Value(0)
&gt;&gt;&gt; e('0 &amp;&amp; 10 / 0')
Value(0)
&gt;&gt;&gt; e('not_defined &amp;&amp; 10 / not_defined')  # doctest: +ELLIPSIS
Exception(SyntaxError('Unknown identifier not_defined'...
&gt;&gt;&gt; e('0 &amp;&amp; 10 / 0 &gt; 1')
Value(0)
&gt;&gt;&gt; e('(0) ? 10 / 0 : 0')
Value(0)
&gt;&gt;&gt; e('0 == 0 || 10 / 0 &gt; 1')
Value(1)
&gt;&gt;&gt; e('(15 &gt;&gt; 2 &gt;&gt; 1 != 1) || (3 &lt;&lt; 2 &lt;&lt; 1 != 24)')
Value(0)
&gt;&gt;&gt; e('(1 | 2) == 3 &amp;&amp; 4 != 5 || 0')
Value(1)
&gt;&gt;&gt; e('1  &gt;  0')
Value(1)
&gt;&gt;&gt; e("'S' != 83")
Value(0)
&gt;&gt;&gt; e("'' != ''")
Value(0)
&gt;&gt;&gt; e('0 + (1 - (2 + (3 - (4 + (5 - (6 + (7 - (8 + (9 - (10 + (11 - (12 +          (13 - (14 + (15 - (16 + (17 - (18 + (19 - (20 + (21 - (22 + (23 -           (24 + (25 - (26 + (27 - (28 + (29 - (30 + (31 - (32 + 0))))))))))           )))))))))))))))))))))) == 0')
Value(1)
&gt;&gt;&gt; e('test_function(X)', functions={'test_function':lambda x: 55})
Value(55)
&gt;&gt;&gt; e('test_identifier', identifiers={'test_identifier':11})
Value(11)
&gt;&gt;&gt; e('defined(X)', functions={'defined':lambda x: 55})
Value(55)
&gt;&gt;&gt; e('defined(X)')  # doctest: +ELLIPSIS
Exception(SyntaxError('Unknown function defined'...
&gt;&gt;&gt; e('__has_include("variant")')  # doctest: +ELLIPSIS
Exception(SyntaxError('Unknown function __has_include'...
&gt;&gt;&gt; e('__has_include(&lt;variant&gt;)')  # doctest: +ELLIPSIS
Exception(SyntaxError('Unknown function __has_include'...
&gt;&gt;&gt; e('5  // comment')
Value(5)
&gt;&gt;&gt; e('5  /* comment */')
Value(5)
&gt;&gt;&gt; e('5  /* comment // more */')
Value(5)
&gt;&gt;&gt; e('5  // /* comment */')
</code></pre>
                            <p>Value(5)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class Evaluator(object):
    &#34;&#34;&#34;Evaluator of #if C preprocessor expressions.
    
    &gt;&gt;&gt; e = Evaluator()
    &gt;&gt;&gt; e(&#39;5&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5+6&#39;)
    Value(11)
    &gt;&gt;&gt; e(&#39;5+6*2&#39;)
    Value(17)
    &gt;&gt;&gt; e(&#39;5/2+6*2&#39;)
    Value(14)
    &gt;&gt;&gt; e(&#39;5 &lt; 6 &lt;= 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;5 &lt; 6 &amp;&amp; 8 &gt; 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;18446744073709551615 == -1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-9223372036854775809 == 9223372036854775807&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-1 &lt; 0U&#39;)
    Value(0U)
    &gt;&gt;&gt; e(&#39;(( 0L &amp;&amp; 0) || (!0L &amp;&amp; !0 ))&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(1)?2:3&#39;)
    Value(2)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0) &lt;= 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0U)&#39;)       # Output type of ? must be common between both choices
    Value(18446744073709551615U)
    &gt;&gt;&gt; e(&#39;(1 ? -1 : 0U) &lt;= 0&#39;)
    Value(0U)
    &gt;&gt;&gt; e(&#39;1 &amp;&amp; 10 / 0&#39;)         # doctest: +ELLIPSIS
    Exception(ZeroDivisionError(&#39;division by zero&#39;...
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0&#39;)         # &amp;&amp; must shortcut
    Value(0)
    &gt;&gt;&gt; e(&#39;1 ? 10 / 0 : 0&#39;)      # doctest: +ELLIPSIS
    Exception(ZeroDivisionError(&#39;division by zero&#39;...
    &gt;&gt;&gt; e(&#39;0 ? 10 / 0 : 0&#39;)      # ? must shortcut
    Value(0)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 != 4&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(2 || 3) != 1 || (2 &amp;&amp; 3) != 1 || (0 || 4) != 1 || (0 &amp;&amp; 5) != 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;-1 &lt;&lt; 3U &gt; 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#34;&#39;N&#39; == 78&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0x3f == 63&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\\\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; e(&#34;&#39;\\\\\\\\&#39;&#34;)
    Value(92)
    &gt;&gt;&gt; e(&#34;&#39;\\\\n&#39; == 0xA&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\\\\\\\\&#39; == 0x5c&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#34;L&#39;\\\\0&#39; == 0&#34;)
    Value(1)
    &gt;&gt;&gt; e(&#39;12 == 12&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;12L == 12&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;-1 &gt;= 0U&#39;)
    Value(1U)
    &gt;&gt;&gt; e(&#39;(1&lt;&lt;2) == 4&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(-!+!9) == -1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(2 || 3) == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;1L * 3 != 3&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(!1L != 0) || (-1L != -1)&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0177777 == 65535&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0Xffff != 65535 || 0XFfFf == 65535&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0L != 0 || 0l != 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1U != 1 || 1u == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;0 &lt;= -1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;1 &lt;&lt; 2 != 4 || 8 &gt;&gt; 1 == 4&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) == 6&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 | 5) == 7&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 &amp; 5) == 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(3 ^ 5) != 6 || (3 | 5) != 7 || (3 &amp; 5) != 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(0 ? 1 : 2) != 2&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;-1 &lt;&lt; 3U &gt; 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;not_defined &amp;&amp; 10 / not_defined&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown identifier not_defined&#39;...
    &gt;&gt;&gt; e(&#39;0 &amp;&amp; 10 / 0 &gt; 1&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(0) ? 10 / 0 : 0&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 == 0 || 10 / 0 &gt; 1&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;(15 &gt;&gt; 2 &gt;&gt; 1 != 1) || (3 &lt;&lt; 2 &lt;&lt; 1 != 24)&#39;)
    Value(0)
    &gt;&gt;&gt; e(&#39;(1 | 2) == 3 &amp;&amp; 4 != 5 || 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;1  &gt;  0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#34;&#39;\123&#39; != 83&#34;)
    Value(0)
    &gt;&gt;&gt; e(&#34;&#39;\x1b&#39; != &#39;\033&#39;&#34;)
    Value(0)
    &gt;&gt;&gt; e(&#39;0 + (1 - (2 + (3 - (4 + (5 - (6 + (7 - (8 + (9 - (10 + (11 - (12 +          (13 - (14 + (15 - (16 + (17 - (18 + (19 - (20 + (21 - (22 + (23 -           (24 + (25 - (26 + (27 - (28 + (29 - (30 + (31 - (32 + 0))))))))))           )))))))))))))))))))))) == 0&#39;)
    Value(1)
    &gt;&gt;&gt; e(&#39;test_function(X)&#39;, functions={&#39;test_function&#39;:lambda x: 55})
    Value(55)
    &gt;&gt;&gt; e(&#39;test_identifier&#39;, identifiers={&#39;test_identifier&#39;:11})
    Value(11)
    &gt;&gt;&gt; e(&#39;defined(X)&#39;, functions={&#39;defined&#39;:lambda x: 55})
    Value(55)
    &gt;&gt;&gt; e(&#39;defined(X)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function defined&#39;...
    &gt;&gt;&gt; e(&#39;__has_include(&#34;variant&#34;)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function __has_include&#39;...
    &gt;&gt;&gt; e(&#39;__has_include(&lt;variant&gt;)&#39;)  # doctest: +ELLIPSIS
    Exception(SyntaxError(&#39;Unknown function __has_include&#39;...
    &gt;&gt;&gt; e(&#39;5  // comment&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  /* comment */&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  /* comment // more */&#39;)
    Value(5)
    &gt;&gt;&gt; e(&#39;5  // /* comment */&#39;)
    Value(5)
    &#34;&#34;&#34;
#    &gt;&gt;&gt; e(&#39;defined X&#39;, functions={&#39;defined&#39;:lambda x: 55})
#    Value(55)

    def __init__(self, lexer = None):
        self.lexer = lexer if lexer is not None else default_lexer()
        self.parser = yacc.yacc(optimize=in_production,debug=not in_production,write_tables=not in_production)

    class __lexer(object):

        def __init__(self, functions, identifiers):
            self.__toks = []
            self.__functions = functions
            self.__identifiers = identifiers

        def input(self, toks):
            self.__toks = [tok for tok in toks if tok.type != &#39;CPP_WS&#39; and tok.type != &#39;CPP_LINECONT&#39; and tok.type != &#39;CPP_COMMENT1&#39; and tok.type != &#39;CPP_COMMENT2&#39;]
            self.__idx = 0

        def token(self):
            if self.__idx &gt;= len(self.__toks):
                return None
            self.__idx = self.__idx + 1
            return self.__toks[self.__idx - 1]

        def on_function_call(self, p):
            if p[1] not in self.__functions:
                raise SyntaxError(&#39;Unknown function %s&#39; % p[1])
            p[0] = Value(self.__functions[p[1]](p[3]))

        def on_identifier(self, p):
            if p[1] not in self.__identifiers:
                raise SyntaxError(&#39;Unknown identifier %s&#39; % p[1])
            p[0] = Value(self.__identifiers[p[1]])
            
    def __call__(self, input, functions = {}, identifiers = {}):
        &#34;&#34;&#34;Execute a fully macro expanded set of tokens representing an expression,
        returning the result of the evaluation.
        &#34;&#34;&#34;
        if not isinstance(input,list):
            self.lexer.input(input)
            input = []
            while True:
                tok = self.lexer.token()
                if not tok:
                    break
                input.append(tok)
        return self.parser.parse(input, lexer = self.__lexer(functions, identifiers))</code></pre>
                        </details>
                        <h3>Methods</h3>
                        <dl>
                            <dt id="pcpp.evaluator.Evaluator.__init__"><code class="name flex">
<span>def <span class="ident">__init__</span></span>(<span>self, lexer=None)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Initialize self.
                                        See help(type(self)) for accurate signature.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def __init__(self, lexer = None):
    self.lexer = lexer if lexer is not None else default_lexer()
    self.parser = yacc.yacc(optimize=in_production,debug=not in_production,write_tables=not in_production)</code></pre>
                                </details>
                            </dd>
                        </dl>
                    </dd>
                    <dt id="pcpp.evaluator.Value"><code class="flex name class">
<span>class <span class="ident">Value</span></span>
<span>(</span><span><small>ancestors:</small> builtins.int)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>A signed or unsigned integer within a preprocessor expression, bounded
                                to within INT_MIN and INT_MAX, or 0 and UINT_MAX. Signed overflow is handled
                                like a two's complement CPU, despite being UB, as that's what GCC and clang do.</p>
                            <pre><code>&gt;&gt;&gt; Value(5)
Value(5)
&gt;&gt;&gt; Value('5L')
Value(5)
&gt;&gt;&gt; Value('5U')
Value(5U)
&gt;&gt;&gt; Value('0')
Value(0)
&gt;&gt;&gt; Value('0U')
Value(0U)
&gt;&gt;&gt; Value('-1U')
Value(18446744073709551615U)
&gt;&gt;&gt; Value(5) * Value(2)
Value(10)
&gt;&gt;&gt; Value(5) + Value('2u')
Value(7U)
&gt;&gt;&gt; Value(5) * 2
Value(10)
&gt;&gt;&gt; Value(5) / 2   # Must return integer
Value(2)
&gt;&gt;&gt; Value(50) % 8
Value(2)
&gt;&gt;&gt; -Value(5)
Value(-5)
&gt;&gt;&gt; +Value(-5)
Value(-5)
&gt;&gt;&gt; ~Value(5)
Value(-6)
&gt;&gt;&gt; Value(6) &amp; 2
Value(2)
&gt;&gt;&gt; Value(4) | 2
Value(6)
&gt;&gt;&gt; Value(6) ^ 2
Value(4)
&gt;&gt;&gt; Value(2) &lt;&lt; 2
Value(8)
&gt;&gt;&gt; Value(8) &gt;&gt; 2
Value(2)
&gt;&gt;&gt; Value(9223372036854775808)
Value(-9223372036854775808)
&gt;&gt;&gt; Value(-9223372036854775809)
Value(9223372036854775807)
&gt;&gt;&gt; Value(18446744073709551615)
Value(-1)
&gt;&gt;&gt; Value(False)
Value(0)
&gt;&gt;&gt; Value(True)
Value(1)
&gt;&gt;&gt; Value(5) == Value(6)
Value(0)
&gt;&gt;&gt; Value(5) == Value(5)
Value(1)
&gt;&gt;&gt; not Value(2)
Traceback (most recent call last):
</code></pre>
                            <p>&hellip;
                                AssertionError</p>
                            <pre><code>&gt;&gt;&gt; Value(4) and Value(2)
Traceback (most recent call last):
</code></pre>
                            <p>&hellip;
                                AssertionError</p>
                            <pre><code>&gt;&gt;&gt; Value(5) and not Value(6)
Traceback (most recent call last):
</code></pre>
                            <p>&hellip;
                                AssertionError</p>
                            <pre><code>&gt;&gt;&gt; Value('0x3f')
Value(63)
&gt;&gt;&gt; Value('077')
Value(63)
&gt;&gt;&gt; Value("'N'")
Value(78)
&gt;&gt;&gt; Value("L'N'")
Value(78)
&gt;&gt;&gt; Value("'\n'")
Value(10)
&gt;&gt;&gt; Value("'\\n'")
Value(10)
&gt;&gt;&gt; Value("'\\'")
Value(92)
&gt;&gt;&gt; Value("'\'")
Traceback (most recent call last):
</code></pre>
                            <dl>
                                <dt>&hellip;</dt>
                                <dt><strong><code>SyntaxError</code></strong> :&ensp;<code>Empty</code>
                                    <code>character</code> <code>escape</code> <code>sequence</code></dt>
                                <dd>&nbsp;</dd>
                            </dl>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class Value(INTBASETYPE):
    &#34;&#34;&#34;A signed or unsigned integer within a preprocessor expression, bounded
    to within INT_MIN and INT_MAX, or 0 and UINT_MAX. Signed overflow is handled
    like a two&#39;s complement CPU, despite being UB, as that&#39;s what GCC and clang do.
    
    &gt;&gt;&gt; Value(5)
    Value(5)
    &gt;&gt;&gt; Value(&#39;5L&#39;)
    Value(5)
    &gt;&gt;&gt; Value(&#39;5U&#39;)
    Value(5U)
    &gt;&gt;&gt; Value(&#39;0&#39;)
    Value(0)
    &gt;&gt;&gt; Value(&#39;0U&#39;)
    Value(0U)
    &gt;&gt;&gt; Value(&#39;-1U&#39;)
    Value(18446744073709551615U)
    &gt;&gt;&gt; Value(5) * Value(2)
    Value(10)
    &gt;&gt;&gt; Value(5) + Value(&#39;2u&#39;)
    Value(7U)
    &gt;&gt;&gt; Value(5) * 2
    Value(10)
    &gt;&gt;&gt; Value(5) / 2   # Must return integer
    Value(2)
    &gt;&gt;&gt; Value(50) % 8
    Value(2)
    &gt;&gt;&gt; -Value(5)
    Value(-5)
    &gt;&gt;&gt; +Value(-5)
    Value(-5)
    &gt;&gt;&gt; ~Value(5)
    Value(-6)
    &gt;&gt;&gt; Value(6) &amp; 2
    Value(2)
    &gt;&gt;&gt; Value(4) | 2
    Value(6)
    &gt;&gt;&gt; Value(6) ^ 2
    Value(4)
    &gt;&gt;&gt; Value(2) &lt;&lt; 2
    Value(8)
    &gt;&gt;&gt; Value(8) &gt;&gt; 2
    Value(2)
    &gt;&gt;&gt; Value(9223372036854775808)
    Value(-9223372036854775808)
    &gt;&gt;&gt; Value(-9223372036854775809)
    Value(9223372036854775807)
    &gt;&gt;&gt; Value(18446744073709551615)
    Value(-1)
    &gt;&gt;&gt; Value(False)
    Value(0)
    &gt;&gt;&gt; Value(True)
    Value(1)
    &gt;&gt;&gt; Value(5) == Value(6)
    Value(0)
    &gt;&gt;&gt; Value(5) == Value(5)
    Value(1)
    &gt;&gt;&gt; not Value(2)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(4) and Value(2)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(5) and not Value(6)
    Traceback (most recent call last):
    ...
    AssertionError
    &gt;&gt;&gt; Value(&#39;0x3f&#39;)
    Value(63)
    &gt;&gt;&gt; Value(&#39;077&#39;)
    Value(63)
    &gt;&gt;&gt; Value(&#34;&#39;N&#39;&#34;)
    Value(78)
    &gt;&gt;&gt; Value(&#34;L&#39;N&#39;&#34;)
    Value(78)
    &gt;&gt;&gt; Value(&#34;&#39;\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; Value(&#34;&#39;\\\\n&#39;&#34;)
    Value(10)
    &gt;&gt;&gt; Value(&#34;&#39;\\\\&#39;&#34;)
    Value(92)
    &gt;&gt;&gt; Value(&#34;&#39;\\&#39;&#34;)
    Traceback (most recent call last):
    ...
    SyntaxError: Empty character escape sequence
    &#34;&#34;&#34;
    INT_MIN = -(1 &lt;&lt; (INTMAXBITS - 1))
    INT_MAX = (1 &lt;&lt; (INTMAXBITS - 1)) - 1
    INT_MASK = (1 &lt;&lt; INTMAXBITS) - 1
    UINT_MIN = 0
    UINT_MAX = (1 &lt;&lt; INTMAXBITS) - 1
    @classmethod
    def __sclamp(cls, value):
        value = INTBASETYPE(value)
        return ((value - cls.INT_MIN) &amp; cls.INT_MASK) + cls.INT_MIN
    @classmethod
    def __uclamp(cls, value):
        value = INTBASETYPE(value)
        return value &amp; cls.UINT_MAX
    def __new__(cls, value, unsigned = False, exception = None):
        if isinstance(value, Value):
            unsigned = value.unsigned
            exception = value.exception
        elif isinstance(value, INTBASETYPE) or isinstance(value, int) or isinstance(value, float):
            value = cls.__uclamp(value) if unsigned else cls.__sclamp(value)
        elif isinstance(value, STRING_TYPES):
            if (value.startswith(&#34;L&#39;&#34;) or value[0] == &#34;&#39;&#34;) and value[-1] == &#34;&#39;&#34;:
                startidx = 2 if value.startswith(&#34;L&#39;&#34;) else 1
                #print(&#34;1. ***&#34;, value, file = sys.stderr)
                value = value[startidx:-1]
                if len(value) == 0:
                    raise SyntaxError(&#39;Empty character escape sequence&#39;)
                #print(&#34;2. ***&#34;, value, file = sys.stderr)
                value = _expand_escape_sequences_pat.sub(lambda x: codecs.decode(x.group(0), &#39;unicode-escape&#39;), value)
                #print(&#34;3. ***&#34;, value, file = sys.stderr)
                x = INTBASETYPE(ord(value))
                #print(&#34;4. ***&#34;, x, file = sys.stderr)
            elif value.startswith(&#39;0x&#39;) or value.startswith(&#39;0X&#39;):
                # Strip any terminators
                while not ((value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;9&#39;) or (value[-1] &gt;= &#39;a&#39; and value[-1] &lt;= &#39;f&#39;) or (value[-1] &gt;= &#39;A&#39; and value[-1] &lt;= &#39;F&#39;)):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value, base = 16)
            elif value.startswith(&#39;0&#39;):
                # Strip any terminators
                while not (value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;7&#39;):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value, base = 8)
            else:
                # Strip any terminators
                while not (value[-1] &gt;= &#39;0&#39; and value[-1] &lt;= &#39;9&#39;):
                    if value[-1] == &#39;u&#39; or value[-1] == &#39;U&#39;:
                        unsigned = True
                    value = value[:-1]
                x = INTBASETYPE(value)
            value = cls.__uclamp(x) if unsigned else cls.__sclamp(x)
            #assert x == value
        else:
            print(&#39;Unknown value type: %s&#39; % repr(type(value)), file = sys.stderr)
            assert False  # Input is an unrecognised type
        inst = super(Value, cls).__new__(cls, value)
        inst.unsigned = unsigned
        inst.exception = exception
        return inst
    def value(self):
        if self.exception is not None:
            raise self.exception
        return INTBASETYPE(self)
    def __add__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) + self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__add__(other))
    def __sub__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) - self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__sub__(other))
    def __mul__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) * self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__mul__(other))
    def __div__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) / self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__div__(other))
    def __truediv__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) / self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__truediv__(other))
    def __mod__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) % self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__mod__(other))
    def __neg__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__neg__(), self.unsigned)
    def __invert__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__invert__(), self.unsigned)
    def __and__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &amp; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__and__(other))
    def __or__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) | self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__or__(other))
    def __pos__(self):
        if self.exception is not None:
            return self
        return Value(super(Value, self).__pos__())
    def __pow__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) ** self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__pow__(other))
    def __lshift__(self, other):
        if self.exception is not None:
            return self
        # Ignore other signedness
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt;&lt; self.__uclamp(other), True) if (self.unsigned) else Value(super(Value, self).__lshift__(other))
    def __rshift__(self, other):
        if self.exception is not None:
            return self
        # Ignore other signedness
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt;&gt; self.__uclamp(other), True) if (self.unsigned) else Value(super(Value, self).__rshift__(other))
    def __xor__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) ^ self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(super(Value, self).__xor__(other))
    def __repr__(self):
        if self.exception is not None:
            return &#34;Exception(%s)&#34; % repr(self.exception)
        elif self.unsigned:
            return &#34;Value(%dU)&#34; % INTBASETYPE(self)
        else:
            return &#34;Value(%d)&#34; % INTBASETYPE(self)
    def __bool__(self):
        assert False  # Do not use Python logical operations
    def __nonzero__(self):
        assert False  # Do not use Python logical operations
    def __cmp__(self, other):
        assert False
    def __lt__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &lt; self.__sclamp(other), False)
    def __le__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &lt;= self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &lt;= self.__sclamp(other), False)
    def __eq__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) == self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) == self.__sclamp(other), False)
    def __ne__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) != self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) != self.__sclamp(other), False)
    def __ge__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt;= self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &gt;= self.__sclamp(other), False)
    def __gt__(self, other):
        if self.exception is not None:
            return self
        other = Value(other)
        if other.exception is not None:
            return other
        return Value(self.__uclamp(self) &gt; self.__uclamp(other), True) if (self.unsigned or other.unsigned) else Value(self.__sclamp(self) &gt; self.__sclamp(other), False)</code></pre>
                        </details>
                        <h3>Class variables</h3>
                        <dl>
                            <dt id="pcpp.evaluator.Value.INT_MASK"><code
                                    class="name">var <span class="ident">INT_MASK</span></code></dt>
                            <dd>
                                <section class="desc"></section>
                            </dd>
                            <dt id="pcpp.evaluator.Value.INT_MAX"><code
                                    class="name">var <span class="ident">INT_MAX</span></code></dt>
                            <dd>
                                <section class="desc"></section>
                            </dd>
                            <dt id="pcpp.evaluator.Value.INT_MIN"><code
                                    class="name">var <span class="ident">INT_MIN</span></code></dt>
                            <dd>
                                <section class="desc"></section>
                            </dd>
                            <dt id="pcpp.evaluator.Value.UINT_MAX"><code
                                    class="name">var <span class="ident">UINT_MAX</span></code></dt>
                            <dd>
                                <section class="desc"></section>
                            </dd>
                            <dt id="pcpp.evaluator.Value.UINT_MIN"><code
                                    class="name">var <span class="ident">UINT_MIN</span></code></dt>
                            <dd>
                                <section class="desc"></section>
                            </dd>
                        </dl>
                        <h3>Methods</h3>
                        <dl>
                            <dt id="pcpp.evaluator.Value.value"><code class="name flex">
<span>def <span class="ident">value</span></span>(<span>self)</span>
</code></dt>
                            <dd>
                                <section class="desc"></section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def value(self):
    if self.exception is not None:
        raise self.exception
    return INTBASETYPE(self)</code></pre>
                                </details>
                            </dd>
                        </dl>
                    </dd>
                </dl>
            </section>
        </article>
        <nav id="sidebar">
            <h1>Index</h1>
            <div class="toc">
                <ul></ul>
            </div>
            <ul id="index">
                <li>
                    <h3>Super-module</h3>
                    <ul>
                        <li><code><a title="pcpp" href="index.html">pcpp</a></code></li>
                    </ul>
                </li>
                <li>
                    <h3><a href="#header-functions">Functions</a></h3>
                    <ul class="">
                        <li><code><a title="pcpp.evaluator.p_error" href="#pcpp.evaluator.p_error">p_error</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_binop" href="#pcpp.evaluator.p_expression_binop">p_expression_binop</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_character" href="#pcpp.evaluator.p_expression_character">p_expression_character</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_conditional" href="#pcpp.evaluator.p_expression_conditional">p_expression_conditional</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_function_call" href="#pcpp.evaluator.p_expression_function_call">p_expression_function_call</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_group" href="#pcpp.evaluator.p_expression_group">p_expression_group</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_identifier" href="#pcpp.evaluator.p_expression_identifier">p_expression_identifier</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_number" href="#pcpp.evaluator.p_expression_number">p_expression_number</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_string" href="#pcpp.evaluator.p_expression_string">p_expression_string</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_uminus" href="#pcpp.evaluator.p_expression_uminus">p_expression_uminus</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_unop" href="#pcpp.evaluator.p_expression_unop">p_expression_unop</a></code>
                        </li>
                        <li><code><a title="pcpp.evaluator.p_expression_uplus" href="#pcpp.evaluator.p_expression_uplus">p_expression_uplus</a></code>
                        </li>
                    </ul>
                </li>
                <li>
                    <h3><a href="#header-classes">Classes</a></h3>
                    <ul>
                        <li>
                            <h4><code><a title="pcpp.evaluator.Evaluator" href="#pcpp.evaluator.Evaluator">Evaluator</a></code>
                            </h4>
                            <ul class="">
                                <li><code><a title="pcpp.evaluator.Evaluator.__init__" href="#pcpp.evaluator.Evaluator.__init__">__init__</a></code>
                                </li>
                            </ul>
                        </li>
                        <li>
                            <h4><code><a title="pcpp.evaluator.Value" href="#pcpp.evaluator.Value">Value</a></code></h4>
                            <ul class="two-column">
                                <li><code><a title="pcpp.evaluator.Value.INT_MASK" href="#pcpp.evaluator.Value.INT_MASK">INT_MASK</a></code>
                                </li>
                                <li><code><a title="pcpp.evaluator.Value.INT_MAX" href="#pcpp.evaluator.Value.INT_MAX">INT_MAX</a></code>
                                </li>
                                <li><code><a title="pcpp.evaluator.Value.INT_MIN" href="#pcpp.evaluator.Value.INT_MIN">INT_MIN</a></code>
                                </li>
                                <li><code><a title="pcpp.evaluator.Value.UINT_MAX" href="#pcpp.evaluator.Value.UINT_MAX">UINT_MAX</a></code>
                                </li>
                                <li><code><a title="pcpp.evaluator.Value.UINT_MIN" href="#pcpp.evaluator.Value.UINT_MIN">UINT_MIN</a></code>
                                </li>
                                <li><code><a title="pcpp.evaluator.Value.value" href="#pcpp.evaluator.Value.value">value</a></code>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </nav>
    </main>
    <footer id="footer">
        <p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.5.3</a>.</p>
    </footer>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
    <script>hljs.initHighlightingOnLoad()</script>
</body>

</html>

================================================
FILE: doc/index.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.5.3" />
<title>pcpp API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.name small{font-weight:normal}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title"><code>pcpp</code> module</h1>
</header>
<section id="section-intro">
<details class="source">
<summary>Source code</summary>
<pre><code class="python">from .evaluator import Evaluator
from .parser import Action, OutputDirective
from .pcmd import main, version, CmdPreprocessor
from .preprocessor import Preprocessor
__version__ = version</code></pre>
</details>
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="pcpp.evaluator" href="evaluator.html">pcpp.evaluator</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="pcpp.lextab" href="lextab.html">pcpp.lextab</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="pcpp.parser" href="parser.html">pcpp.parser</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="pcpp.parsetab" href="parsetab.html">pcpp.parsetab</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="pcpp.pcmd" href="pcmd.html">pcpp.pcmd</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
<dt><code class="name"><a title="pcpp.preprocessor" href="preprocessor.html">pcpp.preprocessor</a></code></dt>
<dd>
<section class="desc"></section>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="pcpp.evaluator" href="evaluator.html">pcpp.evaluator</a></code></li>
<li><code><a title="pcpp.lextab" href="lextab.html">pcpp.lextab</a></code></li>
<li><code><a title="pcpp.parser" href="parser.html">pcpp.parser</a></code></li>
<li><code><a title="pcpp.parsetab" href="parsetab.html">pcpp.parsetab</a></code></li>
<li><code><a title="pcpp.pcmd" href="pcmd.html">pcpp.pcmd</a></code></li>
<li><code><a title="pcpp.preprocessor" href="preprocessor.html">pcpp.preprocessor</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.5.3</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

================================================
FILE: doc/lextab.html
================================================
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.5.3" />
<title>pcpp.lextab API documentation</title>
<meta name="description" content="" />
<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.name small{font-weight:normal}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title"><code>pcpp.lextab</code> module</h1>
</header>
<section id="section-intro">
<details class="source">
<summary>Source code</summary>
<pre><code class="python"># lextab.py. This file automatically created by PLY (version 3.11). Don&#39;t edit!
_tabversion   = &#39;3.10&#39;
_lextokens    = set((&#39;CPP_AMPERSAND&#39;, &#39;CPP_ANDEQUAL&#39;, &#39;CPP_BAR&#39;, &#39;CPP_BSLASH&#39;, &#39;CPP_CHAR&#39;, &#39;CPP_COLON&#39;, &#39;CPP_COMMA&#39;, &#39;CPP_COMMENT1&#39;, &#39;CPP_COMMENT2&#39;, &#39;CPP_DEREFERENCE&#39;, &#39;CPP_DIVIDEEQUAL&#39;, &#39;CPP_DOT&#39;, &#39;CPP_DPOUND&#39;, &#39;CPP_DQUOTE&#39;, &#39;CPP_EQUAL&#39;, &#39;CPP_EQUALITY&#39;, &#39;CPP_EXCLAMATION&#39;, &#39;CPP_FLOAT&#39;, &#39;CPP_FSLASH&#39;, &#39;CPP_GREATER&#39;, &#39;CPP_GREATEREQUAL&#39;, &#39;CPP_HAT&#39;, &#39;CPP_ID&#39;, &#39;CPP_INEQUALITY&#39;, &#39;CPP_INTEGER&#39;, &#39;CPP_LBRACKET&#39;, &#39;CPP_LCURLY&#39;, &#39;CPP_LESS&#39;, &#39;CPP_LESSEQUAL&#39;, &#39;CPP_LINECONT&#39;, &#39;CPP_LOGICALAND&#39;, &#39;CPP_LOGICALOR&#39;, &#39;CPP_LPAREN&#39;, &#39;CPP_LSHIFT&#39;, &#39;CPP_LSHIFTEQUAL&#39;, &#39;CPP_MINUS&#39;, &#39;CPP_MINUSEQUAL&#39;, &#39;CPP_MINUSMINUS&#39;, &#39;CPP_MULTIPLYEQUAL&#39;, &#39;CPP_OREQUAL&#39;, &#39;CPP_PERCENT&#39;, &#39;CPP_PERCENTEQUAL&#39;, &#39;CPP_PLUS&#39;, &#39;CPP_PLUSEQUAL&#39;, &#39;CPP_PLUSPLUS&#39;, &#39;CPP_POUND&#39;, &#39;CPP_QUESTION&#39;, &#39;CPP_RBRACKET&#39;, &#39;CPP_RCURLY&#39;, &#39;CPP_RPAREN&#39;, &#39;CPP_RSHIFT&#39;, &#39;CPP_RSHIFTEQUAL&#39;, &#39;CPP_SEMICOLON&#39;, &#39;CPP_SQUOTE&#39;, &#39;CPP_STAR&#39;, &#39;CPP_STRING&#39;, &#39;CPP_TILDE&#39;, &#39;CPP_WS&#39;, &#39;CPP_XOREQUAL&#39;))
_lexreflags   = 64
_lexliterals  = &#39;+-*/%|&amp;~^&lt;&gt;=!?()[]{}.,;:\\\&#39;&#34;&#39;
_lexstateinfo = {&#39;INITIAL&#39;: &#39;inclusive&#39;}
_lexstatere   = {&#39;INITIAL&#39;: [(&#39;(?P&lt;t_CPP_WS&gt;([ \\t]+|\\n))|(?P&lt;t_CPP_LINECONT&gt;\\\\[ \\t]*\\n)|(?P&lt;t_CPP_INTEGER&gt;(((((0x)|(0X))[0-9a-fA-F]+)|(\\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?))|(?P&lt;t_CPP_STRING&gt;\\&#34;([^\\\\\\n]|(\\\\(.|\\n)))*?\\&#34;)|(?P&lt;t_CPP_CHAR&gt;(L)?\\\&#39;([^\\\\\\n]|(\\\\(.|\\n)))*?\\\&#39;)|(?P&lt;t_CPP_COMMENT1&gt;(/\\*(.|\\n)*?\\*/))|(?P&lt;t_CPP_COMMENT2&gt;(//[^\\n]*))|(?P&lt;t_CPP_FLOAT&gt;((\\d+)(\\.\\d+)(e(\\+|-)?(\\d+))?|(\\d+)e(\\+|-)?(\\d+))([lL]|[fF])?)|(?P&lt;t_CPP_ID&gt;[A-Za-z_][\\w_]*)|(?P&lt;t_CPP_LOGICALOR&gt;\\|\\|)|(?P&lt;t_CPP_PLUSPLUS&gt;\\+\\+)|(?P&lt;t_CPP_DPOUND&gt;\\#\\#)|(?P&lt;t_CPP_LSHIFTEQUAL&gt;&lt;&lt;=)|(?P&lt;t_CPP_OREQUAL&gt;\\|=)|(?P&lt;t_CPP_PLUSEQUAL&gt;\\+=)|(?P&lt;t_CPP_RSHIFTEQUAL&gt;&gt;&gt;=)|(?P&lt;t_CPP_MULTIPLYEQUAL&gt;\\*=)|(?P&lt;t_CPP_BAR&gt;\\|)|(?P&lt;t_CPP_DIVIDEEQUAL&gt;/=)|(?P&lt;t_CPP_POUND&gt;\\#)|(?P&lt;t_CPP_PERCENTEQUAL&gt;%=)|(?P&lt;t_CPP_DEREFERENCE&gt;-&gt;)|(?P&lt;t_CPP_RPAREN&gt;\\))|(?P&lt;t_CPP_ANDEQUAL&gt;&amp;=)|(?P&lt;t_CPP_RBRACKET&gt;\\])|(?P&lt;t_CPP_LPAREN&gt;\\()|(?P&lt;t_CPP_RSHIFT&gt;&gt;&gt;)|(?P&lt;t_CPP_LESSEQUAL&gt;&lt;=)|(?P&lt;t_CPP_HAT&gt;\\^)|(?P&lt;t_CPP_LOGICALAND&gt;&amp;&amp;)|(?P&lt;t_CPP_EQUALITY&gt;==)|(?P&lt;t_CPP_GREATEREQUAL&gt;&gt;=)|(?P&lt;t_CPP_BSLASH&gt;\\\\)|(?P&lt;t_CPP_MINUSEQUAL&gt;-=)|(?P&lt;t_CPP_DOT&gt;\\.)|(?P&lt;t_CPP_MINUSMINUS&gt;--)|(?P&lt;t_CPP_LBRACKET&gt;\\[)|(?P&lt;t_CPP_PLUS&gt;\\+)|(?P&lt;t_CPP_XOREQUAL&gt;^=)|(?P&lt;t_CPP_STAR&gt;\\*)|(?P&lt;t_CPP_QUESTION&gt;\\?)|(?P&lt;t_CPP_LSHIFT&gt;&lt;&lt;)|(?P&lt;t_CPP_INEQUALITY&gt;!=)|(?P&lt;t_CPP_DQUOTE&gt;&#34;)|(?P&lt;t_CPP_MINUS&gt;-)|(?P&lt;t_CPP_RCURLY&gt;})|(?P&lt;t_CPP_GREATER&gt;&gt;)|(?P&lt;t_CPP_LESS&gt;&lt;)|(?P&lt;t_CPP_SQUOTE&gt;\&#39;)|(?P&lt;t_CPP_EXCLAMATION&gt;!)|(?P&lt;t_CPP_LCURLY&gt;{)|(?P&lt;t_CPP_EQUAL&gt;=)|(?P&lt;t_CPP_FSLASH&gt;/)|(?P&lt;t_CPP_COLON&gt;:)|(?P&lt;t_CPP_AMPERSAND&gt;&amp;)|(?P&lt;t_CPP_COMMA&gt;,)|(?P&lt;t_CPP_TILDE&gt;~)|(?P&lt;t_CPP_SEMICOLON&gt;;)|(?P&lt;t_CPP_PERCENT&gt;%)&#39;, [None, (&#39;t_CPP_WS&#39;, &#39;CPP_WS&#39;), None, (&#39;t_CPP_LINECONT&#39;, &#39;CPP_LINECONT&#39;), (&#39;t_CPP_INTEGER&#39;, &#39;CPP_INTEGER&#39;), None, None, None, None, None, None, None, None, (&#39;t_CPP_STRING&#39;, &#39;CPP_STRING&#39;), None, None, None, (&#39;t_CPP_CHAR&#39;, &#39;CPP_CHAR&#39;), None, None, None, None, (&#39;t_CPP_COMMENT1&#39;, &#39;CPP_COMMENT1&#39;), None, None, (&#39;t_CPP_COMMENT2&#39;, &#39;CPP_COMMENT2&#39;), None, (None, &#39;CPP_FLOAT&#39;), None, None, None, None, None, None, None, None, None, None, (None, &#39;CPP_ID&#39;), (None, &#39;CPP_LOGICALOR&#39;), (None, &#39;CPP_PLUSPLUS&#39;), (None, &#39;CPP_DPOUND&#39;), (None, &#39;CPP_LSHIFTEQUAL&#39;), (None, &#39;CPP_OREQUAL&#39;), (None, &#39;CPP_PLUSEQUAL&#39;), (None, &#39;CPP_RSHIFTEQUAL&#39;), (None, &#39;CPP_MULTIPLYEQUAL&#39;), (None, &#39;CPP_BAR&#39;), (None, &#39;CPP_DIVIDEEQUAL&#39;), (None, &#39;CPP_POUND&#39;), (None, &#39;CPP_PERCENTEQUAL&#39;), (None, &#39;CPP_DEREFERENCE&#39;), (None, &#39;CPP_RPAREN&#39;), (None, &#39;CPP_ANDEQUAL&#39;), (None, &#39;CPP_RBRACKET&#39;), (None, &#39;CPP_LPAREN&#39;), (None, &#39;CPP_RSHIFT&#39;), (None, &#39;CPP_LESSEQUAL&#39;), (None, &#39;CPP_HAT&#39;), (None, &#39;CPP_LOGICALAND&#39;), (None, &#39;CPP_EQUALITY&#39;), (None, &#39;CPP_GREATEREQUAL&#39;), (None, &#39;CPP_BSLASH&#39;), (None, &#39;CPP_MINUSEQUAL&#39;), (None, &#39;CPP_DOT&#39;), (None, &#39;CPP_MINUSMINUS&#39;), (None, &#39;CPP_LBRACKET&#39;), (None, &#39;CPP_PLUS&#39;), (None, &#39;CPP_XOREQUAL&#39;), (None, &#39;CPP_STAR&#39;), (None, &#39;CPP_QUESTION&#39;), (None, &#39;CPP_LSHIFT&#39;), (None, &#39;CPP_INEQUALITY&#39;), (None, &#39;CPP_DQUOTE&#39;), (None, &#39;CPP_MINUS&#39;), (None, &#39;CPP_RCURLY&#39;), (None, &#39;CPP_GREATER&#39;), (None, &#39;CPP_LESS&#39;), (None, &#39;CPP_SQUOTE&#39;), (None, &#39;CPP_EXCLAMATION&#39;), (None, &#39;CPP_LCURLY&#39;), (None, &#39;CPP_EQUAL&#39;), (None, &#39;CPP_FSLASH&#39;), (None, &#39;CPP_COLON&#39;), (None, &#39;CPP_AMPERSAND&#39;), (None, &#39;CPP_COMMA&#39;), (None, &#39;CPP_TILDE&#39;), (None, &#39;CPP_SEMICOLON&#39;), (None, &#39;CPP_PERCENT&#39;)])]}
_lexstateignore = {&#39;INITIAL&#39;: &#39;&#39;}
_lexstateerrorf = {&#39;INITIAL&#39;: &#39;t_error&#39;}
_lexstateeoff = {}</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="pcpp" href="index.html">pcpp</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.5.3</a>.</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad()</script>
</body>
</html>

================================================
FILE: doc/parser.html
================================================
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
    <meta name="generator" content="pdoc 0.5.3" />
    <title>pcpp.parser API documentation</title>
    <meta name="description" content="" />
    <link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
    <link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
    <style>
        .flex {
            display: flex !important
        }

        body {
            line-height: 1.5em
        }

        #content {
            padding: 20px
        }

        #sidebar {
            padding: 30px;
            overflow: hidden
        }

        .http-server-breadcrumbs {
            font-size: 130%;
            margin: 0 0 15px 0
        }

        #footer {
            font-size: .75em;
            padding: 5px 30px;
            border-top: 1px solid #ddd;
            text-align: right
        }

        #footer p {
            margin: 0 0 0 1em;
            display: inline-block
        }

        #footer p:last-child {
            margin-right: 30px
        }

        h1,
        h2,
        h3,
        h4,
        h5 {
            font-weight: 300
        }

        h1 {
            font-size: 2.5em;
            line-height: 1.1em
        }

        h2 {
            font-size: 1.75em;
            margin: 1em 0 .50em 0
        }

        h3 {
            font-size: 1.4em;
            margin: 25px 0 10px 0
        }

        h4 {
            margin: 0;
            font-size: 105%
        }

        a {
            color: #058;
            text-decoration: none;
            transition: color .3s ease-in-out
        }

        a:hover {
            color: #e82
        }

        .title code {
            font-weight: bold
        }

        h2[id^="header-"] {
            margin-top: 2em
        }

        .ident {
            color: #900
        }

        pre code {
            background: #f8f8f8;
            font-size: .8em;
            line-height: 1.4em
        }

        code {
            background: #f2f2f1;
            padding: 1px 4px;
            overflow-wrap: break-word
        }

        h1 code {
            background: transparent
        }

        pre {
            background: #f8f8f8;
            border: 0;
            border-top: 1px solid #ccc;
            border-bottom: 1px solid #ccc;
            margin: 1em 0;
            padding: 1ex
        }

        #http-server-module-list {
            display: flex;
            flex-flow: column
        }

        #http-server-module-list div {
            display: flex
        }

        #http-server-module-list dt {
            min-width: 10%
        }

        #http-server-module-list p {
            margin-top: 0
        }

        .toc ul,
        #index {
            list-style-type: none;
            margin: 0;
            padding: 0
        }

        #index code {
            background: transparent
        }

        #index h3 {
            border-bottom: 1px solid #ddd
        }

        #index ul {
            padding: 0
        }

        #index h4 {
            font-weight: bold
        }

        #index h4+ul {
            margin-bottom: .6em
        }

        @media (min-width:200ex) {
            #index .two-column {
                column-count: 2
            }
        }

        @media (min-width:300ex) {
            #index .two-column {
                column-count: 3
            }
        }

        dl {
            margin-bottom: 2em
        }

        dl dl:last-child {
            margin-bottom: 4em
        }

        dd {
            margin: 0 0 1em 3em
        }

        #header-classes+dl>dd {
            margin-bottom: 3em
        }

        dd dd {
            margin-left: 2em
        }

        dd p {
            margin: 10px 0
        }

        .name {
            background: #eee;
            font-weight: bold;
            font-size: .85em;
            padding: 5px 10px;
            display: inline-block;
            min-width: 40%
        }

        .name:hover {
            background: #e0e0e0
        }

        .name>span:first-child {
            white-space: nowrap
        }

        .name.class>span:nth-child(2) {
            margin-left: .4em
        }

        .name small {
            font-weight: normal
        }

        .inherited {
            color: #999;
            border-left: 5px solid #eee;
            padding-left: 1em
        }

        .inheritance em {
            font-style: normal;
            font-weight: bold
        }

        .desc h2 {
            font-weight: 400;
            font-size: 1.25em
        }

        .desc h3 {
            font-size: 1em
        }

        .desc dt code {
            background: inherit
        }

        .source summary {
            color: #666;
            text-align: right;
            font-weight: 400;
            font-size: .8em;
            text-transform: uppercase;
            cursor: pointer
        }

        .source pre {
            max-height: 500px;
            overflow: auto;
            margin: 0
        }

        .source pre code {
            font-size: 12px;
            overflow: visible
        }

        .hlist {
            list-style: none
        }

        .hlist li {
            display: inline
        }

        .hlist li:after {
            content: ',\2002'
        }

        .hlist li:last-child:after {
            content: none
        }

        .hlist .hlist {
            display: inline;
            padding-left: 1em
        }

        img {
            max-width: 100%
        }

        .admonition {
            padding: .1em .5em
        }

        .admonition-title {
            font-weight: bold
        }

        .admonition.note,
        .admonition.info,
        .admonition.important {
            background: #aef
        }

        .admonition.todo,
        .admonition.versionadded,
        .admonition.tip,
        .admonition.hint {
            background: #dfd
        }

        .admonition.warning,
        .admonition.versionchanged,
        .admonition.deprecated {
            background: #fd4
        }

        .admonition.error,
        .admonition.danger,
        .admonition.caution {
            background: lightpink
        }
    </style>
    <style media="screen and (min-width: 700px)">
        @media screen and (min-width:700px) {
            #sidebar {
                width: 30%
            }

            #content {
                width: 70%;
                max-width: 100ch;
                padding: 3em 4em;
                border-left: 1px solid #ddd
            }

            pre code {
                font-size: 1em
            }

            .item .name {
                font-size: 1em
            }

            main {
                display: flex;
                flex-direction: row-reverse;
                justify-content: flex-end
            }

            .toc ul ul,
            #index ul {
                padding-left: 1.5em
            }

            .toc>ul>li {
                margin-top: .5em
            }
        }
    </style>
    <style media="print">
        @media print {
            #sidebar h1 {
                page-break-before: always
            }

            .source {
                display: none
            }
        }

        @media print {
            * {
                background: transparent !important;
                color: #000 !important;
                box-shadow: none !important;
                text-shadow: none !important
            }

            a[href]:after {
                content: " (" attr(href) ")";
                font-size: 90%
            }

            a[href][title]:after {
                content: none
            }

            abbr[title]:after {
                content: " (" attr(title) ")"
            }

            .ir a:after,
            a[href^="javascript:"]:after,
            a[href^="#"]:after {
                content: ""
            }

            pre,
            blockquote {
                border: 1px solid #999;
                page-break-inside: avoid
            }

            thead {
                display: table-header-group
            }

            tr,
            img {
                page-break-inside: avoid
            }

            img {
                max-width: 100% !important
            }

            @page {
                margin: 0.5cm
            }

            p,
            h2,
            h3 {
                orphans: 3;
                widows: 3
            }

            h1,
            h2,
            h3,
            h4,
            h5,
            h6 {
                page-break-after: avoid
            }
        }
    </style>
</head>

<body>
    <main>
        <article id="content">
            <header>
                <h1 class="title"><code>pcpp.parser</code> module</h1>
            </header>
            <section id="section-intro">
                <details class="source">
                    <summary>Source code</summary>
                    <pre><code class="python">#!/usr/bin/python
# Python C99 conforming preprocessor parser config
# (C) 2017-2026 Niall Douglas http://www.nedproductions.biz/
# and (C) 2007-2017 David Beazley http://www.dabeaz.com/
# Started: Feb 2017
#
# This C preprocessor was originally written by David Beazley and the
# original can be found at https://github.com/dabeaz/ply/blob/master/ply/cpp.py
# This edition substantially improves on standards conforming output,
# getting quite close to what clang or GCC outputs.

from __future__ import generators, print_function, absolute_import, division

import sys, re, os

in_production = 1  # Set to 0 if editing pcpp implementation!

# Some Python 3 compatibility shims
if sys.version_info.major &lt; 3:
    STRING_TYPES = (str, unicode)
else:
    STRING_TYPES = str

# -----------------------------------------------------------------------------
# Default preprocessor lexer definitions.   These tokens are enough to get
# a basic preprocessor working.   Other modules may import these if they want
# -----------------------------------------------------------------------------

tokens = (
   &#39;CPP_ID&#39;,&#39;CPP_INTEGER&#39;, &#39;CPP_FLOAT&#39;, &#39;CPP_STRING&#39;, &#39;CPP_CHAR&#39;, &#39;CPP_WS&#39;, &#39;CPP_LINECONT&#39;, &#39;CPP_COMMENT1&#39;, &#39;CPP_COMMENT2&#39;,
   &#39;CPP_POUND&#39;,&#39;CPP_DPOUND&#39;, &#39;CPP_PLUS&#39;, &#39;CPP_MINUS&#39;, &#39;CPP_STAR&#39;, &#39;CPP_FSLASH&#39;, &#39;CPP_PERCENT&#39;, &#39;CPP_BAR&#39;,
   &#39;CPP_AMPERSAND&#39;, &#39;CPP_TILDE&#39;, &#39;CPP_HAT&#39;, &#39;CPP_LESS&#39;, &#39;CPP_GREATER&#39;, &#39;CPP_EQUAL&#39;, &#39;CPP_EXCLAMATION&#39;,
   &#39;CPP_QUESTION&#39;, &#39;CPP_LPAREN&#39;, &#39;CPP_RPAREN&#39;, &#39;CPP_LBRACKET&#39;, &#39;CPP_RBRACKET&#39;, &#39;CPP_LCURLY&#39;, &#39;CPP_RCURLY&#39;,
   &#39;CPP_DOT&#39;, &#39;CPP_COMMA&#39;, &#39;CPP_SEMICOLON&#39;, &#39;CPP_COLON&#39;, &#39;CPP_BSLASH&#39;, &#39;CPP_SQUOTE&#39;, &#39;CPP_DQUOTE&#39;,

   &#39;CPP_DEREFERENCE&#39;, &#39;CPP_MINUSEQUAL&#39;, &#39;CPP_MINUSMINUS&#39;, &#39;CPP_LSHIFT&#39;, &#39;CPP_LESSEQUAL&#39;, &#39;CPP_RSHIFT&#39;,
   &#39;CPP_GREATEREQUAL&#39;, &#39;CPP_LOGICALOR&#39;, &#39;CPP_OREQUAL&#39;, &#39;CPP_LOGICALAND&#39;, &#39;CPP_ANDEQUAL&#39;, &#39;CPP_EQUALITY&#39;,
   &#39;CPP_INEQUALITY&#39;, &#39;CPP_XOREQUAL&#39;, &#39;CPP_MULTIPLYEQUAL&#39;, &#39;CPP_DIVIDEEQUAL&#39;, &#39;CPP_PLUSEQUAL&#39;, &#39;CPP_PLUSPLUS&#39;,
   &#39;CPP_PERCENTEQUAL&#39;, &#39;CPP_LSHIFTEQUAL&#39;, &#39;CPP_RSHIFTEQUAL&#39;
)

literals = &#34;+-*/%|&amp;~^&lt;&gt;=!?()[]{}.,;:\\\&#39;\&#34;&#34;

# Whitespace, but don&#39;t match past the end of a line
def t_CPP_WS(t):
    r&#39;([ \t]+|\n)&#39;
    t.lexer.lineno += t.value.count(&#34;\n&#34;)
    return t

# Line continuation, accept whitespace between the backslash and new line
def t_CPP_LINECONT(t):
    r&#39;\\[ \t]*\n&#39;
    t.value = t.value[1:-1]
    t.lexer.lineno += 1
    return t
_string_literal_linecont_pat = re.compile(r&#39;\\[ \t]*\n&#39;)

t_CPP_POUND = r&#39;\#&#39;
t_CPP_DPOUND = r&#39;\#\#&#39;
t_CPP_PLUS = r&#39;\+&#39;
t_CPP_MINUS = r&#39;-&#39;
t_CPP_STAR = r&#39;\*&#39;
t_CPP_FSLASH = r&#39;/&#39;
t_CPP_PERCENT = r&#39;%&#39;
t_CPP_BAR = r&#39;\|&#39;
t_CPP_AMPERSAND = r&#39;&amp;&#39;
t_CPP_TILDE = r&#39;~&#39;
t_CPP_HAT = r&#39;\^&#39;
t_CPP_LESS = r&#39;&lt;&#39;
t_CPP_GREATER = r&#39;&gt;&#39;
t_CPP_EQUAL = r&#39;=&#39;
t_CPP_EXCLAMATION = r&#39;!&#39;
t_CPP_QUESTION = r&#39;\?&#39;
t_CPP_LPAREN = r&#39;\(&#39;
t_CPP_RPAREN = r&#39;\)&#39;
t_CPP_LBRACKET = r&#39;\[&#39;
t_CPP_RBRACKET = r&#39;\]&#39;
t_CPP_LCURLY = r&#39;{&#39;
t_CPP_RCURLY = r&#39;}&#39;
t_CPP_DOT = r&#39;\.&#39;
t_CPP_COMMA = r&#39;,&#39;
t_CPP_SEMICOLON = r&#39;;&#39;
t_CPP_COLON = r&#39;:&#39;
t_CPP_BSLASH = r&#39;\\&#39;
t_CPP_SQUOTE = r&#34;&#39;&#34;
t_CPP_DQUOTE = r&#39;&#34;&#39;

t_CPP_DEREFERENCE = r&#39;-&gt;&#39;
t_CPP_MINUSEQUAL = r&#39;-=&#39;
t_CPP_MINUSMINUS = r&#39;--&#39;
t_CPP_LSHIFT = r&#39;&lt;&lt;&#39;
t_CPP_LESSEQUAL = r&#39;&lt;=&#39;
t_CPP_RSHIFT = r&#39;&gt;&gt;&#39;
t_CPP_GREATEREQUAL = r&#39;&gt;=&#39;
t_CPP_LOGICALOR = r&#39;\|\|&#39;
t_CPP_OREQUAL = r&#39;\|=&#39;
t_CPP_LOGICALAND = r&#39;&amp;&amp;&#39;
t_CPP_ANDEQUAL = r&#39;&amp;=&#39;
t_CPP_EQUALITY = r&#39;==&#39;
t_CPP_INEQUALITY = r&#39;!=&#39;
t_CPP_XOREQUAL = r&#39;^=&#39;
t_CPP_MULTIPLYEQUAL = r&#39;\*=&#39;
t_CPP_DIVIDEEQUAL = r&#39;/=&#39;
t_CPP_PLUSEQUAL = r&#39;\+=&#39;
t_CPP_PLUSPLUS = r&#39;\+\+&#39;
t_CPP_PERCENTEQUAL = r&#39;%=&#39;
t_CPP_LSHIFTEQUAL = r&#39;&lt;&lt;=&#39;
t_CPP_RSHIFTEQUAL = r&#39;&gt;&gt;=&#39;


# Identifier
t_CPP_ID = r&#39;[A-Za-z_][\w_]*&#39;

# Integer literal
def CPP_INTEGER(t):
    r&#39;(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)&#39;
    return t

t_CPP_INTEGER = CPP_INTEGER

# Floating literal
t_CPP_FLOAT = r&#39;((\d+)(\.\d+)(e(\+|-)?(\d+))?|(\d+)e(\+|-)?(\d+))([lL]|[fF])?&#39;

# String literal
def t_CPP_STRING(t):
    r&#39;\&#34;([^\\\n]|(\\(.|\n)))*?\&#34;&#39;
    t.value, subs_made = _string_literal_linecont_pat.subn(&#39;&#39;, t.value)
    t.lexer.lineno += subs_made + t.value.count(&#34;\n&#34;)
    return t

# Character constant &#39;c&#39; or L&#39;c&#39;
def t_CPP_CHAR(t):
    r&#39;(L)?\&#39;([^\\\n]|(\\(.|\n)))*?\&#39;&#39;
    t.lexer.lineno += t.value.count(&#34;\n&#34;)
    return t

# Comment
def t_CPP_COMMENT1(t):
    r&#39;(/\*(.|\n)*?\*/)&#39;
    ncr = t.value.count(&#34;\n&#34;)
    t.lexer.lineno += ncr
    return t

# Line comment
def t_CPP_COMMENT2(t):
    r&#39;(//[^\n]*)&#39;
    return t
    
def t_error(t):
    t.type = t.value[0]
    t.value = t.value[0]
    t.lexer.skip(1)
    return t


# Python 2/3 compatible way of importing a subpackage
oldsyspath = sys.path
sys.path = [ os.path.join( os.path.dirname( os.path.abspath(__file__) ), &#34;ply&#34; ) ] + sys.path
from ply import lex, yacc
from ply.lex import LexToken
sys.path = oldsyspath
del oldsyspath

# -----------------------------------------------------------------------------
# trigraph()
# 
# Given an input string, this function replaces all trigraph sequences. 
# The following mapping is used:
#
#     ??=    #
#     ??/    \
#     ??&#39;    ^
#     ??(    [
#     ??)    ]
#     ??!    |
#     ??&lt;    {
#     ??&gt;    }
#     ??-    ~
# -----------------------------------------------------------------------------

_trigraph_pat = re.compile(r&#39;&#39;&#39;\?\?[=/\&#39;\(\)\!&lt;&gt;\-]&#39;&#39;&#39;)
_trigraph_rep = {
    &#39;=&#39;:&#39;#&#39;,
    &#39;/&#39;:&#39;\\&#39;,
    &#34;&#39;&#34;:&#39;^&#39;,
    &#39;(&#39;:&#39;[&#39;,
    &#39;)&#39;:&#39;]&#39;,
    &#39;!&#39;:&#39;|&#39;,
    &#39;&lt;&#39;:&#39;{&#39;,
    &#39;&gt;&#39;:&#39;}&#39;,
    &#39;-&#39;:&#39;~&#39;
}

def trigraph(input):
    return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input)

def default_lexer():
    return lex.lex(optimize=in_production)

# ------------------------------------------------------------------
# Macro object
#
# This object holds information about preprocessor macros
#
#    .name      - Macro name (string)
#    .value     - Macro value (a list of tokens)
#    .arglist   - List of argument names
#    .variadic  - Boolean indicating whether or not variadic macro
#    .vararg    - Name of the variadic parameter
#
# When a macro is created, the macro replacement token sequence is
# pre-scanned and used to create patch lists that are later used
# during macro expansion
# ------------------------------------------------------------------

class Macro(object):
    def __init__(self,name,value,arglist=None,variadic=False):
        self.name = name
        self.value = value
        self.arglist = arglist
        self.variadic = variadic
        if variadic:
            self.vararg = arglist[-1]
        self.source = None
        self.lineno = None
    def __repr__(self):
        return &#34;%s(%s)=%s&#34; % (self.name, self.arglist, self.value)

# ------------------------------------------------------------------
# Preprocessor event hooks
#
# Override these to customise preprocessing
# ------------------------------------------------------------------

class Action(object):
    &#34;&#34;&#34;What kind of abort processing to do in OutputDirective&#34;&#34;&#34;
    IgnoreAndPassThrough = 0
    &#34;&#34;&#34;Abort processing (don&#39;t execute), but pass the directive through to output&#34;&#34;&#34;
    IgnoreAndRemove = 1
    &#34;&#34;&#34;Abort processing (don&#39;t execute), and remove from output&#34;&#34;&#34;

class OutputDirective(Exception):
    &#34;&#34;&#34;Raise this exception to abort processing of a preprocessor directive and
    to instead output it as is into the output&#34;&#34;&#34;
    def __init__(self, action):
        self.action = action

class PreprocessorHooks(object):
    &#34;&#34;&#34;Override these in your subclass of Preprocessor to customise preprocessing&#34;&#34;&#34;
    def __init__(self):
        self.lastdirective = None

    def on_error(self,file,line,msg):
        &#34;&#34;&#34;Called when the preprocessor has encountered an error, e.g. malformed input.
        
        The default simply prints to stderr and increments the return code.
        &#34;&#34;&#34;
        print(&#34;%s:%d error: %s&#34; % (file,line,msg), file = sys.stderr)
        self.return_code += 1
        
    def on_file_open(self,is_system_include,includepath):
        &#34;&#34;&#34;Called to open a file for reading.
        
        This hook provides the ability to use ``chardet``, or any other mechanism,
        to inspect a file for its text encoding, and open it appropriately. Be
        aware that this function is used to probe for possible include file locations,
        so ``includepath`` may not exist. If it does not, raise the appropriate
        ``IOError`` exception.
        
        The default calls ``io.open(includepath, &#39;r&#39;, encoding = self.assume_encoding)``,
        examines if it starts with a BOM (if so, it removes it), and returns the file
        object opened. This raises the appropriate exception if the path was not found.
        &#34;&#34;&#34;
        if sys.version_info.major &lt; 3:
            assert self.assume_encoding is None
            ret = open(includepath, &#39;r&#39;)
        else:
            ret = open(includepath, &#39;r&#39;, encoding = self.assume_encoding)
        bom = ret.read(1)
        #print(repr(bom))
        if bom != &#39;\ufeff&#39;:
            ret.seek(0)
        return ret

    def on_include_not_found(self,is_malformed,is_system_include,curdir,includepath):
        &#34;&#34;&#34;Called when a #include wasn&#39;t found.
        
        Raise OutputDirective to pass through or remove, else return
        a suitable path. Remember that Preprocessor.add_path() lets you add search paths.
        
        The default calls ``self.on_error()`` with a suitable error message about the
        include file not found if ``is_malformed`` is False, else a suitable error
        message about a malformed #include, and in both cases raises OutputDirective
        (pass through).
        &#34;&#34;&#34;
        if is_malformed:
            self.on_error(self.lastdirective.source,self.lastdirective.lineno, &#34;Malformed #include statement: %s&#34; % includepath)
        else:
            self.on_error(self.lastdirective.source,self.lastdirective.lineno, &#34;Include file &#39;%s&#39; not found&#34; % includepath)
        raise OutputDirective(Action.IgnoreAndPassThrough)
        
    def on_unknown_macro_in_defined_expr(self,tok):
        &#34;&#34;&#34;Called when an expression passed to an #if contained a defined operator
        performed on something unknown.
        
        Return True if to treat it as defined, False if to treat it as undefined,
        raise OutputDirective to pass through without execution, or return None to
        pass through the mostly expanded #if expression apart from the unknown defined.
        
        The default returns False, as per the C standard.
        &#34;&#34;&#34;
        return False

    def on_unknown_macro_in_expr(self,ident):
        &#34;&#34;&#34;Called when an expression passed to an #if contained an unknown identifier.
        
        Return what value the expression evaluator ought to use, or return None to
        pass through the mostly expanded #if expression.
        
        The default returns an integer 0, as per the C standard.
        &#34;&#34;&#34;
        return 0
    
    def on_unknown_macro_function_in_expr(self,ident):
        &#34;&#34;&#34;Called when an expression passed to an #if contained an unknown function.
        
        Return a callable which will be invoked by the expression evaluator to
        evaluate the input to the function, or return None to pass through the
        mostly expanded #if expression.
        
        The default returns a lambda which returns integer 0, as per the C standard.
        &#34;&#34;&#34;
        return lambda x : 0
    
    def on_directive_handle(self,directive,toks,ifpassthru,precedingtoks):
        &#34;&#34;&#34;Called when there is one of
        
        define, include, undef, ifdef, ifndef, if, elif, else, endif
        
        Return True to execute and remove from the output, raise OutputDirective
        to pass through or remove without execution, or return None to execute
        AND pass through to the output (this only works for #define, #undef).
        
        The default returns True (execute and remove from the output).

        directive is the directive, toks is the tokens after the directive,
        ifpassthru is whether we are in passthru mode, precedingtoks is the
        tokens preceding the directive from the # token until the directive.
        &#34;&#34;&#34;
        self.lastdirective = directive
        return True
        
    def on_directive_unknown(self,directive,toks,ifpassthru,precedingtoks):
        &#34;&#34;&#34;Called when the preprocessor encounters a #directive it doesn&#39;t understand.
        This is actually quite an extensive list as it currently only understands:
        
        define, include, undef, ifdef, ifndef, if, elif, else, endif
        
        Return True to remove from the output, raise OutputDirective
        to pass through or remove, or return None to
        pass through into the output.
        
        The default handles #error and #warning by printing to stderr and returning True
        (remove from output). For everything else it returns None (pass through into output).

        directive is the directive, toks is the tokens after the directive,
        ifpassthru is whether we are in passthru mode, precedingtoks is the
        tokens preceding the directive from the # token until the directive.
        &#34;&#34;&#34;
        if directive.value == &#39;error&#39;:
            print(&#34;%s:%d error: %s&#34; % (directive.source,directive.lineno,&#39;&#39;.join(tok.value for tok in toks)), file = sys.stderr)
            self.return_code += 1
            return True
        elif directive.value == &#39;warning&#39;:
            print(&#34;%s:%d warning: %s&#34; % (directive.source,directive.lineno,&#39;&#39;.join(tok.value for tok in toks)), file = sys.stderr)
            return True
        return None
        
    def on_potential_include_guard(self,macro):
        &#34;&#34;&#34;Called when the preprocessor encounters an #ifndef macro or an #if !defined(macro)
        as the first non-whitespace thing in a file. Unlike the other hooks, macro is a string,
        not a token.
        &#34;&#34;&#34;
        pass
    
    def on_comment(self,tok):
        &#34;&#34;&#34;Called when the preprocessor encounters a comment token. You can modify the token
        in place. You must return True to let the comment pass through, else it will be removed.
        
        Returning False or None modifies the token to become whitespace, becoming a single space
        if the comment is a block comment, else a single new line if the comment is a line comment.
        &#34;&#34;&#34;
        return None</code></pre>
                </details>
            </section>
            <section>
            </section>
            <section>
            </section>
            <section>
                <h2 class="section-title" id="header-functions">Functions</h2>
                <dl>
                    <dt id="pcpp.parser.CPP_INTEGER"><code class="name flex">
<span>def <span class="ident">CPP_INTEGER</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def CPP_INTEGER(t):
    r&#39;(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)&#39;
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.default_lexer"><code class="name flex">
<span>def <span class="ident">default_lexer</span></span>(<span>)</span>
</code></dt>
                    <dd>
                        <section class="desc"></section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def default_lexer():
    return lex.lex(optimize=in_production)</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_CHAR"><code class="name flex">
<span>def <span class="ident">t_CPP_CHAR</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>(L)?'([^\\n]|(\(.|\n)))*?'</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_CHAR(t):
    r&#39;(L)?\&#39;([^\\\n]|(\\(.|\n)))*?\&#39;&#39;
    t.lexer.lineno += t.value.count(&#34;\n&#34;)
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_COMMENT1"><code class="name flex">
<span>def <span class="ident">t_CPP_COMMENT1</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>(/*(.|\n)*?*/)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_COMMENT1(t):
    r&#39;(/\*(.|\n)*?\*/)&#39;
    ncr = t.value.count(&#34;\n&#34;)
    t.lexer.lineno += ncr
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_COMMENT2"><code class="name flex">
<span>def <span class="ident">t_CPP_COMMENT2</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>(//[^\n]*)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_COMMENT2(t):
    r&#39;(//[^\n]*)&#39;
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_INTEGER"><code class="name flex">
<span>def <span class="ident">t_CPP_INTEGER</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def CPP_INTEGER(t):
    r&#39;(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)&#39;
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_LINECONT"><code class="name flex">
<span>def <span class="ident">t_CPP_LINECONT</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>\[ \t]*\n</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_LINECONT(t):
    r&#39;\\[ \t]*\n&#39;
    t.value = t.value[1:-1]
    t.lexer.lineno += 1
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_STRING"><code class="name flex">
<span>def <span class="ident">t_CPP_STRING</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>"([^\\n]|(\(.|\n)))*?"</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_STRING(t):
    r&#39;\&#34;([^\\\n]|(\\(.|\n)))*?\&#34;&#39;
    t.value, subs_made = _string_literal_linecont_pat.subn(&#39;&#39;, t.value)
    t.lexer.lineno += subs_made + t.value.count(&#34;\n&#34;)
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_CPP_WS"><code class="name flex">
<span>def <span class="ident">t_CPP_WS</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>([ \t]+|\n)</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_CPP_WS(t):
    r&#39;([ \t]+|\n)&#39;
    t.lexer.lineno += t.value.count(&#34;\n&#34;)
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.t_error"><code class="name flex">
<span>def <span class="ident">t_error</span></span>(<span>t)</span>
</code></dt>
                    <dd>
                        <section class="desc"></section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def t_error(t):
    t.type = t.value[0]
    t.value = t.value[0]
    t.lexer.skip(1)
    return t</code></pre>
                        </details>
                    </dd>
                    <dt id="pcpp.parser.trigraph"><code class="name flex">
<span>def <span class="ident">trigraph</span></span>(<span>input)</span>
</code></dt>
                    <dd>
                        <section class="desc"></section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">def trigraph(input):
    return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input)</code></pre>
                        </details>
                    </dd>
                </dl>
            </section>
            <section>
                <h2 class="section-title" id="header-classes">Classes</h2>
                <dl>
                    <dt id="pcpp.parser.Action"><code class="flex name class">
<span>class <span class="ident">Action</span></span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>What kind of abort processing to do in OutputDirective</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class Action(object):
    &#34;&#34;&#34;What kind of abort processing to do in OutputDirective&#34;&#34;&#34;
    IgnoreAndPassThrough = 0
    &#34;&#34;&#34;Abort processing (don&#39;t execute), but pass the directive through to output&#34;&#34;&#34;
    IgnoreAndRemove = 1
    &#34;&#34;&#34;Abort processing (don&#39;t execute), and remove from output&#34;&#34;&#34;</code></pre>
                        </details>
                        <h3>Class variables</h3>
                        <dl>
                            <dt id="pcpp.parser.Action.IgnoreAndPassThrough"><code
                                    class="name">var <span class="ident">IgnoreAndPassThrough</span></code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Abort processing (don't execute), but pass the directive through to output</p>
                                </section>
                            </dd>
                            <dt id="pcpp.parser.Action.IgnoreAndRemove"><code
                                    class="name">var <span class="ident">IgnoreAndRemove</span></code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Abort processing (don't execute), and remove from output</p>
                                </section>
                            </dd>
                        </dl>
                    </dd>
                    <dt id="pcpp.parser.Macro"><code class="flex name class">
<span>class <span class="ident">Macro</span></span>
</code></dt>
                    <dd>
                        <section class="desc"></section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class Macro(object):
    def __init__(self,name,value,arglist=None,variadic=False):
        self.name = name
        self.value = value
        self.arglist = arglist
        self.variadic = variadic
        if variadic:
            self.vararg = arglist[-1]
        self.source = None
        self.lineno = None
    def __repr__(self):
        return &#34;%s(%s)=%s&#34; % (self.name, self.arglist, self.value)</code></pre>
                        </details>
                        <h3>Methods</h3>
                        <dl>
                            <dt id="pcpp.parser.Macro.__init__"><code class="name flex">
<span>def <span class="ident">__init__</span></span>(<span>self, name, value, arglist=None, variadic=False)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Initialize self.
                                        See help(type(self)) for accurate signature.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def __init__(self,name,value,arglist=None,variadic=False):
    self.name = name
    self.value = value
    self.arglist = arglist
    self.variadic = variadic
    if variadic:
        self.vararg = arglist[-1]
    self.source = None
    self.lineno = None</code></pre>
                                </details>
                            </dd>
                        </dl>
                    </dd>
                    <dt id="pcpp.parser.OutputDirective"><code class="flex name class">
<span>class <span class="ident">OutputDirective</span></span>
<span>(</span><span><small>ancestors:</small> builtins.Exception, builtins.BaseException)</span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>Raise this exception to abort processing of a preprocessor directive and
                                to instead output it as is into the output</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class OutputDirective(Exception):
    &#34;&#34;&#34;Raise this exception to abort processing of a preprocessor directive and
    to instead output it as is into the output&#34;&#34;&#34;
    def __init__(self, action):
        self.action = action</code></pre>
                        </details>
                        <h3>Methods</h3>
                        <dl>
                            <dt id="pcpp.parser.OutputDirective.__init__"><code class="name flex">
<span>def <span class="ident">__init__</span></span>(<span>self, action)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Initialize self.
                                        See help(type(self)) for accurate signature.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def __init__(self, action):
    self.action = action</code></pre>
                                </details>
                            </dd>
                        </dl>
                    </dd>
                    <dt id="pcpp.parser.PreprocessorHooks"><code class="flex name class">
<span>class <span class="ident">PreprocessorHooks</span></span>
</code></dt>
                    <dd>
                        <section class="desc">
                            <p>Override these in your subclass of Preprocessor to customise preprocessing</p>
                        </section>
                        <details class="source">
                            <summary>Source code</summary>
                            <pre><code class="python">class PreprocessorHooks(object):
    &#34;&#34;&#34;Override these in your subclass of Preprocessor to customise preprocessing&#34;&#34;&#34;
    def __init__(self):
        self.lastdirective = None

    def on_error(self,file,line,msg):
        &#34;&#34;&#34;Called when the preprocessor has encountered an error, e.g. malformed input.
        
        The default simply prints to stderr and increments the return code.
        &#34;&#34;&#34;
        print(&#34;%s:%d error: %s&#34; % (file,line,msg), file = sys.stderr)
        self.return_code += 1
        
    def on_file_open(self,is_system_include,includepath):
        &#34;&#34;&#34;Called to open a file for reading.
        
        This hook provides the ability to use ``chardet``, or any other mechanism,
        to inspect a file for its text encoding, and open it appropriately. Be
        aware that this function is used to probe for possible include file locations,
        so ``includepath`` may not exist. If it does not, raise the appropriate
        ``IOError`` exception.
        
        The default calls ``io.open(includepath, &#39;r&#39;, encoding = self.assume_encoding)``,
        examines if it starts with a BOM (if so, it removes it), and returns the file
        object opened. This raises the appropriate exception if the path was not found.
        &#34;&#34;&#34;
        if sys.version_info.major &lt; 3:
            assert self.assume_encoding is None
            ret = open(includepath, &#39;r&#39;)
        else:
            ret = open(includepath, &#39;r&#39;, encoding = self.assume_encoding)
        bom = ret.read(1)
        #print(repr(bom))
        if bom != &#39;\ufeff&#39;:
            ret.seek(0)
        return ret

    def on_include_not_found(self,is_malformed,is_system_include,curdir,includepath):
        &#34;&#34;&#34;Called when a #include wasn&#39;t found.
        
        Raise OutputDirective to pass through or remove, else return
        a suitable path. Remember that Preprocessor.add_path() lets you add search paths.
        
        The default calls ``self.on_error()`` with a suitable error message about the
        include file not found if ``is_malformed`` is False, else a suitable error
        message about a malformed #include, and in both cases raises OutputDirective
        (pass through).
        &#34;&#34;&#34;
        if is_malformed:
            self.on_error(self.lastdirective.source,self.lastdirective.lineno, &#34;Malformed #include statement: %s&#34; % includepath)
        else:
            self.on_error(self.lastdirective.source,self.lastdirective.lineno, &#34;Include file &#39;%s&#39; not found&#34; % includepath)
        raise OutputDirective(Action.IgnoreAndPassThrough)
        
    def on_unknown_macro_in_defined_expr(self,tok):
        &#34;&#34;&#34;Called when an expression passed to an #if contained a defined operator
        performed on something unknown.
        
        Return True if to treat it as defined, False if to treat it as undefined,
        raise OutputDirective to pass through without execution, or return None to
        pass through the mostly expanded #if expression apart from the unknown defined.
        
        The default returns False, as per the C standard.
        &#34;&#34;&#34;
        return False

    def on_unknown_macro_in_expr(self,ident):
        &#34;&#34;&#34;Called when an expression passed to an #if contained an unknown identifier.
        
        Return what value the expression evaluator ought to use, or return None to
        pass through the mostly expanded #if expression.
        
        The default returns an integer 0, as per the C standard.
        &#34;&#34;&#34;
        return 0
    
    def on_unknown_macro_function_in_expr(self,ident):
        &#34;&#34;&#34;Called when an expression passed to an #if contained an unknown function.
        
        Return a callable which will be invoked by the expression evaluator to
        evaluate the input to the function, or return None to pass through the
        mostly expanded #if expression.
        
        The default returns a lambda which returns integer 0, as per the C standard.
        &#34;&#34;&#34;
        return lambda x : 0
    
    def on_directive_handle(self,directive,toks,ifpassthru,precedingtoks):
        &#34;&#34;&#34;Called when there is one of
        
        define, include, undef, ifdef, ifndef, if, elif, else, endif
        
        Return True to execute and remove from the output, raise OutputDirective
        to pass through or remove without execution, or return None to execute
        AND pass through to the output (this only works for #define, #undef).
        
        The default returns True (execute and remove from the output).

        directive is the directive, toks is the tokens after the directive,
        ifpassthru is whether we are in passthru mode, precedingtoks is the
        tokens preceding the directive from the # token until the directive.
        &#34;&#34;&#34;
        self.lastdirective = directive
        return True
        
    def on_directive_unknown(self,directive,toks,ifpassthru,precedingtoks):
        &#34;&#34;&#34;Called when the preprocessor encounters a #directive it doesn&#39;t understand.
        This is actually quite an extensive list as it currently only understands:
        
        define, include, undef, ifdef, ifndef, if, elif, else, endif
        
        Return True to remove from the output, raise OutputDirective
        to pass through or remove, or return None to
        pass through into the output.
        
        The default handles #error and #warning by printing to stderr and returning True
        (remove from output). For everything else it returns None (pass through into output).

        directive is the directive, toks is the tokens after the directive,
        ifpassthru is whether we are in passthru mode, precedingtoks is the
        tokens preceding the directive from the # token until the directive.
        &#34;&#34;&#34;
        if directive.value == &#39;error&#39;:
            print(&#34;%s:%d error: %s&#34; % (directive.source,directive.lineno,&#39;&#39;.join(tok.value for tok in toks)), file = sys.stderr)
            self.return_code += 1
            return True
        elif directive.value == &#39;warning&#39;:
            print(&#34;%s:%d warning: %s&#34; % (directive.source,directive.lineno,&#39;&#39;.join(tok.value for tok in toks)), file = sys.stderr)
            return True
        return None
        
    def on_potential_include_guard(self,macro):
        &#34;&#34;&#34;Called when the preprocessor encounters an #ifndef macro or an #if !defined(macro)
        as the first non-whitespace thing in a file. Unlike the other hooks, macro is a string,
        not a token.
        &#34;&#34;&#34;
        pass
    
    def on_comment(self,tok):
        &#34;&#34;&#34;Called when the preprocessor encounters a comment token. You can modify the token
        in place. You must return True to let the comment pass through, else it will be removed.
        
        Returning False or None modifies the token to become whitespace, becoming a single space
        if the comment is a block comment, else a single new line if the comment is a line comment.
        &#34;&#34;&#34;
        return None</code></pre>
                        </details>
                        <h3>Subclasses</h3>
                        <ul class="hlist">
                            <li><a title="pcpp.preprocessor.Preprocessor"
                                    href="preprocessor.html#pcpp.preprocessor.Preprocessor">Preprocessor</a></li>
                        </ul>
                        <h3>Methods</h3>
                        <dl>
                            <dt id="pcpp.parser.PreprocessorHooks.__init__"><code class="name flex">
<span>def <span class="ident">__init__</span></span>(<span>self)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Initialize self.
                                        See help(type(self)) for accurate signature.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def __init__(self):
    self.lastdirective = None</code></pre>
                                </details>
                            </dd>
                            <dt id="pcpp.parser.PreprocessorHooks.on_comment"><code class="name flex">
<span>def <span class="ident">on_comment</span></span>(<span>self, tok)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Called when the preprocessor encounters a comment token. You can modify the token
                                        in place. You must return True to let the comment pass through, else it will be
                                        removed.</p>
                                    <p>Returning False or None modifies the token to become whitespace, becoming a
                                        single space
                                        if the comment is a block comment, else a single new line if the comment is a
                                        line comment.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def on_comment(self,tok):
    &#34;&#34;&#34;Called when the preprocessor encounters a comment token. You can modify the token
    in place. You must return True to let the comment pass through, else it will be removed.
    
    Returning False or None modifies the token to become whitespace, becoming a single space
    if the comment is a block comment, else a single new line if the comment is a line comment.
    &#34;&#34;&#34;
    return None</code></pre>
                                </details>
                            </dd>
                            <dt id="pcpp.parser.PreprocessorHooks.on_directive_handle"><code class="name flex">
<span>def <span class="ident">on_directive_handle</span></span>(<span>self, directive, toks, ifpassthru, precedingtoks)</span>
</code></dt>
                            <dd>
                                <section class="desc">
                                    <p>Called when there is one of</p>
                                    <p>define, include, undef, ifdef, ifndef, if, elif, else, endif</p>
                                    <p>Return True to execute and remove from the output, raise OutputDirective
                                        to pass through or remove without execution, or return None to execute
                                        AND pass through to the output (this only works for #define, #undef).</p>
                                    <p>The default returns True (execute and remove from the output).</p>
                                    <p>directive is the directive, toks is the tokens after the directive,
                                        ifpassthru is whether we are in passthru mode, precedingtoks is the
                                        tokens preceding the directive from the # token until the directive.</p>
                                </section>
                                <details class="source">
                                    <summary>Source code</summary>
                                    <pre><code class="python">def on_directive_handle(self,directive,toks,ifpassthru,precedingtoks):
    &#34;&#34;&#34;Called when there is one of
    
    define, include, undef, ifdef, ifndef, if, elif, else, endif
    
    Return True to execute and remove from the output, raise OutputDirective
    to pass through or remove without execution, or return None to execute
    AND pass through to the output (this only works for #define, #undef).
    
    The default returns True (execute and remove from the output).

    directive is the directive, toks is the tokens after the directive,
    ifpassthru is whether we are in passthru mode, precedingtoks is the
    tokens preceding the directive from the # token until the directive.
    &#34;&#34;&#34;
    self.lastdirective = directive
    return True</code></pre>
                                </details>
                            </dd>
                            <dt id="pcpp.parser.PreprocessorHooks.on_directive_unknown"><code class="name flex">
<span>def <span class="ident">on_directive_
Download .txt
gitextract_sih0q66g/

├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .gitmodules
├── AGENTS.md
├── LICENSE.txt
├── README.rst
├── doc/
│   ├── evaluator.html
│   ├── index.html
│   ├── lextab.html
│   ├── parser.html
│   ├── parsetab.html
│   ├── pcmd.html
│   └── preprocessor.html
├── pcpp/
│   ├── __init__.py
│   ├── evaluator.py
│   ├── lextab.py
│   ├── parser.py
│   ├── parsetab.py
│   ├── pcmd.py
│   └── preprocessor.py
├── pyproject.toml
├── requirements.txt
├── setup.py
└── tests/
    ├── Readme.md
    ├── __init__.py
    ├── alternate_input_encodings.py
    ├── alternate_input_encodings1_ucs16le.c
    ├── alternate_input_encodings2_ucs16le.c
    ├── cstd.py
    ├── doctests.py
    ├── embedded.py
    ├── eval.py
    ├── issue0017/
    │   ├── inc.h
    │   └── issue0017.c
    ├── issue0017-ref.i
    ├── issue0017.py
    ├── issue0025/
    │   ├── inc.h
    │   └── main.c
    ├── issue0025-ref.i
    ├── issue0025.py
    ├── issue0027.py
    ├── issue0030/
    │   ├── source1.c
    │   ├── source2.c
    │   └── source3.c
    ├── issue0030.py
    ├── issue0032.py
    ├── issue0037/
    │   └── inc.h
    ├── issue0037.py
    ├── issue0044.h
    ├── issue0044.py
    ├── issue0051.c
    ├── issue0051.h
    ├── issue0051.py
    ├── issue0057.h
    ├── issue0057.py
    ├── issue0059.py
    ├── issue0059a.h
    ├── issue0059b.h
    ├── issue0063.c
    ├── issue0063.h
    ├── issue0063.py
    ├── issue0079.py
    ├── issue0098/
    │   ├── dir1/
    │   │   └── header.h
    │   ├── dir2/
    │   │   └── header.h
    │   ├── dir3/
    │   │   └── header.h
    │   └── dir4/
    │       └── header.h
    ├── issue0098.py
    ├── issue0103.py
    ├── n_std-clang.i
    ├── n_std-gcc.i
    ├── n_std-pcpp.i
    ├── n_std.i
    ├── n_std.py
    ├── passthru.py
    └── test-c/
        ├── LICENSE
        ├── defs.h
        ├── e_12_8.c
        ├── e_14.c
        ├── e_14_10.c
        ├── e_14_7.c
        ├── e_14_9.c
        ├── e_15_3.c
        ├── e_16.c
        ├── e_17.c
        ├── e_18_4.c
        ├── e_19_3.c
        ├── e_23_3.c
        ├── e_24_6.c
        ├── e_25_6.c
        ├── e_27_7.c
        ├── e_29_3.c
        ├── e_31.c
        ├── e_31_3.c
        ├── e_32_5.c
        ├── e_33_2.c
        ├── e_35_2.c
        ├── e_4_3.c
        ├── e_7_4.c
        ├── e_std.c
        ├── header.h
        ├── i_32_3.c
        ├── i_35.c
        ├── i_35_3.c
        ├── ifdef15.h
        ├── line.h
        ├── m1024.h
        ├── m_33_big5.c
        ├── m_33_eucjp.c
        ├── m_33_gb.c
        ├── m_33_jis.c
        ├── m_33_ksc.c
        ├── m_33_sjis.c
        ├── m_33_utf8.c
        ├── m_34_big5.c
        ├── m_34_eucjp.c
        ├── m_34_gb.c
        ├── m_34_jis.c
        ├── m_34_ksc.c
        ├── m_34_sjis.c
        ├── m_34_utf8.c
        ├── m_36_big5.c
        ├── m_36_jis.c
        ├── m_36_sjis.c
        ├── n_1.c
        ├── n_10.c
        ├── n_11.c
        ├── n_12.c
        ├── n_13.c
        ├── n_13_13.c
        ├── n_13_5.c
        ├── n_13_7.c
        ├── n_13_8.c
        ├── n_15.c
        ├── n_18.c
        ├── n_19.c
        ├── n_2.c
        ├── n_20.c
        ├── n_21.c
        ├── n_22.c
        ├── n_23.c
        ├── n_24.c
        ├── n_25.c
        ├── n_26.c
        ├── n_27.c
        ├── n_28.c
        ├── n_29.c
        ├── n_3.c
        ├── n_30.c
        ├── n_32.c
        ├── n_37.c
        ├── n_3_4.c
        ├── n_4.c
        ├── n_5.c
        ├── n_6.c
        ├── n_7.c
        ├── n_8.c
        ├── n_8_2.c
        ├── n_9.c
        ├── n_i_.lst
        ├── n_std.c
        ├── nest1.h
        ├── nest10.h
        ├── nest11.h
        ├── nest12.h
        ├── nest13.h
        ├── nest14.h
        ├── nest15.h
        ├── nest2.h
        ├── nest3.h
        ├── nest4.h
        ├── nest5.h
        ├── nest6.h
        ├── nest7.h
        ├── nest8.h
        ├── nest9.h
        ├── side_cpp
        ├── u_1_1.c
        ├── u_1_11.c
        ├── u_1_12.c
        ├── u_1_13.c
        ├── u_1_14.c
        ├── u_1_17.c
        ├── u_1_19.c
        ├── u_1_22.c
        ├── u_1_23.c
        ├── u_1_24.c
        ├── u_1_25.c
        ├── u_1_27.c
        ├── u_1_28.c
        ├── u_1_5.c
        ├── u_1_7_big5.c
        ├── u_1_7_eucjp.c
        ├── u_1_7_gb.c
        ├── u_1_7_jis.c
        ├── u_1_7_ksc.c
        ├── u_1_7_sjis.c
        ├── u_1_7_utf8.c
        ├── u_1_8.c
        ├── u_2.c
        ├── unbal1.h
        ├── unbal2.h
        ├── unbal3.h
        ├── unbal4.h
        ├── unbal5.h
        ├── unbal6.h
        ├── undefs.c
        ├── unspcs.c
        └── warns.c
Download .txt
SYMBOL INDEX (371 symbols across 125 files)

FILE: pcpp/evaluator.py
  class Value (line 28) | class Value(INTBASETYPE):
    method __sclamp (line 134) | def __sclamp(cls, value):
    method __uclamp (line 138) | def __uclamp(cls, value):
    method __new__ (line 141) | def __new__(cls, value, unsigned = False, exception = None):
    method value (line 193) | def value(self):
    method __add__ (line 197) | def __add__(self, other):
    method __sub__ (line 204) | def __sub__(self, other):
    method __mul__ (line 211) | def __mul__(self, other):
    method __div__ (line 218) | def __div__(self, other):
    method __truediv__ (line 225) | def __truediv__(self, other):
    method __mod__ (line 232) | def __mod__(self, other):
    method __neg__ (line 239) | def __neg__(self):
    method __invert__ (line 243) | def __invert__(self):
    method __and__ (line 247) | def __and__(self, other):
    method __or__ (line 254) | def __or__(self, other):
    method __pos__ (line 261) | def __pos__(self):
    method __pow__ (line 265) | def __pow__(self, other):
    method __lshift__ (line 272) | def __lshift__(self, other):
    method __rshift__ (line 280) | def __rshift__(self, other):
    method __xor__ (line 288) | def __xor__(self, other):
    method __repr__ (line 295) | def __repr__(self):
    method __bool__ (line 302) | def __bool__(self):
    method __cmp__ (line 304) | def __cmp__(self, other):
    method __lt__ (line 306) | def __lt__(self, other):
    method __le__ (line 313) | def __le__(self, other):
    method __eq__ (line 320) | def __eq__(self, other):
    method __ne__ (line 327) | def __ne__(self, other):
    method __ge__ (line 334) | def __ge__(self, other):
    method __gt__ (line 341) | def __gt__(self, other):
  function p_error (line 397) | def p_error(p):
  function p_expression_number (line 403) | def p_expression_number(p):
  function p_expression_character (line 411) | def p_expression_character(p):
  function p_expression_string (line 415) | def p_expression_string(p):
  function p_expression_group (line 422) | def p_expression_group(t):
  function p_expression_uplus (line 426) | def p_expression_uplus(p):
  function p_expression_uminus (line 430) | def p_expression_uminus(p):
  function p_expression_unop (line 434) | def p_expression_unop(p):
  function p_expression_binop (line 447) | def p_expression_binop(p):
  function p_expression_conditional (line 512) | def p_expression_conditional(p):
  function p_expression_function_call (line 524) | def p_expression_function_call(p):
  function p_expression_identifier (line 531) | def p_expression_identifier(p):
  class Evaluator (line 539) | class Evaluator(object):
    method __init__ (line 687) | def __init__(self, lexer = None):
    class __lexer (line 691) | class __lexer(object):
      method __init__ (line 693) | def __init__(self, functions, identifiers):
      method input (line 698) | def input(self, toks):
      method token (line 702) | def token(self):
      method on_function_call (line 708) | def on_function_call(self, p):
      method on_identifier (line 713) | def on_identifier(self, p):
    method __call__ (line 718) | def __call__(self, input, functions = {}, identifiers = {}):

FILE: pcpp/parser.py
  function t_CPP_WS (line 39) | def t_CPP_WS(t):
  function t_CPP_LINECONT (line 45) | def t_CPP_LINECONT(t):
  function PP_NUMBER (line 109) | def PP_NUMBER(t):
  function t_CPP_STRING (line 116) | def t_CPP_STRING(t):
  function t_CPP_CHAR (line 123) | def t_CPP_CHAR(t):
  function t_CPP_COMMENT1 (line 129) | def t_CPP_COMMENT1(t):
  function t_CPP_COMMENT2 (line 136) | def t_CPP_COMMENT2(t):
  function t_error (line 140) | def t_error(t):
  function trigraph (line 185) | def trigraph(input):
  function default_lexer (line 188) | def default_lexer():
  class Macro (line 207) | class Macro(object):
    method __init__ (line 208) | def __init__(self,name,value,arglist=None,variadic=False):
    method __repr__ (line 217) | def __repr__(self):
  class Action (line 226) | class Action(object):
  class OutputDirective (line 233) | class OutputDirective(Exception):
    method __init__ (line 236) | def __init__(self, action):
  class PreprocessorHooks (line 239) | class PreprocessorHooks(object):
    method __init__ (line 241) | def __init__(self):
    method on_error (line 244) | def on_error(self,file,line,msg):
    method on_file_open (line 252) | def on_file_open(self,is_system_include,includepath):
    method on_include_not_found (line 272) | def on_include_not_found(self,is_malformed,is_system_include,curdir,in...
    method on_unknown_macro_in_defined_expr (line 289) | def on_unknown_macro_in_defined_expr(self,tok):
    method on_unknown_macro_in_expr (line 301) | def on_unknown_macro_in_expr(self,ident):
    method on_unknown_macro_function_in_expr (line 311) | def on_unknown_macro_function_in_expr(self,ident):
    method on_directive_handle (line 322) | def on_directive_handle(self,directive,toks,ifpassthru,precedingtoks):
    method on_directive_unknown (line 340) | def on_directive_unknown(self,directive,toks,ifpassthru,precedingtoks):
    method on_potential_include_guard (line 366) | def on_potential_include_guard(self,macro):
    method on_comment (line 373) | def on_comment(self,tok):

FILE: pcpp/pcmd.py
  class FileAction (line 15) | class FileAction(argparse.Action):
    method __init__ (line 16) | def __init__(self, option_strings, dest, **kwargs):
    method __call__ (line 19) | def __call__(self, parser, namespace, values, option_string=None):
  class CmdPreprocessor (line 27) | class CmdPreprocessor(Preprocessor):
    method __init__ (line 28) | def __init__(self, argv):
    method on_include_not_found (line 196) | def on_include_not_found(self,is_malformed,is_system_include,curdir,in...
    method on_unknown_macro_in_defined_expr (line 201) | def on_unknown_macro_in_defined_expr(self,tok):
    method on_unknown_macro_in_expr (line 209) | def on_unknown_macro_in_expr(self,ident):
    method on_unknown_macro_function_in_expr (line 217) | def on_unknown_macro_function_in_expr(self,ident):
    method on_directive_handle (line 225) | def on_directive_handle(self,directive,toks,ifpassthru,precedingtoks):
    method on_directive_unknown (line 240) | def on_directive_unknown(self,directive,toks,ifpassthru,precedingtoks):
    method on_potential_include_guard (line 245) | def on_potential_include_guard(self,macro):
    method on_comment (line 249) | def on_comment(self,tok):
  function main (line 254) | def main(argv=None):

FILE: pcpp/preprocessor.py
  class FileInclusionTime (line 30) | class FileInclusionTime(object):
    method __init__ (line 32) | def __init__(self,including_path,included_path,included_abspath,depth):
  class Preprocessor (line 46) | class Preprocessor(PreprocessorHooks):
    method __init__ (line 47) | def __init__(self,lexer=None):
    method __file_unique_id (line 88) | def __file_unique_id(fh):
    method tokenize (line 98) | def tokenize(self,text):
    method __lexprobe (line 118) | def __lexprobe(self):
    method add_path (line 232) | def add_path(self,path):
    method group_lines (line 254) | def group_lines(self,input,abssource):
    method tokenstrip (line 290) | def tokenstrip(self,tokens):
    method collect_args (line 319) | def collect_args(self,tokenlist,ignore_errors=False):
    method macro_prescan (line 384) | def macro_prescan(self,macro):
    method macro_expand_args (line 440) | def macro_expand_args(self,macro,args,expanding_from):
    method expand_macros (line 556) | def expand_macros(self,tokens,expanding_from=[]):
    method evalexpr (line 670) | def evalexpr(self,tokens):
    method parsegen (line 826) | def parsegen(self,input,source=None,abssource=None):
    method include (line 1161) | def include(self,tokens,original_line,include_next_is_active=False,inc...
    method define (line 1255) | def define(self,tokens):
    method undef (line 1337) | def undef(self,tokens):
    method parse (line 1352) | def parse(self,input,source=None,ignore={}):
    method token (line 1369) | def token(self):
    method write (line 1380) | def write(self, oh=sys.stdout):

FILE: setup.py
  class PyTest (line 10) | class PyTest(TestCommand):
    method initialize_options (line 14) | def initialize_options(self):
    method run_tests (line 18) | def run_tests(self):

FILE: tests/alternate_input_encodings.py
  class runner (line 13) | class runner(object):
    method runTest (line 14) | def runTest(self):
  class single_input_file (line 36) | class single_input_file(unittest.TestCase, runner):
  class multiple_input_files (line 40) | class multiple_input_files(unittest.TestCase, runner):

FILE: tests/cstd.py
  class runner (line 6) | class runner(object):
    method runTest (line 7) | def runTest(self):
  class std1 (line 27) | class std1(unittest.TestCase, runner):
  class std2 (line 55) | class std2(unittest.TestCase, runner):
  class std3 (line 65) | class std3(unittest.TestCase, runner):
  class std4 (line 75) | class std4(unittest.TestCase, runner):
  class std5 (line 95) | class std5(unittest.TestCase, runner):
  class std6 (line 122) | class std6(unittest.TestCase, runner):
  class std7 (line 135) | class std7(unittest.TestCase, runner):
  class std8 (line 152) | class std8(unittest.TestCase, runner):
  class std9 (line 170) | class std9(unittest.TestCase, runner):
  class std10 (line 180) | class std10(unittest.TestCase, runner):
  class std11 (line 192) | class std11(unittest.TestCase, runner):
  class test12 (line 212) | class test12(unittest.TestCase, runner):
  class test13 (line 287) | class test13(unittest.TestCase, runner):
  class test14 (line 302) | class test14(unittest.TestCase, runner):
  class test15 (line 331) | class test15(unittest.TestCase, runner):
  class test16 (line 339) | class test16(unittest.TestCase, runner):
  class test17 (line 349) | class test17(unittest.TestCase, runner):
  class test18 (line 358) | class test18(unittest.TestCase, runner):
  class test19 (line 377) | class test19(unittest.TestCase, runner):
  class test20 (line 393) | class test20(unittest.TestCase, runner):
  class test21 (line 408) | class test21(unittest.TestCase, runner):
  class test22 (line 423) | class test22(unittest.TestCase, runner):
  class test23 (line 443) | class test23(unittest.TestCase, runner):
  class test24 (line 484) | class test24(unittest.TestCase, runner):
  class test25 (line 493) | class test25(unittest.TestCase, runner):
  class test26 (line 502) | class test26(unittest.TestCase, runner):
  class test27 (line 517) | class test27(unittest.TestCase, runner):
  class test28 (line 532) | class test28(unittest.TestCase, runner):
  class test29 (line 546) | class test29(unittest.TestCase, runner):
  class test30 (line 562) | class test30(unittest.TestCase, runner):
  class test31 (line 574) | class test31(unittest.TestCase, runner):

FILE: tests/doctests.py
  class pcpp_doctests (line 3) | class pcpp_doctests(unittest.TestCase):
    method runTest (line 4) | def runTest(self):

FILE: tests/embedded.py
  class embedded1 (line 5) | class embedded1(unittest.TestCase):
    method runTest (line 6) | def runTest(self):

FILE: tests/eval.py
  class runner (line 5) | class runner(object):
    method runTest (line 6) | def runTest(self):
  class eval1 (line 28) | class eval1(unittest.TestCase, runner):
  class eval2 (line 36) | class eval2(unittest.TestCase, runner):
  class eval3 (line 44) | class eval3(unittest.TestCase, runner):
  class eval4 (line 52) | class eval4(unittest.TestCase, runner):

FILE: tests/issue0017.py
  class issue0017 (line 4) | class issue0017(unittest.TestCase):
    method runTest (line 5) | def runTest(self):

FILE: tests/issue0025.py
  class issue0025 (line 4) | class issue0025(unittest.TestCase):
    method runTest (line 5) | def runTest(self):

FILE: tests/issue0027.py
  class runner (line 6) | class runner(object):
    method runTest (line 7) | def runTest(self):
  class space_after_hash (line 32) | class space_after_hash(unittest.TestCase, runner):

FILE: tests/issue0030.py
  class runner (line 8) | class runner(object):
    method runTest (line 9) | def runTest(self):
  class multiple_input_files (line 24) | class multiple_input_files(unittest.TestCase, runner):

FILE: tests/issue0032.py
  class runner (line 8) | class runner(object):
    method runTest (line 9) | def runTest(self):
  class no_output_file (line 15) | class no_output_file(unittest.TestCase, runner):

FILE: tests/issue0037.py
  class runner (line 10) | class runner(object):
    method runTest (line 11) | def runTest(self):
  class multiline_comments (line 25) | class multiline_comments(unittest.TestCase, runner):

FILE: tests/issue0044.py
  class runner (line 13) | class runner(object):
    method runTest (line 14) | def runTest(self):
  class empty_line_directive (line 32) | class empty_line_directive(unittest.TestCase, runner):

FILE: tests/issue0051.py
  class runner (line 5) | class runner(object):
    method runTest (line 6) | def runTest(self):
  class normal_inclusion (line 21) | class normal_inclusion(unittest.TestCase, runner):
  class exclude_inclusion (line 31) | class exclude_inclusion(unittest.TestCase, runner):

FILE: tests/issue0057.py
  class runner (line 6) | class runner(object):
    method runTest (line 7) | def runTest(self):
  class newline_after_passthru_include1 (line 32) | class newline_after_passthru_include1(unittest.TestCase, runner):
  class newline_after_passthru_include2 (line 44) | class newline_after_passthru_include2(unittest.TestCase, runner):
  class newline_after_passthru_include3 (line 56) | class newline_after_passthru_include3(unittest.TestCase, runner):

FILE: tests/issue0059.py
  class runner (line 6) | class runner(object):
    method runTest (line 7) | def runTest(self):
  class multiple_inclusion (line 32) | class multiple_inclusion(unittest.TestCase, runner):

FILE: tests/issue0063.py
  class runner (line 5) | class runner(object):
    method runTest (line 6) | def runTest(self):
  class include_after_continued_macro1 (line 21) | class include_after_continued_macro1(unittest.TestCase, runner):
  class include_after_continued_macro2 (line 28) | class include_after_continued_macro2(unittest.TestCase, runner):
  class include_after_continued_macro3 (line 41) | class include_after_continued_macro3(unittest.TestCase, runner):

FILE: tests/issue0079.py
  class runner (line 4) | class runner(object):
    method runTest (line 5) | def runTest(self):
  class pp_number_pasting (line 19) | class pp_number_pasting(unittest.TestCase, runner):

FILE: tests/issue0098.py
  class runner (line 5) | class runner(object):
    method runTest (line 6) | def runTest(self):
  class include_next_works (line 27) | class include_next_works(unittest.TestCase, runner):
  class has_include_works (line 40) | class has_include_works(unittest.TestCase, runner):

FILE: tests/issue0103.py
  class runner (line 5) | class runner(object):
    method runTest (line 6) | def runTest(self):
  class multiline_char_literals1 (line 19) | class multiline_char_literals1(unittest.TestCase, runner):
  class multiline_char_literals2 (line 36) | class multiline_char_literals2(unittest.TestCase, runner):

FILE: tests/n_std.py
  class n_std (line 5) | class n_std(unittest.TestCase):
    method runTest (line 6) | def runTest(self):

FILE: tests/passthru.py
  class runner (line 6) | class runner(object):
    method runTest (line 7) | def runTest(self):
  class test1 (line 53) | class test1(unittest.TestCase, runner):
  class test2 (line 63) | class test2(unittest.TestCase, runner):
  class test3 (line 76) | class test3(unittest.TestCase, runner):
  class test4 (line 93) | class test4(unittest.TestCase, runner):
  class test5 (line 112) | class test5(unittest.TestCase, runner):
  class test6 (line 131) | class test6(unittest.TestCase, runner):
  class test7 (line 145) | class test7(unittest.TestCase, runner):
  class test8 (line 164) | class test8(unittest.TestCase, runner):
  class test9 (line 207) | class test9(unittest.TestCase, runner):
  class test10 (line 219) | class test10(unittest.TestCase, runner):
  class test11 (line 237) | class test11(unittest.TestCase, runner):
  class test12 (line 264) | class test12(unittest.TestCase, runner):
  class test18 (line 294) | class test18(unittest.TestCase, runner):
  class test19 (line 312) | class test19(unittest.TestCase, runner):
  class test20 (line 337) | class test20(unittest.TestCase, runner):
  class test21 (line 345) | class test21(unittest.TestCase, runner):
  class test22 (line 357) | class test22(unittest.TestCase, runner):
  class test23 (line 369) | class test23(unittest.TestCase, runner):

FILE: tests/test-c/e_12_8.c
  function main (line 7) | main( void)

FILE: tests/test-c/e_14.c
  function main (line 39) | main( void)

FILE: tests/test-c/e_14_10.c
  function main (line 15) | int main( void)

FILE: tests/test-c/e_14_7.c
  function main (line 15) | main( void)

FILE: tests/test-c/e_14_9.c
  function main (line 7) | int main( void)

FILE: tests/test-c/e_16.c
  function MACRO_0 (line 9) | MACRO_0

FILE: tests/test-c/e_18_4.c
  function main (line 32) | main( void)

FILE: tests/test-c/e_19_3.c
  function main (line 33) | main( void)

FILE: tests/test-c/e_23_3.c
  function main (line 12) | main( void)

FILE: tests/test-c/e_24_6.c
  function main (line 7) | main( void)

FILE: tests/test-c/e_25_6.c
  function main (line 14) | main( void)

FILE: tests/test-c/e_27_7.c
  function main (line 12) | main( void)

FILE: tests/test-c/e_29_3.c
  function main (line 13) | main( void)

FILE: tests/test-c/e_31.c
  function main (line 11) | main( void)

FILE: tests/test-c/e_31_3.c
  function main (line 11) | main( void)

FILE: tests/test-c/e_32_5.c
  function main (line 8) | main( void)

FILE: tests/test-c/e_33_2.c
  function main (line 8) | main( void)

FILE: tests/test-c/e_35_2.c
  function main (line 9) | main( void)

FILE: tests/test-c/e_7_4.c
  function main (line 8) | main( void)

FILE: tests/test-c/e_std.c
  function main (line 18) | main( void)
  function e_19_3 (line 237) | void    e_19_3( void)
  function e_25_6 (line 290) | void    e_25_6( void)
  function e_27_7 (line 305) | void    e_27_7( void)
  function e_31 (line 328) | void    e_31( void)

FILE: tests/test-c/i_32_3.c
  function main (line 5) | main( void)

FILE: tests/test-c/i_35.c
  function main (line 5) | main( void)

FILE: tests/test-c/i_35_3.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_33_big5.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_eucjp.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_gb.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_jis.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_ksc.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_sjis.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_33_utf8.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_34_big5.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_eucjp.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_gb.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_jis.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_ksc.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_sjis.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_34_utf8.c
  function main (line 5) | main( void)

FILE: tests/test-c/m_36_big5.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_36_jis.c
  function main (line 7) | main( void)

FILE: tests/test-c/m_36_sjis.c
  function main (line 7) | main( void)

FILE: tests/test-c/n_1.c
  function main (line 8) | main( void)

FILE: tests/test-c/n_10.c
  function main (line 8) | main( void)

FILE: tests/test-c/n_11.c
  function main (line 9) | main( void)

FILE: tests/test-c/n_12.c
  function main (line 6) | main( void)

FILE: tests/test-c/n_13.c
  function main (line 20) | main( void)

FILE: tests/test-c/n_13_13.c
  function main (line 12) | main( void)

FILE: tests/test-c/n_13_5.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_13_7.c
  function main (line 6) | main( void)

FILE: tests/test-c/n_13_8.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_15.c
  function main (line 8) | main( void)

FILE: tests/test-c/n_18.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_19.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_2.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_20.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_21.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_22.c
  function main (line 9) | main( void)

FILE: tests/test-c/n_23.c
  function main (line 10) | main( void)

FILE: tests/test-c/n_24.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_25.c
  function main (line 16) | main( void)

FILE: tests/test-c/n_26.c
  function f (line 5) | int     f( a)
  function g (line 11) | int     g( a)
  function main (line 17) | main( void)

FILE: tests/test-c/n_27.c
  function main (line 8) | main( void)

FILE: tests/test-c/n_28.c
  function main (line 6) | main( void)

FILE: tests/test-c/n_29.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_3.c
  function main (line 7) | main( void)

FILE: tests/test-c/n_30.c
  function main (line 12) | main( void)

FILE: tests/test-c/n_32.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_37.c
  function main (line 9) | main( void)

FILE: tests/test-c/n_4.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_5.c
  function main (line 7) | main( void)

FILE: tests/test-c/n_6.c
  function main (line 10) | main( void)

FILE: tests/test-c/n_7.c
  function main (line 5) | main( void)

FILE: tests/test-c/n_9.c
  function main (line 10) | main( void)

FILE: tests/test-c/n_std.c
  function main (line 63) | int main( void)
  function n_2 (line 104) | void    n_2( void)
  function n_3 (line 134) | void    n_3( void)
  function n_5 (line 159) | void    n_5( void)
  function n_6 (line 178) | void    n_6( void)
  function n_7 (line 196) | void    n_7( void)
  function n_9 (line 219) | void    n_9( void)
  function n_10 (line 228) | void    n_10( void)
  function n_11 (line 253) | void    n_11( void)
  function n_12 (line 285) | void    n_12( void)
  function n_13 (line 327) | void    n_13( void)
  function n_13_5 (line 365) | void    n_13_5( void)
  function n_13_7 (line 389) | void    n_13_7( void)
  function n_13_8 (line 408) | void    n_13_8( void)
  function n_13_13 (line 441) | void    n_13_13( void)
  function n_15 (line 468) | void    n_15( void)
  function n_19 (line 509) | void    n_19( void)
  function n_20 (line 524) | void    n_20( void)
  function n_21 (line 533) | void    n_21( void)
  function n_22 (line 550) | void    n_22( void)
  function n_23 (line 566) | void    n_23( void)
  function n_24 (line 580) | void    n_24( void)
  function n_25 (line 606) | void    n_25( void)
  function f (line 636) | int     f( a)
  function g (line 642) | int     g( a)
  function f (line 648) | int     f( int a)
  function g (line 653) | int     g( int a)
  function n_26 (line 659) | void    n_26( void)
  function n_27 (line 694) | void    n_27( void)
  function n_28 (line 741) | void    n_28( void)
  function n_29 (line 770) | void    n_29( void)
  function n_30 (line 784) | void    n_30( void)
  function n_32 (line 810) | void    n_32( void)
  function n_37 (line 824) | void    n_37( void)

FILE: tests/test-c/u_1_1.c
  function main (line 3) | main( void)

FILE: tests/test-c/u_1_11.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_12.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_13.c
  function Junk (line 5) | Junk

FILE: tests/test-c/u_1_14.c
  function main (line 3) | main( void)

FILE: tests/test-c/u_1_17.c
  function main (line 5) | main( void)

FILE: tests/test-c/u_1_19.c
  function main (line 5) | main( void)

FILE: tests/test-c/u_1_22.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_23.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_24.c
  function main (line 21) | main( void)

FILE: tests/test-c/u_1_25.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_27.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_28.c
  function main (line 13) | main( void)

FILE: tests/test-c/u_1_5.c
  function main (line 14) | main( void)

FILE: tests/test-c/u_1_7_big5.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_7_eucjp.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_7_gb.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_7_jis.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_7_ksc.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_7_sjis.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_1_7_utf8.c
  function main (line 7) | main( void)

FILE: tests/test-c/u_1_8.c
  function main (line 8) | main( void)

FILE: tests/test-c/u_2.c
  function main (line 13) | main( void)

FILE: tests/test-c/undefs.c
  function main (line 16) | main( void)

FILE: tests/test-c/unspcs.c
  function main (line 21) | main( void)

FILE: tests/test-c/warns.c
  function main (line 15) | main( void)
Condensed preview — 210 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (925K chars).
[
  {
    "path": ".gitattributes",
    "chars": 3966,
    "preview": "* text=auto !eol svneol=native#text/plain\n*.gitattributes text svneol=native#text/plain\n\n# Scriptish formats\n*.bat      "
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 14,
    "preview": "github: ned14\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2979,
    "preview": "name: CI\n\non:\n  push:\n    branches:\n      - master\n  pull_request:\n\njobs:\n  Build:\n    runs-on: ubuntu-24.04\n    strateg"
  },
  {
    "path": ".gitignore",
    "chars": 37,
    "preview": "*.pyc\nbuild/*\ndist/*\npcpp.egg-info/*\n"
  },
  {
    "path": ".gitmodules",
    "chars": 117,
    "preview": "[submodule \"pcpp/ply\"]\n\tpath = pcpp/ply\n\turl = https://github.com/ned14/ply.git\n\tbranch = master\n\tignore = untracked\n"
  },
  {
    "path": "AGENTS.md",
    "chars": 343,
    "preview": "# Agent Overview for pcpp (Pure Python C Preprocessor)\n\n## How to build\n- `python setup.py build`\n\n## How to test\n- `pyt"
  },
  {
    "path": "LICENSE.txt",
    "chars": 1552,
    "preview": "(C) 2018-2026 Niall Douglas http://www.nedproductions.biz/\nand (C) 2007-2019 David Beazley http://www.dabeaz.com/\n\nAll r"
  },
  {
    "path": "README.rst",
    "chars": 25372,
    "preview": "A C99 preprocessor written in pure Python\n=========================================\n.. role:: c(code)\n   :language: c\n\n."
  },
  {
    "path": "doc/evaluator.html",
    "chars": 93376,
    "preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-widt"
  },
  {
    "path": "doc/index.html",
    "chars": 7006,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initia"
  },
  {
    "path": "doc/lextab.html",
    "chars": 11429,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initia"
  },
  {
    "path": "doc/parser.html",
    "chars": 75467,
    "preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-widt"
  },
  {
    "path": "doc/parsetab.html",
    "chars": 20311,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initia"
  },
  {
    "path": "doc/pcmd.html",
    "chars": 27203,
    "preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-widt"
  },
  {
    "path": "doc/preprocessor.html",
    "chars": 265106,
    "preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-widt"
  },
  {
    "path": "pcpp/__init__.py",
    "chars": 187,
    "preview": "from .evaluator import Evaluator\nfrom .parser import Action, OutputDirective\nfrom .pcmd import main, version, CmdPreproc"
  },
  {
    "path": "pcpp/evaluator.py",
    "chars": 26642,
    "preview": "#!/usr/bin/python\n# Python C99 conforming preprocessor expression evaluator\n# (C) 2019-2026 Niall Douglas http://www.ned"
  },
  {
    "path": "pcpp/lextab.py",
    "chars": 4207,
    "preview": "# lextab.py. This file automatically created by PLY (version 3.11). Don't edit!\n_tabversion   = '3.10'\n_lextokens    = s"
  },
  {
    "path": "pcpp/parser.py",
    "chars": 13812,
    "preview": "#!/usr/bin/python\n# Python C99 conforming preprocessor parser config\n# (C) 2017-2026 Niall Douglas http://www.nedproduct"
  },
  {
    "path": "pcpp/parsetab.py",
    "chars": 13515,
    "preview": "\n# parsetab.py\n# This file is automatically generated. Do not edit.\n# pylint: disable=W,C,R\n_tabversion = '3.10'\n\n_lr_me"
  },
  {
    "path": "pcpp/pcmd.py",
    "chars": 16148,
    "preview": "#!/usr/bin/python\n# Python C99 conforming preprocessor command line\n# (C) 2017-2026 Niall Douglas http://www.nedproducti"
  },
  {
    "path": "pcpp/preprocessor.py",
    "chars": 69296,
    "preview": "#!/usr/bin/python\n# Python C99 conforming preprocessor useful for generating single include files\n# (C) 2017-2026 Niall "
  },
  {
    "path": "pyproject.toml",
    "chars": 1167,
    "preview": "[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"pcpp\"\nversion = \"1.3"
  },
  {
    "path": "requirements.txt",
    "chars": 24,
    "preview": "setuptools\nwheel\npytest\n"
  },
  {
    "path": "setup.py",
    "chars": 2558,
    "preview": "#!/usr/bin/env python\n\nfrom setuptools import setup\nfrom setuptools.command.test import test as TestCommand\nimport os\nim"
  },
  {
    "path": "tests/Readme.md",
    "chars": 96,
    "preview": "test-c was borrowed from the test suite for the mcpp preprocessor\n\nhttp://mcpp.sourceforge.net/\n"
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/alternate_input_encodings.py",
    "chars": 1721,
    "preview": "import unittest, sys, io, os\n\nshouldbe1 = r'''#line 1 \"tests/alternate_input_encodings1_ucs16le.c\"\n语言处理\n'''\n\nshouldbe2 "
  },
  {
    "path": "tests/cstd.py",
    "chars": 16036,
    "preview": "\nimport unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n "
  },
  {
    "path": "tests/doctests.py",
    "chars": 441,
    "preview": "import unittest\n\nclass pcpp_doctests(unittest.TestCase):\n    def runTest(self):\n        import doctest, pcpp.preprocesso"
  },
  {
    "path": "tests/embedded.py",
    "chars": 601,
    "preview": "\nimport unittest, sys\nfrom io import StringIO\n\nclass embedded1(unittest.TestCase):\n    def runTest(self):\n        from p"
  },
  {
    "path": "tests/eval.py",
    "chars": 1262,
    "preview": "import unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n  "
  },
  {
    "path": "tests/issue0017/inc.h",
    "chars": 75,
    "preview": "inc1\n#ifndef __inc_h__\ninc2\n#define __inc_h__\ninc3\n#endif //__inc_h__\ninc4\n"
  },
  {
    "path": "tests/issue0017/issue0017.c",
    "chars": 46,
    "preview": "#include \"inc.h\"\ntest1\n#include \"inc.h\"\ntest2\n"
  },
  {
    "path": "tests/issue0017-ref.i",
    "chars": 190,
    "preview": "#line 1 \"tests/issue0017/inc.h\"\ninc1\n\ninc2\n\ninc3\n\ninc4\n#line 2 \"tests/issue0017/issue0017.c\"\ntest1\n#line 1 \"tests/issue0"
  },
  {
    "path": "tests/issue0017.py",
    "chars": 802,
    "preview": "\nimport unittest, os\n\nclass issue0017(unittest.TestCase):\n    def runTest(self):\n        from pcpp import Preprocessor\n "
  },
  {
    "path": "tests/issue0025/inc.h",
    "chars": 67,
    "preview": "OUTCOME_TRY_UNIQUE_NAME __LINE__\n\nOUTCOME_TRY_UNIQUE_NAME __LINE__\n"
  },
  {
    "path": "tests/issue0025/main.c",
    "chars": 388,
    "preview": "#define OUTCOME_TRY_GLUE2(x, y) x##y\n#define OUTCOME_TRY_GLUE(x, y) OUTCOME_TRY_GLUE2(x, y)\n#define OUTCOME_TRY_UNIQUE_N"
  },
  {
    "path": "tests/issue0025-ref.i",
    "chars": 513,
    "preview": "#line 5 \"tests/issue0025/main.c\"\n_outcome_try_unique_name_temporary5 5\n_outcome_try_unique_name_temporary6 6\n_outcome_tr"
  },
  {
    "path": "tests/issue0025.py",
    "chars": 797,
    "preview": "\nimport unittest, os\n\nclass issue0025(unittest.TestCase):\n    def runTest(self):\n        from pcpp import Preprocessor\n "
  },
  {
    "path": "tests/issue0027.py",
    "chars": 1302,
    "preview": "\nimport unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n "
  },
  {
    "path": "tests/issue0030/source1.c",
    "chars": 25,
    "preview": "#undef FOO\n#define FOO 1\n"
  },
  {
    "path": "tests/issue0030/source2.c",
    "chars": 25,
    "preview": "#undef FOO\n#define FOO 2\n"
  },
  {
    "path": "tests/issue0030/source3.c",
    "chars": 4,
    "preview": "FOO\n"
  },
  {
    "path": "tests/issue0030.py",
    "chars": 856,
    "preview": "\nimport unittest, sys, os\n\nshouldbe = r'''#line 1 \"tests/issue0030/source3.c\"\n2\n'''\n\nclass runner(object):\n    def runTe"
  },
  {
    "path": "tests/issue0032.py",
    "chars": 375,
    "preview": "\nimport unittest, sys\n\nshouldbe = r'''#line 1 \"tests/issue0030/source3.c\"\n2\n'''\n\nclass runner(object):\n    def runTest(s"
  },
  {
    "path": "tests/issue0037/inc.h",
    "chars": 75,
    "preview": "    /** this spans\n        two lines */\n    virtual std::string baseOnly();"
  },
  {
    "path": "tests/issue0037.py",
    "chars": 866,
    "preview": "\nimport unittest, sys, os\n\nshouldbe = r'''#line 1 \"tests/issue0037/inc.h\"\n    /** this spans\n        two lines */\n    vi"
  },
  {
    "path": "tests/issue0044.h",
    "chars": 31,
    "preview": "a1\n#if 0\nsample text\n#endif\nb1\n"
  },
  {
    "path": "tests/issue0044.py",
    "chars": 974,
    "preview": "\nimport unittest\nimport sys, os\n\nshouldbe = r'''a1\n\n\n\nb1\n'''\n\n\nclass runner(object):\n    def runTest(self):\n        from"
  },
  {
    "path": "tests/issue0051.c",
    "chars": 63,
    "preview": "#include \"issue0051.h\"\n\n#ifdef FOO\n  TRUE\n#else\n  FALSE\n#endif\n"
  },
  {
    "path": "tests/issue0051.h",
    "chars": 66,
    "preview": "#define FOO 1\n\nvoid my_func1();\nvoid my_func2();\nvoid my_func3();\n"
  },
  {
    "path": "tests/issue0051.py",
    "chars": 1072,
    "preview": "\nimport unittest\nimport sys, os\n\nclass runner(object):\n    def runTest(self):\n        from pcpp import CmdPreprocessor\n "
  },
  {
    "path": "tests/issue0057.h",
    "chars": 12,
    "preview": "headertoken\n"
  },
  {
    "path": "tests/issue0057.py",
    "chars": 1882,
    "preview": "\nimport unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n "
  },
  {
    "path": "tests/issue0059.py",
    "chars": 1612,
    "preview": "\nimport unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n "
  },
  {
    "path": "tests/issue0059a.h",
    "chars": 38,
    "preview": "#pragma once\n#define FOO __COUNTER__\n\n"
  },
  {
    "path": "tests/issue0059b.h",
    "chars": 11,
    "preview": "#undef FOO\n"
  },
  {
    "path": "tests/issue0063.c",
    "chars": 85,
    "preview": "#define x\\\n\\\n\n#include \"issue0063.h\"\n\n#undef x\n#define x\\\n \\\n\n#include \"issue0063.h\"\n"
  },
  {
    "path": "tests/issue0063.h",
    "chars": 9,
    "preview": "int f();\n"
  },
  {
    "path": "tests/issue0063.py",
    "chars": 1310,
    "preview": "\nimport unittest\nimport sys, os\n\nclass runner(object):\n    def runTest(self):\n        from pcpp import CmdPreprocessor\n "
  },
  {
    "path": "tests/issue0079.py",
    "chars": 816,
    "preview": "import unittest, time\nfrom io import StringIO\n\nclass runner(object):\n    def runTest(self):\n        from pcpp import Pre"
  },
  {
    "path": "tests/issue0098/dir1/header.h",
    "chars": 33,
    "preview": "header1\n#include_next \"header.h\"\n"
  },
  {
    "path": "tests/issue0098/dir2/header.h",
    "chars": 33,
    "preview": "header2\n#include_next \"header.h\"\n"
  },
  {
    "path": "tests/issue0098/dir3/header.h",
    "chars": 33,
    "preview": "header3\n#include_next \"header.h\"\n"
  },
  {
    "path": "tests/issue0098/dir4/header.h",
    "chars": 8,
    "preview": "header4\n"
  },
  {
    "path": "tests/issue0098.py",
    "chars": 1465,
    "preview": "\nimport unittest, sys\nfrom io import StringIO\n\nclass runner(object):\n    def runTest(self):\n        from pcpp import Pre"
  },
  {
    "path": "tests/issue0103.py",
    "chars": 910,
    "preview": "\nimport unittest, sys\nfrom io import StringIO\n\nclass runner(object):\n    def runTest(self):\n        from pcpp import Pre"
  },
  {
    "path": "tests/n_std-clang.i",
    "chars": 8049,
    "preview": "# 1 \"tests/test-c/n_std.c\"\n# 1 \"<built-in>\" 1\n# 1 \"<built-in>\" 3\n# 312 \"<built-in>\" 3\n# 1 \"<command line>\" 1\n# 1 \"<built"
  },
  {
    "path": "tests/n_std-gcc.i",
    "chars": 8113,
    "preview": "# 1 \"tests/test-c/n_std.c\"\n# 1 \"<built-in>\"\n# 1 \"<command-line>\"\n# 1 \"/usr/include/stdc-predef.h\" 1 3 4\n# 1 \"<command-li"
  },
  {
    "path": "tests/n_std-pcpp.i",
    "chars": 7808,
    "preview": "# 30 \"tests/test-c/n_std.c\"\nvoid n_1( void);\nvoid n_2( void);\nvoid n_3( void);\nvoid n_4( void);\nvoid n_5( void);\nvoid n_"
  },
  {
    "path": "tests/n_std.i",
    "chars": 7808,
    "preview": "# 30 \"tests/test-c/n_std.c\"\nvoid n_1( void);\nvoid n_2( void);\nvoid n_3( void);\nvoid n_4( void);\nvoid n_5( void);\nvoid n_"
  },
  {
    "path": "tests/n_std.py",
    "chars": 1262,
    "preview": "\nimport unittest, time, difflib\nclock = time.process_time\n\nclass n_std(unittest.TestCase):\n    def runTest(self):\n      "
  },
  {
    "path": "tests/passthru.py",
    "chars": 6801,
    "preview": "\nimport unittest, time\nfrom io import StringIO\nclock = time.process_time\n\nclass runner(object):\n    def runTest(self):\n "
  },
  {
    "path": "tests/test-c/LICENSE",
    "chars": 1460,
    "preview": "/*-\n * Copyright (c) 1998, 2002-2008 Kiyoshi Matsui <kmatsui@t3.rim.or.jp>\n * All rights reserved.\n *\n * This software i"
  },
  {
    "path": "tests/test-c/defs.h",
    "chars": 691,
    "preview": "/* defs.h   */\n\n#ifndef NO_SYSTEM_HEADERS\n#include    <stdio.h>\n\n/* assert(): Enable one of these three. */\n/* Note: Thi"
  },
  {
    "path": "tests/test-c/e_12_8.c",
    "chars": 217,
    "preview": "/* e_12_8.c:    Out of range of integer pp-token in #if expression. */\n\n/* 12.8:    Preprocessing number perhaps out of "
  },
  {
    "path": "tests/test-c/e_14.c",
    "chars": 731,
    "preview": "/* e_14.c:  Illegal #if expressions.    */\n\n#define A   1\n#define B   1\n\n/* 14.1:    String literal is not allowed in #i"
  },
  {
    "path": "tests/test-c/e_14_10.c",
    "chars": 267,
    "preview": "/* e_14_10.c:   Overflow of constant expression in #if directive.   */\n\n/* 14.10:   */\n#include    <limits.h>\n\n#if     L"
  },
  {
    "path": "tests/test-c/e_14_7.c",
    "chars": 381,
    "preview": "/* e_14_7.c:    There is no keyword in #if expression.  */\n\n/* 14.7:    sizeof operator is disallowed.  */\n/*  Evaluated"
  },
  {
    "path": "tests/test-c/e_14_9.c",
    "chars": 157,
    "preview": "/* e_14_9.c:    Out of range in #if expression (division by 0). */\n\n/* 14.9:    Divided by 0.   */\n#if     1 / 0\n#endif\n"
  },
  {
    "path": "tests/test-c/e_15_3.c",
    "chars": 282,
    "preview": "/* e_15_3.c:    #ifdef, #ifndef syntax errors.  */\n\n/* 15.3:    Not an identifier.  */\n#ifdef  \"string\"\n#endif\n#ifdef  1"
  },
  {
    "path": "tests/test-c/e_16.c",
    "chars": 234,
    "preview": "/* e_16.c:  Trailing junk of #else, #endif. */\n\n/* 16.1:    Trailing junk of #else. */\n#define MACRO_0     0\n#if     MAC"
  },
  {
    "path": "tests/test-c/e_17.c",
    "chars": 640,
    "preview": "/* e_17.c:  Ill-formed group in a source file.  */\n\n#define MACRO_1     1\n\n/* 17.1:    Error of #endif without #if.    *"
  },
  {
    "path": "tests/test-c/e_18_4.c",
    "chars": 908,
    "preview": "/* e_18_4.c:    #define syntax errors.  */\n\n/* 18.4:    Not an identifier.  */\n#define \"string\"\n#define 123\n\n/* 18.5:   "
  },
  {
    "path": "tests/test-c/e_19_3.c",
    "chars": 826,
    "preview": "/* e_19_3.c:    Redefinitions of macros.    */\n\n#include    \"defs.h\"\n#define     str( s)     # s\n#define     xstr( s)   "
  },
  {
    "path": "tests/test-c/e_23_3.c",
    "chars": 364,
    "preview": "/* e_23_3.c:    ## operator shall not occur at the beginning or at the end of\n        replacement list for either form o"
  },
  {
    "path": "tests/test-c/e_24_6.c",
    "chars": 179,
    "preview": "/* e_24_6.c:    Operand of # operator in function-like macro definition should\n        be a parameter. */\n\n/* 24.6:    *"
  },
  {
    "path": "tests/test-c/e_25_6.c",
    "chars": 500,
    "preview": "/* e_25_6.c:    Macro arguments are pre-expanded separately.    */\n\n/* 25.6:    */\n#define sub( x, y)      (x - y)\n#defi"
  },
  {
    "path": "tests/test-c/e_27_7.c",
    "chars": 305,
    "preview": "/* e_27_7.c:    Error of rescanning.    */\n\n#define sub( x, y)      (x - y)\n\n/* 27.7:    */\n#define TWO_TOKENS      a,b\n"
  },
  {
    "path": "tests/test-c/e_29_3.c",
    "chars": 241,
    "preview": "/* e_29_3.c:    #undef errors.  */\n\n/* 29.3:    Not an identifier.  */\n#undef  \"string\"\n#undef  123\n\n/* 29.4:    Excessi"
  },
  {
    "path": "tests/test-c/e_31.c",
    "chars": 225,
    "preview": "/* e_31.c:  Illegal macro calls.    */\n\n#define sub( x, y)      (x - y)\n\n/* 31.1:    Too many arguments error.   */\n    "
  },
  {
    "path": "tests/test-c/e_31_3.c",
    "chars": 285,
    "preview": "/* e_31_3.c:    Macro call in control line should complete in the line. */\n\n#define glue( a, b)     a ## b\n#define str( "
  },
  {
    "path": "tests/test-c/e_32_5.c",
    "chars": 268,
    "preview": "/* e_32_5.c:    Range error of character constant.  */\n\n/* 32.5:    Value of a numerical escape sequence in character co"
  },
  {
    "path": "tests/test-c/e_33_2.c",
    "chars": 314,
    "preview": "/* e_33_2.c:    Out of range of numerical escape sequence in wide-char. */\n\n/* 33.2:    Value of a numerical escape sequ"
  },
  {
    "path": "tests/test-c/e_35_2.c",
    "chars": 243,
    "preview": "/* e_35_2.c:    Out of range of character constant. */\n\n/* In ASCII character set.  */\n/* 35.2:    */\n#if     'abcdefghi"
  },
  {
    "path": "tests/test-c/e_4_3.c",
    "chars": 254,
    "preview": "/* e_4_3.c:     Illegal pp-token.   */\n\n/* 4.3:     Empty character constant is an error.   */\n#if     '' == 0     /* Th"
  },
  {
    "path": "tests/test-c/e_7_4.c",
    "chars": 191,
    "preview": "/* e_7_4.c:     #line error.    */\n\n/* 7.4:     string literal in #line directive shall be a character string\n        li"
  },
  {
    "path": "tests/test-c/e_std.c",
    "chars": 8048,
    "preview": "/*\n *      e_std.c\n *\n * 1998/08      made public                                     kmatsui\n * 2002/08      revised no"
  },
  {
    "path": "tests/test-c/header.h",
    "chars": 40,
    "preview": "/* header.h */\n\n#define MACRO_abc   abc\n"
  },
  {
    "path": "tests/test-c/i_32_3.c",
    "chars": 525,
    "preview": "/* i_32_3.c:    Character constant in #if expression.   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\n\", "
  },
  {
    "path": "tests/test-c/i_35.c",
    "chars": 370,
    "preview": "/* i_35.c:  Multi-character character constant. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\n\", stderr);"
  },
  {
    "path": "tests/test-c/i_35_3.c",
    "chars": 396,
    "preview": "/* i_35_3.c:    Multi-character wide character constant.    */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\"
  },
  {
    "path": "tests/test-c/ifdef15.h",
    "chars": 587,
    "preview": "/* ifdef15.h    */\n\n#ifdef  X01\n#else\n#ifdef  X02\n#else\n#ifdef  X03\n#else\n#ifdef  X04\n#else\n#ifdef  X05\n#else\n#ifdef  X0"
  },
  {
    "path": "tests/test-c/line.h",
    "chars": 140,
    "preview": "/* line.h   */\n\n{\n    char *  file = __FILE__;\n    file += strlen( file) - 6;\n    assert( __LINE__ == 6 && strcmp( file,"
  },
  {
    "path": "tests/test-c/m1024.h",
    "chars": 11282,
    "preview": "/* m1024.h  */\n\n#define AA\n#define AB\n#define AC\n#define AD\n#define AE\n#define AF\n#define AG\n#define AH\n#define AI\n#defi"
  },
  {
    "path": "tests/test-c/m_33_big5.c",
    "chars": 771,
    "preview": "/* m_33_big5.c: Wide character constant encoded in Big-Five.    */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define "
  },
  {
    "path": "tests/test-c/m_33_eucjp.c",
    "chars": 765,
    "preview": "/* m_33_eucjp.c:    Wide character constant encoded in EUC-JP.  */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define "
  },
  {
    "path": "tests/test-c/m_33_gb.c",
    "chars": 761,
    "preview": "/* m_33_gb.c:   Wide character constant encoded in GB-2312. */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define     "
  },
  {
    "path": "tests/test-c/m_33_jis.c",
    "chars": 935,
    "preview": "/* m_33_jis.c:  Wide character constant encoded in ISO-2022-JP. */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define "
  },
  {
    "path": "tests/test-c/m_33_ksc.c",
    "chars": 769,
    "preview": "/* m_33_ksc.c:  Wide character constant encoded in KSC-5601.    */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define "
  },
  {
    "path": "tests/test-c/m_33_sjis.c",
    "chars": 773,
    "preview": "/* m_33_sjis.c: Wide character constant encoded in shift-JIS.   */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define "
  },
  {
    "path": "tests/test-c/m_33_utf8.c",
    "chars": 825,
    "preview": "/* m_33_utf8.c: Wide character constant encoded in UTF-8.   */\n\n#include    \"defs.h\"\n#include    <limits.h>\n#define     "
  },
  {
    "path": "tests/test-c/m_34_big5.c",
    "chars": 560,
    "preview": "/* m_34_big5.t: Multi-byte character constant encoded in Big-Five.  */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char *  "
  },
  {
    "path": "tests/test-c/m_34_eucjp.c",
    "chars": 561,
    "preview": "/* m_34_eucjp.c:    Multi-byte character constant encoded in EUC-JP.    */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char"
  },
  {
    "path": "tests/test-c/m_34_gb.c",
    "chars": 556,
    "preview": "/* m_34_gb.c:   Multi-byte character constant encoded in GB-2312.   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char *  "
  },
  {
    "path": "tests/test-c/m_34_jis.c",
    "chars": 655,
    "preview": "/* m_34_jis.c:  Multi-byte character constant encoded in ISO-2022-JP.   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char"
  },
  {
    "path": "tests/test-c/m_34_ksc.c",
    "chars": 559,
    "preview": "/* m_34_ksc.c:  Multi-byte character constant encoded in KSC-5601.  */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char *  "
  },
  {
    "path": "tests/test-c/m_34_sjis.c",
    "chars": 562,
    "preview": "/* m_34_sjis.c: Multi-byte character constant encoded in shift-JIS. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char *  "
  },
  {
    "path": "tests/test-c/m_34_utf8.c",
    "chars": 554,
    "preview": "/* m_34_utf8.c: Multi-byte character constant encoded in UTF-8. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    char *  ptr;"
  },
  {
    "path": "tests/test-c/m_36_big5.c",
    "chars": 741,
    "preview": "/* m_36_big5.c: Handling of '\\\\' in BigFive multi-byte character.    */\n\n#include    \"defs.h\"\n\n#define     str( a)     #"
  },
  {
    "path": "tests/test-c/m_36_jis.c",
    "chars": 1042,
    "preview": "/* m_36_jis.c:  Handling of '\\\\' in ISO-2022-JP multi--byte character.  */\n\n#include    \"defs.h\"\n\n#define     str( a)   "
  },
  {
    "path": "tests/test-c/m_36_sjis.c",
    "chars": 735,
    "preview": "/* m_36_sjis.c: Handling of '\\\\' in shift-JIS multi-byte character. */\n\n#include    \"defs.h\"\n\n#define     str( a)     # "
  },
  {
    "path": "tests/test-c/n_1.c",
    "chars": 741,
    "preview": "/* n_1.c:   Conversion of trigraph sequences.   */\n\n#include    \"defs.h\"\n\nchar    quasi_trigraph[] = { '?', '?', ' ', '?"
  },
  {
    "path": "tests/test-c/n_10.c",
    "chars": 789,
    "preview": "/* n_10.c:  #if, #elif, #else and #endif pp-directive.  */\n\n#include    \"defs.h\"\n\n#define MACRO_0     0\n#define MACRO_1 "
  },
  {
    "path": "tests/test-c/n_11.c",
    "chars": 794,
    "preview": "/* n_11.c:  Operator \"defined\" in #if or #elif directive.   */\n\n#include    \"defs.h\"\n\n#define MACRO_abc   abc\n#define MA"
  },
  {
    "path": "tests/test-c/n_12.c",
    "chars": 1297,
    "preview": "/* n_12.c:  Integer preprocessing number token and type of #if expression.  */\n\n#include    \"defs.h\"\n#include    <limits"
  },
  {
    "path": "tests/test-c/n_13.c",
    "chars": 1049,
    "preview": "/* n_13.c:  Valid operators in #if expression.  */\n\n/* Valid operators are (precedence in this order) :\n    defined, (un"
  },
  {
    "path": "tests/test-c/n_13_13.c",
    "chars": 922,
    "preview": "/* n_13_13.c:   #if expression with macros. */\n\n#include    \"defs.h\"\n#define ZERO_TOKEN\n#define MACRO_0         0\n#defin"
  },
  {
    "path": "tests/test-c/n_13_5.c",
    "chars": 892,
    "preview": "/* n_13_5.c:    Arithmetic conversion in #if expressions.   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\"
  },
  {
    "path": "tests/test-c/n_13_7.c",
    "chars": 618,
    "preview": "/* n_13_7.c:    Short-circuit evaluation of #if expression. */\n\n#include    \"defs.h\"\n#define MACRO_0     0\n\nmain( void)\n"
  },
  {
    "path": "tests/test-c/n_13_8.c",
    "chars": 1257,
    "preview": "/* n_13_8.c:    Grouping of sub-expressions in #if expression.  */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"star"
  },
  {
    "path": "tests/test-c/n_15.c",
    "chars": 484,
    "preview": "/* n_15.c:  #ifdef, #ifndef directives. */\n\n#include    \"defs.h\"\n\n#define MACRO_0     0\n#define MACRO_1     1\n\nmain( voi"
  },
  {
    "path": "tests/test-c/n_18.c",
    "chars": 728,
    "preview": "/* n_18.c:  #define directive.  */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    int     c = 3;\n\n/* Excerpts from ISO C 6.8.3"
  },
  {
    "path": "tests/test-c/n_19.c",
    "chars": 563,
    "preview": "/* n_19.c:  Valid re-definitions of macros. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    int     c = 1;\n\n    fputs( \"star"
  },
  {
    "path": "tests/test-c/n_2.c",
    "chars": 897,
    "preview": "/* n_2.c:   Line splicing by <backslash><newline> sequence. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    int     ab = 1, "
  },
  {
    "path": "tests/test-c/n_20.c",
    "chars": 275,
    "preview": "/* n_20.c:  Macro lexically identical to keyword. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n\n/* 20.1:    */\n#define float "
  },
  {
    "path": "tests/test-c/n_21.c",
    "chars": 471,
    "preview": "/* n_21.c:  Tokenization (No preprocessing tokens are merged implicitly).   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    "
  },
  {
    "path": "tests/test-c/n_22.c",
    "chars": 643,
    "preview": "/* n_22.c:  Tokenization of preprocessing number.   */\n\n#include    \"defs.h\"\n\n#define str( a)     # a\n#define xstr( a)  "
  },
  {
    "path": "tests/test-c/n_23.c",
    "chars": 464,
    "preview": "/* n_23.c:  ## operator in macro definition.    */\n\n#include    \"defs.h\"\n\n#define glue( a, b)     a ## b\n#define xglue( "
  },
  {
    "path": "tests/test-c/n_24.c",
    "chars": 1011,
    "preview": "/* n_24.c:  # operator in macro definition. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\n\", stderr);\n\n/*"
  },
  {
    "path": "tests/test-c/n_25.c",
    "chars": 1191,
    "preview": "/* n_25.c:  Macro arguments are pre-expanded (unless the argument is an\n        operand of # or ## operator) separately,"
  },
  {
    "path": "tests/test-c/n_26.c",
    "chars": 1049,
    "preview": "/* n_26.c:  The name once replaced is not furthur replaced. */\n\n#include    \"defs.h\"\n\nint     f( a)\n    int     a;\n{\n   "
  },
  {
    "path": "tests/test-c/n_27.c",
    "chars": 1738,
    "preview": "/* n_27.c:  Rescanning of a macro replace any macro call in the replacement\n        text after substitution of parameter"
  },
  {
    "path": "tests/test-c/n_28.c",
    "chars": 735,
    "preview": "/* n_28.c:  __FILE__, __LINE__, __DATE__, __TIME__, __STDC__ and\n            __STDC_VERSION__ are predefined.    */\n\n#in"
  },
  {
    "path": "tests/test-c/n_29.c",
    "chars": 368,
    "preview": "/* n_29.c:  #undef directive.   */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    int     DEFINED = 1;\n\n    fputs( \"started\\n\""
  },
  {
    "path": "tests/test-c/n_3.c",
    "chars": 652,
    "preview": "/* n_3.c:   Handling of comment.    */\n\n#include    \"defs.h\"\n\n#define str( a)     # a\n\nmain( void)\n{\n    int     abcd = "
  },
  {
    "path": "tests/test-c/n_30.c",
    "chars": 714,
    "preview": "/* n_30.c:  Macro calls.    */\n/*  Note:   Comma separate the arguments of function-like macro call,\n        but comma b"
  },
  {
    "path": "tests/test-c/n_32.c",
    "chars": 531,
    "preview": "/* n_32.c:  Escape sequence in character constant in #if expression.    */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fput"
  },
  {
    "path": "tests/test-c/n_37.c",
    "chars": 3587,
    "preview": "/* n_37.c:  Translation limits. */\n\n#include    \"defs.h\"\n\n/* 37.1:    Number of parameters in macro: at least 31. */\n#de"
  },
  {
    "path": "tests/test-c/n_3_4.c",
    "chars": 322,
    "preview": "/* n_3_4.c: Handling of comment and <backslash><newline>.   */\n\n/* 3.4: Comment and <backslash><newline> in #error line."
  },
  {
    "path": "tests/test-c/n_4.c",
    "chars": 405,
    "preview": "/* n_4.c:   Special tokens. */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n/* 4.1: Digraph spellings in directive line.    */\n%"
  },
  {
    "path": "tests/test-c/n_5.c",
    "chars": 491,
    "preview": "/* n_5.c:   Spaces or tabs are allowed at any place in pp-directive line,\n        including between the top of a pp-dire"
  },
  {
    "path": "tests/test-c/n_6.c",
    "chars": 688,
    "preview": "/* n_6.c:   #include directive. */\n\n#include    \"defs.h\"\n/* 6.1: Header-name quoted by \" and \" as well as by < and > can"
  },
  {
    "path": "tests/test-c/n_7.c",
    "chars": 606,
    "preview": "/* n_7.c:   #line directive.    */\n\n#include    \"defs.h\"\n\nmain( void)\n{\n    fputs( \"started\\n\", stderr);\n\n/* 7.1: Line n"
  },
  {
    "path": "tests/test-c/n_8.c",
    "chars": 342,
    "preview": "/* n_8.c:   #error directive.   */\n\n/* 8.1:     Argument of #error directive is not a subject of macro expansion.\n    Ou"
  },
  {
    "path": "tests/test-c/n_8_2.c",
    "chars": 103,
    "preview": "/* n_8_2.c:     Argument of #error is optional. */\n\n/* 8.2:     #error should be executed.  */\n#error\n\n"
  },
  {
    "path": "tests/test-c/n_9.c",
    "chars": 303,
    "preview": "/* n_9.c:   #pragma directive.  */\n\n#include    \"stdio.h\"\n\n/* 9.1: Any #pragma directive should be processed or ignored,"
  },
  {
    "path": "tests/test-c/n_i_.lst",
    "chars": 180,
    "preview": "n_1\nn_2\nn_3\nn_4\nn_5\nn_6\nn_7\nn_9\nn_10\nn_11\nn_12\nn_13\nn_13_5\nn_13_7\nn_13_8\nn_13_13\nn_15\nn_18\nn_19\nn_20\nn_21\nn_22\nn_23\nn_24"
  },
  {
    "path": "tests/test-c/n_std.c",
    "chars": 23761,
    "preview": "/*\n *      n_std.c\n *\n * 1998/08      made public                                     kmatsui\n * 2002/08      revised no"
  },
  {
    "path": "tests/test-c/nest1.h",
    "chars": 53,
    "preview": "/* nest1.h  */\n\n    nest = 1;\n\n#include    \"nest2.h\"\n"
  },
  {
    "path": "tests/test-c/nest10.h",
    "chars": 35,
    "preview": "/* nest10.h */\n#include \"nest11.h\"\n"
  },
  {
    "path": "tests/test-c/nest11.h",
    "chars": 35,
    "preview": "/* nest11.h */\n#include \"nest12.h\"\n"
  },
  {
    "path": "tests/test-c/nest12.h",
    "chars": 35,
    "preview": "/* nest12.h */\n#include \"nest13.h\"\n"
  },
  {
    "path": "tests/test-c/nest13.h",
    "chars": 35,
    "preview": "/* nest13.h */\n#include \"nest14.h\"\n"
  },
  {
    "path": "tests/test-c/nest14.h",
    "chars": 35,
    "preview": "/* nest14.h */\n#include \"nest15.h\"\n"
  },
  {
    "path": "tests/test-c/nest15.h",
    "chars": 51,
    "preview": "/* nest15.h */\n#ifdef  X0F\n    nest = 0x0f;\n#endif\n"
  },
  {
    "path": "tests/test-c/nest2.h",
    "chars": 53,
    "preview": "/* nest2.h  */\n\n    nest = 2;\n\n#include    \"nest3.h\"\n"
  },
  {
    "path": "tests/test-c/nest3.h",
    "chars": 53,
    "preview": "/* nest3.h  */\n\n    nest = 3;\n\n#include    \"nest4.h\"\n"
  },
  {
    "path": "tests/test-c/nest4.h",
    "chars": 53,
    "preview": "/* nest4.h  */\n\n    nest = 4;\n\n#include    \"nest5.h\"\n"
  },
  {
    "path": "tests/test-c/nest5.h",
    "chars": 53,
    "preview": "/* nest5.h  */\n\n    nest = 5;\n\n#include    \"nest6.h\"\n"
  },
  {
    "path": "tests/test-c/nest6.h",
    "chars": 53,
    "preview": "/* nest6.h  */\n\n    nest = 6;\n\n#include    \"nest7.h\"\n"
  },
  {
    "path": "tests/test-c/nest7.h",
    "chars": 53,
    "preview": "/* nest7.h  */\n\n    nest = 7;\n\n#include    \"nest8.h\"\n"
  },
  {
    "path": "tests/test-c/nest8.h",
    "chars": 78,
    "preview": "/* nest8.h  */\n\n#ifndef X0F\n    nest = 8;\n#else\n#include    \"nest9.h\"\n#endif\n\n"
  },
  {
    "path": "tests/test-c/nest9.h",
    "chars": 34,
    "preview": "/* nest9.h */\n#include \"nest10.h\"\n"
  },
  {
    "path": "tests/test-c/side_cpp",
    "chars": 1806,
    "preview": "                                        \n                                        \n                                      "
  },
  {
    "path": "tests/test-c/u_1_1.c",
    "chars": 487,
    "preview": "/* u_1_1.c:     Undefined behaviors on unterminated line, comment or macro. */\n\nmain( void)\n{\n\n/* u.1.1:   End of a sour"
  },
  {
    "path": "tests/test-c/u_1_11.c",
    "chars": 363,
    "preview": "/* u_1_11.c:    Undefined behaviors on undefined #include syntax or header-\n        name.   */\n\n/* u.1.11:  Header-name "
  },
  {
    "path": "tests/test-c/u_1_12.c",
    "chars": 213,
    "preview": "/* u_1_12.c:    Undefined behaviors on undefined #include syntax or header-\n        name.   */\n\n/* u.1.12:  Argument of "
  },
  {
    "path": "tests/test-c/u_1_13.c",
    "chars": 217,
    "preview": "/* u_1_13.c:    Undefined behaviors on undefined #include syntax or header-\n        name.   */\n\n/* u.1.13:  Excessive ar"
  },
  {
    "path": "tests/test-c/u_1_14.c",
    "chars": 396,
    "preview": "/* u_1_14.c:    Undefined behaviors on undefined #line syntax.  */\n\nmain( void)\n{\n\n/* u.1.14:  #line directive without a"
  },
  {
    "path": "tests/test-c/u_1_17.c",
    "chars": 662,
    "preview": "/* u_1_17.c:    Undefined behaviors on out-of-range #line number.   */\n\n#include    <stdio.h>\n\nmain( void)\n{\n\n/* u.1.17:"
  },
  {
    "path": "tests/test-c/u_1_19.c",
    "chars": 1096,
    "preview": "/* u_1_19.c:    Undefined behaviors on undefined #define and #undef syntax. */\n\n#include    <stdio.h>\n\nmain( void)\n{\n\n/*"
  },
  {
    "path": "tests/test-c/u_1_22.c",
    "chars": 755,
    "preview": "/* u_1_22.c:    Undefined behaviors on generating invalid pp-token by ##\n        operator.   */\n\n#include    <stdio.h>\n#"
  },
  {
    "path": "tests/test-c/u_1_23.c",
    "chars": 353,
    "preview": "/* u_1_23.c:    Undefined behaviors on generating invalid pp-token by #\n        operator.   */\n\n#include    <stdio.h>\n#d"
  },
  {
    "path": "tests/test-c/u_1_24.c",
    "chars": 1293,
    "preview": "/* u_1_24.c:    Undefined behaviors on empty argument of macro call.    */\n\n/* u.1.24:  Empty argument of macro call.   "
  },
  {
    "path": "tests/test-c/u_1_25.c",
    "chars": 574,
    "preview": "/* u_1_25.c:    Undefined behaviors on undefined macro argument.    */\n\n#include    <stdio.h>\n#define str( a)     # a\n#d"
  },
  {
    "path": "tests/test-c/u_1_27.c",
    "chars": 212,
    "preview": "/* u_1_27.c:    Pseudo-directive-line.  */\n\n/* u.1.27:  Unknown preprocessing directive (other than #pragma).   */\n#ifde"
  },
  {
    "path": "tests/test-c/u_1_28.c",
    "chars": 538,
    "preview": "/* u_1_28.c:    Macro expanding to name identical to directive. */\n\n#define D   define\n/* u.1.28:  There are following t"
  },
  {
    "path": "tests/test-c/u_1_5.c",
    "chars": 428,
    "preview": "/* u_1_5.c:     Undefined behaviors on illegal characters.  */\n\n/* u.1.5:   Illegal characters (in other than string lit"
  },
  {
    "path": "tests/test-c/u_1_7_big5.c",
    "chars": 364,
    "preview": "/* u_1_7_big5.c:    Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or"
  },
  {
    "path": "tests/test-c/u_1_7_eucjp.c",
    "chars": 301,
    "preview": "/* u_1_7_eucjp.c:   Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or"
  },
  {
    "path": "tests/test-c/u_1_7_gb.c",
    "chars": 360,
    "preview": "/* u_1_7_gb.c:  Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or com"
  },
  {
    "path": "tests/test-c/u_1_7_jis.c",
    "chars": 305,
    "preview": "/* u_1_7_jis.c: Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or com"
  },
  {
    "path": "tests/test-c/u_1_7_ksc.c",
    "chars": 360,
    "preview": "/* u_1_7_ksc.c: Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or com"
  },
  {
    "path": "tests/test-c/u_1_7_sjis.c",
    "chars": 365,
    "preview": "/* u_1_7_sjis.c:    Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or"
  },
  {
    "path": "tests/test-c/u_1_7_utf8.c",
    "chars": 494,
    "preview": "/* u_1_7_utf8.c:    Invalid multi-byte character sequence (in string literal,\n        character constant, header-name or"
  },
  {
    "path": "tests/test-c/u_1_8.c",
    "chars": 540,
    "preview": "/* u_1_8.c:     Undefined behaviors on unterminated quotations. */\n\n/* u.1.8:   Unterminated character constant.    */\n/"
  },
  {
    "path": "tests/test-c/u_2.c",
    "chars": 258,
    "preview": "/* u_2.c:   Undefined behaviors on undefined constant expression.   */\n\n/* u.2.1:   Undefined escape sequence.  */\n#if  "
  },
  {
    "path": "tests/test-c/unbal1.h",
    "chars": 22,
    "preview": "/* unbal1.h */\n#endif\n"
  }
]

// ... and 10 more files (download for full content)

About this extraction

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

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

Copied to clipboard!