Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/INSTALLER +1 -0
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/LICENSE +13 -0
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/METADATA +1264 -0
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/RECORD +62 -0
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/REQUESTED +0 -0
- rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/WHEEL +5 -0
- rtme/lib/python3.10/site-packages/einops/__init__.py +15 -0
- rtme/lib/python3.10/site-packages/einops/__pycache__/_torch_specific.cpython-310.pyc +0 -0
- rtme/lib/python3.10/site-packages/einops/__pycache__/parsing.cpython-310.pyc +0 -0
- rtme/lib/python3.10/site-packages/einops/_torch_specific.py +127 -0
- rtme/lib/python3.10/site-packages/einops/experimental/__init__.py +0 -0
- rtme/lib/python3.10/site-packages/einops/experimental/indexing.py +393 -0
- rtme/lib/python3.10/site-packages/einops/layers/__init__.py +106 -0
- rtme/lib/python3.10/site-packages/einops/layers/_einmix.py +176 -0
- rtme/lib/python3.10/site-packages/einops/layers/chainer.py +53 -0
- rtme/lib/python3.10/site-packages/einops/layers/flax.py +80 -0
- rtme/lib/python3.10/site-packages/einops/layers/keras.py +9 -0
- rtme/lib/python3.10/site-packages/einops/layers/paddle.py +59 -0
- rtme/lib/python3.10/site-packages/idna/compat.py +15 -0
- rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/METADATA +42 -0
- rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/REQUESTED +0 -0
- rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/WHEEL +5 -0
- rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/entry_points.txt +18 -0
- rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/top_level.txt +1 -0
- rtme/lib/python3.10/site-packages/mpmath/tests/test_rootfinding.py +91 -0
- rtme/lib/python3.10/site-packages/mpmath/tests/test_visualization.py +32 -0
- rtme/lib/python3.10/site-packages/mpmath/tests/torture.py +224 -0
- rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/INSTALLER +1 -0
- rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/METADATA +173 -0
- rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/RECORD +17 -0
- rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/WHEEL +4 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/License.txt +31 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/METADATA +35 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/RECORD +14 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/REQUESTED +0 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/WHEEL +5 -0
- rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/top_level.txt +1 -0
- rtme/lib/python3.10/site-packages/nvidia_nvjitlink_cu12-12.8.93.dist-info/License.txt +1568 -0
- rtme/lib/python3.10/site-packages/pycparser/__init__.py +93 -0
- rtme/lib/python3.10/site-packages/pycparser/_ast_gen.py +336 -0
- rtme/lib/python3.10/site-packages/pycparser/_build_tables.py +40 -0
- rtme/lib/python3.10/site-packages/pycparser/_c_ast.cfg +195 -0
- rtme/lib/python3.10/site-packages/pycparser/ast_transforms.py +164 -0
- rtme/lib/python3.10/site-packages/pycparser/c_ast.py +1125 -0
- rtme/lib/python3.10/site-packages/pycparser/c_generator.py +502 -0
- rtme/lib/python3.10/site-packages/pycparser/c_lexer.py +555 -0
- rtme/lib/python3.10/site-packages/pycparser/c_parser.py +1950 -0
- rtme/lib/python3.10/site-packages/pycparser/lextab.py +10 -0
- rtme/lib/python3.10/site-packages/pycparser/ply/__init__.py +5 -0
- rtme/lib/python3.10/site-packages/pycparser/ply/cpp.py +905 -0
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
uv
|
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) 2014-2017, Mozilla Foundation
|
| 2 |
+
|
| 3 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 4 |
+
you may not use this file except in compliance with the License.
|
| 5 |
+
You may obtain a copy of the License at
|
| 6 |
+
|
| 7 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 8 |
+
|
| 9 |
+
Unless required by applicable law or agreed to in writing, software
|
| 10 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 11 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 12 |
+
See the License for the specific language governing permissions and
|
| 13 |
+
limitations under the License.
|
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,1264 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: bleach
|
| 3 |
+
Version: 6.2.0
|
| 4 |
+
Summary: An easy safelist-based HTML-sanitizing tool.
|
| 5 |
+
Home-page: https://github.com/mozilla/bleach
|
| 6 |
+
Maintainer: Will Kahn-Greene
|
| 7 |
+
Maintainer-email: willkg@mozilla.com
|
| 8 |
+
License: Apache Software License
|
| 9 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 10 |
+
Classifier: Environment :: Web Environment
|
| 11 |
+
Classifier: Intended Audience :: Developers
|
| 12 |
+
Classifier: License :: OSI Approved :: Apache Software License
|
| 13 |
+
Classifier: Operating System :: OS Independent
|
| 14 |
+
Classifier: Programming Language :: Python
|
| 15 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 16 |
+
Classifier: Programming Language :: Python :: 3
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 21 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 22 |
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
| 23 |
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
| 24 |
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
| 25 |
+
Requires-Python: >=3.9
|
| 26 |
+
Description-Content-Type: text/x-rst
|
| 27 |
+
License-File: LICENSE
|
| 28 |
+
Requires-Dist: webencodings
|
| 29 |
+
Provides-Extra: css
|
| 30 |
+
Requires-Dist: tinycss2 <1.5,>=1.1.0 ; extra == 'css'
|
| 31 |
+
|
| 32 |
+
======
|
| 33 |
+
Bleach
|
| 34 |
+
======
|
| 35 |
+
|
| 36 |
+
.. image:: https://github.com/mozilla/bleach/workflows/Test/badge.svg
|
| 37 |
+
:target: https://github.com/mozilla/bleach/actions?query=workflow%3ATest
|
| 38 |
+
|
| 39 |
+
.. image:: https://github.com/mozilla/bleach/workflows/Lint/badge.svg
|
| 40 |
+
:target: https://github.com/mozilla/bleach/actions?query=workflow%3ALint
|
| 41 |
+
|
| 42 |
+
.. image:: https://badge.fury.io/py/bleach.svg
|
| 43 |
+
:target: http://badge.fury.io/py/bleach
|
| 44 |
+
|
| 45 |
+
**NOTE: 2023-01-23: Bleach is deprecated.** See issue:
|
| 46 |
+
`<https://github.com/mozilla/bleach/issues/698>`__
|
| 47 |
+
|
| 48 |
+
Bleach is an allowed-list-based HTML sanitizing library that escapes or strips
|
| 49 |
+
markup and attributes.
|
| 50 |
+
|
| 51 |
+
Bleach can also linkify text safely, applying filters that Django's ``urlize``
|
| 52 |
+
filter cannot, and optionally setting ``rel`` attributes, even on links already
|
| 53 |
+
in the text.
|
| 54 |
+
|
| 55 |
+
Bleach is intended for sanitizing text from *untrusted* sources. If you find
|
| 56 |
+
yourself jumping through hoops to allow your site administrators to do lots of
|
| 57 |
+
things, you're probably outside the use cases. Either trust those users, or
|
| 58 |
+
don't.
|
| 59 |
+
|
| 60 |
+
Because it relies on html5lib_, Bleach is as good as modern browsers at dealing
|
| 61 |
+
with weird, quirky HTML fragments. And *any* of Bleach's methods will fix
|
| 62 |
+
unbalanced or mis-nested tags.
|
| 63 |
+
|
| 64 |
+
The version on GitHub_ is the most up-to-date and contains the latest bug
|
| 65 |
+
fixes. You can find full documentation on `ReadTheDocs`_.
|
| 66 |
+
|
| 67 |
+
:Code: https://github.com/mozilla/bleach
|
| 68 |
+
:Documentation: https://bleach.readthedocs.io/
|
| 69 |
+
:Issue tracker: https://github.com/mozilla/bleach/issues
|
| 70 |
+
:License: Apache License v2; see LICENSE file
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
Reporting Bugs
|
| 74 |
+
==============
|
| 75 |
+
|
| 76 |
+
For regular bugs, please report them `in our issue tracker
|
| 77 |
+
<https://github.com/mozilla/bleach/issues>`_.
|
| 78 |
+
|
| 79 |
+
If you believe that you've found a security vulnerability, please `file a secure
|
| 80 |
+
bug report in our bug tracker
|
| 81 |
+
<https://bugzilla.mozilla.org/enter_bug.cgi?assigned_to=nobody%40mozilla.org&product=Webtools&component=Bleach-security&groups=webtools-security>`_
|
| 82 |
+
or send an email to *security AT mozilla DOT org*.
|
| 83 |
+
|
| 84 |
+
For more information on security-related bug disclosure and the PGP key to use
|
| 85 |
+
for sending encrypted mail or to verify responses received from that address,
|
| 86 |
+
please read our wiki page at
|
| 87 |
+
`<https://www.mozilla.org/en-US/security/#For_Developers>`_.
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
Security
|
| 91 |
+
========
|
| 92 |
+
|
| 93 |
+
Bleach is a security-focused library.
|
| 94 |
+
|
| 95 |
+
We have a responsible security vulnerability reporting process. Please use
|
| 96 |
+
that if you're reporting a security issue.
|
| 97 |
+
|
| 98 |
+
Security issues are fixed in private. After we land such a fix, we'll do a
|
| 99 |
+
release.
|
| 100 |
+
|
| 101 |
+
For every release, we mark security issues we've fixed in the ``CHANGES`` in
|
| 102 |
+
the **Security issues** section. We include any relevant CVE links.
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
Installing Bleach
|
| 106 |
+
=================
|
| 107 |
+
|
| 108 |
+
Bleach is available on PyPI_, so you can install it with ``pip``::
|
| 109 |
+
|
| 110 |
+
$ pip install bleach
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
Upgrading Bleach
|
| 114 |
+
================
|
| 115 |
+
|
| 116 |
+
.. warning::
|
| 117 |
+
|
| 118 |
+
Before doing any upgrades, read through `Bleach Changes
|
| 119 |
+
<https://bleach.readthedocs.io/en/latest/changes.html>`_ for backwards
|
| 120 |
+
incompatible changes, newer versions, etc.
|
| 121 |
+
|
| 122 |
+
Bleach follows `semver 2`_ versioning. Vendored libraries will not
|
| 123 |
+
be changed in patch releases.
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
Basic use
|
| 127 |
+
=========
|
| 128 |
+
|
| 129 |
+
The simplest way to use Bleach is:
|
| 130 |
+
|
| 131 |
+
.. code-block:: python
|
| 132 |
+
|
| 133 |
+
>>> import bleach
|
| 134 |
+
|
| 135 |
+
>>> bleach.clean('an <script>evil()</script> example')
|
| 136 |
+
u'an <script>evil()</script> example'
|
| 137 |
+
|
| 138 |
+
>>> bleach.linkify('an http://example.com url')
|
| 139 |
+
u'an <a href="http://example.com" rel="nofollow">http://example.com</a> url'
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
Code of Conduct
|
| 143 |
+
===============
|
| 144 |
+
|
| 145 |
+
This project and repository is governed by Mozilla's code of conduct and
|
| 146 |
+
etiquette guidelines. For more details please see the `CODE_OF_CONDUCT.md
|
| 147 |
+
</CODE_OF_CONDUCT.md>`_
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
.. _html5lib: https://github.com/html5lib/html5lib-python
|
| 151 |
+
.. _GitHub: https://github.com/mozilla/bleach
|
| 152 |
+
.. _ReadTheDocs: https://bleach.readthedocs.io/
|
| 153 |
+
.. _PyPI: https://pypi.org/project/bleach/
|
| 154 |
+
.. _semver 2: https://semver.org/
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
Bleach changes
|
| 158 |
+
==============
|
| 159 |
+
|
| 160 |
+
Version 6.2.0 (October 29th, 2024)
|
| 161 |
+
----------------------------------
|
| 162 |
+
**Backwards incompatible changes**
|
| 163 |
+
|
| 164 |
+
* Dropped support for Python 3.8. (#737)
|
| 165 |
+
|
| 166 |
+
**Security fixes**
|
| 167 |
+
|
| 168 |
+
None
|
| 169 |
+
|
| 170 |
+
**Bug fixes**
|
| 171 |
+
|
| 172 |
+
* Add support for Python 3.13. (#736)
|
| 173 |
+
* Remove six depdenncy. (#618)
|
| 174 |
+
* Update known-good versions for tinycss2. (#732)
|
| 175 |
+
* Fix additional < followed by characters and EOF issues. (#728)
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
Version 6.1.0 (October 6th, 2023)
|
| 179 |
+
---------------------------------
|
| 180 |
+
|
| 181 |
+
**Backwards incompatible changes**
|
| 182 |
+
|
| 183 |
+
* Dropped support for Python 3.7. (#709)
|
| 184 |
+
|
| 185 |
+
**Security fixes**
|
| 186 |
+
|
| 187 |
+
None
|
| 188 |
+
|
| 189 |
+
**Bug fixes**
|
| 190 |
+
|
| 191 |
+
* Add support for Python 3.12. (#710)
|
| 192 |
+
* Fix linkify with arrays in querystring (#436)
|
| 193 |
+
* Handle more cases with < followed by character data (#705)
|
| 194 |
+
* Fix entities inside a tags in linkification (#704)
|
| 195 |
+
* Update cap for tinycss2 to <1.3 (#702)
|
| 196 |
+
* Updated Sphinx requirement
|
| 197 |
+
* Add dependabot for github actions and update github actions
|
| 198 |
+
|
| 199 |
+
|
| 200 |
+
Version 6.0.0 (January 23rd, 2023)
|
| 201 |
+
----------------------------------
|
| 202 |
+
|
| 203 |
+
**Backwards incompatible changes**
|
| 204 |
+
|
| 205 |
+
* ``bleach.clean``, ``bleach.sanitizer.Cleaner``,
|
| 206 |
+
``bleach.html5lib_shim.BleachHTMLParser``: the ``tags`` and ``protocols``
|
| 207 |
+
arguments were changed from lists to sets.
|
| 208 |
+
|
| 209 |
+
Old pre-6.0.0:
|
| 210 |
+
|
| 211 |
+
.. code-block:: python
|
| 212 |
+
|
| 213 |
+
bleach.clean(
|
| 214 |
+
"some text",
|
| 215 |
+
tags=["a", "p", "img"],
|
| 216 |
+
# ^ ^ list
|
| 217 |
+
protocols=["http", "https"],
|
| 218 |
+
# ^ ^ list
|
| 219 |
+
)
|
| 220 |
+
|
| 221 |
+
|
| 222 |
+
New 6.0.0 and later:
|
| 223 |
+
|
| 224 |
+
.. code-block:: python
|
| 225 |
+
|
| 226 |
+
bleach.clean(
|
| 227 |
+
"some text",
|
| 228 |
+
tags={"a", "p", "img"},
|
| 229 |
+
# ^ ^ set
|
| 230 |
+
protocols={"http", "https"},
|
| 231 |
+
# ^ ^ set
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
* ``bleach.linkify``, ``bleach.linkifier.Linker``: the ``skip_tags`` and
|
| 235 |
+
``recognized_tags`` arguments were changed from lists to sets.
|
| 236 |
+
|
| 237 |
+
Old pre-6.0.0:
|
| 238 |
+
|
| 239 |
+
.. code-block:: python
|
| 240 |
+
|
| 241 |
+
bleach.linkify(
|
| 242 |
+
"some text",
|
| 243 |
+
skip_tags=["pre"],
|
| 244 |
+
# ^ ^ list
|
| 245 |
+
)
|
| 246 |
+
|
| 247 |
+
linker = Linker(
|
| 248 |
+
skip_tags=["pre"],
|
| 249 |
+
# ^ ^ list
|
| 250 |
+
recognized_tags=html5lib_shim.HTML_TAGS + ["custom-element"],
|
| 251 |
+
# ^ ^ ^ list
|
| 252 |
+
# |
|
| 253 |
+
# | list concatenation
|
| 254 |
+
)
|
| 255 |
+
|
| 256 |
+
New 6.0.0 and later:
|
| 257 |
+
|
| 258 |
+
.. code-block:: python
|
| 259 |
+
|
| 260 |
+
bleach.linkify(
|
| 261 |
+
"some text",
|
| 262 |
+
skip_tags={"pre"},
|
| 263 |
+
# ^ ^ set
|
| 264 |
+
)
|
| 265 |
+
|
| 266 |
+
linker = Linker(
|
| 267 |
+
skip_tags={"pre"},
|
| 268 |
+
# ^ ^ set
|
| 269 |
+
recognized_tags=html5lib_shim.HTML_TAGS | {"custom-element"},
|
| 270 |
+
# ^ ^ ^ set
|
| 271 |
+
# |
|
| 272 |
+
# | union operator
|
| 273 |
+
)
|
| 274 |
+
|
| 275 |
+
* ``bleach.sanitizer.BleachSanitizerFilter``: ``strip_allowed_elements`` is now
|
| 276 |
+
``strip_allowed_tags``. We now use "tags" everywhere rather than a mishmash
|
| 277 |
+
of "tags" in some places and "elements" in others.
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
**Security fixes**
|
| 281 |
+
|
| 282 |
+
None
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
**Bug fixes**
|
| 286 |
+
|
| 287 |
+
* Add support for Python 3.11. (#675)
|
| 288 |
+
|
| 289 |
+
* Fix API weirness in ``BleachSanitizerFilter``. (#649)
|
| 290 |
+
|
| 291 |
+
We're using "tags" instead of "elements" everywhere--no more weird
|
| 292 |
+
overloading of "elements" anymore.
|
| 293 |
+
|
| 294 |
+
Also, it no longer calls the superclass constructor.
|
| 295 |
+
|
| 296 |
+
* Add warning when ``css_sanitizer`` isn't set, but the ``style``
|
| 297 |
+
attribute is allowed. (#676)
|
| 298 |
+
|
| 299 |
+
* Fix linkify handling of character entities. (#501)
|
| 300 |
+
|
| 301 |
+
* Rework dev dependencies to use ``requirements-dev.txt`` and
|
| 302 |
+
``requirements-flake8.txt`` instead of extras.
|
| 303 |
+
|
| 304 |
+
* Fix project infrastructure to be tox-based so it's easier to have CI
|
| 305 |
+
run the same things we're running in development and with flake8
|
| 306 |
+
in an isolated environment.
|
| 307 |
+
|
| 308 |
+
* Update action versions in CI.
|
| 309 |
+
|
| 310 |
+
* Switch to f-strings where possible. Make tests parametrized to be
|
| 311 |
+
easier to read/maintain.
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
Version 5.0.1 (June 27th, 2022)
|
| 315 |
+
-------------------------------
|
| 316 |
+
|
| 317 |
+
**Security fixes**
|
| 318 |
+
|
| 319 |
+
None
|
| 320 |
+
|
| 321 |
+
|
| 322 |
+
**Bug fixes**
|
| 323 |
+
|
| 324 |
+
* Add missing comma to tinycss2 require. Thank you, @shadchin!
|
| 325 |
+
|
| 326 |
+
* Add url parse tests based on wpt url tests. (#688)
|
| 327 |
+
|
| 328 |
+
* Support scheme-less urls if "https" is in allow list. (#662)
|
| 329 |
+
|
| 330 |
+
* Handle escaping ``<`` in edge cases where it doesn't start a tag. (#544)
|
| 331 |
+
|
| 332 |
+
* Fix reference warnings in docs. (#660)
|
| 333 |
+
|
| 334 |
+
* Correctly urlencode email address parts. Thank you, @larseggert! (#659)
|
| 335 |
+
|
| 336 |
+
|
| 337 |
+
Version 5.0.0 (April 7th, 2022)
|
| 338 |
+
-------------------------------
|
| 339 |
+
|
| 340 |
+
**Backwards incompatible changes**
|
| 341 |
+
|
| 342 |
+
* ``clean`` and ``linkify`` now preserve the order of HTML attributes. Thank
|
| 343 |
+
you, @askoretskly! (#566)
|
| 344 |
+
|
| 345 |
+
* Drop support for Python 3.6. Thank you, @hugovk! (#629)
|
| 346 |
+
|
| 347 |
+
* CSS sanitization in style tags is completely different now. If you're using
|
| 348 |
+
Bleach ``clean`` to sanitize css in style tags, you'll need to update your
|
| 349 |
+
code and you'll need to install the ``css`` extras::
|
| 350 |
+
|
| 351 |
+
pip install 'bleach[css]'
|
| 352 |
+
|
| 353 |
+
See `the documentation on sanitizing CSS for how to do it
|
| 354 |
+
<https://bleach.readthedocs.io/en/latest/clean.html#sanitizing-css>`_. (#633)
|
| 355 |
+
|
| 356 |
+
**Security fixes**
|
| 357 |
+
|
| 358 |
+
None
|
| 359 |
+
|
| 360 |
+
**Bug fixes**
|
| 361 |
+
|
| 362 |
+
* Rework dev dependencies. We no longer have
|
| 363 |
+
``requirements-dev.in``/``requirements-dev.txt``. Instead, we're using
|
| 364 |
+
``dev`` extras.
|
| 365 |
+
|
| 366 |
+
See `development docs <https://bleach.readthedocs.io/en/latest/dev.html>`_
|
| 367 |
+
for more details. (#620)
|
| 368 |
+
|
| 369 |
+
* Add newline when dropping block-level tags. Thank you, @jvanasco! (#369)
|
| 370 |
+
|
| 371 |
+
|
| 372 |
+
Version 4.1.0 (August 25th, 2021)
|
| 373 |
+
---------------------------------
|
| 374 |
+
|
| 375 |
+
**Features**
|
| 376 |
+
|
| 377 |
+
* Python 3.9 support
|
| 378 |
+
|
| 379 |
+
**Security fixes**
|
| 380 |
+
|
| 381 |
+
None
|
| 382 |
+
|
| 383 |
+
**Bug fixes**
|
| 384 |
+
|
| 385 |
+
* Update sanitizer clean to use vendored 3.6.14 stdlib urllib.parse to
|
| 386 |
+
fix test failures on Python 3.9. (#536)
|
| 387 |
+
|
| 388 |
+
|
| 389 |
+
Version 4.0.0 (August 3rd, 2021)
|
| 390 |
+
--------------------------------
|
| 391 |
+
|
| 392 |
+
**Backwards incompatible changes**
|
| 393 |
+
|
| 394 |
+
* Drop support for unsupported Python versions <3.6. (#520)
|
| 395 |
+
|
| 396 |
+
**Security fixes**
|
| 397 |
+
|
| 398 |
+
None
|
| 399 |
+
|
| 400 |
+
**Features**
|
| 401 |
+
|
| 402 |
+
* fix attribute name in the linkify docs (thanks @CheesyFeet!)
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
Version 3.3.1 (July 14th, 2021)
|
| 406 |
+
-------------------------------
|
| 407 |
+
|
| 408 |
+
**Security fixes**
|
| 409 |
+
|
| 410 |
+
None
|
| 411 |
+
|
| 412 |
+
**Features**
|
| 413 |
+
|
| 414 |
+
* add more tests for CVE-2021-23980 / GHSA-vv2x-vrpj-qqpq
|
| 415 |
+
* bump python version to 3.8 for tox doc, vendorverify, and lint targets
|
| 416 |
+
* update bug report template tag
|
| 417 |
+
* update vendorverify script to detect and fail when extra files are vendored
|
| 418 |
+
* update release process docs to check vendorverify passes locally
|
| 419 |
+
|
| 420 |
+
**Bug fixes**
|
| 421 |
+
|
| 422 |
+
* remove extra vendored django present in the v3.3.0 whl (#595)
|
| 423 |
+
* duplicate h1 header doc fix (thanks Nguyễn Gia Phong / @McSinyx!)
|
| 424 |
+
|
| 425 |
+
|
| 426 |
+
Version 3.3.0 (February 1st, 2021)
|
| 427 |
+
----------------------------------
|
| 428 |
+
|
| 429 |
+
**Backwards incompatible changes**
|
| 430 |
+
|
| 431 |
+
* clean escapes HTML comments even when strip_comments=False
|
| 432 |
+
|
| 433 |
+
**Security fixes**
|
| 434 |
+
|
| 435 |
+
* Fix bug 1621692 / GHSA-m6xf-fq7q-8743. See the advisory for details.
|
| 436 |
+
|
| 437 |
+
**Features**
|
| 438 |
+
|
| 439 |
+
None
|
| 440 |
+
|
| 441 |
+
**Bug fixes**
|
| 442 |
+
|
| 443 |
+
None
|
| 444 |
+
|
| 445 |
+
|
| 446 |
+
Version 3.2.3 (January 26th, 2021)
|
| 447 |
+
----------------------------------
|
| 448 |
+
|
| 449 |
+
**Security fixes**
|
| 450 |
+
|
| 451 |
+
None
|
| 452 |
+
|
| 453 |
+
**Features**
|
| 454 |
+
|
| 455 |
+
None
|
| 456 |
+
|
| 457 |
+
**Bug fixes**
|
| 458 |
+
|
| 459 |
+
* fix clean and linkify raising ValueErrors for certain inputs. Thank you @Google-Autofuzz.
|
| 460 |
+
|
| 461 |
+
|
| 462 |
+
Version 3.2.2 (January 20th, 2021)
|
| 463 |
+
----------------------------------
|
| 464 |
+
|
| 465 |
+
**Security fixes**
|
| 466 |
+
|
| 467 |
+
None
|
| 468 |
+
|
| 469 |
+
**Features**
|
| 470 |
+
|
| 471 |
+
* Migrate CI to Github Actions. Thank you @hugovk.
|
| 472 |
+
|
| 473 |
+
**Bug fixes**
|
| 474 |
+
|
| 475 |
+
* fix linkify raising an IndexError on certain inputs. Thank you @Google-Autofuzz.
|
| 476 |
+
|
| 477 |
+
|
| 478 |
+
Version 3.2.1 (September 18th, 2020)
|
| 479 |
+
------------------------------------
|
| 480 |
+
|
| 481 |
+
**Security fixes**
|
| 482 |
+
|
| 483 |
+
None
|
| 484 |
+
|
| 485 |
+
**Features**
|
| 486 |
+
|
| 487 |
+
None
|
| 488 |
+
|
| 489 |
+
**Bug fixes**
|
| 490 |
+
|
| 491 |
+
* change linkifier to add rel="nofollow" as documented. Thank you @mitar.
|
| 492 |
+
* suppress html5lib sanitizer DeprecationWarnings (#557)
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
Version 3.2.0 (September 16th, 2020)
|
| 496 |
+
------------------------------------
|
| 497 |
+
|
| 498 |
+
**Security fixes**
|
| 499 |
+
|
| 500 |
+
None
|
| 501 |
+
|
| 502 |
+
**Features**
|
| 503 |
+
|
| 504 |
+
None
|
| 505 |
+
|
| 506 |
+
**Bug fixes**
|
| 507 |
+
|
| 508 |
+
* ``html5lib`` dependency to version 1.1.0. Thank you Sam Sneddon.
|
| 509 |
+
* update tests_website terminology. Thank you Thomas Grainger.
|
| 510 |
+
|
| 511 |
+
|
| 512 |
+
Version 3.1.5 (April 29th, 2020)
|
| 513 |
+
--------------------------------
|
| 514 |
+
|
| 515 |
+
**Security fixes**
|
| 516 |
+
|
| 517 |
+
None
|
| 518 |
+
|
| 519 |
+
**Features**
|
| 520 |
+
|
| 521 |
+
None
|
| 522 |
+
|
| 523 |
+
**Bug fixes**
|
| 524 |
+
|
| 525 |
+
* replace missing ``setuptools`` dependency with ``packaging``. Thank you Benjamin Peterson.
|
| 526 |
+
|
| 527 |
+
|
| 528 |
+
Version 3.1.4 (March 24th, 2020)
|
| 529 |
+
--------------------------------
|
| 530 |
+
|
| 531 |
+
**Security fixes**
|
| 532 |
+
|
| 533 |
+
* ``bleach.clean`` behavior parsing style attributes could result in a
|
| 534 |
+
regular expression denial of service (ReDoS).
|
| 535 |
+
|
| 536 |
+
Calls to ``bleach.clean`` with an allowed tag with an allowed
|
| 537 |
+
``style`` attribute were vulnerable to ReDoS. For example,
|
| 538 |
+
``bleach.clean(..., attributes={'a': ['style']})``.
|
| 539 |
+
|
| 540 |
+
This issue was confirmed in Bleach versions v3.1.3, v3.1.2, v3.1.1,
|
| 541 |
+
v3.1.0, v3.0.0, v2.1.4, and v2.1.3. Earlier versions used a similar
|
| 542 |
+
regular expression and should be considered vulnerable too.
|
| 543 |
+
|
| 544 |
+
Anyone using Bleach <=v3.1.3 is encouraged to upgrade.
|
| 545 |
+
|
| 546 |
+
https://bugzilla.mozilla.org/show_bug.cgi?id=1623633
|
| 547 |
+
|
| 548 |
+
**Backwards incompatible changes**
|
| 549 |
+
|
| 550 |
+
* Style attributes with dashes, or single or double quoted values are
|
| 551 |
+
cleaned instead of passed through.
|
| 552 |
+
|
| 553 |
+
**Features**
|
| 554 |
+
|
| 555 |
+
None
|
| 556 |
+
|
| 557 |
+
**Bug fixes**
|
| 558 |
+
|
| 559 |
+
None
|
| 560 |
+
|
| 561 |
+
|
| 562 |
+
Version 3.1.3 (March 17th, 2020)
|
| 563 |
+
--------------------------------
|
| 564 |
+
|
| 565 |
+
**Security fixes**
|
| 566 |
+
|
| 567 |
+
None
|
| 568 |
+
|
| 569 |
+
**Backwards incompatible changes**
|
| 570 |
+
|
| 571 |
+
* Drop support for Python 3.4. Thank you, @hugovk!
|
| 572 |
+
|
| 573 |
+
* Drop deprecated ``setup.py test`` support. Thank you, @jdufresne! (#507)
|
| 574 |
+
|
| 575 |
+
**Features**
|
| 576 |
+
|
| 577 |
+
* Add support for Python 3.8. Thank you, @jdufresne!
|
| 578 |
+
|
| 579 |
+
* Add support for PyPy 7. Thank you, @hugovk!
|
| 580 |
+
|
| 581 |
+
* Add pypy3 testing to tox and travis. Thank you, @jdufresne!
|
| 582 |
+
|
| 583 |
+
**Bug fixes**
|
| 584 |
+
|
| 585 |
+
* Add relative link to code of conduct. (#442)
|
| 586 |
+
|
| 587 |
+
* Fix typo: curren -> current in tests/test_clean.py Thank you, timgates42! (#504)
|
| 588 |
+
|
| 589 |
+
* Fix handling of non-ascii style attributes. Thank you, @sekineh! (#426)
|
| 590 |
+
|
| 591 |
+
* Simplify tox configuration. Thank you, @jdufresne!
|
| 592 |
+
|
| 593 |
+
* Make documentation reproducible. Thank you, @lamby!
|
| 594 |
+
|
| 595 |
+
* Fix typos in code comments. Thank you, @zborboa-g!
|
| 596 |
+
|
| 597 |
+
* Fix exception value testing. Thank you, @mastizada!
|
| 598 |
+
|
| 599 |
+
* Fix parser-tags NoneType exception. Thank you, @bope!
|
| 600 |
+
|
| 601 |
+
* Improve TLD support in linkify. Thank you, @pc-coholic!
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
Version 3.1.2 (March 11th, 2020)
|
| 605 |
+
--------------------------------
|
| 606 |
+
|
| 607 |
+
**Security fixes**
|
| 608 |
+
|
| 609 |
+
* ``bleach.clean`` behavior parsing embedded MathML and SVG content
|
| 610 |
+
with RCDATA tags did not match browser behavior and could result in
|
| 611 |
+
a mutation XSS.
|
| 612 |
+
|
| 613 |
+
Calls to ``bleach.clean`` with ``strip=False`` and ``math`` or
|
| 614 |
+
``svg`` tags and one or more of the RCDATA tags ``script``,
|
| 615 |
+
``noscript``, ``style``, ``noframes``, ``iframe``, ``noembed``, or
|
| 616 |
+
``xmp`` in the allowed tags whitelist were vulnerable to a mutation
|
| 617 |
+
XSS.
|
| 618 |
+
|
| 619 |
+
This security issue was confirmed in Bleach version v3.1.1. Earlier
|
| 620 |
+
versions are likely affected too.
|
| 621 |
+
|
| 622 |
+
Anyone using Bleach <=v3.1.1 is encouraged to upgrade.
|
| 623 |
+
|
| 624 |
+
https://bugzilla.mozilla.org/show_bug.cgi?id=1621692
|
| 625 |
+
|
| 626 |
+
**Backwards incompatible changes**
|
| 627 |
+
|
| 628 |
+
None
|
| 629 |
+
|
| 630 |
+
**Features**
|
| 631 |
+
|
| 632 |
+
None
|
| 633 |
+
|
| 634 |
+
**Bug fixes**
|
| 635 |
+
|
| 636 |
+
None
|
| 637 |
+
|
| 638 |
+
|
| 639 |
+
Version 3.1.1 (February 13th, 2020)
|
| 640 |
+
-----------------------------------
|
| 641 |
+
|
| 642 |
+
**Security fixes**
|
| 643 |
+
|
| 644 |
+
* ``bleach.clean`` behavior parsing ``noscript`` tags did not match
|
| 645 |
+
browser behavior.
|
| 646 |
+
|
| 647 |
+
Calls to ``bleach.clean`` allowing ``noscript`` and one or more of
|
| 648 |
+
the raw text tags (``title``, ``textarea``, ``script``, ``style``,
|
| 649 |
+
``noembed``, ``noframes``, ``iframe``, and ``xmp``) were vulnerable
|
| 650 |
+
to a mutation XSS.
|
| 651 |
+
|
| 652 |
+
This security issue was confirmed in Bleach versions v2.1.4, v3.0.2,
|
| 653 |
+
and v3.1.0. Earlier versions are probably affected too.
|
| 654 |
+
|
| 655 |
+
Anyone using Bleach <=v3.1.0 is highly encouraged to upgrade.
|
| 656 |
+
|
| 657 |
+
https://bugzilla.mozilla.org/show_bug.cgi?id=1615315
|
| 658 |
+
|
| 659 |
+
**Backwards incompatible changes**
|
| 660 |
+
|
| 661 |
+
None
|
| 662 |
+
|
| 663 |
+
**Features**
|
| 664 |
+
|
| 665 |
+
None
|
| 666 |
+
|
| 667 |
+
**Bug fixes**
|
| 668 |
+
|
| 669 |
+
None
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
Version 3.1.0 (January 9th, 2019)
|
| 673 |
+
---------------------------------
|
| 674 |
+
|
| 675 |
+
**Security fixes**
|
| 676 |
+
|
| 677 |
+
None
|
| 678 |
+
|
| 679 |
+
**Backwards incompatible changes**
|
| 680 |
+
|
| 681 |
+
None
|
| 682 |
+
|
| 683 |
+
**Features**
|
| 684 |
+
|
| 685 |
+
* Add ``recognized_tags`` argument to the linkify ``Linker`` class. This
|
| 686 |
+
fixes issues when linkifying on its own and having some tags get escaped.
|
| 687 |
+
It defaults to a list of HTML5 tags. Thank you, Chad Birch! (#409)
|
| 688 |
+
|
| 689 |
+
**Bug fixes**
|
| 690 |
+
|
| 691 |
+
* Add ``six>=1.9`` to requirements. Thank you, Dave Shawley (#416)
|
| 692 |
+
|
| 693 |
+
* Fix cases where attribute names could have invalid characters in them.
|
| 694 |
+
(#419)
|
| 695 |
+
|
| 696 |
+
* Fix problems with ``LinkifyFilter`` not being able to match links
|
| 697 |
+
across ``&``. (#422)
|
| 698 |
+
|
| 699 |
+
* Fix ``InputStreamWithMemory`` when the ``BleachHTMLParser`` is
|
| 700 |
+
parsing ``meta`` tags. (#431)
|
| 701 |
+
|
| 702 |
+
* Fix doctests. (#357)
|
| 703 |
+
|
| 704 |
+
|
| 705 |
+
Version 3.0.2 (October 11th, 2018)
|
| 706 |
+
----------------------------------
|
| 707 |
+
|
| 708 |
+
**Security fixes**
|
| 709 |
+
|
| 710 |
+
None
|
| 711 |
+
|
| 712 |
+
**Backwards incompatible changes**
|
| 713 |
+
|
| 714 |
+
None
|
| 715 |
+
|
| 716 |
+
**Features**
|
| 717 |
+
|
| 718 |
+
None
|
| 719 |
+
|
| 720 |
+
**Bug fixes**
|
| 721 |
+
|
| 722 |
+
* Merge ``Characters`` tokens after sanitizing them. This fixes issues in the
|
| 723 |
+
``LinkifyFilter`` where it was only linkifying parts of urls. (#374)
|
| 724 |
+
|
| 725 |
+
|
| 726 |
+
Version 3.0.1 (October 9th, 2018)
|
| 727 |
+
---------------------------------
|
| 728 |
+
|
| 729 |
+
**Security fixes**
|
| 730 |
+
|
| 731 |
+
None
|
| 732 |
+
|
| 733 |
+
**Backwards incompatible changes**
|
| 734 |
+
|
| 735 |
+
None
|
| 736 |
+
|
| 737 |
+
**Features**
|
| 738 |
+
|
| 739 |
+
* Support Python 3.7. It supported Python 3.7 just fine, but we added 3.7 to
|
| 740 |
+
the list of Python environments we test so this is now officially supported.
|
| 741 |
+
(#377)
|
| 742 |
+
|
| 743 |
+
**Bug fixes**
|
| 744 |
+
|
| 745 |
+
* Fix ``list`` object has no attribute ``lower`` in ``clean``. (#398)
|
| 746 |
+
* Fix ``abbr`` getting escaped in ``linkify``. (#400)
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
Version 3.0.0 (October 3rd, 2018)
|
| 750 |
+
---------------------------------
|
| 751 |
+
|
| 752 |
+
**Security fixes**
|
| 753 |
+
|
| 754 |
+
None
|
| 755 |
+
|
| 756 |
+
**Backwards incompatible changes**
|
| 757 |
+
|
| 758 |
+
* A bunch of functions were moved from one module to another.
|
| 759 |
+
|
| 760 |
+
These were moved from ``bleach.sanitizer`` to ``bleach.html5lib_shim``:
|
| 761 |
+
|
| 762 |
+
* ``convert_entity``
|
| 763 |
+
* ``convert_entities``
|
| 764 |
+
* ``match_entity``
|
| 765 |
+
* ``next_possible_entity``
|
| 766 |
+
* ``BleachHTMLSerializer``
|
| 767 |
+
* ``BleachHTMLTokenizer``
|
| 768 |
+
* ``BleachHTMLParser``
|
| 769 |
+
|
| 770 |
+
These functions and classes weren't documented and aren't part of the
|
| 771 |
+
public API, but people read code and might be using them so we're
|
| 772 |
+
considering it an incompatible API change.
|
| 773 |
+
|
| 774 |
+
If you're using them, you'll need to update your code.
|
| 775 |
+
|
| 776 |
+
**Features**
|
| 777 |
+
|
| 778 |
+
* Bleach no longer depends on html5lib. html5lib==1.0.1 is now vendored into
|
| 779 |
+
Bleach. You can remove it from your requirements file if none of your other
|
| 780 |
+
requirements require html5lib.
|
| 781 |
+
|
| 782 |
+
This means Bleach will now work fine with other libraries that depend on
|
| 783 |
+
html5lib regardless of what version of html5lib they require. (#386)
|
| 784 |
+
|
| 785 |
+
**Bug fixes**
|
| 786 |
+
|
| 787 |
+
* Fixed tags getting added when using clean or linkify. This was a
|
| 788 |
+
long-standing regression from the Bleach 2.0 rewrite. (#280, #392)
|
| 789 |
+
|
| 790 |
+
* Fixed ``<isindex>`` getting replaced with a string. Now it gets escaped or
|
| 791 |
+
stripped depending on whether it's in the allowed tags or not. (#279)
|
| 792 |
+
|
| 793 |
+
|
| 794 |
+
Version 2.1.4 (August 16th, 2018)
|
| 795 |
+
---------------------------------
|
| 796 |
+
|
| 797 |
+
**Security fixes**
|
| 798 |
+
|
| 799 |
+
None
|
| 800 |
+
|
| 801 |
+
**Backwards incompatible changes**
|
| 802 |
+
|
| 803 |
+
* Dropped support for Python 3.3. (#328)
|
| 804 |
+
|
| 805 |
+
**Features**
|
| 806 |
+
|
| 807 |
+
None
|
| 808 |
+
|
| 809 |
+
**Bug fixes**
|
| 810 |
+
|
| 811 |
+
* Handle ambiguous ampersands in correctly. (#359)
|
| 812 |
+
|
| 813 |
+
|
| 814 |
+
Version 2.1.3 (March 5th, 2018)
|
| 815 |
+
-------------------------------
|
| 816 |
+
|
| 817 |
+
**Security fixes**
|
| 818 |
+
|
| 819 |
+
* Attributes that have URI values weren't properly sanitized if the
|
| 820 |
+
values contained character entities. Using character entities, it
|
| 821 |
+
was possible to construct a URI value with a scheme that was not
|
| 822 |
+
allowed that would slide through unsanitized.
|
| 823 |
+
|
| 824 |
+
This security issue was introduced in Bleach 2.1. Anyone using
|
| 825 |
+
Bleach 2.1 is highly encouraged to upgrade.
|
| 826 |
+
|
| 827 |
+
https://bugzilla.mozilla.org/show_bug.cgi?id=1442745
|
| 828 |
+
|
| 829 |
+
**Backwards incompatible changes**
|
| 830 |
+
|
| 831 |
+
None
|
| 832 |
+
|
| 833 |
+
**Features**
|
| 834 |
+
|
| 835 |
+
None
|
| 836 |
+
|
| 837 |
+
**Bug fixes**
|
| 838 |
+
|
| 839 |
+
* Fixed some other edge cases for attribute URI value sanitizing and
|
| 840 |
+
improved testing of this code.
|
| 841 |
+
|
| 842 |
+
|
| 843 |
+
Version 2.1.2 (December 7th, 2017)
|
| 844 |
+
----------------------------------
|
| 845 |
+
|
| 846 |
+
**Security fixes**
|
| 847 |
+
|
| 848 |
+
None
|
| 849 |
+
|
| 850 |
+
**Backwards incompatible changes**
|
| 851 |
+
|
| 852 |
+
None
|
| 853 |
+
|
| 854 |
+
**Features**
|
| 855 |
+
|
| 856 |
+
None
|
| 857 |
+
|
| 858 |
+
**Bug fixes**
|
| 859 |
+
|
| 860 |
+
* Support html5lib-python 1.0.1. (#337)
|
| 861 |
+
|
| 862 |
+
* Add deprecation warning for supporting html5lib-python < 1.0.
|
| 863 |
+
|
| 864 |
+
* Switch to semver.
|
| 865 |
+
|
| 866 |
+
|
| 867 |
+
Version 2.1.1 (October 2nd, 2017)
|
| 868 |
+
---------------------------------
|
| 869 |
+
|
| 870 |
+
**Security fixes**
|
| 871 |
+
|
| 872 |
+
None
|
| 873 |
+
|
| 874 |
+
**Backwards incompatible changes**
|
| 875 |
+
|
| 876 |
+
None
|
| 877 |
+
|
| 878 |
+
**Features**
|
| 879 |
+
|
| 880 |
+
None
|
| 881 |
+
|
| 882 |
+
**Bug fixes**
|
| 883 |
+
|
| 884 |
+
* Fix ``setup.py`` opening files when ``LANG=``. (#324)
|
| 885 |
+
|
| 886 |
+
|
| 887 |
+
Version 2.1 (September 28th, 2017)
|
| 888 |
+
----------------------------------
|
| 889 |
+
|
| 890 |
+
**Security fixes**
|
| 891 |
+
|
| 892 |
+
* Convert control characters (backspace particularly) to "?" preventing
|
| 893 |
+
malicious copy-and-paste situations. (#298)
|
| 894 |
+
|
| 895 |
+
See `<https://github.com/mozilla/bleach/issues/298>`_ for more details.
|
| 896 |
+
|
| 897 |
+
This affects all previous versions of Bleach. Check the comments on that
|
| 898 |
+
issue for ways to alleviate the issue if you can't upgrade to Bleach 2.1.
|
| 899 |
+
|
| 900 |
+
|
| 901 |
+
**Backwards incompatible changes**
|
| 902 |
+
|
| 903 |
+
* Redid versioning. ``bleach.VERSION`` is no longer available. Use the string
|
| 904 |
+
version at ``bleach.__version__`` and parse it with
|
| 905 |
+
``pkg_resources.parse_version``. (#307)
|
| 906 |
+
|
| 907 |
+
* clean, linkify: linkify and clean should only accept text types; thank you,
|
| 908 |
+
Janusz! (#292)
|
| 909 |
+
|
| 910 |
+
* clean, linkify: accept only unicode or utf-8-encoded str (#176)
|
| 911 |
+
|
| 912 |
+
|
| 913 |
+
**Features**
|
| 914 |
+
|
| 915 |
+
|
| 916 |
+
**Bug fixes**
|
| 917 |
+
|
| 918 |
+
* ``bleach.clean()`` no longer unescapes entities including ones that are missing
|
| 919 |
+
a ``;`` at the end which can happen in urls and other places. (#143)
|
| 920 |
+
|
| 921 |
+
* linkify: fix http links inside of mailto links; thank you, sedrubal! (#300)
|
| 922 |
+
|
| 923 |
+
* clarify security policy in docs (#303)
|
| 924 |
+
|
| 925 |
+
* fix dependency specification for html5lib 1.0b8, 1.0b9, and 1.0b10; thank you,
|
| 926 |
+
Zoltán! (#268)
|
| 927 |
+
|
| 928 |
+
* add Bleach vs. html5lib comparison to README; thank you, Stu Cox! (#278)
|
| 929 |
+
|
| 930 |
+
* fix KeyError exceptions on tags without href attr; thank you, Alex Defsen!
|
| 931 |
+
(#273)
|
| 932 |
+
|
| 933 |
+
* add test website and scripts to test ``bleach.clean()`` output in browser;
|
| 934 |
+
thank you, Greg Guthe!
|
| 935 |
+
|
| 936 |
+
|
| 937 |
+
Version 2.0 (March 8th, 2017)
|
| 938 |
+
-----------------------------
|
| 939 |
+
|
| 940 |
+
**Security fixes**
|
| 941 |
+
|
| 942 |
+
* None
|
| 943 |
+
|
| 944 |
+
|
| 945 |
+
**Backwards incompatible changes**
|
| 946 |
+
|
| 947 |
+
* Removed support for Python 2.6. (#206)
|
| 948 |
+
|
| 949 |
+
* Removed support for Python 3.2. (#224)
|
| 950 |
+
|
| 951 |
+
* Bleach no longer supports html5lib < 0.99999999 (8 9s).
|
| 952 |
+
|
| 953 |
+
This version is a rewrite to use the new sanitizing API since the old
|
| 954 |
+
one was dropped in html5lib 0.99999999 (8 9s).
|
| 955 |
+
|
| 956 |
+
If you're using 0.9999999 (7 9s) upgrade to 0.99999999 (8 9s) or higher.
|
| 957 |
+
|
| 958 |
+
If you're using 1.0b8 (equivalent to 0.9999999 (7 9s)), upgrade to 1.0b9
|
| 959 |
+
(equivalent to 0.99999999 (8 9s)) or higher.
|
| 960 |
+
|
| 961 |
+
* ``bleach.clean`` and friends were rewritten
|
| 962 |
+
|
| 963 |
+
``clean`` was reimplemented as an html5lib filter and happens at a different
|
| 964 |
+
step in the HTML parsing -> traversing -> serializing process. Because of
|
| 965 |
+
that, there are some differences in clean's output as compared with previous
|
| 966 |
+
versions.
|
| 967 |
+
|
| 968 |
+
Amongst other things, this version will add end tags even if the tag in
|
| 969 |
+
question is to be escaped.
|
| 970 |
+
|
| 971 |
+
* ``bleach.clean`` and friends attribute callables now take three arguments:
|
| 972 |
+
tag, attribute name and attribute value. Previously they only took attribute
|
| 973 |
+
name and attribute value.
|
| 974 |
+
|
| 975 |
+
All attribute callables will need to be updated.
|
| 976 |
+
|
| 977 |
+
* ``bleach.linkify`` was rewritten
|
| 978 |
+
|
| 979 |
+
``linkify`` was reimplemented as an html5lib Filter. As such, it no longer
|
| 980 |
+
accepts a ``tokenizer`` argument.
|
| 981 |
+
|
| 982 |
+
The callback functions for adjusting link attributes now takes a namespaced
|
| 983 |
+
attribute.
|
| 984 |
+
|
| 985 |
+
Previously you'd do something like this::
|
| 986 |
+
|
| 987 |
+
def check_protocol(attrs, is_new):
|
| 988 |
+
if not attrs.get('href', '').startswith('http:', 'https:')):
|
| 989 |
+
return None
|
| 990 |
+
return attrs
|
| 991 |
+
|
| 992 |
+
Now it's more like this::
|
| 993 |
+
|
| 994 |
+
def check_protocol(attrs, is_new):
|
| 995 |
+
if not attrs.get((None, u'href'), u'').startswith(('http:', 'https:')):
|
| 996 |
+
# ^^^^^^^^^^^^^^^
|
| 997 |
+
return None
|
| 998 |
+
return attrs
|
| 999 |
+
|
| 1000 |
+
Further, you need to make sure you're always using unicode values. If you
|
| 1001 |
+
don't then html5lib will raise an assertion error that the value is not
|
| 1002 |
+
unicode.
|
| 1003 |
+
|
| 1004 |
+
All linkify filters will need to be updated.
|
| 1005 |
+
|
| 1006 |
+
* ``bleach.linkify`` and friends had a ``skip_pre`` argument--that's been
|
| 1007 |
+
replaced with a more general ``skip_tags`` argument.
|
| 1008 |
+
|
| 1009 |
+
Before, you might do::
|
| 1010 |
+
|
| 1011 |
+
bleach.linkify(some_text, skip_pre=True)
|
| 1012 |
+
|
| 1013 |
+
The equivalent with Bleach 2.0 is::
|
| 1014 |
+
|
| 1015 |
+
bleach.linkify(some_text, skip_tags=['pre'])
|
| 1016 |
+
|
| 1017 |
+
You can skip other tags, too, like ``style`` or ``script`` or other places
|
| 1018 |
+
where you don't want linkification happening.
|
| 1019 |
+
|
| 1020 |
+
All uses of linkify that use ``skip_pre`` will need to be updated.
|
| 1021 |
+
|
| 1022 |
+
|
| 1023 |
+
**Changes**
|
| 1024 |
+
|
| 1025 |
+
* Supports Python 3.6.
|
| 1026 |
+
|
| 1027 |
+
* Supports html5lib >= 0.99999999 (8 9s).
|
| 1028 |
+
|
| 1029 |
+
* There's a ``bleach.sanitizer.Cleaner`` class that you can instantiate with your
|
| 1030 |
+
favorite clean settings for easy reuse.
|
| 1031 |
+
|
| 1032 |
+
* There's a ``bleach.linkifier.Linker`` class that you can instantiate with your
|
| 1033 |
+
favorite linkify settings for easy reuse.
|
| 1034 |
+
|
| 1035 |
+
* There's a ``bleach.linkifier.LinkifyFilter`` which is an htm5lib filter that
|
| 1036 |
+
you can pass as a filter to ``bleach.sanitizer.Cleaner`` allowing you to clean
|
| 1037 |
+
and linkify in one pass.
|
| 1038 |
+
|
| 1039 |
+
* ``bleach.clean`` and friends can now take a callable as an attributes arg value.
|
| 1040 |
+
|
| 1041 |
+
* Tons of bug fixes.
|
| 1042 |
+
|
| 1043 |
+
* Cleaned up tests.
|
| 1044 |
+
|
| 1045 |
+
* Documentation fixes.
|
| 1046 |
+
|
| 1047 |
+
|
| 1048 |
+
Version 1.5 (November 4th, 2016)
|
| 1049 |
+
--------------------------------
|
| 1050 |
+
|
| 1051 |
+
**Security fixes**
|
| 1052 |
+
|
| 1053 |
+
* None
|
| 1054 |
+
|
| 1055 |
+
**Backwards incompatible changes**
|
| 1056 |
+
|
| 1057 |
+
* clean: The list of ``ALLOWED_PROTOCOLS`` now defaults to http, https and
|
| 1058 |
+
mailto.
|
| 1059 |
+
|
| 1060 |
+
Previously it was a long list of protocols something like ed2k, ftp, http,
|
| 1061 |
+
https, irc, mailto, news, gopher, nntp, telnet, webcal, xmpp, callto, feed,
|
| 1062 |
+
urn, aim, rsync, tag, ssh, sftp, rtsp, afs, data. (#149)
|
| 1063 |
+
|
| 1064 |
+
**Changes**
|
| 1065 |
+
|
| 1066 |
+
* clean: Added ``protocols`` to arguments list to let you override the list of
|
| 1067 |
+
allowed protocols. Thank you, Andreas Malecki! (#149)
|
| 1068 |
+
|
| 1069 |
+
* linkify: Fix a bug involving periods at the end of an email address. Thank you,
|
| 1070 |
+
Lorenz Schori! (#219)
|
| 1071 |
+
|
| 1072 |
+
* linkify: Fix linkification of non-ascii ports. Thank you Alexandre, Macabies!
|
| 1073 |
+
(#207)
|
| 1074 |
+
|
| 1075 |
+
* linkify: Fix linkify inappropriately removing node tails when dropping nodes.
|
| 1076 |
+
(#132)
|
| 1077 |
+
|
| 1078 |
+
* Fixed a test that failed periodically. (#161)
|
| 1079 |
+
|
| 1080 |
+
* Switched from nose to py.test. (#204)
|
| 1081 |
+
|
| 1082 |
+
* Add test matrix for all supported Python and html5lib versions. (#230)
|
| 1083 |
+
|
| 1084 |
+
* Limit to html5lib ``>=0.999,!=0.9999,!=0.99999,<0.99999999`` because 0.9999
|
| 1085 |
+
and 0.99999 are busted.
|
| 1086 |
+
|
| 1087 |
+
* Add support for ``python setup.py test``. (#97)
|
| 1088 |
+
|
| 1089 |
+
|
| 1090 |
+
Version 1.4.3 (May 23rd, 2016)
|
| 1091 |
+
------------------------------
|
| 1092 |
+
|
| 1093 |
+
**Security fixes**
|
| 1094 |
+
|
| 1095 |
+
* None
|
| 1096 |
+
|
| 1097 |
+
**Changes**
|
| 1098 |
+
|
| 1099 |
+
* Limit to html5lib ``>=0.999,<0.99999999`` because of impending change to
|
| 1100 |
+
sanitizer api. #195
|
| 1101 |
+
|
| 1102 |
+
|
| 1103 |
+
Version 1.4.2 (September 11, 2015)
|
| 1104 |
+
----------------------------------
|
| 1105 |
+
|
| 1106 |
+
**Changes**
|
| 1107 |
+
|
| 1108 |
+
* linkify: Fix hang in linkify with ``parse_email=True``. (#124)
|
| 1109 |
+
|
| 1110 |
+
* linkify: Fix crash in linkify when removing a link that is a first-child. (#136)
|
| 1111 |
+
|
| 1112 |
+
* Updated TLDs.
|
| 1113 |
+
|
| 1114 |
+
* linkify: Don't remove exterior brackets when linkifying. (#146)
|
| 1115 |
+
|
| 1116 |
+
|
| 1117 |
+
Version 1.4.1 (December 15, 2014)
|
| 1118 |
+
---------------------------------
|
| 1119 |
+
|
| 1120 |
+
**Changes**
|
| 1121 |
+
|
| 1122 |
+
* Consistent order of attributes in output.
|
| 1123 |
+
|
| 1124 |
+
* Python 3.4 support.
|
| 1125 |
+
|
| 1126 |
+
|
| 1127 |
+
Version 1.4 (January 12, 2014)
|
| 1128 |
+
------------------------------
|
| 1129 |
+
|
| 1130 |
+
**Changes**
|
| 1131 |
+
|
| 1132 |
+
* linkify: Update linkify to use etree type Treewalker instead of simpletree.
|
| 1133 |
+
|
| 1134 |
+
* Updated html5lib to version ``>=0.999``.
|
| 1135 |
+
|
| 1136 |
+
* Update all code to be compatible with Python 3 and 2 using six.
|
| 1137 |
+
|
| 1138 |
+
* Switch to Apache License.
|
| 1139 |
+
|
| 1140 |
+
|
| 1141 |
+
Version 1.3
|
| 1142 |
+
-----------
|
| 1143 |
+
|
| 1144 |
+
* Used by Python 3-only fork.
|
| 1145 |
+
|
| 1146 |
+
|
| 1147 |
+
Version 1.2.2 (May 18, 2013)
|
| 1148 |
+
----------------------------
|
| 1149 |
+
|
| 1150 |
+
* Pin html5lib to version 0.95 for now due to major API break.
|
| 1151 |
+
|
| 1152 |
+
|
| 1153 |
+
Version 1.2.1 (February 19, 2013)
|
| 1154 |
+
---------------------------------
|
| 1155 |
+
|
| 1156 |
+
* ``clean()`` no longer considers ``feed:`` an acceptable protocol due to
|
| 1157 |
+
inconsistencies in browser behavior.
|
| 1158 |
+
|
| 1159 |
+
|
| 1160 |
+
Version 1.2 (January 28, 2013)
|
| 1161 |
+
------------------------------
|
| 1162 |
+
|
| 1163 |
+
* ``linkify()`` has changed considerably. Many keyword arguments have been
|
| 1164 |
+
replaced with a single callbacks list. Please see the documentation for more
|
| 1165 |
+
information.
|
| 1166 |
+
|
| 1167 |
+
* Bleach will no longer consider unacceptable protocols when linkifying.
|
| 1168 |
+
|
| 1169 |
+
* ``linkify()`` now takes a tokenizer argument that allows it to skip
|
| 1170 |
+
sanitization.
|
| 1171 |
+
|
| 1172 |
+
* ``delinkify()`` is gone.
|
| 1173 |
+
|
| 1174 |
+
* Removed exception handling from ``_render``. ``clean()`` and ``linkify()`` may
|
| 1175 |
+
now throw.
|
| 1176 |
+
|
| 1177 |
+
* ``linkify()`` correctly ignores case for protocols and domain names.
|
| 1178 |
+
|
| 1179 |
+
* ``linkify()`` correctly handles markup within an <a> tag.
|
| 1180 |
+
|
| 1181 |
+
|
| 1182 |
+
Version 1.1.5
|
| 1183 |
+
-------------
|
| 1184 |
+
|
| 1185 |
+
|
| 1186 |
+
Version 1.1.4
|
| 1187 |
+
-------------
|
| 1188 |
+
|
| 1189 |
+
|
| 1190 |
+
Version 1.1.3 (July 10, 2012)
|
| 1191 |
+
-----------------------------
|
| 1192 |
+
|
| 1193 |
+
* Fix parsing bare URLs when parse_email=True.
|
| 1194 |
+
|
| 1195 |
+
|
| 1196 |
+
Version 1.1.2 (June 1, 2012)
|
| 1197 |
+
----------------------------
|
| 1198 |
+
|
| 1199 |
+
* Fix hang in style attribute sanitizer. (#61)
|
| 1200 |
+
|
| 1201 |
+
* Allow ``/`` in style attribute values.
|
| 1202 |
+
|
| 1203 |
+
|
| 1204 |
+
Version 1.1.1 (February 17, 2012)
|
| 1205 |
+
---------------------------------
|
| 1206 |
+
|
| 1207 |
+
* Fix tokenizer for html5lib 0.9.5.
|
| 1208 |
+
|
| 1209 |
+
|
| 1210 |
+
Version 1.1.0 (October 24, 2011)
|
| 1211 |
+
--------------------------------
|
| 1212 |
+
|
| 1213 |
+
* ``linkify()`` now understands port numbers. (#38)
|
| 1214 |
+
|
| 1215 |
+
* Documented character encoding behavior. (#41)
|
| 1216 |
+
|
| 1217 |
+
* Add an optional target argument to ``linkify()``.
|
| 1218 |
+
|
| 1219 |
+
* Add ``delinkify()`` method. (#45)
|
| 1220 |
+
|
| 1221 |
+
* Support subdomain whitelist for ``delinkify()``. (#47, #48)
|
| 1222 |
+
|
| 1223 |
+
|
| 1224 |
+
Version 1.0.4 (September 2, 2011)
|
| 1225 |
+
---------------------------------
|
| 1226 |
+
|
| 1227 |
+
* Switch to SemVer git tags.
|
| 1228 |
+
|
| 1229 |
+
* Make ``linkify()`` smarter about trailing punctuation. (#30)
|
| 1230 |
+
|
| 1231 |
+
* Pass ``exc_info`` to logger during rendering issues.
|
| 1232 |
+
|
| 1233 |
+
* Add wildcard key for attributes. (#19)
|
| 1234 |
+
|
| 1235 |
+
* Make ``linkify()`` use the ``HTMLSanitizer`` tokenizer. (#36)
|
| 1236 |
+
|
| 1237 |
+
* Fix URLs wrapped in parentheses. (#23)
|
| 1238 |
+
|
| 1239 |
+
* Make ``linkify()`` UTF-8 safe. (#33)
|
| 1240 |
+
|
| 1241 |
+
|
| 1242 |
+
Version 1.0.3 (June 14, 2011)
|
| 1243 |
+
-----------------------------
|
| 1244 |
+
|
| 1245 |
+
* ``linkify()`` works with 3rd level domains. (#24)
|
| 1246 |
+
|
| 1247 |
+
* ``clean()`` supports vendor prefixes in style values. (#31, #32)
|
| 1248 |
+
|
| 1249 |
+
* Fix ``linkify()`` email escaping.
|
| 1250 |
+
|
| 1251 |
+
|
| 1252 |
+
Version 1.0.2 (June 6, 2011)
|
| 1253 |
+
----------------------------
|
| 1254 |
+
|
| 1255 |
+
* ``linkify()`` supports email addresses.
|
| 1256 |
+
|
| 1257 |
+
* ``clean()`` supports callables in attributes filter.
|
| 1258 |
+
|
| 1259 |
+
|
| 1260 |
+
Version 1.0.1 (April 12, 2011)
|
| 1261 |
+
------------------------------
|
| 1262 |
+
|
| 1263 |
+
* ``linkify()`` doesn't drop trailing slashes. (#21)
|
| 1264 |
+
* ``linkify()`` won't linkify 'libgl.so.1'. (#22)
|
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/RECORD
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
bleach-6.2.0.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
|
| 2 |
+
bleach-6.2.0.dist-info/LICENSE,sha256=vsIjjBSaYyuPsmgT9oes6rq4AyfzJwdpwsFhV4g9MTA,569
|
| 3 |
+
bleach-6.2.0.dist-info/METADATA,sha256=mnXcN317OOMalmF3_BsKK_6pjezoghNxZxvKw2Xu9ik,30774
|
| 4 |
+
bleach-6.2.0.dist-info/RECORD,,
|
| 5 |
+
bleach-6.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 6 |
+
bleach-6.2.0.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
| 7 |
+
bleach-6.2.0.dist-info/top_level.txt,sha256=dcv0wKIySB0zMjAEXLwY4V0-3IN9UZQGAT1wDmfQICY,7
|
| 8 |
+
bleach/__init__.py,sha256=eVGkZTvQBVC8huukdCp3k5vBrtl48uBYWmVN2k15izQ,3649
|
| 9 |
+
bleach/_vendor/README.rst,sha256=eXeKT2JdZB4WX1kuhTa8W9Jp9VXtwIKFxo5RUL5exmM,2160
|
| 10 |
+
bleach/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 11 |
+
bleach/_vendor/html5lib-1.1.dist-info/AUTHORS.rst,sha256=DrNAMifoDpuQyJn-KW-H6K8Tt2a5rKnV2UF4-DRrGUI,983
|
| 12 |
+
bleach/_vendor/html5lib-1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 13 |
+
bleach/_vendor/html5lib-1.1.dist-info/LICENSE,sha256=FqOZkWGekvGGgJMtoqkZn999ld8-yu3FLqBiGKq6_W8,1084
|
| 14 |
+
bleach/_vendor/html5lib-1.1.dist-info/METADATA,sha256=Y3w-nd_22HQnQRy3yypVsV_ke2FF94uUD4-vGpc2DnI,16076
|
| 15 |
+
bleach/_vendor/html5lib-1.1.dist-info/RECORD,sha256=u-y_W5lhdsHC1OSMnA4bCi3-11IgQ_FAIW6viMu8_LA,3486
|
| 16 |
+
bleach/_vendor/html5lib-1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 17 |
+
bleach/_vendor/html5lib-1.1.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
|
| 18 |
+
bleach/_vendor/html5lib-1.1.dist-info/top_level.txt,sha256=XEX6CHpskSmvjJB4tP6m4Q5NYXhIf_0ceMc0PNbzJPQ,9
|
| 19 |
+
bleach/_vendor/html5lib/__init__.py,sha256=pWnYcfZ69wNLrdQL7bpr49FUi8O8w0KhKCOHsyRgYGQ,1143
|
| 20 |
+
bleach/_vendor/html5lib/_ihatexml.py,sha256=ifOwF7pXqmyThIXc3boWc96s4MDezqRrRVp7FwDYUFs,16728
|
| 21 |
+
bleach/_vendor/html5lib/_inputstream.py,sha256=468J4yFSbIqJaZs9tKtdYjh9b1_NSOV2Y6n4XItzX0c,32318
|
| 22 |
+
bleach/_vendor/html5lib/_tokenizer.py,sha256=qB8oJPqJFt6ziwqd35y7rbgDA2UY2BgaqVFktrl3Jfo,77040
|
| 23 |
+
bleach/_vendor/html5lib/_trie/__init__.py,sha256=nqfgO910329BEVJ5T4psVwQtjd2iJyEXQ2-X8c1YxwU,109
|
| 24 |
+
bleach/_vendor/html5lib/_trie/_base.py,sha256=CaybYyMro8uERQYjby2tTeSUatnWDfWroUN9N7ety5w,1013
|
| 25 |
+
bleach/_vendor/html5lib/_trie/py.py,sha256=FEahIAELKHkq1yQTYd-6lynOLXwGebzuzmkwdKhxiaE,1775
|
| 26 |
+
bleach/_vendor/html5lib/_utils.py,sha256=Db3cH4s_APLkqSqzRiJymZ0Ni_dEmGZqKM6r7LyWsiw,4931
|
| 27 |
+
bleach/_vendor/html5lib/constants.py,sha256=Ll-yzLU_jcjyAI_h57zkqZ7aQWE5t5xA4y_jQgoUUhw,83464
|
| 28 |
+
bleach/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 29 |
+
bleach/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919
|
| 30 |
+
bleach/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286
|
| 31 |
+
bleach/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945
|
| 32 |
+
bleach/_vendor/html5lib/filters/lint.py,sha256=QqntYftPoZWNHvKYgk-X1rCfvlgGxBQXKvmlOFDRpnc,3643
|
| 33 |
+
bleach/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588
|
| 34 |
+
bleach/_vendor/html5lib/filters/sanitizer.py,sha256=LAwxng7L1d3EGI7toU2dbl7PAXPQpMvrN0F5LN-O-hQ,26891
|
| 35 |
+
bleach/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214
|
| 36 |
+
bleach/_vendor/html5lib/html5parser.py,sha256=OydS1YNYFgTMfOHXPVXOfcFD4FdV18zXm4FW5oqi37k,117164
|
| 37 |
+
bleach/_vendor/html5lib/serializer.py,sha256=2PKBf5aWa5ZOopxF9mpFuwfnkGWlnjduCRl1LnG4fdg,15759
|
| 38 |
+
bleach/_vendor/html5lib/treeadapters/__init__.py,sha256=18hyI-at2aBsdKzpwRwa5lGF1ipgctaTYXoU9En2ZQg,650
|
| 39 |
+
bleach/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715
|
| 40 |
+
bleach/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776
|
| 41 |
+
bleach/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592
|
| 42 |
+
bleach/_vendor/html5lib/treebuilders/base.py,sha256=63eJjPXwJ_IphPGS-DDYMGQ5M8hR3dsqtSvpaJDb8qk,14565
|
| 43 |
+
bleach/_vendor/html5lib/treebuilders/dom.py,sha256=22whb0C71zXIsai5mamg6qzBEiigcBIvaDy4Asw3at0,8925
|
| 44 |
+
bleach/_vendor/html5lib/treebuilders/etree.py,sha256=SiOi50OH4xI41dtL7TKRng8Fz3XIEkDlE7mh8y0xDN0,12836
|
| 45 |
+
bleach/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=UNGYWOVMigC_t77SMaWbcJaPAbjk_UTNA-_531_52Hg,14766
|
| 46 |
+
bleach/_vendor/html5lib/treewalkers/__init__.py,sha256=OBPtc1TU5mGyy18QDMxKEyYEz0wxFUUNj5v0-XgmYhY,5719
|
| 47 |
+
bleach/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476
|
| 48 |
+
bleach/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413
|
| 49 |
+
bleach/_vendor/html5lib/treewalkers/etree.py,sha256=Fo7NwpokK8I1Sisg83TKnEVv2bOKz20QiJyBMUGT8co,4551
|
| 50 |
+
bleach/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=q_z3IkU18ikNomqyzNmCyYPblj485RnAUkgsZjv9vqQ,6357
|
| 51 |
+
bleach/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309
|
| 52 |
+
bleach/_vendor/parse.py,sha256=Rq-WbjO2JHrh1X2UWRFaPrRs2p-AnJ8U4FKrwv6NrLI,39023
|
| 53 |
+
bleach/_vendor/parse.py.SHA256SUM,sha256=-AaiqN-9otw_X0vFjKkbKWFvkp68iLME92_wI-8-vm0,75
|
| 54 |
+
bleach/_vendor/vendor.txt,sha256=6FFZyenumgWqnhLgbCa4yzL4HVNaSUDC2DHNyR5Fy6w,184
|
| 55 |
+
bleach/_vendor/vendor_install.sh,sha256=wMRUBf6IJ4LgRVO_0soLSsO2b1aphbZzqd3aqHVC75Q,553
|
| 56 |
+
bleach/callbacks.py,sha256=JNTGiM5_3bKsGltpR9ZYEz_C_b7-vfDlTTdQCirbdyc,752
|
| 57 |
+
bleach/css_sanitizer.py,sha256=QFMxRKBUMSuNvYkVpB2WRBQO609eFbU-p9P_LhU6jtM,2526
|
| 58 |
+
bleach/html5lib_shim.py,sha256=FGob47ScPLEh8_EihRAOINiGcGFjL4GRj7SfsD_bNBI,23619
|
| 59 |
+
bleach/linkifier.py,sha256=vWOXKuRXirpCwejUEEyfe8EWJ7rBlieMDEerg95OhPU,22375
|
| 60 |
+
bleach/parse_shim.py,sha256=VDPOdBOKbuDEceKVvfoggcr6A332bkcq4Z8jMtOJlAQ,50
|
| 61 |
+
bleach/sanitizer.py,sha256=JqDuTINOybpc_eHBzG_H7cnkHdFskZGbfsaBc-hDPH8,21934
|
| 62 |
+
bleach/six_shim.py,sha256=4nLv5WcDyCYaYEpQVuI9I_3t06VMUBr_n4CJAn4nQwQ,305
|
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/REQUESTED
ADDED
|
File without changes
|
rtme/lib/python3.10/site-packages/bleach-6.2.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (75.3.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
rtme/lib/python3.10/site-packages/einops/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__author__ = 'Alex Rogozhnikov'
|
| 2 |
+
__version__ = '0.7.0'
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class EinopsError(RuntimeError):
|
| 6 |
+
""" Runtime error thrown by einops """
|
| 7 |
+
pass
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
__all__ = ['rearrange', 'reduce', 'repeat', 'einsum',
|
| 11 |
+
'pack', 'unpack',
|
| 12 |
+
'parse_shape', 'asnumpy', 'EinopsError']
|
| 13 |
+
|
| 14 |
+
from .einops import rearrange, reduce, repeat, einsum, parse_shape, asnumpy
|
| 15 |
+
from .packing import pack, unpack
|
rtme/lib/python3.10/site-packages/einops/__pycache__/_torch_specific.cpython-310.pyc
ADDED
|
Binary file (4.18 kB). View file
|
|
|
rtme/lib/python3.10/site-packages/einops/__pycache__/parsing.cpython-310.pyc
ADDED
|
Binary file (4.98 kB). View file
|
|
|
rtme/lib/python3.10/site-packages/einops/_torch_specific.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Specialization of einops for torch.
|
| 3 |
+
|
| 4 |
+
Unfortunately, torch's jit scripting mechanism isn't strong enough,
|
| 5 |
+
and to have scripting supported at least for layers,
|
| 6 |
+
a number of additional moves is needed.
|
| 7 |
+
|
| 8 |
+
Design of main operations (dynamic resolution by lookup) is unlikely
|
| 9 |
+
to be implemented by torch.jit.script,
|
| 10 |
+
but torch.compile seems to work with operations just fine.
|
| 11 |
+
"""
|
| 12 |
+
import warnings
|
| 13 |
+
from typing import Dict, List, Tuple
|
| 14 |
+
|
| 15 |
+
import torch
|
| 16 |
+
from einops.einops import TransformRecipe, _reconstruct_from_shape_uncached
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class TorchJitBackend:
|
| 20 |
+
"""
|
| 21 |
+
Completely static backend that mimics part of normal backend functionality
|
| 22 |
+
but restricted to be within torchscript.
|
| 23 |
+
"""
|
| 24 |
+
|
| 25 |
+
@staticmethod
|
| 26 |
+
def reduce(x: torch.Tensor, operation: str, reduced_axes: List[int]):
|
| 27 |
+
if operation == "min":
|
| 28 |
+
return x.amin(dim=reduced_axes)
|
| 29 |
+
elif operation == "max":
|
| 30 |
+
return x.amax(dim=reduced_axes)
|
| 31 |
+
elif operation == "sum":
|
| 32 |
+
return x.sum(dim=reduced_axes)
|
| 33 |
+
elif operation == "mean":
|
| 34 |
+
return x.mean(dim=reduced_axes)
|
| 35 |
+
elif operation == "prod":
|
| 36 |
+
for i in list(sorted(reduced_axes))[::-1]:
|
| 37 |
+
x = x.prod(dim=i)
|
| 38 |
+
return x
|
| 39 |
+
else:
|
| 40 |
+
raise NotImplementedError("Unknown reduction ", operation)
|
| 41 |
+
|
| 42 |
+
@staticmethod
|
| 43 |
+
def transpose(x, axes: List[int]):
|
| 44 |
+
return x.permute(axes)
|
| 45 |
+
|
| 46 |
+
@staticmethod
|
| 47 |
+
def stack_on_zeroth_dimension(tensors: List[torch.Tensor]):
|
| 48 |
+
return torch.stack(tensors)
|
| 49 |
+
|
| 50 |
+
@staticmethod
|
| 51 |
+
def tile(x, repeats: List[int]):
|
| 52 |
+
return x.repeat(repeats)
|
| 53 |
+
|
| 54 |
+
@staticmethod
|
| 55 |
+
def add_axes(x, n_axes: int, pos2len: Dict[int, int]):
|
| 56 |
+
repeats = [-1] * n_axes
|
| 57 |
+
for axis_position, axis_length in pos2len.items():
|
| 58 |
+
x = torch.unsqueeze(x, axis_position)
|
| 59 |
+
repeats[axis_position] = axis_length
|
| 60 |
+
return x.expand(repeats)
|
| 61 |
+
|
| 62 |
+
@staticmethod
|
| 63 |
+
def is_float_type(x):
|
| 64 |
+
return x.dtype in [torch.float16, torch.float32, torch.float64, torch.bfloat16]
|
| 65 |
+
|
| 66 |
+
@staticmethod
|
| 67 |
+
def shape(x):
|
| 68 |
+
return x.shape
|
| 69 |
+
|
| 70 |
+
@staticmethod
|
| 71 |
+
def reshape(x, shape: List[int]):
|
| 72 |
+
return x.reshape(shape)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# mirrors einops.einops._apply_recipe
|
| 76 |
+
def apply_for_scriptable_torch(
|
| 77 |
+
recipe: TransformRecipe, tensor: torch.Tensor, reduction_type: str, axes_dims: List[Tuple[str, int]]
|
| 78 |
+
) -> torch.Tensor:
|
| 79 |
+
backend = TorchJitBackend
|
| 80 |
+
(
|
| 81 |
+
init_shapes,
|
| 82 |
+
axes_reordering,
|
| 83 |
+
reduced_axes,
|
| 84 |
+
added_axes,
|
| 85 |
+
final_shapes,
|
| 86 |
+
n_axes_w_added,
|
| 87 |
+
) = _reconstruct_from_shape_uncached(recipe, backend.shape(tensor), axes_dims=axes_dims)
|
| 88 |
+
if init_shapes is not None:
|
| 89 |
+
tensor = backend.reshape(tensor, init_shapes)
|
| 90 |
+
if axes_reordering is not None:
|
| 91 |
+
tensor = backend.transpose(tensor, axes_reordering)
|
| 92 |
+
if len(reduced_axes) > 0:
|
| 93 |
+
tensor = backend.reduce(tensor, operation=reduction_type, reduced_axes=reduced_axes)
|
| 94 |
+
if len(added_axes) > 0:
|
| 95 |
+
tensor = backend.add_axes(tensor, n_axes=n_axes_w_added, pos2len=added_axes)
|
| 96 |
+
if final_shapes is not None:
|
| 97 |
+
tensor = backend.reshape(tensor, final_shapes)
|
| 98 |
+
return tensor
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def allow_ops_in_compiled_graph():
|
| 102 |
+
if hasattr(torch, "__version__") and torch.__version__[0] < "2":
|
| 103 |
+
# torch._dynamo and torch.compile appear in pytorch 2.0
|
| 104 |
+
return
|
| 105 |
+
try:
|
| 106 |
+
from torch._dynamo import allow_in_graph
|
| 107 |
+
except ImportError:
|
| 108 |
+
warnings.warn("allow_ops_in_compiled_graph failed to import torch: ensure pytorch >=2.0", ImportWarning)
|
| 109 |
+
return
|
| 110 |
+
|
| 111 |
+
from .einops import rearrange, reduce, repeat, einsum
|
| 112 |
+
from .packing import pack, unpack
|
| 113 |
+
|
| 114 |
+
allow_in_graph(rearrange)
|
| 115 |
+
allow_in_graph(reduce)
|
| 116 |
+
allow_in_graph(repeat)
|
| 117 |
+
allow_in_graph(einsum)
|
| 118 |
+
allow_in_graph(pack)
|
| 119 |
+
allow_in_graph(unpack)
|
| 120 |
+
|
| 121 |
+
# CF: https://github.com/pytorch/pytorch/blob/2df939aacac68e9621fbd5d876c78d86e72b41e2/torch/_dynamo/__init__.py#L222
|
| 122 |
+
global _ops_were_registered_in_torchdynamo
|
| 123 |
+
_ops_were_registered_in_torchdynamo = True
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
# module import automatically registers ops in torchdynamo
|
| 127 |
+
allow_ops_in_compiled_graph()
|
rtme/lib/python3.10/site-packages/einops/experimental/__init__.py
ADDED
|
File without changes
|
rtme/lib/python3.10/site-packages/einops/experimental/indexing.py
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
|
| 3 |
+
Indexing one array with the other(s).
|
| 4 |
+
|
| 5 |
+
Concept for discussion.
|
| 6 |
+
|
| 7 |
+
Notation targets hard cases, not simple ones, like indexing of 1d-array with another 1d-array
|
| 8 |
+
(notation supports that, but you can't simplify arr[ind], and there is no reason to)
|
| 9 |
+
|
| 10 |
+
Examples
|
| 11 |
+
|
| 12 |
+
1. query for every token in sequence a token in the image. Images and sequences are paired
|
| 13 |
+
einindex('b t c <- b h w c, [h, w] b t', arr_bhwc, [h_indices_bt, w_indices_bt])
|
| 14 |
+
|
| 15 |
+
this is equivalent, so you can pass indexers idependently or together
|
| 16 |
+
einindex('b t c <- b h w c, [h, w] b t', arr_bhwc, np.asarray([h_indices_bt, w_indices_bt]))
|
| 17 |
+
|
| 18 |
+
after some thinking I decided that having first axis for indexing variable is not too restrictive,
|
| 19 |
+
but should simplify mapping of such cases.
|
| 20 |
+
For this reason [...] part should always go first in indexer.
|
| 21 |
+
|
| 22 |
+
This makes the largest difference with einindex https://github.com/malmaud/einindex,
|
| 23 |
+
which has almost identical grammar, but puts special dimension last, while we put it first.
|
| 24 |
+
This trick allows naturally decomposing multiindex into individual dimensions or visa versa.
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
2. query for every token in the video the most suitable word in a (matching) sentence
|
| 28 |
+
einindex('b t h w <- seq b, [seq] t b h w', arr_tbc, [t_indices_bhw])
|
| 29 |
+
|
| 30 |
+
note, that only one indexer is used, but still it has to be enclosed in the list.
|
| 31 |
+
That's a price for being generic. Alternatively leading singleton dimension can be added.
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
3. (not supported now, future planning)
|
| 35 |
+
for every timeframe in a video, find the token with the highest norm (across h and w), and compose a new stack of them
|
| 36 |
+
indices_2bt = argmax(x_bthwc.norm(dim=-1), 'b t h w -> [h, w] b t')
|
| 37 |
+
selected_embeddings_btc = einindex('b t c <- b t h w c, [h, w] b t', x_bthwc, indices_2bt)
|
| 38 |
+
|
| 39 |
+
while currently question is around 'how do we index',
|
| 40 |
+
it is important to pre-align that with a question 'what are natural ways to get indices'.
|
| 41 |
+
Most common are min/max. less common options: topk (works here), random sampling.
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
Some important properties of this notation:
|
| 46 |
+
- support for multiple indexers, including using a single tensor to keep multiple indexers
|
| 47 |
+
- 'batch' indexing, when some axes of indexer and array should be matched
|
| 48 |
+
- universal (one-indexing-to-rule-them-all)
|
| 49 |
+
- extensible for (named) ellipses, including variadic number of indexers
|
| 50 |
+
- extensible for einops-style compositions and decompositions
|
| 51 |
+
- extensible for outer indexing when indexers are not aligned
|
| 52 |
+
|
| 53 |
+
Current implementation based on python array api and uses loops,
|
| 54 |
+
because no appropriate indexing available in the standard.
|
| 55 |
+
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
from typing import List, Union, TypeVar, Tuple
|
| 59 |
+
|
| 60 |
+
from einops import EinopsError
|
| 61 |
+
|
| 62 |
+
T = TypeVar('T')
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
class CompositionDecomposition:
|
| 66 |
+
def __init__(
|
| 67 |
+
self,
|
| 68 |
+
decomposed_shape: List[str],
|
| 69 |
+
composed_shape: List[List[str]],
|
| 70 |
+
):
|
| 71 |
+
flat_shape = []
|
| 72 |
+
for x in composed_shape:
|
| 73 |
+
flat_shape.extend(x)
|
| 74 |
+
|
| 75 |
+
self.compose_transposition: Tuple[int, ...] = tuple([decomposed_shape.index(x) for x in flat_shape])
|
| 76 |
+
self.decompose_transposition: Tuple[int, ...] = tuple([flat_shape.index(x) for x in decomposed_shape])
|
| 77 |
+
self.composed_shape = composed_shape
|
| 78 |
+
self.decomposed_shape = decomposed_shape
|
| 79 |
+
|
| 80 |
+
def decompose(self, x, known_axes_lengths: dict[str, int]):
|
| 81 |
+
xp = x.__array_namespace__()
|
| 82 |
+
shape = x.shape
|
| 83 |
+
|
| 84 |
+
flat_shape = []
|
| 85 |
+
|
| 86 |
+
for i, axis_group in enumerate(self.composed_shape):
|
| 87 |
+
unknown_axis_name = None
|
| 88 |
+
known_sizes_prod = 1
|
| 89 |
+
for axis_name in axis_group:
|
| 90 |
+
if axis_name in known_axes_lengths:
|
| 91 |
+
known_sizes_prod *= known_axes_lengths[axis_name]
|
| 92 |
+
else:
|
| 93 |
+
if unknown_axis_name is None:
|
| 94 |
+
unknown_axis_name = axis_name
|
| 95 |
+
else:
|
| 96 |
+
raise EinopsError("Can't infer the size")
|
| 97 |
+
|
| 98 |
+
if unknown_axis_name is None:
|
| 99 |
+
assert shape[i] == known_sizes_prod
|
| 100 |
+
else:
|
| 101 |
+
known_axes_lengths[unknown_axis_name] = shape[i] // known_sizes_prod
|
| 102 |
+
|
| 103 |
+
for axis in axis_group:
|
| 104 |
+
flat_shape.append(known_axes_lengths[axis])
|
| 105 |
+
|
| 106 |
+
x = xp.reshape(x, flat_shape)
|
| 107 |
+
return xp.permute_dims(x, self.decompose_transposition)
|
| 108 |
+
|
| 109 |
+
def compose(self, x, known_axes_lengths: dict[str, int]):
|
| 110 |
+
xp = x.__array_namespace__()
|
| 111 |
+
|
| 112 |
+
for axis_len, axis_name in zip(x.shape, self.decomposed_shape):
|
| 113 |
+
if axis_name in known_axes_lengths:
|
| 114 |
+
assert known_axes_lengths[axis_name] == axis_len
|
| 115 |
+
else:
|
| 116 |
+
known_axes_lengths[axis_name] = axis_len
|
| 117 |
+
|
| 118 |
+
x = xp.permute_dims(x, self.compose_transposition)
|
| 119 |
+
new_shape = []
|
| 120 |
+
for axis_group in self.composed_shape:
|
| 121 |
+
composed_axis_size = 1
|
| 122 |
+
for axis_name in axis_group:
|
| 123 |
+
composed_axis_size *= known_axes_lengths[axis_name]
|
| 124 |
+
new_shape.append(composed_axis_size)
|
| 125 |
+
|
| 126 |
+
return xp.reshape(x, tuple(new_shape))
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def arange_at_position(xp, n_axes, axis, axis_len, device=None):
|
| 130 |
+
x = xp.arange(axis_len, dtype=xp.int64, device=device)
|
| 131 |
+
shape = [1] * n_axes
|
| 132 |
+
shape[axis] = axis_len
|
| 133 |
+
x = xp.reshape(x, shape)
|
| 134 |
+
return x
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
class IndexingFormula:
|
| 138 |
+
|
| 139 |
+
def __init__(self, pattern: str):
|
| 140 |
+
"""
|
| 141 |
+
:param pattern: example 'b t c <- b hsel wsel c, [hsel, wsel] b t'
|
| 142 |
+
"""
|
| 143 |
+
self.pattern = pattern
|
| 144 |
+
left, right = pattern.split('<-')
|
| 145 |
+
arg_split = right.index(',')
|
| 146 |
+
arr_pattern, ind_pattern = right[:arg_split], right[arg_split + 1:]
|
| 147 |
+
ind_pattern = ind_pattern.strip()
|
| 148 |
+
# print(
|
| 149 |
+
# arr_pattern, '\n',
|
| 150 |
+
# ind_pattern,
|
| 151 |
+
# )
|
| 152 |
+
assert ind_pattern.startswith('['), 'composition axis should go first in indexer (second argument) [h w] i j k'
|
| 153 |
+
composition_start = ind_pattern.index('[')
|
| 154 |
+
composition_end = ind_pattern.index(']')
|
| 155 |
+
composition = ind_pattern[composition_start + 1: composition_end]
|
| 156 |
+
ind_other_axes = ind_pattern[composition_end + 1:]
|
| 157 |
+
|
| 158 |
+
self.result_axes_names = left.split()
|
| 159 |
+
self.array_axes_names = arr_pattern.split()
|
| 160 |
+
self.indexing_axes_names = [x.strip() for x in composition.split(',')]
|
| 161 |
+
self.indexer_other_axes_names = ind_other_axes.split()
|
| 162 |
+
|
| 163 |
+
for group_name, group in [
|
| 164 |
+
('result', self.result_axes_names),
|
| 165 |
+
('array', self.array_axes_names),
|
| 166 |
+
('indexer', self.indexing_axes_names + self.indexer_other_axes_names),
|
| 167 |
+
]:
|
| 168 |
+
if len(set(group)) != len(group):
|
| 169 |
+
# need more verbosity, which axis, raise
|
| 170 |
+
raise EinopsError(f'{group_name} pattern ({group}) contains a duplicated axis')
|
| 171 |
+
|
| 172 |
+
axis_groups = [
|
| 173 |
+
self.result_axes_names,
|
| 174 |
+
self.array_axes_names,
|
| 175 |
+
self.indexing_axes_names,
|
| 176 |
+
self.indexer_other_axes_names,
|
| 177 |
+
]
|
| 178 |
+
|
| 179 |
+
all_axes = set()
|
| 180 |
+
for group in axis_groups:
|
| 181 |
+
all_axes.update(group)
|
| 182 |
+
|
| 183 |
+
self.indexer_axes = []
|
| 184 |
+
self.batch_axes = []
|
| 185 |
+
self.result_and_index_axes = []
|
| 186 |
+
self.result_and_array_axes = []
|
| 187 |
+
|
| 188 |
+
for axis in all_axes:
|
| 189 |
+
presence = tuple(axis in g for g in axis_groups)
|
| 190 |
+
# want match-case here. sweet dreams
|
| 191 |
+
if presence == (False, True, True, False):
|
| 192 |
+
self.indexer_axes.append(axis)
|
| 193 |
+
elif presence[2]:
|
| 194 |
+
raise EinopsError(f'Wrong usage of indexer variable {axis}')
|
| 195 |
+
elif presence == (True, True, False, True):
|
| 196 |
+
self.batch_axes.append(axis)
|
| 197 |
+
elif presence == (True, False, False, True):
|
| 198 |
+
self.result_and_index_axes.append(axis)
|
| 199 |
+
elif presence == (True, True, False, False):
|
| 200 |
+
self.result_and_array_axes.append(axis)
|
| 201 |
+
else:
|
| 202 |
+
# TODO better categorization of wrong usage patterns
|
| 203 |
+
raise EinopsError(f'{axis} is used incorrectly in {pattern}')
|
| 204 |
+
|
| 205 |
+
assert set(self.indexer_axes) == set(self.indexing_axes_names)
|
| 206 |
+
# order of these variables matters, since we can't lose mapping here
|
| 207 |
+
self.indexer_axes = self.indexing_axes_names
|
| 208 |
+
|
| 209 |
+
self.array_composition = CompositionDecomposition(
|
| 210 |
+
decomposed_shape=self.array_axes_names,
|
| 211 |
+
composed_shape=[self.batch_axes + self.indexer_axes, self.result_and_array_axes],
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
+
self.index_composition = CompositionDecomposition(
|
| 215 |
+
decomposed_shape=self.indexer_other_axes_names,
|
| 216 |
+
# single axis after composition
|
| 217 |
+
composed_shape=[self.batch_axes + self.result_and_index_axes],
|
| 218 |
+
)
|
| 219 |
+
|
| 220 |
+
self.result_composition = CompositionDecomposition(
|
| 221 |
+
decomposed_shape=self.result_axes_names,
|
| 222 |
+
composed_shape=[self.batch_axes + self.result_and_index_axes, self.result_and_array_axes],
|
| 223 |
+
)
|
| 224 |
+
|
| 225 |
+
def apply_to_array_api(self, arr: T, ind: Union[T, List[T]]):
|
| 226 |
+
known_axes_sizes: dict[str, int] = {}
|
| 227 |
+
xp = arr.__array_namespace__()
|
| 228 |
+
|
| 229 |
+
if not isinstance(ind, list):
|
| 230 |
+
ind = [ind[i, ...] for i in range(ind.shape[0])]
|
| 231 |
+
|
| 232 |
+
for indexer in ind:
|
| 233 |
+
assert len(indexer.shape) == len(self.indexer_other_axes_names)
|
| 234 |
+
|
| 235 |
+
# step 1. transpose, reshapes of arr; learn its dimensions
|
| 236 |
+
arr_2d = self.array_composition.compose(arr, known_axes_sizes)
|
| 237 |
+
|
| 238 |
+
# step 2. compute shifts and create an actual indexing array
|
| 239 |
+
shift = 1
|
| 240 |
+
full_index = xp.zeros([1] * len(ind[0].shape), dtype=xp.int64, device=arr.device)
|
| 241 |
+
|
| 242 |
+
# original order: [*batch-like axes, *indexing_axes,]
|
| 243 |
+
# now we need to traverse them in the opposite direction
|
| 244 |
+
|
| 245 |
+
for axis_name, indexer in list(zip(self.indexing_axes_names, ind))[::-1]:
|
| 246 |
+
full_index = full_index + shift * (indexer % known_axes_sizes[axis_name])
|
| 247 |
+
shift *= known_axes_sizes[axis_name]
|
| 248 |
+
|
| 249 |
+
for axis_name in self.batch_axes[::-1]:
|
| 250 |
+
axis_id = self.indexer_other_axes_names.index(axis_name)
|
| 251 |
+
full_index = full_index + arange_at_position(
|
| 252 |
+
xp, len(self.indexer_other_axes_names), axis=axis_id, axis_len=known_axes_sizes[axis_name],
|
| 253 |
+
device=arr.device,
|
| 254 |
+
) * shift
|
| 255 |
+
shift *= known_axes_sizes[axis_name]
|
| 256 |
+
|
| 257 |
+
assert shift == arr_2d.shape[0]
|
| 258 |
+
|
| 259 |
+
# step 3. Flatten index
|
| 260 |
+
full_index = self.index_composition.compose(full_index, known_axes_sizes)
|
| 261 |
+
|
| 262 |
+
# step 4. indexing
|
| 263 |
+
# python array api lacks any integer indexing, so... I use loops.
|
| 264 |
+
# did you know that there is conceptual programming ... just like art?
|
| 265 |
+
# result_2d = arr_2d[full_index]
|
| 266 |
+
result_2d = xp.stack([arr_2d[full_index[i], :] for i in range(full_index.shape[0])])
|
| 267 |
+
|
| 268 |
+
# step 5. doing resulting
|
| 269 |
+
result = self.result_composition.decompose(result_2d, known_axes_sizes)
|
| 270 |
+
return result
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
def einindex(pattern: str, arr: T, /, ind: Union[T, List[T]]):
|
| 274 |
+
"""
|
| 275 |
+
Demonstrates how einindex should work.
|
| 276 |
+
Supports data-api compliant arrays.
|
| 277 |
+
"""
|
| 278 |
+
formula = IndexingFormula(pattern)
|
| 279 |
+
return formula.apply_to_array_api(arr, ind)
|
| 280 |
+
|
| 281 |
+
|
| 282 |
+
def test_composition_and_decomposition():
|
| 283 |
+
import numpy.array_api as np
|
| 284 |
+
x = np.arange(2 * 3 * 5 * 7)
|
| 285 |
+
x = np.reshape(x, (2, 3, 5, 7))
|
| 286 |
+
comp = CompositionDecomposition(
|
| 287 |
+
decomposed_shape=['a', 'b', 'c', 'd'],
|
| 288 |
+
composed_shape=[['a', 'b'], ['c', 'd']],
|
| 289 |
+
)
|
| 290 |
+
assert comp.compose(x, known_axes_lengths={}).shape == (2 * 3, 5 * 7)
|
| 291 |
+
|
| 292 |
+
y = CompositionDecomposition(
|
| 293 |
+
decomposed_shape=['a', 'b', 'c', 'd'],
|
| 294 |
+
composed_shape=[['a', 'b'], [], ['c', 'd']],
|
| 295 |
+
).compose(x, {})
|
| 296 |
+
assert y.shape == (2 * 3, 1, 5 * 7)
|
| 297 |
+
assert np.all(np.reshape(x, (-1,)) == np.reshape(y, (-1,)))
|
| 298 |
+
|
| 299 |
+
comp = CompositionDecomposition(
|
| 300 |
+
decomposed_shape=['a', 'b', 'e', 'c', 'd'],
|
| 301 |
+
composed_shape=[['e', 'c'], ['b'], ['a', 'd']],
|
| 302 |
+
)
|
| 303 |
+
x = np.arange(2 * 3 * 5 * 7 * 3)
|
| 304 |
+
x = np.reshape(x, (2, 3, 5, 7, 3))
|
| 305 |
+
|
| 306 |
+
axes = {}
|
| 307 |
+
y = comp.compose(x, axes)
|
| 308 |
+
x2 = comp.decompose(y, axes)
|
| 309 |
+
assert np.all(x == x2)
|
| 310 |
+
|
| 311 |
+
|
| 312 |
+
def test_simple_indexing():
|
| 313 |
+
import numpy.array_api as np
|
| 314 |
+
|
| 315 |
+
# simple 2d test
|
| 316 |
+
arr = np.reshape(np.arange(5 * 7), (5, 7))
|
| 317 |
+
ind = np.arange(7) % 5
|
| 318 |
+
x = einindex('j <- i j, [i] j', arr, [ind])
|
| 319 |
+
for j, i in enumerate(ind):
|
| 320 |
+
assert arr[i, j] == x[j]
|
| 321 |
+
|
| 322 |
+
y = einindex('j <- j i, [i] j', np.permute_dims(arr, (1, 0)), [ind])
|
| 323 |
+
for j, i in enumerate(ind):
|
| 324 |
+
assert arr[i, j] == y[j]
|
| 325 |
+
|
| 326 |
+
|
| 327 |
+
def test_multidimensional_indexing():
|
| 328 |
+
import numpy.array_api as np
|
| 329 |
+
|
| 330 |
+
embedding_bhwc = (
|
| 331 |
+
+ arange_at_position(np, 4, 0, 2) * 1000
|
| 332 |
+
+ arange_at_position(np, 4, 1, 3) * 100
|
| 333 |
+
+ arange_at_position(np, 4, 2, 5) * 10
|
| 334 |
+
+ arange_at_position(np, 4, 3, 7) * 1
|
| 335 |
+
)
|
| 336 |
+
|
| 337 |
+
hindices_bt = np.reshape(np.arange(6), (2, 3)) % 3
|
| 338 |
+
windices_bt = np.reshape(np.arange(6), (2, 3)) % 5
|
| 339 |
+
|
| 340 |
+
# imagine that you have pairs of image <> sentence
|
| 341 |
+
# your goal is to get most suitable token from image for every token in sentence
|
| 342 |
+
# thus for every token in sentence you compute best k and v
|
| 343 |
+
|
| 344 |
+
result = einindex('c t b <- b h w c, [h, w] b t', embedding_bhwc, [hindices_bt, windices_bt])
|
| 345 |
+
# example of using a single array for indexing multiple axes
|
| 346 |
+
hw_indices_bt = np.stack([hindices_bt, windices_bt])
|
| 347 |
+
result2 = einindex('c t b <- b h w c, [h, w] b t', embedding_bhwc, hw_indices_bt)
|
| 348 |
+
assert np.all(result == result2)
|
| 349 |
+
|
| 350 |
+
# check vs manual element computation
|
| 351 |
+
result_manual = result * 0
|
| 352 |
+
for b in range(2):
|
| 353 |
+
for t in range(3):
|
| 354 |
+
for c in range(7):
|
| 355 |
+
h = hindices_bt[b, t]
|
| 356 |
+
w = windices_bt[b, t]
|
| 357 |
+
result_manual[c, t, b] = embedding_bhwc[b, h, w, c]
|
| 358 |
+
|
| 359 |
+
assert np.all(result == result_manual)
|
| 360 |
+
|
| 361 |
+
|
| 362 |
+
def test_reverse_indexing():
|
| 363 |
+
import numpy.array_api as np
|
| 364 |
+
|
| 365 |
+
C, T, B = 2, 3, 5
|
| 366 |
+
# G = GPU, batch-like varaible
|
| 367 |
+
G = 4
|
| 368 |
+
H = 7
|
| 369 |
+
W = 9
|
| 370 |
+
|
| 371 |
+
arr_gtbc = (
|
| 372 |
+
+ arange_at_position(np, 4, 0, G) * 1000
|
| 373 |
+
+ arange_at_position(np, 4, 1, T) * 100
|
| 374 |
+
+ arange_at_position(np, 4, 2, B) * 10
|
| 375 |
+
+ arange_at_position(np, 4, 3, C) * 1
|
| 376 |
+
)
|
| 377 |
+
|
| 378 |
+
t_indices_gbhw = np.reshape(np.arange(G * B * H * W), (G, B, H, W)) % T
|
| 379 |
+
|
| 380 |
+
result = einindex('g b c h w <- g t b c, [t] g b h w', arr_gtbc, [t_indices_gbhw])
|
| 381 |
+
|
| 382 |
+
result_manual = result * 0
|
| 383 |
+
for g in range(G):
|
| 384 |
+
for b in range(B):
|
| 385 |
+
for c in range(C):
|
| 386 |
+
for h in range(H):
|
| 387 |
+
for w in range(W):
|
| 388 |
+
t = t_indices_gbhw[g, b, h, w]
|
| 389 |
+
result_manual[g, b, c, h, w] = arr_gtbc[g, t, b, c]
|
| 390 |
+
|
| 391 |
+
assert np.all(result == result_manual)
|
| 392 |
+
|
| 393 |
+
|
rtme/lib/python3.10/site-packages/einops/layers/__init__.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__author__ = 'Alex Rogozhnikov'
|
| 2 |
+
|
| 3 |
+
from typing import Any, Dict
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
from ..einops import TransformRecipe, _apply_recipe, _prepare_recipes_for_all_dims, get_backend
|
| 7 |
+
from .. import EinopsError
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
class RearrangeMixin:
|
| 11 |
+
"""
|
| 12 |
+
Rearrange layer behaves identically to einops.rearrange operation.
|
| 13 |
+
|
| 14 |
+
:param pattern: str, rearrangement pattern
|
| 15 |
+
:param axes_lengths: any additional specification of dimensions
|
| 16 |
+
|
| 17 |
+
See einops.rearrange for source_examples.
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
def __init__(self, pattern: str, **axes_lengths: Any) -> None:
|
| 21 |
+
super().__init__()
|
| 22 |
+
self.pattern = pattern
|
| 23 |
+
self.axes_lengths = axes_lengths
|
| 24 |
+
# self._recipe = self.recipe() # checking parameters
|
| 25 |
+
self._multirecipe = self.multirecipe()
|
| 26 |
+
self._axes_lengths = tuple(self.axes_lengths.items())
|
| 27 |
+
|
| 28 |
+
def __repr__(self) -> str:
|
| 29 |
+
params = repr(self.pattern)
|
| 30 |
+
for axis, length in self.axes_lengths.items():
|
| 31 |
+
params += ', {}={}'.format(axis, length)
|
| 32 |
+
return '{}({})'.format(self.__class__.__name__, params)
|
| 33 |
+
|
| 34 |
+
def multirecipe(self) -> Dict[int, TransformRecipe]:
|
| 35 |
+
try:
|
| 36 |
+
return _prepare_recipes_for_all_dims(
|
| 37 |
+
self.pattern, operation='rearrange', axes_names=tuple(self.axes_lengths)
|
| 38 |
+
)
|
| 39 |
+
except EinopsError as e:
|
| 40 |
+
raise EinopsError(' Error while preparing {!r}\n {}'.format(self, e))
|
| 41 |
+
|
| 42 |
+
def _apply_recipe(self, x):
|
| 43 |
+
backend = get_backend(x)
|
| 44 |
+
return _apply_recipe(
|
| 45 |
+
backend=backend,
|
| 46 |
+
recipe=self._multirecipe[len(x.shape)],
|
| 47 |
+
tensor=x,
|
| 48 |
+
reduction_type='rearrange',
|
| 49 |
+
axes_lengths=self._axes_lengths,
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
def __getstate__(self):
|
| 53 |
+
return {'pattern': self.pattern, 'axes_lengths': self.axes_lengths}
|
| 54 |
+
|
| 55 |
+
def __setstate__(self, state):
|
| 56 |
+
self.__init__(pattern=state['pattern'], **state['axes_lengths'])
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
class ReduceMixin:
|
| 60 |
+
"""
|
| 61 |
+
Reduce layer behaves identically to einops.reduce operation.
|
| 62 |
+
|
| 63 |
+
:param pattern: str, rearrangement pattern
|
| 64 |
+
:param reduction: one of available reductions ('min', 'max', 'sum', 'mean', 'prod'), case-sensitive
|
| 65 |
+
:param axes_lengths: any additional specification of dimensions
|
| 66 |
+
|
| 67 |
+
See einops.reduce for source_examples.
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
def __init__(self, pattern: str, reduction: str, **axes_lengths: Any):
|
| 71 |
+
super().__init__()
|
| 72 |
+
self.pattern = pattern
|
| 73 |
+
self.reduction = reduction
|
| 74 |
+
self.axes_lengths = axes_lengths
|
| 75 |
+
self._multirecipe = self.multirecipe()
|
| 76 |
+
self._axes_lengths = tuple(self.axes_lengths.items())
|
| 77 |
+
|
| 78 |
+
def __repr__(self):
|
| 79 |
+
params = '{!r}, {!r}'.format(self.pattern, self.reduction)
|
| 80 |
+
for axis, length in self.axes_lengths.items():
|
| 81 |
+
params += ', {}={}'.format(axis, length)
|
| 82 |
+
return '{}({})'.format(self.__class__.__name__, params)
|
| 83 |
+
|
| 84 |
+
def multirecipe(self) -> Dict[int, TransformRecipe]:
|
| 85 |
+
try:
|
| 86 |
+
return _prepare_recipes_for_all_dims(
|
| 87 |
+
self.pattern, operation=self.reduction, axes_names=tuple(self.axes_lengths)
|
| 88 |
+
)
|
| 89 |
+
except EinopsError as e:
|
| 90 |
+
raise EinopsError(' Error while preparing {!r}\n {}'.format(self, e))
|
| 91 |
+
|
| 92 |
+
def _apply_recipe(self, x):
|
| 93 |
+
backend = get_backend(x)
|
| 94 |
+
return _apply_recipe(
|
| 95 |
+
backend=backend,
|
| 96 |
+
recipe=self._multirecipe[len(x.shape)],
|
| 97 |
+
tensor=x,
|
| 98 |
+
reduction_type=self.reduction,
|
| 99 |
+
axes_lengths=self._axes_lengths,
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
def __getstate__(self):
|
| 103 |
+
return {'pattern': self.pattern, 'reduction': self.reduction, 'axes_lengths': self.axes_lengths}
|
| 104 |
+
|
| 105 |
+
def __setstate__(self, state):
|
| 106 |
+
self.__init__(pattern=state['pattern'], reduction=state['reduction'], **state['axes_lengths'])
|
rtme/lib/python3.10/site-packages/einops/layers/_einmix.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, List, Optional, Dict
|
| 2 |
+
|
| 3 |
+
from einops import EinopsError
|
| 4 |
+
from einops.parsing import ParsedExpression
|
| 5 |
+
import warnings
|
| 6 |
+
import string
|
| 7 |
+
from ..einops import _product
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def _report_axes(axes: set, report_message: str):
|
| 11 |
+
if len(axes) > 0:
|
| 12 |
+
raise EinopsError(report_message.format(axes))
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class _EinmixMixin:
|
| 16 |
+
def __init__(self, pattern: str, weight_shape: str, bias_shape: Optional[str]=None, **axes_lengths: Any):
|
| 17 |
+
"""
|
| 18 |
+
EinMix - Einstein summation with automated tensor management and axis packing/unpacking.
|
| 19 |
+
|
| 20 |
+
EinMix is an advanced tool, helpful tutorial:
|
| 21 |
+
https://github.com/arogozhnikov/einops/blob/master/docs/3-einmix-layer.ipynb
|
| 22 |
+
|
| 23 |
+
Imagine taking einsum with two arguments, one of each input, and one - tensor with weights
|
| 24 |
+
>>> einsum('time batch channel_in, channel_in channel_out -> time batch channel_out', input, weight)
|
| 25 |
+
|
| 26 |
+
This layer manages weights for you, syntax highlights separate role of weight matrix
|
| 27 |
+
>>> EinMix('time batch channel_in -> time batch channel_out', weight_shape='channel_in channel_out')
|
| 28 |
+
But otherwise it is the same einsum under the hood.
|
| 29 |
+
|
| 30 |
+
Simple linear layer with bias term (you have one like that in your framework)
|
| 31 |
+
>>> EinMix('t b cin -> t b cout', weight_shape='cin cout', bias_shape='cout', cin=10, cout=20)
|
| 32 |
+
There is no restriction to mix the last axis. Let's mix along height
|
| 33 |
+
>>> EinMix('h w c-> hout w c', weight_shape='h hout', bias_shape='hout', h=32, hout=32)
|
| 34 |
+
Channel-wise multiplication (like one used in normalizations)
|
| 35 |
+
>>> EinMix('t b c -> t b c', weight_shape='c', c=128)
|
| 36 |
+
Multi-head linear layer (each head is own linear layer):
|
| 37 |
+
>>> EinMix('t b (head cin) -> t b (head cout)', weight_shape='head cin cout', ...)
|
| 38 |
+
|
| 39 |
+
... ah yes, you need to specify all dimensions of weight shape/bias shape in parameters.
|
| 40 |
+
|
| 41 |
+
Use cases:
|
| 42 |
+
- when channel dimension is not last, use EinMix, not transposition
|
| 43 |
+
- patch/segment embeddings
|
| 44 |
+
- when need only within-group connections to reduce number of weights and computations
|
| 45 |
+
- perfect as a part of sequential models
|
| 46 |
+
- next-gen MLPs (follow tutorial to learn more)
|
| 47 |
+
|
| 48 |
+
Uniform He initialization is applied to weight tensor and encounters for number of elements mixed.
|
| 49 |
+
|
| 50 |
+
Parameters
|
| 51 |
+
:param pattern: transformation pattern, left side - dimensions of input, right side - dimensions of output
|
| 52 |
+
:param weight_shape: axes of weight. A tensor of this shape is created, stored, and optimized in a layer
|
| 53 |
+
:param bias_shape: axes of bias added to output. Weights of this shape are created and stored. If `None` (the default), no bias is added.
|
| 54 |
+
:param axes_lengths: dimensions of weight tensor
|
| 55 |
+
"""
|
| 56 |
+
super().__init__()
|
| 57 |
+
self.pattern = pattern
|
| 58 |
+
self.weight_shape = weight_shape
|
| 59 |
+
self.bias_shape = bias_shape
|
| 60 |
+
self.axes_lengths = axes_lengths
|
| 61 |
+
self.initialize_einmix(pattern=pattern, weight_shape=weight_shape, bias_shape=bias_shape, axes_lengths=axes_lengths)
|
| 62 |
+
|
| 63 |
+
def initialize_einmix(self, pattern: str, weight_shape: str, bias_shape: Optional[str], axes_lengths: dict):
|
| 64 |
+
left_pattern, right_pattern = pattern.split('->')
|
| 65 |
+
left = ParsedExpression(left_pattern)
|
| 66 |
+
right = ParsedExpression(right_pattern)
|
| 67 |
+
weight = ParsedExpression(weight_shape)
|
| 68 |
+
_report_axes(
|
| 69 |
+
set.difference(right.identifiers, {*left.identifiers, *weight.identifiers}),
|
| 70 |
+
'Unrecognized identifiers on the right side of EinMix {}'
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
if left.has_ellipsis or right.has_ellipsis or weight.has_ellipsis:
|
| 74 |
+
raise EinopsError('Ellipsis is not supported in EinMix (right now)')
|
| 75 |
+
if any(x.has_non_unitary_anonymous_axes for x in [left, right, weight]):
|
| 76 |
+
raise EinopsError('Anonymous axes (numbers) are not allowed in EinMix')
|
| 77 |
+
if '(' in weight_shape or ')' in weight_shape:
|
| 78 |
+
raise EinopsError(f'Parenthesis is not allowed in weight shape: {weight_shape}')
|
| 79 |
+
|
| 80 |
+
pre_reshape_pattern = None
|
| 81 |
+
pre_reshape_lengths = None
|
| 82 |
+
post_reshape_pattern = None
|
| 83 |
+
if any(len(group) != 1 for group in left.composition):
|
| 84 |
+
names: List[str] = []
|
| 85 |
+
for group in left.composition:
|
| 86 |
+
names += group
|
| 87 |
+
composition = ' '.join(names)
|
| 88 |
+
pre_reshape_pattern = f'{left_pattern}->{composition}'
|
| 89 |
+
pre_reshape_lengths = {name: length for name, length in axes_lengths.items() if name in names}
|
| 90 |
+
|
| 91 |
+
if any(len(group) != 1 for group in right.composition):
|
| 92 |
+
names = []
|
| 93 |
+
for group in right.composition:
|
| 94 |
+
names += group
|
| 95 |
+
composition = ' '.join(names)
|
| 96 |
+
post_reshape_pattern = f'{composition}->{right_pattern}'
|
| 97 |
+
|
| 98 |
+
self._create_rearrange_layers(pre_reshape_pattern, pre_reshape_lengths, post_reshape_pattern, {})
|
| 99 |
+
|
| 100 |
+
for axis in weight.identifiers:
|
| 101 |
+
if axis not in axes_lengths:
|
| 102 |
+
raise EinopsError('Dimension {} of weight should be specified'.format(axis))
|
| 103 |
+
_report_axes(
|
| 104 |
+
set.difference(set(axes_lengths), {*left.identifiers, *weight.identifiers}),
|
| 105 |
+
'Axes {} are not used in pattern',
|
| 106 |
+
)
|
| 107 |
+
_report_axes(
|
| 108 |
+
set.difference(weight.identifiers, {*left.identifiers, *right.identifiers}),
|
| 109 |
+
'Weight axes {} are redundant'
|
| 110 |
+
)
|
| 111 |
+
if len(weight.identifiers) == 0:
|
| 112 |
+
warnings.warn('EinMix: weight has no dimensions (means multiplication by a number)')
|
| 113 |
+
|
| 114 |
+
_weight_shape = [axes_lengths[axis] for axis, in weight.composition]
|
| 115 |
+
# single output element is a combination of fan_in input elements
|
| 116 |
+
_fan_in = _product([axes_lengths[axis] for axis, in weight.composition if axis not in right.identifiers])
|
| 117 |
+
if bias_shape is not None:
|
| 118 |
+
if not isinstance(bias_shape, str):
|
| 119 |
+
raise EinopsError('bias shape should be string specifying which axes bias depends on')
|
| 120 |
+
bias = ParsedExpression(bias_shape)
|
| 121 |
+
_report_axes(
|
| 122 |
+
set.difference(bias.identifiers, right.identifiers),
|
| 123 |
+
'Bias axes {} not present in output'
|
| 124 |
+
)
|
| 125 |
+
_report_axes(
|
| 126 |
+
set.difference(bias.identifiers, set(axes_lengths)),
|
| 127 |
+
'Sizes not provided for bias axes {}',
|
| 128 |
+
)
|
| 129 |
+
|
| 130 |
+
_bias_shape = []
|
| 131 |
+
for axes in right.composition:
|
| 132 |
+
for axis in axes:
|
| 133 |
+
if axis in bias.identifiers:
|
| 134 |
+
_bias_shape.append(axes_lengths[axis])
|
| 135 |
+
else:
|
| 136 |
+
_bias_shape.append(1)
|
| 137 |
+
else:
|
| 138 |
+
_bias_shape = None
|
| 139 |
+
|
| 140 |
+
weight_bound = (3 / _fan_in) ** 0.5
|
| 141 |
+
bias_bound = (1 / _fan_in) ** 0.5
|
| 142 |
+
self._create_parameters(_weight_shape, weight_bound, _bias_shape, bias_bound)
|
| 143 |
+
|
| 144 |
+
# rewrite einsum expression with single-letter latin identifiers so that
|
| 145 |
+
# expression will be understood by any framework
|
| 146 |
+
mapped_identifiers = {*left.identifiers, *right.identifiers, *weight.identifiers}
|
| 147 |
+
mapping2letters = {k: letter for letter, k in zip(string.ascii_lowercase, mapped_identifiers)}
|
| 148 |
+
|
| 149 |
+
def write_flat(axes: list):
|
| 150 |
+
return ''.join(mapping2letters[axis] for axis in axes)
|
| 151 |
+
|
| 152 |
+
self.einsum_pattern: str = '{},{}->{}'.format(
|
| 153 |
+
write_flat(left.flat_axes_order()),
|
| 154 |
+
write_flat(weight.flat_axes_order()),
|
| 155 |
+
write_flat(right.flat_axes_order()),
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
def _create_rearrange_layers(self,
|
| 159 |
+
pre_reshape_pattern: Optional[str],
|
| 160 |
+
pre_reshape_lengths: Optional[Dict],
|
| 161 |
+
post_reshape_pattern: Optional[str],
|
| 162 |
+
post_reshape_lengths: Optional[Dict]):
|
| 163 |
+
raise NotImplementedError('Should be defined in framework implementations')
|
| 164 |
+
|
| 165 |
+
def _create_parameters(self, weight_shape, weight_bound, bias_shape, bias_bound):
|
| 166 |
+
""" Shape and implementations """
|
| 167 |
+
raise NotImplementedError('Should be defined in framework implementations')
|
| 168 |
+
|
| 169 |
+
def __repr__(self):
|
| 170 |
+
params = repr(self.pattern)
|
| 171 |
+
params += f", '{self.weight_shape}'"
|
| 172 |
+
if self.bias_shape is not None:
|
| 173 |
+
params += f", '{self.bias_shape}'"
|
| 174 |
+
for axis, length in self.axes_lengths.items():
|
| 175 |
+
params += ', {}={}'.format(axis, length)
|
| 176 |
+
return '{}({})'.format(self.__class__.__name__, params)
|
rtme/lib/python3.10/site-packages/einops/layers/chainer.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Dict, cast
|
| 2 |
+
|
| 3 |
+
import chainer
|
| 4 |
+
|
| 5 |
+
from . import RearrangeMixin, ReduceMixin
|
| 6 |
+
from ._einmix import _EinmixMixin
|
| 7 |
+
|
| 8 |
+
__author__ = 'Alex Rogozhnikov'
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class Rearrange(RearrangeMixin, chainer.Link):
|
| 12 |
+
def __call__(self, x):
|
| 13 |
+
return self._apply_recipe(x)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class Reduce(ReduceMixin, chainer.Link):
|
| 17 |
+
def __call__(self, x):
|
| 18 |
+
return self._apply_recipe(x)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class EinMix(_EinmixMixin, chainer.Link):
|
| 22 |
+
def _create_parameters(self, weight_shape, weight_bound, bias_shape, bias_bound):
|
| 23 |
+
uniform = chainer.variable.initializers.Uniform
|
| 24 |
+
with self.init_scope():
|
| 25 |
+
self.weight = chainer.variable.Parameter(uniform(weight_bound), weight_shape)
|
| 26 |
+
if bias_shape is not None:
|
| 27 |
+
self.bias = chainer.variable.Parameter(uniform(bias_bound), bias_shape)
|
| 28 |
+
else:
|
| 29 |
+
self.bias = None
|
| 30 |
+
|
| 31 |
+
def _create_rearrange_layers(self,
|
| 32 |
+
pre_reshape_pattern: Optional[str],
|
| 33 |
+
pre_reshape_lengths: Optional[Dict],
|
| 34 |
+
post_reshape_pattern: Optional[str],
|
| 35 |
+
post_reshape_lengths: Optional[Dict],
|
| 36 |
+
):
|
| 37 |
+
self.pre_rearrange = None
|
| 38 |
+
if pre_reshape_pattern is not None:
|
| 39 |
+
self.pre_rearrange = Rearrange(pre_reshape_pattern, **cast(dict, pre_reshape_lengths))
|
| 40 |
+
|
| 41 |
+
self.post_rearrange = None
|
| 42 |
+
if post_reshape_pattern is not None:
|
| 43 |
+
self.post_rearrange = Rearrange(post_reshape_pattern, **cast(dict, post_reshape_lengths))
|
| 44 |
+
|
| 45 |
+
def __call__(self, input):
|
| 46 |
+
if self.pre_rearrange is not None:
|
| 47 |
+
input = self.pre_rearrange(input)
|
| 48 |
+
result = chainer.functions.einsum(self.einsum_pattern, input, self.weight)
|
| 49 |
+
if self.bias is not None:
|
| 50 |
+
result = result + self.bias
|
| 51 |
+
if self.post_rearrange is not None:
|
| 52 |
+
result = self.post_rearrange(result)
|
| 53 |
+
return result
|
rtme/lib/python3.10/site-packages/einops/layers/flax.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from dataclasses import field
|
| 2 |
+
from typing import Optional, Dict, cast
|
| 3 |
+
|
| 4 |
+
import flax.linen as nn
|
| 5 |
+
import jax
|
| 6 |
+
import jax.numpy as jnp
|
| 7 |
+
|
| 8 |
+
from . import RearrangeMixin, ReduceMixin
|
| 9 |
+
from ._einmix import _EinmixMixin
|
| 10 |
+
|
| 11 |
+
__author__ = 'Alex Rogozhnikov'
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class Reduce(nn.Module):
|
| 15 |
+
pattern: str
|
| 16 |
+
reduction: str
|
| 17 |
+
sizes: dict = field(default_factory=lambda: {})
|
| 18 |
+
|
| 19 |
+
def setup(self):
|
| 20 |
+
self.reducer = ReduceMixin(self.pattern, self.reduction, **self.sizes)
|
| 21 |
+
|
| 22 |
+
def __call__(self, input):
|
| 23 |
+
return self.reducer._apply_recipe(input)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class Rearrange(nn.Module):
|
| 27 |
+
pattern: str
|
| 28 |
+
sizes: dict = field(default_factory=lambda: {})
|
| 29 |
+
|
| 30 |
+
def setup(self):
|
| 31 |
+
self.rearranger = RearrangeMixin(self.pattern, **self.sizes)
|
| 32 |
+
|
| 33 |
+
def __call__(self, input):
|
| 34 |
+
return self.rearranger._apply_recipe(input)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class EinMix(nn.Module, _EinmixMixin):
|
| 38 |
+
pattern: str
|
| 39 |
+
weight_shape: str
|
| 40 |
+
bias_shape: Optional[str] = None
|
| 41 |
+
sizes: dict = field(default_factory=lambda: {})
|
| 42 |
+
|
| 43 |
+
def setup(self):
|
| 44 |
+
self.initialize_einmix(
|
| 45 |
+
pattern=self.pattern,
|
| 46 |
+
weight_shape=self.weight_shape,
|
| 47 |
+
bias_shape=self.bias_shape,
|
| 48 |
+
axes_lengths=self.sizes,
|
| 49 |
+
)
|
| 50 |
+
|
| 51 |
+
def _create_parameters(self, weight_shape, weight_bound, bias_shape, bias_bound):
|
| 52 |
+
self.weight = self.param("weight", jax.nn.initializers.uniform(weight_bound), weight_shape)
|
| 53 |
+
|
| 54 |
+
if bias_shape is not None:
|
| 55 |
+
self.bias = self.param("bias", jax.nn.initializers.uniform(bias_bound), bias_shape)
|
| 56 |
+
else:
|
| 57 |
+
self.bias = None
|
| 58 |
+
|
| 59 |
+
def _create_rearrange_layers(self,
|
| 60 |
+
pre_reshape_pattern: Optional[str],
|
| 61 |
+
pre_reshape_lengths: Optional[Dict],
|
| 62 |
+
post_reshape_pattern: Optional[str],
|
| 63 |
+
post_reshape_lengths: Optional[Dict]):
|
| 64 |
+
self.pre_rearrange = None
|
| 65 |
+
if pre_reshape_pattern is not None:
|
| 66 |
+
self.pre_rearrange = Rearrange(pre_reshape_pattern, sizes=cast(dict, pre_reshape_lengths))
|
| 67 |
+
|
| 68 |
+
self.post_rearrange = None
|
| 69 |
+
if post_reshape_pattern is not None:
|
| 70 |
+
self.post_rearrange = Rearrange(post_reshape_pattern, sizes=cast(dict, post_reshape_lengths))
|
| 71 |
+
|
| 72 |
+
def __call__(self, input):
|
| 73 |
+
if self.pre_rearrange is not None:
|
| 74 |
+
input = self.pre_rearrange(input)
|
| 75 |
+
result = jnp.einsum(self.einsum_pattern, input, self.weight)
|
| 76 |
+
if self.bias is not None:
|
| 77 |
+
result += self.bias
|
| 78 |
+
if self.post_rearrange is not None:
|
| 79 |
+
result = self.post_rearrange(result)
|
| 80 |
+
return result
|
rtme/lib/python3.10/site-packages/einops/layers/keras.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__author__ = 'Alex Rogozhnikov'
|
| 2 |
+
|
| 3 |
+
from ..layers.tensorflow import Rearrange, Reduce, EinMix
|
| 4 |
+
|
| 5 |
+
keras_custom_objects = {
|
| 6 |
+
Rearrange.__name__: Rearrange,
|
| 7 |
+
Reduce.__name__: Reduce,
|
| 8 |
+
EinMix.__name__: EinMix,
|
| 9 |
+
}
|
rtme/lib/python3.10/site-packages/einops/layers/paddle.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Optional, Dict, cast
|
| 2 |
+
|
| 3 |
+
import paddle
|
| 4 |
+
|
| 5 |
+
from . import RearrangeMixin, ReduceMixin
|
| 6 |
+
from ._einmix import _EinmixMixin
|
| 7 |
+
|
| 8 |
+
__author__ = 'PaddlePaddle'
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class Rearrange(RearrangeMixin, paddle.nn.Layer):
|
| 12 |
+
def forward(self, input):
|
| 13 |
+
return self._apply_recipe(input)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class Reduce(ReduceMixin, paddle.nn.Layer):
|
| 17 |
+
def forward(self, input):
|
| 18 |
+
return self._apply_recipe(input)
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class EinMix(_EinmixMixin, paddle.nn.Layer):
|
| 22 |
+
def _create_parameters(self, weight_shape, weight_bound, bias_shape, bias_bound):
|
| 23 |
+
self.weight = self.create_parameter(
|
| 24 |
+
weight_shape,
|
| 25 |
+
default_initializer=paddle.nn.initializer.Uniform(-weight_bound, weight_bound)
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
if bias_shape is not None:
|
| 29 |
+
self.bias = self.create_parameter(
|
| 30 |
+
bias_shape,
|
| 31 |
+
default_initializer=paddle.nn.initializer.Uniform(-bias_bound, bias_bound)
|
| 32 |
+
)
|
| 33 |
+
else:
|
| 34 |
+
self.bias = None
|
| 35 |
+
|
| 36 |
+
def _create_rearrange_layers(self,
|
| 37 |
+
pre_reshape_pattern: Optional[str],
|
| 38 |
+
pre_reshape_lengths: Optional[Dict],
|
| 39 |
+
post_reshape_pattern: Optional[str],
|
| 40 |
+
post_reshape_lengths: Optional[Dict],
|
| 41 |
+
):
|
| 42 |
+
self.pre_rearrange = None
|
| 43 |
+
if pre_reshape_pattern is not None:
|
| 44 |
+
self.pre_rearrange = Rearrange(pre_reshape_pattern, **cast(dict, pre_reshape_lengths))
|
| 45 |
+
|
| 46 |
+
self.post_rearrange = None
|
| 47 |
+
if post_reshape_pattern is not None:
|
| 48 |
+
self.post_rearrange = Rearrange(post_reshape_pattern, **cast(dict, post_reshape_lengths))
|
| 49 |
+
|
| 50 |
+
def forward(self, input):
|
| 51 |
+
if self.pre_rearrange is not None:
|
| 52 |
+
input = self.pre_rearrange(input)
|
| 53 |
+
|
| 54 |
+
result = paddle.einsum(self.einsum_pattern, input, self.weight)
|
| 55 |
+
if self.bias is not None:
|
| 56 |
+
result += self.bias
|
| 57 |
+
if self.post_rearrange is not None:
|
| 58 |
+
result = self.post_rearrange(result)
|
| 59 |
+
return result
|
rtme/lib/python3.10/site-packages/idna/compat.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import Any, Union
|
| 2 |
+
|
| 3 |
+
from .core import decode, encode
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def ToASCII(label: str) -> bytes:
|
| 7 |
+
return encode(label)
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def ToUnicode(label: Union[bytes, bytearray]) -> str:
|
| 11 |
+
return decode(label)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def nameprep(s: Any) -> None:
|
| 15 |
+
raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol")
|
rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/METADATA
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: jupyter-lsp
|
| 3 |
+
Version: 2.2.5
|
| 4 |
+
Summary: Multi-Language Server WebSocket proxy for Jupyter Notebook/Lab server
|
| 5 |
+
Author: jupyter-lsp Contributors
|
| 6 |
+
Author-email: project.jupyter@gmail.com
|
| 7 |
+
License: BSD-3-Clause
|
| 8 |
+
Project-URL: Bug Tracker, https://github.com/jupyter-lsp/jupyterlab-lsp/issues
|
| 9 |
+
Project-URL: Documentation, https://jupyterlab-lsp.readthedocs.io/
|
| 10 |
+
Project-URL: Source Code, https://github.com/jupyter-lsp/jupyterlab-lsp
|
| 11 |
+
Keywords: Interactive,Language Server,LSP
|
| 12 |
+
Classifier: Framework :: Jupyter
|
| 13 |
+
Classifier: Intended Audience :: Developers
|
| 14 |
+
Classifier: Intended Audience :: Information Technology
|
| 15 |
+
Classifier: License :: OSI Approved :: BSD License
|
| 16 |
+
Classifier: Programming Language :: Python
|
| 17 |
+
Requires-Python: >=3.8
|
| 18 |
+
Description-Content-Type: text/markdown
|
| 19 |
+
License-File: LICENSE
|
| 20 |
+
Requires-Dist: jupyter-server >=1.1.2
|
| 21 |
+
Requires-Dist: importlib-metadata >=4.8.3 ; python_version < "3.10"
|
| 22 |
+
|
| 23 |
+
# jupyter-lsp
|
| 24 |
+
|
| 25 |
+
Multi-[Language Server][language-server] WebSocket proxy for your Jupyter
|
| 26 |
+
`notebook` or `lab` server. For Python 3.6+.
|
| 27 |
+
|
| 28 |
+
> See the parent of this repository,
|
| 29 |
+
> [jupyterlab-lsp](https://github.com/jupyter-lsp/jupyterlab-lsp) for the
|
| 30 |
+
> reference client implementation for [JupyterLab][].
|
| 31 |
+
|
| 32 |
+
# Language Servers
|
| 33 |
+
|
| 34 |
+
`jupyter-lsp` does not come with any Language Servers! Learn more about installing
|
| 35 |
+
and configuring [language servers][language servers docs]
|
| 36 |
+
|
| 37 |
+
[language-server]: https://microsoft.github.io/language-server-protocol/specification
|
| 38 |
+
[langserver]: https://langserver.org
|
| 39 |
+
[lsp-implementations]: https://microsoft.github.io/language-server-protocol/implementors/servers
|
| 40 |
+
[jupyter-lsp]: https://github.com/jupyter-lsp/jupyterlab-lsp.git
|
| 41 |
+
[jupyterlab]: https://github.com/jupyterlab/jupyterlab
|
| 42 |
+
[language servers docs]: https://jupyterlab-lsp.readthedocs.io/en/latest/Language%20Servers.html
|
rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/REQUESTED
ADDED
|
File without changes
|
rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: bdist_wheel (0.43.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/entry_points.txt
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[jupyter_lsp_spec_v1]
|
| 2 |
+
bash-language-server = jupyter_lsp.specs:bash
|
| 3 |
+
dockerfile-language-server-nodejs = jupyter_lsp.specs:dockerfile
|
| 4 |
+
javascript-typescript-langserver = jupyter_lsp.specs:ts_old
|
| 5 |
+
jedi-language-server = jupyter_lsp.specs:jedi
|
| 6 |
+
julia-language-server = jupyter_lsp.specs:julia
|
| 7 |
+
pyright = jupyter_lsp.specs:pyright
|
| 8 |
+
python-language-server = jupyter_lsp.specs:py_palantir
|
| 9 |
+
python-lsp-server = jupyter_lsp.specs:py_lsp_server
|
| 10 |
+
r-languageserver = jupyter_lsp.specs:r
|
| 11 |
+
sql-language-server = jupyter_lsp.specs:sql
|
| 12 |
+
texlab = jupyter_lsp.specs:tex
|
| 13 |
+
typescript-language-server = jupyter_lsp.specs:ts
|
| 14 |
+
unified-language-server = jupyter_lsp.specs:md
|
| 15 |
+
vscode-css-languageserver-bin = jupyter_lsp.specs:css
|
| 16 |
+
vscode-html-languageserver-bin = jupyter_lsp.specs:html
|
| 17 |
+
vscode-json-languageserver-bin = jupyter_lsp.specs:json
|
| 18 |
+
yaml-language-server = jupyter_lsp.specs:yaml
|
rtme/lib/python3.10/site-packages/jupyter_lsp-2.2.5.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
jupyter_lsp
|
rtme/lib/python3.10/site-packages/mpmath/tests/test_rootfinding.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pytest
|
| 2 |
+
from mpmath import *
|
| 3 |
+
from mpmath.calculus.optimization import Secant, Muller, Bisection, Illinois, \
|
| 4 |
+
Pegasus, Anderson, Ridder, ANewton, Newton, MNewton, MDNewton
|
| 5 |
+
|
| 6 |
+
def test_findroot():
|
| 7 |
+
# old tests, assuming secant
|
| 8 |
+
mp.dps = 15
|
| 9 |
+
assert findroot(lambda x: 4*x-3, mpf(5)).ae(0.75)
|
| 10 |
+
assert findroot(sin, mpf(3)).ae(pi)
|
| 11 |
+
assert findroot(sin, (mpf(3), mpf(3.14))).ae(pi)
|
| 12 |
+
assert findroot(lambda x: x*x+1, mpc(2+2j)).ae(1j)
|
| 13 |
+
# test all solvers with 1 starting point
|
| 14 |
+
f = lambda x: cos(x)
|
| 15 |
+
for solver in [Newton, Secant, MNewton, Muller, ANewton]:
|
| 16 |
+
x = findroot(f, 2., solver=solver)
|
| 17 |
+
assert abs(f(x)) < eps
|
| 18 |
+
# test all solvers with interval of 2 points
|
| 19 |
+
for solver in [Secant, Muller, Bisection, Illinois, Pegasus, Anderson,
|
| 20 |
+
Ridder]:
|
| 21 |
+
x = findroot(f, (1., 2.), solver=solver)
|
| 22 |
+
assert abs(f(x)) < eps
|
| 23 |
+
# test types
|
| 24 |
+
f = lambda x: (x - 2)**2
|
| 25 |
+
|
| 26 |
+
assert isinstance(findroot(f, 1, tol=1e-10), mpf)
|
| 27 |
+
assert isinstance(iv.findroot(f, 1., tol=1e-10), iv.mpf)
|
| 28 |
+
assert isinstance(fp.findroot(f, 1, tol=1e-10), float)
|
| 29 |
+
assert isinstance(fp.findroot(f, 1+0j, tol=1e-10), complex)
|
| 30 |
+
|
| 31 |
+
# issue 401
|
| 32 |
+
with pytest.raises(ValueError):
|
| 33 |
+
with workprec(2):
|
| 34 |
+
findroot(lambda x: x**2 - 4456178*x + 60372201703370,
|
| 35 |
+
mpc(real='5.278e+13', imag='-5.278e+13'))
|
| 36 |
+
|
| 37 |
+
# issue 192
|
| 38 |
+
with pytest.raises(ValueError):
|
| 39 |
+
findroot(lambda x: -1, 0)
|
| 40 |
+
|
| 41 |
+
# issue 387
|
| 42 |
+
with pytest.raises(ValueError):
|
| 43 |
+
findroot(lambda p: (1 - p)**30 - 1, 0.9)
|
| 44 |
+
|
| 45 |
+
def test_bisection():
|
| 46 |
+
# issue 273
|
| 47 |
+
assert findroot(lambda x: x**2-1,(0,2),solver='bisect') == 1
|
| 48 |
+
|
| 49 |
+
def test_mnewton():
|
| 50 |
+
f = lambda x: polyval([1,3,3,1],x)
|
| 51 |
+
x = findroot(f, -0.9, solver='mnewton')
|
| 52 |
+
assert abs(f(x)) < eps
|
| 53 |
+
|
| 54 |
+
def test_anewton():
|
| 55 |
+
f = lambda x: (x - 2)**100
|
| 56 |
+
x = findroot(f, 1., solver=ANewton)
|
| 57 |
+
assert abs(f(x)) < eps
|
| 58 |
+
|
| 59 |
+
def test_muller():
|
| 60 |
+
f = lambda x: (2 + x)**3 + 2
|
| 61 |
+
x = findroot(f, 1., solver=Muller)
|
| 62 |
+
assert abs(f(x)) < eps
|
| 63 |
+
|
| 64 |
+
def test_multiplicity():
|
| 65 |
+
for i in range(1, 5):
|
| 66 |
+
assert multiplicity(lambda x: (x - 1)**i, 1) == i
|
| 67 |
+
assert multiplicity(lambda x: x**2, 1) == 0
|
| 68 |
+
|
| 69 |
+
def test_multidimensional():
|
| 70 |
+
def f(*x):
|
| 71 |
+
return [3*x[0]**2-2*x[1]**2-1, x[0]**2-2*x[0]+x[1]**2+2*x[1]-8]
|
| 72 |
+
assert mnorm(jacobian(f, (1,-2)) - matrix([[6,8],[0,-2]]),1) < 1.e-7
|
| 73 |
+
for x, error in MDNewton(mp, f, (1,-2), verbose=0,
|
| 74 |
+
norm=lambda x: norm(x, inf)):
|
| 75 |
+
pass
|
| 76 |
+
assert norm(f(*x), 2) < 1e-14
|
| 77 |
+
# The Chinese mathematician Zhu Shijie was the very first to solve this
|
| 78 |
+
# nonlinear system 700 years ago
|
| 79 |
+
f1 = lambda x, y: -x + 2*y
|
| 80 |
+
f2 = lambda x, y: (x**2 + x*(y**2 - 2) - 4*y) / (x + 4)
|
| 81 |
+
f3 = lambda x, y: sqrt(x**2 + y**2)
|
| 82 |
+
def f(x, y):
|
| 83 |
+
f1x = f1(x, y)
|
| 84 |
+
return (f2(x, y) - f1x, f3(x, y) - f1x)
|
| 85 |
+
x = findroot(f, (10, 10))
|
| 86 |
+
assert [int(round(i)) for i in x] == [3, 4]
|
| 87 |
+
|
| 88 |
+
def test_trivial():
|
| 89 |
+
assert findroot(lambda x: 0, 1) == 1
|
| 90 |
+
assert findroot(lambda x: x, 0) == 0
|
| 91 |
+
#assert findroot(lambda x, y: x + y, (1, -1)) == (1, -1)
|
rtme/lib/python3.10/site-packages/mpmath/tests/test_visualization.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Limited tests of the visualization module. Right now it just makes
|
| 3 |
+
sure that passing custom Axes works.
|
| 4 |
+
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from mpmath import mp, fp
|
| 8 |
+
|
| 9 |
+
def test_axes():
|
| 10 |
+
try:
|
| 11 |
+
import matplotlib
|
| 12 |
+
version = matplotlib.__version__.split("-")[0]
|
| 13 |
+
version = version.split(".")[:2]
|
| 14 |
+
if [int(_) for _ in version] < [0,99]:
|
| 15 |
+
raise ImportError
|
| 16 |
+
import pylab
|
| 17 |
+
except ImportError:
|
| 18 |
+
print("\nSkipping test (pylab not available or too old version)\n")
|
| 19 |
+
return
|
| 20 |
+
fig = pylab.figure()
|
| 21 |
+
axes = fig.add_subplot(111)
|
| 22 |
+
for ctx in [mp, fp]:
|
| 23 |
+
ctx.plot(lambda x: x**2, [0, 3], axes=axes)
|
| 24 |
+
assert axes.get_xlabel() == 'x'
|
| 25 |
+
assert axes.get_ylabel() == 'f(x)'
|
| 26 |
+
|
| 27 |
+
fig = pylab.figure()
|
| 28 |
+
axes = fig.add_subplot(111)
|
| 29 |
+
for ctx in [mp, fp]:
|
| 30 |
+
ctx.cplot(lambda z: z, [-2, 2], [-10, 10], axes=axes)
|
| 31 |
+
assert axes.get_xlabel() == 'Re(z)'
|
| 32 |
+
assert axes.get_ylabel() == 'Im(z)'
|
rtme/lib/python3.10/site-packages/mpmath/tests/torture.py
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Torture tests for asymptotics and high precision evaluation of
|
| 3 |
+
special functions.
|
| 4 |
+
|
| 5 |
+
(Other torture tests may also be placed here.)
|
| 6 |
+
|
| 7 |
+
Running this file (gmpy recommended!) takes several CPU minutes.
|
| 8 |
+
With Python 2.6+, multiprocessing is used automatically to run tests
|
| 9 |
+
in parallel if many cores are available. (A single test may take between
|
| 10 |
+
a second and several minutes; possibly more.)
|
| 11 |
+
|
| 12 |
+
The idea:
|
| 13 |
+
|
| 14 |
+
* We evaluate functions at positive, negative, imaginary, 45- and 135-degree
|
| 15 |
+
complex values with magnitudes between 10^-20 to 10^20, at precisions between
|
| 16 |
+
5 and 150 digits (we can go even higher for fast functions).
|
| 17 |
+
|
| 18 |
+
* Comparing the result from two different precision levels provides
|
| 19 |
+
a strong consistency check (particularly for functions that use
|
| 20 |
+
different algorithms at different precision levels).
|
| 21 |
+
|
| 22 |
+
* That the computation finishes at all (without failure), within reasonable
|
| 23 |
+
time, provides a check that evaluation works at all: that the code runs,
|
| 24 |
+
that it doesn't get stuck in an infinite loop, and that it doesn't use
|
| 25 |
+
some extremely slowly algorithm where it could use a faster one.
|
| 26 |
+
|
| 27 |
+
TODO:
|
| 28 |
+
|
| 29 |
+
* Speed up those functions that take long to finish!
|
| 30 |
+
* Generalize to test more cases; more options.
|
| 31 |
+
* Implement a timeout mechanism.
|
| 32 |
+
* Some functions are notably absent, including the following:
|
| 33 |
+
* inverse trigonometric functions (some become inaccurate for complex arguments)
|
| 34 |
+
* ci, si (not implemented properly for large complex arguments)
|
| 35 |
+
* zeta functions (need to modify test not to try too large imaginary values)
|
| 36 |
+
* and others...
|
| 37 |
+
|
| 38 |
+
"""
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
import sys, os
|
| 42 |
+
from timeit import default_timer as clock
|
| 43 |
+
|
| 44 |
+
if "-nogmpy" in sys.argv:
|
| 45 |
+
sys.argv.remove('-nogmpy')
|
| 46 |
+
os.environ['MPMATH_NOGMPY'] = 'Y'
|
| 47 |
+
|
| 48 |
+
filt = ''
|
| 49 |
+
if not sys.argv[-1].endswith(".py"):
|
| 50 |
+
filt = sys.argv[-1]
|
| 51 |
+
|
| 52 |
+
from mpmath import *
|
| 53 |
+
from mpmath.libmp.backend import exec_
|
| 54 |
+
|
| 55 |
+
def test_asymp(f, maxdps=150, verbose=False, huge_range=False):
|
| 56 |
+
dps = [5,15,25,50,90,150,500,1500,5000,10000]
|
| 57 |
+
dps = [p for p in dps if p <= maxdps]
|
| 58 |
+
def check(x,y,p,inpt):
|
| 59 |
+
if abs(x-y)/abs(y) < workprec(20)(power)(10, -p+1):
|
| 60 |
+
return
|
| 61 |
+
print()
|
| 62 |
+
print("Error!")
|
| 63 |
+
print("Input:", inpt)
|
| 64 |
+
print("dps =", p)
|
| 65 |
+
print("Result 1:", x)
|
| 66 |
+
print("Result 2:", y)
|
| 67 |
+
print("Absolute error:", abs(x-y))
|
| 68 |
+
print("Relative error:", abs(x-y)/abs(y))
|
| 69 |
+
raise AssertionError
|
| 70 |
+
exponents = range(-20,20)
|
| 71 |
+
if huge_range:
|
| 72 |
+
exponents += [-1000, -100, -50, 50, 100, 1000]
|
| 73 |
+
for n in exponents:
|
| 74 |
+
if verbose:
|
| 75 |
+
sys.stdout.write(". ")
|
| 76 |
+
mp.dps = 25
|
| 77 |
+
xpos = mpf(10)**n / 1.1287
|
| 78 |
+
xneg = -xpos
|
| 79 |
+
ximag = xpos*j
|
| 80 |
+
xcomplex1 = xpos*(1+j)
|
| 81 |
+
xcomplex2 = xpos*(-1+j)
|
| 82 |
+
for i in range(len(dps)):
|
| 83 |
+
if verbose:
|
| 84 |
+
print("Testing dps = %s" % dps[i])
|
| 85 |
+
mp.dps = dps[i]
|
| 86 |
+
new = f(xpos), f(xneg), f(ximag), f(xcomplex1), f(xcomplex2)
|
| 87 |
+
if i != 0:
|
| 88 |
+
p = dps[i-1]
|
| 89 |
+
check(prev[0], new[0], p, xpos)
|
| 90 |
+
check(prev[1], new[1], p, xneg)
|
| 91 |
+
check(prev[2], new[2], p, ximag)
|
| 92 |
+
check(prev[3], new[3], p, xcomplex1)
|
| 93 |
+
check(prev[4], new[4], p, xcomplex2)
|
| 94 |
+
prev = new
|
| 95 |
+
if verbose:
|
| 96 |
+
print()
|
| 97 |
+
|
| 98 |
+
a1, a2, a3, a4, a5 = 1.5, -2.25, 3.125, 4, 2
|
| 99 |
+
|
| 100 |
+
def test_bernoulli_huge():
|
| 101 |
+
p, q = bernfrac(9000)
|
| 102 |
+
assert p % 10**10 == 9636701091
|
| 103 |
+
assert q == 4091851784687571609141381951327092757255270
|
| 104 |
+
mp.dps = 15
|
| 105 |
+
assert str(bernoulli(10**100)) == '-2.58183325604736e+987675256497386331227838638980680030172857347883537824464410652557820800494271520411283004120790908623'
|
| 106 |
+
mp.dps = 50
|
| 107 |
+
assert str(bernoulli(10**100)) == '-2.5818332560473632073252488656039475548106223822913e+987675256497386331227838638980680030172857347883537824464410652557820800494271520411283004120790908623'
|
| 108 |
+
mp.dps = 15
|
| 109 |
+
|
| 110 |
+
cases = """\
|
| 111 |
+
test_bernoulli_huge()
|
| 112 |
+
test_asymp(lambda z: +pi, maxdps=10000)
|
| 113 |
+
test_asymp(lambda z: +e, maxdps=10000)
|
| 114 |
+
test_asymp(lambda z: +ln2, maxdps=10000)
|
| 115 |
+
test_asymp(lambda z: +ln10, maxdps=10000)
|
| 116 |
+
test_asymp(lambda z: +phi, maxdps=10000)
|
| 117 |
+
test_asymp(lambda z: +catalan, maxdps=5000)
|
| 118 |
+
test_asymp(lambda z: +euler, maxdps=5000)
|
| 119 |
+
test_asymp(lambda z: +glaisher, maxdps=1000)
|
| 120 |
+
test_asymp(lambda z: +khinchin, maxdps=1000)
|
| 121 |
+
test_asymp(lambda z: +twinprime, maxdps=150)
|
| 122 |
+
test_asymp(lambda z: stieltjes(2), maxdps=150)
|
| 123 |
+
test_asymp(lambda z: +mertens, maxdps=150)
|
| 124 |
+
test_asymp(lambda z: +apery, maxdps=5000)
|
| 125 |
+
test_asymp(sqrt, maxdps=10000, huge_range=True)
|
| 126 |
+
test_asymp(cbrt, maxdps=5000, huge_range=True)
|
| 127 |
+
test_asymp(lambda z: root(z,4), maxdps=5000, huge_range=True)
|
| 128 |
+
test_asymp(lambda z: root(z,-5), maxdps=5000, huge_range=True)
|
| 129 |
+
test_asymp(exp, maxdps=5000, huge_range=True)
|
| 130 |
+
test_asymp(expm1, maxdps=1500)
|
| 131 |
+
test_asymp(ln, maxdps=5000, huge_range=True)
|
| 132 |
+
test_asymp(cosh, maxdps=5000)
|
| 133 |
+
test_asymp(sinh, maxdps=5000)
|
| 134 |
+
test_asymp(tanh, maxdps=1500)
|
| 135 |
+
test_asymp(sin, maxdps=5000, huge_range=True)
|
| 136 |
+
test_asymp(cos, maxdps=5000, huge_range=True)
|
| 137 |
+
test_asymp(tan, maxdps=1500)
|
| 138 |
+
test_asymp(agm, maxdps=1500, huge_range=True)
|
| 139 |
+
test_asymp(ellipk, maxdps=1500)
|
| 140 |
+
test_asymp(ellipe, maxdps=1500)
|
| 141 |
+
test_asymp(lambertw, huge_range=True)
|
| 142 |
+
test_asymp(lambda z: lambertw(z,-1))
|
| 143 |
+
test_asymp(lambda z: lambertw(z,1))
|
| 144 |
+
test_asymp(lambda z: lambertw(z,4))
|
| 145 |
+
test_asymp(gamma)
|
| 146 |
+
test_asymp(loggamma) # huge_range=True ?
|
| 147 |
+
test_asymp(ei)
|
| 148 |
+
test_asymp(e1)
|
| 149 |
+
test_asymp(li, huge_range=True)
|
| 150 |
+
test_asymp(ci)
|
| 151 |
+
test_asymp(si)
|
| 152 |
+
test_asymp(chi)
|
| 153 |
+
test_asymp(shi)
|
| 154 |
+
test_asymp(erf)
|
| 155 |
+
test_asymp(erfc)
|
| 156 |
+
test_asymp(erfi)
|
| 157 |
+
test_asymp(lambda z: besselj(2, z))
|
| 158 |
+
test_asymp(lambda z: bessely(2, z))
|
| 159 |
+
test_asymp(lambda z: besseli(2, z))
|
| 160 |
+
test_asymp(lambda z: besselk(2, z))
|
| 161 |
+
test_asymp(lambda z: besselj(-2.25, z))
|
| 162 |
+
test_asymp(lambda z: bessely(-2.25, z))
|
| 163 |
+
test_asymp(lambda z: besseli(-2.25, z))
|
| 164 |
+
test_asymp(lambda z: besselk(-2.25, z))
|
| 165 |
+
test_asymp(airyai)
|
| 166 |
+
test_asymp(airybi)
|
| 167 |
+
test_asymp(lambda z: hyp0f1(a1, z))
|
| 168 |
+
test_asymp(lambda z: hyp1f1(a1, a2, z))
|
| 169 |
+
test_asymp(lambda z: hyp1f2(a1, a2, a3, z))
|
| 170 |
+
test_asymp(lambda z: hyp2f0(a1, a2, z))
|
| 171 |
+
test_asymp(lambda z: hyperu(a1, a2, z))
|
| 172 |
+
test_asymp(lambda z: hyp2f1(a1, a2, a3, z))
|
| 173 |
+
test_asymp(lambda z: hyp2f2(a1, a2, a3, a4, z))
|
| 174 |
+
test_asymp(lambda z: hyp2f3(a1, a2, a3, a4, a5, z))
|
| 175 |
+
test_asymp(lambda z: coulombf(a1, a2, z))
|
| 176 |
+
test_asymp(lambda z: coulombg(a1, a2, z))
|
| 177 |
+
test_asymp(lambda z: polylog(2,z))
|
| 178 |
+
test_asymp(lambda z: polylog(3,z))
|
| 179 |
+
test_asymp(lambda z: polylog(-2,z))
|
| 180 |
+
test_asymp(lambda z: expint(4, z))
|
| 181 |
+
test_asymp(lambda z: expint(-4, z))
|
| 182 |
+
test_asymp(lambda z: expint(2.25, z))
|
| 183 |
+
test_asymp(lambda z: gammainc(2.5, z, 5))
|
| 184 |
+
test_asymp(lambda z: gammainc(2.5, 5, z))
|
| 185 |
+
test_asymp(lambda z: hermite(3, z))
|
| 186 |
+
test_asymp(lambda z: hermite(2.5, z))
|
| 187 |
+
test_asymp(lambda z: legendre(3, z))
|
| 188 |
+
test_asymp(lambda z: legendre(4, z))
|
| 189 |
+
test_asymp(lambda z: legendre(2.5, z))
|
| 190 |
+
test_asymp(lambda z: legenp(a1, a2, z))
|
| 191 |
+
test_asymp(lambda z: legenq(a1, a2, z), maxdps=90) # abnormally slow
|
| 192 |
+
test_asymp(lambda z: jtheta(1, z, 0.5))
|
| 193 |
+
test_asymp(lambda z: jtheta(2, z, 0.5))
|
| 194 |
+
test_asymp(lambda z: jtheta(3, z, 0.5))
|
| 195 |
+
test_asymp(lambda z: jtheta(4, z, 0.5))
|
| 196 |
+
test_asymp(lambda z: jtheta(1, z, 0.5, 1))
|
| 197 |
+
test_asymp(lambda z: jtheta(2, z, 0.5, 1))
|
| 198 |
+
test_asymp(lambda z: jtheta(3, z, 0.5, 1))
|
| 199 |
+
test_asymp(lambda z: jtheta(4, z, 0.5, 1))
|
| 200 |
+
test_asymp(barnesg, maxdps=90)
|
| 201 |
+
"""
|
| 202 |
+
|
| 203 |
+
def testit(line):
|
| 204 |
+
if filt in line:
|
| 205 |
+
print(line)
|
| 206 |
+
t1 = clock()
|
| 207 |
+
exec_(line, globals(), locals())
|
| 208 |
+
t2 = clock()
|
| 209 |
+
elapsed = t2-t1
|
| 210 |
+
print("Time:", elapsed, "for", line, "(OK)")
|
| 211 |
+
|
| 212 |
+
if __name__ == '__main__':
|
| 213 |
+
try:
|
| 214 |
+
from multiprocessing import Pool
|
| 215 |
+
mapf = Pool(None).map
|
| 216 |
+
print("Running tests with multiprocessing")
|
| 217 |
+
except ImportError:
|
| 218 |
+
print("Not using multiprocessing")
|
| 219 |
+
mapf = map
|
| 220 |
+
t1 = clock()
|
| 221 |
+
tasks = cases.splitlines()
|
| 222 |
+
mapf(testit, tasks)
|
| 223 |
+
t2 = clock()
|
| 224 |
+
print("Cumulative wall time:", t2-t1)
|
rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
uv
|
rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/METADATA
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: nbclient
|
| 3 |
+
Version: 0.10.2
|
| 4 |
+
Summary: A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor.
|
| 5 |
+
Project-URL: Documentation, https://nbclient.readthedocs.io
|
| 6 |
+
Project-URL: Funding, https://numfocus.org/
|
| 7 |
+
Project-URL: Homepage, https://jupyter.org
|
| 8 |
+
Project-URL: Source, https://github.com/jupyter/nbclient
|
| 9 |
+
Project-URL: Tracker, https://github.com/jupyter/nbclient/issues
|
| 10 |
+
Author-email: Jupyter Development Team <jupyter@googlegroups.com>
|
| 11 |
+
License: BSD 3-Clause License
|
| 12 |
+
|
| 13 |
+
Copyright (c) 2020-, Jupyter Development Team
|
| 14 |
+
|
| 15 |
+
All rights reserved.
|
| 16 |
+
|
| 17 |
+
Redistribution and use in source and binary forms, with or without
|
| 18 |
+
modification, are permitted provided that the following conditions are met:
|
| 19 |
+
|
| 20 |
+
1. Redistributions of source code must retain the above copyright notice, this
|
| 21 |
+
list of conditions and the following disclaimer.
|
| 22 |
+
|
| 23 |
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
| 24 |
+
this list of conditions and the following disclaimer in the documentation
|
| 25 |
+
and/or other materials provided with the distribution.
|
| 26 |
+
|
| 27 |
+
3. Neither the name of the copyright holder nor the names of its
|
| 28 |
+
contributors may be used to endorse or promote products derived from
|
| 29 |
+
this software without specific prior written permission.
|
| 30 |
+
|
| 31 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 32 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 33 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| 34 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
| 35 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
| 36 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
| 37 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
| 38 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
| 39 |
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 40 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 41 |
+
License-File: LICENSE
|
| 42 |
+
Keywords: executor,jupyter,notebook,pipeline
|
| 43 |
+
Classifier: Intended Audience :: Developers
|
| 44 |
+
Classifier: Intended Audience :: Science/Research
|
| 45 |
+
Classifier: Intended Audience :: System Administrators
|
| 46 |
+
Classifier: License :: OSI Approved :: BSD License
|
| 47 |
+
Classifier: Programming Language :: Python
|
| 48 |
+
Classifier: Programming Language :: Python :: 3
|
| 49 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 50 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 51 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 52 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 53 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 54 |
+
Requires-Python: >=3.9.0
|
| 55 |
+
Requires-Dist: jupyter-client>=6.1.12
|
| 56 |
+
Requires-Dist: jupyter-core!=5.0.*,>=4.12
|
| 57 |
+
Requires-Dist: nbformat>=5.1
|
| 58 |
+
Requires-Dist: traitlets>=5.4
|
| 59 |
+
Provides-Extra: dev
|
| 60 |
+
Requires-Dist: pre-commit; extra == 'dev'
|
| 61 |
+
Provides-Extra: docs
|
| 62 |
+
Requires-Dist: autodoc-traits; extra == 'docs'
|
| 63 |
+
Requires-Dist: flaky; extra == 'docs'
|
| 64 |
+
Requires-Dist: ipykernel>=6.19.3; extra == 'docs'
|
| 65 |
+
Requires-Dist: ipython; extra == 'docs'
|
| 66 |
+
Requires-Dist: ipywidgets; extra == 'docs'
|
| 67 |
+
Requires-Dist: mock; extra == 'docs'
|
| 68 |
+
Requires-Dist: moto; extra == 'docs'
|
| 69 |
+
Requires-Dist: myst-parser; extra == 'docs'
|
| 70 |
+
Requires-Dist: nbconvert>=7.1.0; extra == 'docs'
|
| 71 |
+
Requires-Dist: pytest-asyncio; extra == 'docs'
|
| 72 |
+
Requires-Dist: pytest-cov>=4.0; extra == 'docs'
|
| 73 |
+
Requires-Dist: pytest<8,>=7.0; extra == 'docs'
|
| 74 |
+
Requires-Dist: sphinx-book-theme; extra == 'docs'
|
| 75 |
+
Requires-Dist: sphinx>=1.7; extra == 'docs'
|
| 76 |
+
Requires-Dist: sphinxcontrib-spelling; extra == 'docs'
|
| 77 |
+
Requires-Dist: testpath; extra == 'docs'
|
| 78 |
+
Requires-Dist: xmltodict; extra == 'docs'
|
| 79 |
+
Provides-Extra: test
|
| 80 |
+
Requires-Dist: flaky; extra == 'test'
|
| 81 |
+
Requires-Dist: ipykernel>=6.19.3; extra == 'test'
|
| 82 |
+
Requires-Dist: ipython; extra == 'test'
|
| 83 |
+
Requires-Dist: ipywidgets; extra == 'test'
|
| 84 |
+
Requires-Dist: nbconvert>=7.1.0; extra == 'test'
|
| 85 |
+
Requires-Dist: pytest-asyncio; extra == 'test'
|
| 86 |
+
Requires-Dist: pytest-cov>=4.0; extra == 'test'
|
| 87 |
+
Requires-Dist: pytest<8,>=7.0; extra == 'test'
|
| 88 |
+
Requires-Dist: testpath; extra == 'test'
|
| 89 |
+
Requires-Dist: xmltodict; extra == 'test'
|
| 90 |
+
Description-Content-Type: text/markdown
|
| 91 |
+
|
| 92 |
+
[](https://mybinder.org/v2/gh/jupyter/nbclient/main?filepath=binder%2Frun_nbclient.ipynb)
|
| 93 |
+
[](https://github.com/jupyter/nbclient/actions)
|
| 94 |
+
[](https://nbclient.readthedocs.io/en/latest/?badge=latest)
|
| 95 |
+
[](https://www.python.org/downloads/release/python-370/)
|
| 96 |
+
[](https://www.python.org/downloads/release/python-380/)
|
| 97 |
+
[](https://www.python.org/downloads/release/python-390/)
|
| 98 |
+
[](https://www.python.org/downloads/release/python-3100/)
|
| 99 |
+
[](https://www.python.org/downloads/release/python-3110/)
|
| 100 |
+
[](https://github.com/ambv/black)
|
| 101 |
+
|
| 102 |
+
# nbclient
|
| 103 |
+
|
| 104 |
+
**NBClient** lets you **execute** notebooks.
|
| 105 |
+
|
| 106 |
+
A client library for programmatic notebook execution, **NBClient** is a tool for running Jupyter Notebooks in
|
| 107 |
+
different execution contexts, including the command line.
|
| 108 |
+
|
| 109 |
+
## Interactive Demo
|
| 110 |
+
|
| 111 |
+
To demo **NBClient** interactively, click this Binder badge to start the demo:
|
| 112 |
+
|
| 113 |
+
[](https://mybinder.org/v2/gh/jupyter/nbclient/main?filepath=binder%2Frun_nbclient.ipynb)
|
| 114 |
+
|
| 115 |
+
## Installation
|
| 116 |
+
|
| 117 |
+
In a terminal, run:
|
| 118 |
+
|
| 119 |
+
```
|
| 120 |
+
python3 -m pip install nbclient
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
## Documentation
|
| 124 |
+
|
| 125 |
+
See [ReadTheDocs](https://nbclient.readthedocs.io/en/latest/) for more in-depth details about the project and the
|
| 126 |
+
[API Reference](https://nbclient.readthedocs.io/en/latest/reference/index.html).
|
| 127 |
+
|
| 128 |
+
## Python Version Support
|
| 129 |
+
|
| 130 |
+
This library currently supports Python 3.6+ versions. As minor Python
|
| 131 |
+
versions are officially sunset by the Python org, nbclient will similarly
|
| 132 |
+
drop support in the future.
|
| 133 |
+
|
| 134 |
+
## Origins
|
| 135 |
+
|
| 136 |
+
This library used to be part of the [nbconvert](https://nbconvert.readthedocs.io/en/latest/) project. NBClient extracted nbconvert's `ExecutePreprocessor`into its own library for easier updating and importing by downstream libraries and applications.
|
| 137 |
+
|
| 138 |
+
## Relationship to JupyterClient
|
| 139 |
+
|
| 140 |
+
NBClient and JupyterClient are distinct projects.
|
| 141 |
+
|
| 142 |
+
`jupyter_client` is a client library for the jupyter protocol. Specifically, `jupyter_client` provides the Python API
|
| 143 |
+
for starting, managing and communicating with Jupyter kernels.
|
| 144 |
+
|
| 145 |
+
While, nbclient allows notebooks to be run in different execution contexts.
|
| 146 |
+
|
| 147 |
+
## About the Jupyter Development Team
|
| 148 |
+
|
| 149 |
+
The Jupyter Development Team is the set of all contributors to the Jupyter project.
|
| 150 |
+
This includes all of the Jupyter subprojects.
|
| 151 |
+
|
| 152 |
+
The core team that coordinates development on GitHub can be found here:
|
| 153 |
+
https://github.com/jupyter/.
|
| 154 |
+
|
| 155 |
+
## Our Copyright Policy
|
| 156 |
+
|
| 157 |
+
Jupyter uses a shared copyright model. Each contributor maintains copyright
|
| 158 |
+
over their contributions to Jupyter. But, it is important to note that these
|
| 159 |
+
contributions are typically only changes to the repositories. Thus, the Jupyter
|
| 160 |
+
source code, in its entirety is not the copyright of any single person or
|
| 161 |
+
institution. Instead, it is the collective copyright of the entire Jupyter
|
| 162 |
+
Development Team. If individual contributors want to maintain a record of what
|
| 163 |
+
changes/contributions they have specific copyright on, they should indicate
|
| 164 |
+
their copyright in the commit message of the change, when they commit the
|
| 165 |
+
change to one of the Jupyter repositories.
|
| 166 |
+
|
| 167 |
+
With this in mind, the following banner should be used in any source code file
|
| 168 |
+
to indicate the copyright and license terms:
|
| 169 |
+
|
| 170 |
+
```
|
| 171 |
+
# Copyright (c) Jupyter Development Team.
|
| 172 |
+
# Distributed under the terms of the Modified BSD License.
|
| 173 |
+
```
|
rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/RECORD
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
../../../bin/jupyter-execute,sha256=LXdZDsUAfwoAml30TSiHdEODuUqidJvHf8Pr4q5wv3Y,305
|
| 2 |
+
nbclient-0.10.2.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
|
| 3 |
+
nbclient-0.10.2.dist-info/METADATA,sha256=AgHaGDYAlNOBeiTo_-BlrwTXXodzUIN_YTLCAqElpKY,8263
|
| 4 |
+
nbclient-0.10.2.dist-info/RECORD,,
|
| 5 |
+
nbclient-0.10.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 6 |
+
nbclient-0.10.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
| 7 |
+
nbclient-0.10.2.dist-info/entry_points.txt,sha256=sHJQnUBVokK46O2PK-g1WG9QAhTmaXy3fwshQ_t7TFA,54
|
| 8 |
+
nbclient-0.10.2.dist-info/licenses/LICENSE,sha256=g8VsLeKipxIn0KmP0kYEnmMgwJTQPi1WDHwMCz7Fduk,1534
|
| 9 |
+
nbclient/__init__.py,sha256=kOkox4riED023V62iBDJMKbI1VcH3LM6VERaX9l6v6c,164
|
| 10 |
+
nbclient/_version.py,sha256=Is9ur6poRQor3aJ9NVAjRbJKzjjJPGDme4jZnTB1S2M,463
|
| 11 |
+
nbclient/cli.py,sha256=4ZedIorMbtVFyqmwlhgXx-_F2w2-at30ef7c7zWcwzM,6781
|
| 12 |
+
nbclient/client.py,sha256=OjAYdEnS_qbOYGPnnLqg7fFHiUcJmotm2NL7MKBBiXE,49833
|
| 13 |
+
nbclient/exceptions.py,sha256=3j6tm0lJVASZHTo4cnpvqBxN9FKEpkHUaYyDG7CrIjY,4065
|
| 14 |
+
nbclient/jsonutil.py,sha256=WPJhDujbq8tC8o1shj4xoganZCBIeIDckL0uOQOfrJY,4612
|
| 15 |
+
nbclient/output_widget.py,sha256=g7EKyKu_jM76OZnQ3nnqpDOdTr0wjQhd7iVJGx-Bo8I,4527
|
| 16 |
+
nbclient/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 17 |
+
nbclient/util.py,sha256=bWzTnKHVBoN9iP1rXYyCGm7qyCQpRQDwDO4FBtjjE7c,544
|
rtme/lib/python3.10/site-packages/nbclient-0.10.2.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: hatchling 1.27.0
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/License.txt
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved.
|
| 3 |
+
|
| 4 |
+
Redistribution and use in source and binary forms, with or without
|
| 5 |
+
modification, are permitted provided that the following conditions
|
| 6 |
+
are met:
|
| 7 |
+
* Redistributions of source code must retain the above copyright
|
| 8 |
+
notice, this list of conditions and the following disclaimer.
|
| 9 |
+
* Redistributions in binary form must reproduce the above copyright
|
| 10 |
+
notice, this list of conditions and the following disclaimer in the
|
| 11 |
+
documentation and/or other materials provided with the distribution.
|
| 12 |
+
* Neither the name of NVIDIA CORPORATION, Lawrence Berkeley National
|
| 13 |
+
Laboratory, the U.S. Department of Energy, nor the names of their
|
| 14 |
+
contributors may be used to endorse or promote products derived
|
| 15 |
+
from this software without specific prior written permission.
|
| 16 |
+
|
| 17 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
|
| 18 |
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 19 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
| 20 |
+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
| 21 |
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
| 22 |
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
| 23 |
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
| 24 |
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
| 25 |
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 26 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 27 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 28 |
+
|
| 29 |
+
The U.S. Department of Energy funded the development of this software
|
| 30 |
+
under subcontract 7078610 with Lawrence Berkeley National Laboratory.
|
| 31 |
+
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: nvidia-nccl-cu12
|
| 3 |
+
Version: 2.18.1
|
| 4 |
+
Summary: NVIDIA Collective Communication Library (NCCL) Runtime
|
| 5 |
+
Home-page: https://developer.nvidia.com/cuda-zone
|
| 6 |
+
Author: Nvidia CUDA Installer Team
|
| 7 |
+
Author-email: cuda_installer@nvidia.com
|
| 8 |
+
License: NVIDIA Proprietary Software
|
| 9 |
+
Keywords: cuda,nvidia,runtime,machine learning,deep learning
|
| 10 |
+
Classifier: Development Status :: 4 - Beta
|
| 11 |
+
Classifier: Intended Audience :: Developers
|
| 12 |
+
Classifier: Intended Audience :: Education
|
| 13 |
+
Classifier: Intended Audience :: Science/Research
|
| 14 |
+
Classifier: License :: Other/Proprietary License
|
| 15 |
+
Classifier: Natural Language :: English
|
| 16 |
+
Classifier: Programming Language :: Python :: 3
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.5
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.6
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.7
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 21 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 22 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 23 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 24 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 25 |
+
Classifier: Topic :: Scientific/Engineering
|
| 26 |
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
| 27 |
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
| 28 |
+
Classifier: Topic :: Software Development
|
| 29 |
+
Classifier: Topic :: Software Development :: Libraries
|
| 30 |
+
Classifier: Operating System :: Microsoft :: Windows
|
| 31 |
+
Classifier: Operating System :: POSIX :: Linux
|
| 32 |
+
Requires-Python: >=3
|
| 33 |
+
License-File: License.txt
|
| 34 |
+
|
| 35 |
+
NCCL (pronounced "Nickel") is a stand-alone library of standard collective communication routines for GPUs, implementing all-reduce, all-gather, reduce, broadcast, and reduce-scatter. It has been optimized to achieve high bandwidth on any platform using PCIe, NVLink, NVswitch, as well as networking using InfiniBand Verbs or TCP/IP sockets.
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
nvidia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 2 |
+
nvidia/nccl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 3 |
+
nvidia/nccl/include/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 4 |
+
nvidia/nccl/include/nccl.h,sha256=1DDHVeNWqBd7rIGxYcki1evzSuGZvfKeftJlHAVerQc,17843
|
| 5 |
+
nvidia/nccl/include/nccl_net.h,sha256=KMi30WhfKTQY5a_IPx_YNNy-ZZIrsWlPiOKbYYXCm20,17159
|
| 6 |
+
nvidia/nccl/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 7 |
+
nvidia/nccl/lib/libnccl.so.2,sha256=3k6qYwb1re30tFWjNMnDubzwx8FBq7OqeAjeNj4OFCk,279451776
|
| 8 |
+
nvidia_nccl_cu12-2.18.1.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
|
| 9 |
+
nvidia_nccl_cu12-2.18.1.dist-info/License.txt,sha256=92n6LTYyE_WZNm2kbiqNZQyG6q6EWuxNRLL1_QHU7Fk,1735
|
| 10 |
+
nvidia_nccl_cu12-2.18.1.dist-info/METADATA,sha256=PIuDGtu7EpZYbm7enS-Q0tINbhOj7pNwmhxDhD6apnk,1834
|
| 11 |
+
nvidia_nccl_cu12-2.18.1.dist-info/RECORD,,
|
| 12 |
+
nvidia_nccl_cu12-2.18.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 13 |
+
nvidia_nccl_cu12-2.18.1.dist-info/WHEEL,sha256=-kQi_VMfvRQozZJT7HUPMfY-5vLo0LVTmAylNJ3Ft98,106
|
| 14 |
+
nvidia_nccl_cu12-2.18.1.dist-info/top_level.txt,sha256=fTkAtiFuL16nUrB9ytDDtpytz2t0B4NvYTnRzwAhO14,7
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/REQUESTED
ADDED
|
File without changes
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: bdist_wheel (0.37.1)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-manylinux1_x86_64
|
| 5 |
+
|
rtme/lib/python3.10/site-packages/nvidia_nccl_cu12-2.18.1.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
nvidia
|
rtme/lib/python3.10/site-packages/nvidia_nvjitlink_cu12-12.8.93.dist-info/License.txt
ADDED
|
@@ -0,0 +1,1568 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
End User License Agreement
|
| 2 |
+
--------------------------
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
Preface
|
| 6 |
+
-------
|
| 7 |
+
|
| 8 |
+
The Software License Agreement in Chapter 1 and the Supplement
|
| 9 |
+
in Chapter 2 contain license terms and conditions that govern
|
| 10 |
+
the use of NVIDIA software. By accepting this agreement, you
|
| 11 |
+
agree to comply with all the terms and conditions applicable
|
| 12 |
+
to the product(s) included herein.
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
NVIDIA Driver
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
Description
|
| 19 |
+
|
| 20 |
+
This package contains the operating system driver and
|
| 21 |
+
fundamental system software components for NVIDIA GPUs.
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
NVIDIA CUDA Toolkit
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
Description
|
| 28 |
+
|
| 29 |
+
The NVIDIA CUDA Toolkit provides command-line and graphical
|
| 30 |
+
tools for building, debugging and optimizing the performance
|
| 31 |
+
of applications accelerated by NVIDIA GPUs, runtime and math
|
| 32 |
+
libraries, and documentation including programming guides,
|
| 33 |
+
user manuals, and API references.
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
Default Install Location of CUDA Toolkit
|
| 37 |
+
|
| 38 |
+
Windows platform:
|
| 39 |
+
|
| 40 |
+
%ProgramFiles%\NVIDIA GPU Computing Toolkit\CUDA\v#.#
|
| 41 |
+
|
| 42 |
+
Linux platform:
|
| 43 |
+
|
| 44 |
+
/usr/local/cuda-#.#
|
| 45 |
+
|
| 46 |
+
Mac platform:
|
| 47 |
+
|
| 48 |
+
/Developer/NVIDIA/CUDA-#.#
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
NVIDIA CUDA Samples
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
Description
|
| 55 |
+
|
| 56 |
+
This package includes over 100+ CUDA examples that demonstrate
|
| 57 |
+
various CUDA programming principles, and efficient CUDA
|
| 58 |
+
implementation of algorithms in specific application domains.
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
Default Install Location of CUDA Samples
|
| 62 |
+
|
| 63 |
+
Windows platform:
|
| 64 |
+
|
| 65 |
+
%ProgramData%\NVIDIA Corporation\CUDA Samples\v#.#
|
| 66 |
+
|
| 67 |
+
Linux platform:
|
| 68 |
+
|
| 69 |
+
/usr/local/cuda-#.#/samples
|
| 70 |
+
|
| 71 |
+
and
|
| 72 |
+
|
| 73 |
+
$HOME/NVIDIA_CUDA-#.#_Samples
|
| 74 |
+
|
| 75 |
+
Mac platform:
|
| 76 |
+
|
| 77 |
+
/Developer/NVIDIA/CUDA-#.#/samples
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
NVIDIA Nsight Visual Studio Edition (Windows only)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
Description
|
| 84 |
+
|
| 85 |
+
NVIDIA Nsight Development Platform, Visual Studio Edition is a
|
| 86 |
+
development environment integrated into Microsoft Visual
|
| 87 |
+
Studio that provides tools for debugging, profiling, analyzing
|
| 88 |
+
and optimizing your GPU computing and graphics applications.
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
Default Install Location of Nsight Visual Studio Edition
|
| 92 |
+
|
| 93 |
+
Windows platform:
|
| 94 |
+
|
| 95 |
+
%ProgramFiles(x86)%\NVIDIA Corporation\Nsight Visual Studio Edition #.#
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
1. License Agreement for NVIDIA Software Development Kits
|
| 99 |
+
---------------------------------------------------------
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
Release Date: July 26, 2018
|
| 103 |
+
---------------------------
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
Important NoticeRead before downloading, installing,
|
| 107 |
+
copying or using the licensed software:
|
| 108 |
+
-------------------------------------------------------
|
| 109 |
+
|
| 110 |
+
This license agreement, including exhibits attached
|
| 111 |
+
("Agreement”) is a legal agreement between you and NVIDIA
|
| 112 |
+
Corporation ("NVIDIA") and governs your use of a NVIDIA
|
| 113 |
+
software development kit (“SDK”).
|
| 114 |
+
|
| 115 |
+
Each SDK has its own set of software and materials, but here
|
| 116 |
+
is a description of the types of items that may be included in
|
| 117 |
+
a SDK: source code, header files, APIs, data sets and assets
|
| 118 |
+
(examples include images, textures, models, scenes, videos,
|
| 119 |
+
native API input/output files), binary software, sample code,
|
| 120 |
+
libraries, utility programs, programming code and
|
| 121 |
+
documentation.
|
| 122 |
+
|
| 123 |
+
This Agreement can be accepted only by an adult of legal age
|
| 124 |
+
of majority in the country in which the SDK is used.
|
| 125 |
+
|
| 126 |
+
If you are entering into this Agreement on behalf of a company
|
| 127 |
+
or other legal entity, you represent that you have the legal
|
| 128 |
+
authority to bind the entity to this Agreement, in which case
|
| 129 |
+
“you” will mean the entity you represent.
|
| 130 |
+
|
| 131 |
+
If you don’t have the required age or authority to accept
|
| 132 |
+
this Agreement, or if you don’t accept all the terms and
|
| 133 |
+
conditions of this Agreement, do not download, install or use
|
| 134 |
+
the SDK.
|
| 135 |
+
|
| 136 |
+
You agree to use the SDK only for purposes that are permitted
|
| 137 |
+
by (a) this Agreement, and (b) any applicable law, regulation
|
| 138 |
+
or generally accepted practices or guidelines in the relevant
|
| 139 |
+
jurisdictions.
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
1.1. License
|
| 143 |
+
|
| 144 |
+
|
| 145 |
+
1.1.1. License Grant
|
| 146 |
+
|
| 147 |
+
Subject to the terms of this Agreement, NVIDIA hereby grants
|
| 148 |
+
you a non-exclusive, non-transferable license, without the
|
| 149 |
+
right to sublicense (except as expressly provided in this
|
| 150 |
+
Agreement) to:
|
| 151 |
+
|
| 152 |
+
1. Install and use the SDK,
|
| 153 |
+
|
| 154 |
+
2. Modify and create derivative works of sample source code
|
| 155 |
+
delivered in the SDK, and
|
| 156 |
+
|
| 157 |
+
3. Distribute those portions of the SDK that are identified
|
| 158 |
+
in this Agreement as distributable, as incorporated in
|
| 159 |
+
object code format into a software application that meets
|
| 160 |
+
the distribution requirements indicated in this Agreement.
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
1.1.2. Distribution Requirements
|
| 164 |
+
|
| 165 |
+
These are the distribution requirements for you to exercise
|
| 166 |
+
the distribution grant:
|
| 167 |
+
|
| 168 |
+
1. Your application must have material additional
|
| 169 |
+
functionality, beyond the included portions of the SDK.
|
| 170 |
+
|
| 171 |
+
2. The distributable portions of the SDK shall only be
|
| 172 |
+
accessed by your application.
|
| 173 |
+
|
| 174 |
+
3. The following notice shall be included in modifications
|
| 175 |
+
and derivative works of sample source code distributed:
|
| 176 |
+
“This software contains source code provided by NVIDIA
|
| 177 |
+
Corporation.”
|
| 178 |
+
|
| 179 |
+
4. Unless a developer tool is identified in this Agreement
|
| 180 |
+
as distributable, it is delivered for your internal use
|
| 181 |
+
only.
|
| 182 |
+
|
| 183 |
+
5. The terms under which you distribute your application
|
| 184 |
+
must be consistent with the terms of this Agreement,
|
| 185 |
+
including (without limitation) terms relating to the
|
| 186 |
+
license grant and license restrictions and protection of
|
| 187 |
+
NVIDIA’s intellectual property rights. Additionally, you
|
| 188 |
+
agree that you will protect the privacy, security and
|
| 189 |
+
legal rights of your application users.
|
| 190 |
+
|
| 191 |
+
6. You agree to notify NVIDIA in writing of any known or
|
| 192 |
+
suspected distribution or use of the SDK not in compliance
|
| 193 |
+
with the requirements of this Agreement, and to enforce
|
| 194 |
+
the terms of your agreements with respect to distributed
|
| 195 |
+
SDK.
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
1.1.3. Authorized Users
|
| 199 |
+
|
| 200 |
+
You may allow employees and contractors of your entity or of
|
| 201 |
+
your subsidiary(ies) to access and use the SDK from your
|
| 202 |
+
secure network to perform work on your behalf.
|
| 203 |
+
|
| 204 |
+
If you are an academic institution you may allow users
|
| 205 |
+
enrolled or employed by the academic institution to access and
|
| 206 |
+
use the SDK from your secure network.
|
| 207 |
+
|
| 208 |
+
You are responsible for the compliance with the terms of this
|
| 209 |
+
Agreement by your authorized users. If you become aware that
|
| 210 |
+
your authorized users didn’t follow the terms of this
|
| 211 |
+
Agreement, you agree to take reasonable steps to resolve the
|
| 212 |
+
non-compliance and prevent new occurrences.
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
1.1.4. Pre-Release SDK
|
| 216 |
+
|
| 217 |
+
The SDK versions identified as alpha, beta, preview or
|
| 218 |
+
otherwise as pre-release, may not be fully functional, may
|
| 219 |
+
contain errors or design flaws, and may have reduced or
|
| 220 |
+
different security, privacy, accessibility, availability, and
|
| 221 |
+
reliability standards relative to commercial versions of
|
| 222 |
+
NVIDIA software and materials. Use of a pre-release SDK may
|
| 223 |
+
result in unexpected results, loss of data, project delays or
|
| 224 |
+
other unpredictable damage or loss.
|
| 225 |
+
|
| 226 |
+
You may use a pre-release SDK at your own risk, understanding
|
| 227 |
+
that pre-release SDKs are not intended for use in production
|
| 228 |
+
or business-critical systems.
|
| 229 |
+
|
| 230 |
+
NVIDIA may choose not to make available a commercial version
|
| 231 |
+
of any pre-release SDK. NVIDIA may also choose to abandon
|
| 232 |
+
development and terminate the availability of a pre-release
|
| 233 |
+
SDK at any time without liability.
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
1.1.5. Updates
|
| 237 |
+
|
| 238 |
+
NVIDIA may, at its option, make available patches, workarounds
|
| 239 |
+
or other updates to this SDK. Unless the updates are provided
|
| 240 |
+
with their separate governing terms, they are deemed part of
|
| 241 |
+
the SDK licensed to you as provided in this Agreement. You
|
| 242 |
+
agree that the form and content of the SDK that NVIDIA
|
| 243 |
+
provides may change without prior notice to you. While NVIDIA
|
| 244 |
+
generally maintains compatibility between versions, NVIDIA may
|
| 245 |
+
in some cases make changes that introduce incompatibilities in
|
| 246 |
+
future versions of the SDK.
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
1.1.6. Third Party Licenses
|
| 250 |
+
|
| 251 |
+
The SDK may come bundled with, or otherwise include or be
|
| 252 |
+
distributed with, third party software licensed by a NVIDIA
|
| 253 |
+
supplier and/or open source software provided under an open
|
| 254 |
+
source license. Use of third party software is subject to the
|
| 255 |
+
third-party license terms, or in the absence of third party
|
| 256 |
+
terms, the terms of this Agreement. Copyright to third party
|
| 257 |
+
software is held by the copyright holders indicated in the
|
| 258 |
+
third-party software or license.
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
1.1.7. Reservation of Rights
|
| 262 |
+
|
| 263 |
+
NVIDIA reserves all rights, title, and interest in and to the
|
| 264 |
+
SDK, not expressly granted to you under this Agreement.
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
1.2. Limitations
|
| 268 |
+
|
| 269 |
+
The following license limitations apply to your use of the
|
| 270 |
+
SDK:
|
| 271 |
+
|
| 272 |
+
1. You may not reverse engineer, decompile or disassemble,
|
| 273 |
+
or remove copyright or other proprietary notices from any
|
| 274 |
+
portion of the SDK or copies of the SDK.
|
| 275 |
+
|
| 276 |
+
2. Except as expressly provided in this Agreement, you may
|
| 277 |
+
not copy, sell, rent, sublicense, transfer, distribute,
|
| 278 |
+
modify, or create derivative works of any portion of the
|
| 279 |
+
SDK. For clarity, you may not distribute or sublicense the
|
| 280 |
+
SDK as a stand-alone product.
|
| 281 |
+
|
| 282 |
+
3. Unless you have an agreement with NVIDIA for this
|
| 283 |
+
purpose, you may not indicate that an application created
|
| 284 |
+
with the SDK is sponsored or endorsed by NVIDIA.
|
| 285 |
+
|
| 286 |
+
4. You may not bypass, disable, or circumvent any
|
| 287 |
+
encryption, security, digital rights management or
|
| 288 |
+
authentication mechanism in the SDK.
|
| 289 |
+
|
| 290 |
+
5. You may not use the SDK in any manner that would cause it
|
| 291 |
+
to become subject to an open source software license. As
|
| 292 |
+
examples, licenses that require as a condition of use,
|
| 293 |
+
modification, and/or distribution that the SDK be:
|
| 294 |
+
|
| 295 |
+
a. Disclosed or distributed in source code form;
|
| 296 |
+
|
| 297 |
+
b. Licensed for the purpose of making derivative works;
|
| 298 |
+
or
|
| 299 |
+
|
| 300 |
+
c. Redistributable at no charge.
|
| 301 |
+
|
| 302 |
+
6. Unless you have an agreement with NVIDIA for this
|
| 303 |
+
purpose, you may not use the SDK with any system or
|
| 304 |
+
application where the use or failure of the system or
|
| 305 |
+
application can reasonably be expected to threaten or
|
| 306 |
+
result in personal injury, death, or catastrophic loss.
|
| 307 |
+
Examples include use in avionics, navigation, military,
|
| 308 |
+
medical, life support or other life critical applications.
|
| 309 |
+
NVIDIA does not design, test or manufacture the SDK for
|
| 310 |
+
these critical uses and NVIDIA shall not be liable to you
|
| 311 |
+
or any third party, in whole or in part, for any claims or
|
| 312 |
+
damages arising from such uses.
|
| 313 |
+
|
| 314 |
+
7. You agree to defend, indemnify and hold harmless NVIDIA
|
| 315 |
+
and its affiliates, and their respective employees,
|
| 316 |
+
contractors, agents, officers and directors, from and
|
| 317 |
+
against any and all claims, damages, obligations, losses,
|
| 318 |
+
liabilities, costs or debt, fines, restitutions and
|
| 319 |
+
expenses (including but not limited to attorney’s fees
|
| 320 |
+
and costs incident to establishing the right of
|
| 321 |
+
indemnification) arising out of or related to your use of
|
| 322 |
+
the SDK outside of the scope of this Agreement, or not in
|
| 323 |
+
compliance with its terms.
|
| 324 |
+
|
| 325 |
+
|
| 326 |
+
1.3. Ownership
|
| 327 |
+
|
| 328 |
+
1. NVIDIA or its licensors hold all rights, title and
|
| 329 |
+
interest in and to the SDK and its modifications and
|
| 330 |
+
derivative works, including their respective intellectual
|
| 331 |
+
property rights, subject to your rights described in this
|
| 332 |
+
section. This SDK may include software and materials from
|
| 333 |
+
NVIDIA’s licensors, and these licensors are intended
|
| 334 |
+
third party beneficiaries that may enforce this Agreement
|
| 335 |
+
with respect to their intellectual property rights.
|
| 336 |
+
|
| 337 |
+
2. You hold all rights, title and interest in and to your
|
| 338 |
+
applications and your derivative works of the sample
|
| 339 |
+
source code delivered in the SDK, including their
|
| 340 |
+
respective intellectual property rights, subject to
|
| 341 |
+
NVIDIA’s rights described in this section.
|
| 342 |
+
|
| 343 |
+
3. You may, but don’t have to, provide to NVIDIA
|
| 344 |
+
suggestions, feature requests or other feedback regarding
|
| 345 |
+
the SDK, including possible enhancements or modifications
|
| 346 |
+
to the SDK. For any feedback that you voluntarily provide,
|
| 347 |
+
you hereby grant NVIDIA and its affiliates a perpetual,
|
| 348 |
+
non-exclusive, worldwide, irrevocable license to use,
|
| 349 |
+
reproduce, modify, license, sublicense (through multiple
|
| 350 |
+
tiers of sublicensees), and distribute (through multiple
|
| 351 |
+
tiers of distributors) it without the payment of any
|
| 352 |
+
royalties or fees to you. NVIDIA will use feedback at its
|
| 353 |
+
choice. NVIDIA is constantly looking for ways to improve
|
| 354 |
+
its products, so you may send feedback to NVIDIA through
|
| 355 |
+
the developer portal at https://developer.nvidia.com.
|
| 356 |
+
|
| 357 |
+
|
| 358 |
+
1.4. No Warranties
|
| 359 |
+
|
| 360 |
+
THE SDK IS PROVIDED BY NVIDIA “AS IS” AND “WITH ALL
|
| 361 |
+
FAULTS.” TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND
|
| 362 |
+
ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND
|
| 363 |
+
OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING,
|
| 364 |
+
BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
|
| 365 |
+
FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, OR THE
|
| 366 |
+
ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO
|
| 367 |
+
WARRANTY IS MADE ON THE BASIS OF TRADE USAGE, COURSE OF
|
| 368 |
+
DEALING OR COURSE OF TRADE.
|
| 369 |
+
|
| 370 |
+
|
| 371 |
+
1.5. Limitation of Liability
|
| 372 |
+
|
| 373 |
+
TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND ITS
|
| 374 |
+
AFFILIATES SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
|
| 375 |
+
PUNITIVE OR CONSEQUENTIAL DAMAGES, OR ANY LOST PROFITS, LOSS
|
| 376 |
+
OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS OF
|
| 377 |
+
PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION
|
| 378 |
+
WITH THIS AGREEMENT OR THE USE OR PERFORMANCE OF THE SDK,
|
| 379 |
+
WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH
|
| 380 |
+
OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE),
|
| 381 |
+
PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF
|
| 382 |
+
LIABILITY. IN NO EVENT WILL NVIDIA’S AND ITS AFFILIATES
|
| 383 |
+
TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS
|
| 384 |
+
AGREEMENT EXCEED US$10.00. THE NATURE OF THE LIABILITY OR THE
|
| 385 |
+
NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR EXTEND THIS
|
| 386 |
+
LIMIT.
|
| 387 |
+
|
| 388 |
+
These exclusions and limitations of liability shall apply
|
| 389 |
+
regardless if NVIDIA or its affiliates have been advised of
|
| 390 |
+
the possibility of such damages, and regardless of whether a
|
| 391 |
+
remedy fails its essential purpose. These exclusions and
|
| 392 |
+
limitations of liability form an essential basis of the
|
| 393 |
+
bargain between the parties, and, absent any of these
|
| 394 |
+
exclusions or limitations of liability, the provisions of this
|
| 395 |
+
Agreement, including, without limitation, the economic terms,
|
| 396 |
+
would be substantially different.
|
| 397 |
+
|
| 398 |
+
|
| 399 |
+
1.6. Termination
|
| 400 |
+
|
| 401 |
+
1. This Agreement will continue to apply until terminated by
|
| 402 |
+
either you or NVIDIA as described below.
|
| 403 |
+
|
| 404 |
+
2. If you want to terminate this Agreement, you may do so by
|
| 405 |
+
stopping to use the SDK.
|
| 406 |
+
|
| 407 |
+
3. NVIDIA may, at any time, terminate this Agreement if:
|
| 408 |
+
|
| 409 |
+
a. (i) you fail to comply with any term of this
|
| 410 |
+
Agreement and the non-compliance is not fixed within
|
| 411 |
+
thirty (30) days following notice from NVIDIA (or
|
| 412 |
+
immediately if you violate NVIDIA’s intellectual
|
| 413 |
+
property rights);
|
| 414 |
+
|
| 415 |
+
b. (ii) you commence or participate in any legal
|
| 416 |
+
proceeding against NVIDIA with respect to the SDK; or
|
| 417 |
+
|
| 418 |
+
c. (iii) NVIDIA decides to no longer provide the SDK in
|
| 419 |
+
a country or, in NVIDIA’s sole discretion, the
|
| 420 |
+
continued use of it is no longer commercially viable.
|
| 421 |
+
|
| 422 |
+
4. Upon any termination of this Agreement, you agree to
|
| 423 |
+
promptly discontinue use of the SDK and destroy all copies
|
| 424 |
+
in your possession or control. Your prior distributions in
|
| 425 |
+
accordance with this Agreement are not affected by the
|
| 426 |
+
termination of this Agreement. Upon written request, you
|
| 427 |
+
will certify in writing that you have complied with your
|
| 428 |
+
commitments under this section. Upon any termination of
|
| 429 |
+
this Agreement all provisions survive except for the
|
| 430 |
+
license grant provisions.
|
| 431 |
+
|
| 432 |
+
|
| 433 |
+
1.7. General
|
| 434 |
+
|
| 435 |
+
If you wish to assign this Agreement or your rights and
|
| 436 |
+
obligations, including by merger, consolidation, dissolution
|
| 437 |
+
or operation of law, contact NVIDIA to ask for permission. Any
|
| 438 |
+
attempted assignment not approved by NVIDIA in writing shall
|
| 439 |
+
be void and of no effect. NVIDIA may assign, delegate or
|
| 440 |
+
transfer this Agreement and its rights and obligations, and if
|
| 441 |
+
to a non-affiliate you will be notified.
|
| 442 |
+
|
| 443 |
+
You agree to cooperate with NVIDIA and provide reasonably
|
| 444 |
+
requested information to verify your compliance with this
|
| 445 |
+
Agreement.
|
| 446 |
+
|
| 447 |
+
This Agreement will be governed in all respects by the laws of
|
| 448 |
+
the United States and of the State of Delaware as those laws
|
| 449 |
+
are applied to contracts entered into and performed entirely
|
| 450 |
+
within Delaware by Delaware residents, without regard to the
|
| 451 |
+
conflicts of laws principles. The United Nations Convention on
|
| 452 |
+
Contracts for the International Sale of Goods is specifically
|
| 453 |
+
disclaimed. You agree to all terms of this Agreement in the
|
| 454 |
+
English language.
|
| 455 |
+
|
| 456 |
+
The state or federal courts residing in Santa Clara County,
|
| 457 |
+
California shall have exclusive jurisdiction over any dispute
|
| 458 |
+
or claim arising out of this Agreement. Notwithstanding this,
|
| 459 |
+
you agree that NVIDIA shall still be allowed to apply for
|
| 460 |
+
injunctive remedies or an equivalent type of urgent legal
|
| 461 |
+
relief in any jurisdiction.
|
| 462 |
+
|
| 463 |
+
If any court of competent jurisdiction determines that any
|
| 464 |
+
provision of this Agreement is illegal, invalid or
|
| 465 |
+
unenforceable, such provision will be construed as limited to
|
| 466 |
+
the extent necessary to be consistent with and fully
|
| 467 |
+
enforceable under the law and the remaining provisions will
|
| 468 |
+
remain in full force and effect. Unless otherwise specified,
|
| 469 |
+
remedies are cumulative.
|
| 470 |
+
|
| 471 |
+
Each party acknowledges and agrees that the other is an
|
| 472 |
+
independent contractor in the performance of this Agreement.
|
| 473 |
+
|
| 474 |
+
The SDK has been developed entirely at private expense and is
|
| 475 |
+
“commercial items” consisting of “commercial computer
|
| 476 |
+
software” and “commercial computer software
|
| 477 |
+
documentation” provided with RESTRICTED RIGHTS. Use,
|
| 478 |
+
duplication or disclosure by the U.S. Government or a U.S.
|
| 479 |
+
Government subcontractor is subject to the restrictions in
|
| 480 |
+
this Agreement pursuant to DFARS 227.7202-3(a) or as set forth
|
| 481 |
+
in subparagraphs (c)(1) and (2) of the Commercial Computer
|
| 482 |
+
Software - Restricted Rights clause at FAR 52.227-19, as
|
| 483 |
+
applicable. Contractor/manufacturer is NVIDIA, 2788 San Tomas
|
| 484 |
+
Expressway, Santa Clara, CA 95051.
|
| 485 |
+
|
| 486 |
+
The SDK is subject to United States export laws and
|
| 487 |
+
regulations. You agree that you will not ship, transfer or
|
| 488 |
+
export the SDK into any country, or use the SDK in any manner,
|
| 489 |
+
prohibited by the United States Bureau of Industry and
|
| 490 |
+
Security or economic sanctions regulations administered by the
|
| 491 |
+
U.S. Department of Treasury’s Office of Foreign Assets
|
| 492 |
+
Control (OFAC), or any applicable export laws, restrictions or
|
| 493 |
+
regulations. These laws include restrictions on destinations,
|
| 494 |
+
end users and end use. By accepting this Agreement, you
|
| 495 |
+
confirm that you are not a resident or citizen of any country
|
| 496 |
+
currently embargoed by the U.S. and that you are not otherwise
|
| 497 |
+
prohibited from receiving the SDK.
|
| 498 |
+
|
| 499 |
+
Any notice delivered by NVIDIA to you under this Agreement
|
| 500 |
+
will be delivered via mail, email or fax. You agree that any
|
| 501 |
+
notices that NVIDIA sends you electronically will satisfy any
|
| 502 |
+
legal communication requirements. Please direct your legal
|
| 503 |
+
notices or other correspondence to NVIDIA Corporation, 2788
|
| 504 |
+
San Tomas Expressway, Santa Clara, California 95051, United
|
| 505 |
+
States of America, Attention: Legal Department.
|
| 506 |
+
|
| 507 |
+
This Agreement and any exhibits incorporated into this
|
| 508 |
+
Agreement constitute the entire agreement of the parties with
|
| 509 |
+
respect to the subject matter of this Agreement and supersede
|
| 510 |
+
all prior negotiations or documentation exchanged between the
|
| 511 |
+
parties relating to this SDK license. Any additional and/or
|
| 512 |
+
conflicting terms on documents issued by you are null, void,
|
| 513 |
+
and invalid. Any amendment or waiver under this Agreement
|
| 514 |
+
shall be in writing and signed by representatives of both
|
| 515 |
+
parties.
|
| 516 |
+
|
| 517 |
+
|
| 518 |
+
2. CUDA Toolkit Supplement to Software License Agreement for
|
| 519 |
+
NVIDIA Software Development Kits
|
| 520 |
+
------------------------------------------------------------
|
| 521 |
+
|
| 522 |
+
|
| 523 |
+
Release date: August 16, 2018
|
| 524 |
+
-----------------------------
|
| 525 |
+
|
| 526 |
+
The terms in this supplement govern your use of the NVIDIA
|
| 527 |
+
CUDA Toolkit SDK under the terms of your license agreement
|
| 528 |
+
(“Agreement”) as modified by this supplement. Capitalized
|
| 529 |
+
terms used but not defined below have the meaning assigned to
|
| 530 |
+
them in the Agreement.
|
| 531 |
+
|
| 532 |
+
This supplement is an exhibit to the Agreement and is
|
| 533 |
+
incorporated as an integral part of the Agreement. In the
|
| 534 |
+
event of conflict between the terms in this supplement and the
|
| 535 |
+
terms in the Agreement, the terms in this supplement govern.
|
| 536 |
+
|
| 537 |
+
|
| 538 |
+
2.1. License Scope
|
| 539 |
+
|
| 540 |
+
The SDK is licensed for you to develop applications only for
|
| 541 |
+
use in systems with NVIDIA GPUs.
|
| 542 |
+
|
| 543 |
+
|
| 544 |
+
2.2. Distribution
|
| 545 |
+
|
| 546 |
+
The portions of the SDK that are distributable under the
|
| 547 |
+
Agreement are listed in Attachment A.
|
| 548 |
+
|
| 549 |
+
|
| 550 |
+
2.3. Operating Systems
|
| 551 |
+
|
| 552 |
+
Those portions of the SDK designed exclusively for use on the
|
| 553 |
+
Linux or FreeBSD operating systems, or other operating systems
|
| 554 |
+
derived from the source code to these operating systems, may
|
| 555 |
+
be copied and redistributed for use in accordance with this
|
| 556 |
+
Agreement, provided that the object code files are not
|
| 557 |
+
modified in any way (except for unzipping of compressed
|
| 558 |
+
files).
|
| 559 |
+
|
| 560 |
+
|
| 561 |
+
2.4. Audio and Video Encoders and Decoders
|
| 562 |
+
|
| 563 |
+
You acknowledge and agree that it is your sole responsibility
|
| 564 |
+
to obtain any additional third-party licenses required to
|
| 565 |
+
make, have made, use, have used, sell, import, and offer for
|
| 566 |
+
sale your products or services that include or incorporate any
|
| 567 |
+
third-party software and content relating to audio and/or
|
| 568 |
+
video encoders and decoders from, including but not limited
|
| 569 |
+
to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A.,
|
| 570 |
+
MPEG-LA, and Coding Technologies. NVIDIA does not grant to you
|
| 571 |
+
under this Agreement any necessary patent or other rights with
|
| 572 |
+
respect to any audio and/or video encoders and decoders.
|
| 573 |
+
|
| 574 |
+
|
| 575 |
+
2.5. Licensing
|
| 576 |
+
|
| 577 |
+
If the distribution terms in this Agreement are not suitable
|
| 578 |
+
for your organization, or for any questions regarding this
|
| 579 |
+
Agreement, please contact NVIDIA at
|
| 580 |
+
nvidia-compute-license-questions@nvidia.com.
|
| 581 |
+
|
| 582 |
+
|
| 583 |
+
2.6. Attachment A
|
| 584 |
+
|
| 585 |
+
The following portions of the SDK are distributable under the
|
| 586 |
+
Agreement:
|
| 587 |
+
|
| 588 |
+
Component
|
| 589 |
+
|
| 590 |
+
CUDA Runtime
|
| 591 |
+
|
| 592 |
+
Windows
|
| 593 |
+
|
| 594 |
+
cudart.dll, cudart_static.lib, cudadevrt.lib
|
| 595 |
+
|
| 596 |
+
Mac OSX
|
| 597 |
+
|
| 598 |
+
libcudart.dylib, libcudart_static.a, libcudadevrt.a
|
| 599 |
+
|
| 600 |
+
Linux
|
| 601 |
+
|
| 602 |
+
libcudart.so, libcudart_static.a, libcudadevrt.a
|
| 603 |
+
|
| 604 |
+
Android
|
| 605 |
+
|
| 606 |
+
libcudart.so, libcudart_static.a, libcudadevrt.a
|
| 607 |
+
|
| 608 |
+
Component
|
| 609 |
+
|
| 610 |
+
CUDA FFT Library
|
| 611 |
+
|
| 612 |
+
Windows
|
| 613 |
+
|
| 614 |
+
cufft.dll, cufftw.dll, cufft.lib, cufftw.lib
|
| 615 |
+
|
| 616 |
+
Mac OSX
|
| 617 |
+
|
| 618 |
+
libcufft.dylib, libcufft_static.a, libcufftw.dylib,
|
| 619 |
+
libcufftw_static.a
|
| 620 |
+
|
| 621 |
+
Linux
|
| 622 |
+
|
| 623 |
+
libcufft.so, libcufft_static.a, libcufftw.so,
|
| 624 |
+
libcufftw_static.a
|
| 625 |
+
|
| 626 |
+
Android
|
| 627 |
+
|
| 628 |
+
libcufft.so, libcufft_static.a, libcufftw.so,
|
| 629 |
+
libcufftw_static.a
|
| 630 |
+
|
| 631 |
+
Component
|
| 632 |
+
|
| 633 |
+
CUDA BLAS Library
|
| 634 |
+
|
| 635 |
+
Windows
|
| 636 |
+
|
| 637 |
+
cublas.dll, cublasLt.dll
|
| 638 |
+
|
| 639 |
+
Mac OSX
|
| 640 |
+
|
| 641 |
+
libcublas.dylib, libcublasLt.dylib, libcublas_static.a,
|
| 642 |
+
libcublasLt_static.a
|
| 643 |
+
|
| 644 |
+
Linux
|
| 645 |
+
|
| 646 |
+
libcublas.so, libcublasLt.so, libcublas_static.a,
|
| 647 |
+
libcublasLt_static.a
|
| 648 |
+
|
| 649 |
+
Android
|
| 650 |
+
|
| 651 |
+
libcublas.so, libcublasLt.so, libcublas_static.a,
|
| 652 |
+
libcublasLt_static.a
|
| 653 |
+
|
| 654 |
+
Component
|
| 655 |
+
|
| 656 |
+
NVIDIA "Drop-in" BLAS Library
|
| 657 |
+
|
| 658 |
+
Windows
|
| 659 |
+
|
| 660 |
+
nvblas.dll
|
| 661 |
+
|
| 662 |
+
Mac OSX
|
| 663 |
+
|
| 664 |
+
libnvblas.dylib
|
| 665 |
+
|
| 666 |
+
Linux
|
| 667 |
+
|
| 668 |
+
libnvblas.so
|
| 669 |
+
|
| 670 |
+
Component
|
| 671 |
+
|
| 672 |
+
CUDA Sparse Matrix Library
|
| 673 |
+
|
| 674 |
+
Windows
|
| 675 |
+
|
| 676 |
+
cusparse.dll, cusparse.lib
|
| 677 |
+
|
| 678 |
+
Mac OSX
|
| 679 |
+
|
| 680 |
+
libcusparse.dylib, libcusparse_static.a
|
| 681 |
+
|
| 682 |
+
Linux
|
| 683 |
+
|
| 684 |
+
libcusparse.so, libcusparse_static.a
|
| 685 |
+
|
| 686 |
+
Android
|
| 687 |
+
|
| 688 |
+
libcusparse.so, libcusparse_static.a
|
| 689 |
+
|
| 690 |
+
Component
|
| 691 |
+
|
| 692 |
+
CUDA Linear Solver Library
|
| 693 |
+
|
| 694 |
+
Windows
|
| 695 |
+
|
| 696 |
+
cusolver.dll, cusolver.lib
|
| 697 |
+
|
| 698 |
+
Mac OSX
|
| 699 |
+
|
| 700 |
+
libcusolver.dylib, libcusolver_static.a
|
| 701 |
+
|
| 702 |
+
Linux
|
| 703 |
+
|
| 704 |
+
libcusolver.so, libcusolver_static.a
|
| 705 |
+
|
| 706 |
+
Android
|
| 707 |
+
|
| 708 |
+
libcusolver.so, libcusolver_static.a
|
| 709 |
+
|
| 710 |
+
Component
|
| 711 |
+
|
| 712 |
+
CUDA Random Number Generation Library
|
| 713 |
+
|
| 714 |
+
Windows
|
| 715 |
+
|
| 716 |
+
curand.dll, curand.lib
|
| 717 |
+
|
| 718 |
+
Mac OSX
|
| 719 |
+
|
| 720 |
+
libcurand.dylib, libcurand_static.a
|
| 721 |
+
|
| 722 |
+
Linux
|
| 723 |
+
|
| 724 |
+
libcurand.so, libcurand_static.a
|
| 725 |
+
|
| 726 |
+
Android
|
| 727 |
+
|
| 728 |
+
libcurand.so, libcurand_static.a
|
| 729 |
+
|
| 730 |
+
Component
|
| 731 |
+
|
| 732 |
+
CUDA Accelerated Graph Library
|
| 733 |
+
|
| 734 |
+
Component
|
| 735 |
+
|
| 736 |
+
NVIDIA Performance Primitives Library
|
| 737 |
+
|
| 738 |
+
Windows
|
| 739 |
+
|
| 740 |
+
nppc.dll, nppc.lib, nppial.dll, nppial.lib, nppicc.dll,
|
| 741 |
+
nppicc.lib, nppicom.dll, nppicom.lib, nppidei.dll,
|
| 742 |
+
nppidei.lib, nppif.dll, nppif.lib, nppig.dll, nppig.lib,
|
| 743 |
+
nppim.dll, nppim.lib, nppist.dll, nppist.lib, nppisu.dll,
|
| 744 |
+
nppisu.lib, nppitc.dll, nppitc.lib, npps.dll, npps.lib
|
| 745 |
+
|
| 746 |
+
Mac OSX
|
| 747 |
+
|
| 748 |
+
libnppc.dylib, libnppc_static.a, libnppial.dylib,
|
| 749 |
+
libnppial_static.a, libnppicc.dylib, libnppicc_static.a,
|
| 750 |
+
libnppicom.dylib, libnppicom_static.a, libnppidei.dylib,
|
| 751 |
+
libnppidei_static.a, libnppif.dylib, libnppif_static.a,
|
| 752 |
+
libnppig.dylib, libnppig_static.a, libnppim.dylib,
|
| 753 |
+
libnppisu_static.a, libnppitc.dylib, libnppitc_static.a,
|
| 754 |
+
libnpps.dylib, libnpps_static.a
|
| 755 |
+
|
| 756 |
+
Linux
|
| 757 |
+
|
| 758 |
+
libnppc.so, libnppc_static.a, libnppial.so,
|
| 759 |
+
libnppial_static.a, libnppicc.so, libnppicc_static.a,
|
| 760 |
+
libnppicom.so, libnppicom_static.a, libnppidei.so,
|
| 761 |
+
libnppidei_static.a, libnppif.so, libnppif_static.a
|
| 762 |
+
libnppig.so, libnppig_static.a, libnppim.so,
|
| 763 |
+
libnppim_static.a, libnppist.so, libnppist_static.a,
|
| 764 |
+
libnppisu.so, libnppisu_static.a, libnppitc.so
|
| 765 |
+
libnppitc_static.a, libnpps.so, libnpps_static.a
|
| 766 |
+
|
| 767 |
+
Android
|
| 768 |
+
|
| 769 |
+
libnppc.so, libnppc_static.a, libnppial.so,
|
| 770 |
+
libnppial_static.a, libnppicc.so, libnppicc_static.a,
|
| 771 |
+
libnppicom.so, libnppicom_static.a, libnppidei.so,
|
| 772 |
+
libnppidei_static.a, libnppif.so, libnppif_static.a
|
| 773 |
+
libnppig.so, libnppig_static.a, libnppim.so,
|
| 774 |
+
libnppim_static.a, libnppist.so, libnppist_static.a,
|
| 775 |
+
libnppisu.so, libnppisu_static.a, libnppitc.so
|
| 776 |
+
libnppitc_static.a, libnpps.so, libnpps_static.a
|
| 777 |
+
|
| 778 |
+
Component
|
| 779 |
+
|
| 780 |
+
NVIDIA JPEG Library
|
| 781 |
+
|
| 782 |
+
Linux
|
| 783 |
+
|
| 784 |
+
libnvjpeg.so, libnvjpeg_static.a
|
| 785 |
+
|
| 786 |
+
Component
|
| 787 |
+
|
| 788 |
+
Internal common library required for statically linking to
|
| 789 |
+
cuBLAS, cuSPARSE, cuFFT, cuRAND, nvJPEG and NPP
|
| 790 |
+
|
| 791 |
+
Mac OSX
|
| 792 |
+
|
| 793 |
+
libculibos.a
|
| 794 |
+
|
| 795 |
+
Linux
|
| 796 |
+
|
| 797 |
+
libculibos.a
|
| 798 |
+
|
| 799 |
+
Component
|
| 800 |
+
|
| 801 |
+
NVIDIA Runtime Compilation Library and Header
|
| 802 |
+
|
| 803 |
+
All
|
| 804 |
+
|
| 805 |
+
nvrtc.h
|
| 806 |
+
|
| 807 |
+
Windows
|
| 808 |
+
|
| 809 |
+
nvrtc.dll, nvrtc-builtins.dll
|
| 810 |
+
|
| 811 |
+
Mac OSX
|
| 812 |
+
|
| 813 |
+
libnvrtc.dylib, libnvrtc-builtins.dylib
|
| 814 |
+
|
| 815 |
+
Linux
|
| 816 |
+
|
| 817 |
+
libnvrtc.so, libnvrtc-builtins.so
|
| 818 |
+
|
| 819 |
+
Component
|
| 820 |
+
|
| 821 |
+
NVIDIA Optimizing Compiler Library
|
| 822 |
+
|
| 823 |
+
Windows
|
| 824 |
+
|
| 825 |
+
nvvm.dll
|
| 826 |
+
|
| 827 |
+
Mac OSX
|
| 828 |
+
|
| 829 |
+
libnvvm.dylib
|
| 830 |
+
|
| 831 |
+
Linux
|
| 832 |
+
|
| 833 |
+
libnvvm.so
|
| 834 |
+
|
| 835 |
+
Component
|
| 836 |
+
|
| 837 |
+
NVIDIA Common Device Math Functions Library
|
| 838 |
+
|
| 839 |
+
Windows
|
| 840 |
+
|
| 841 |
+
libdevice.10.bc
|
| 842 |
+
|
| 843 |
+
Mac OSX
|
| 844 |
+
|
| 845 |
+
libdevice.10.bc
|
| 846 |
+
|
| 847 |
+
Linux
|
| 848 |
+
|
| 849 |
+
libdevice.10.bc
|
| 850 |
+
|
| 851 |
+
Component
|
| 852 |
+
|
| 853 |
+
CUDA Occupancy Calculation Header Library
|
| 854 |
+
|
| 855 |
+
All
|
| 856 |
+
|
| 857 |
+
cuda_occupancy.h
|
| 858 |
+
|
| 859 |
+
Component
|
| 860 |
+
|
| 861 |
+
CUDA Half Precision Headers
|
| 862 |
+
|
| 863 |
+
All
|
| 864 |
+
|
| 865 |
+
cuda_fp16.h, cuda_fp16.hpp
|
| 866 |
+
|
| 867 |
+
Component
|
| 868 |
+
|
| 869 |
+
CUDA Profiling Tools Interface (CUPTI) Library
|
| 870 |
+
|
| 871 |
+
Windows
|
| 872 |
+
|
| 873 |
+
cupti.dll
|
| 874 |
+
|
| 875 |
+
Mac OSX
|
| 876 |
+
|
| 877 |
+
libcupti.dylib
|
| 878 |
+
|
| 879 |
+
Linux
|
| 880 |
+
|
| 881 |
+
libcupti.so
|
| 882 |
+
|
| 883 |
+
Component
|
| 884 |
+
|
| 885 |
+
NVIDIA Tools Extension Library
|
| 886 |
+
|
| 887 |
+
Windows
|
| 888 |
+
|
| 889 |
+
nvToolsExt.dll, nvToolsExt.lib
|
| 890 |
+
|
| 891 |
+
Mac OSX
|
| 892 |
+
|
| 893 |
+
libnvToolsExt.dylib
|
| 894 |
+
|
| 895 |
+
Linux
|
| 896 |
+
|
| 897 |
+
libnvToolsExt.so
|
| 898 |
+
|
| 899 |
+
Component
|
| 900 |
+
|
| 901 |
+
NVIDIA CUDA Driver Libraries
|
| 902 |
+
|
| 903 |
+
Linux
|
| 904 |
+
|
| 905 |
+
libcuda.so, libnvidia-fatbinaryloader.so,
|
| 906 |
+
libnvidia-ptxjitcompiler.so
|
| 907 |
+
|
| 908 |
+
The NVIDIA CUDA Driver Libraries are only distributable in
|
| 909 |
+
applications that meet this criteria:
|
| 910 |
+
|
| 911 |
+
1. The application was developed starting from a NVIDIA CUDA
|
| 912 |
+
container obtained from Docker Hub or the NVIDIA GPU
|
| 913 |
+
Cloud, and
|
| 914 |
+
|
| 915 |
+
2. The resulting application is packaged as a Docker
|
| 916 |
+
container and distributed to users on Docker Hub or the
|
| 917 |
+
NVIDIA GPU Cloud only.
|
| 918 |
+
|
| 919 |
+
|
| 920 |
+
2.7. Attachment B
|
| 921 |
+
|
| 922 |
+
|
| 923 |
+
Additional Licensing Obligations
|
| 924 |
+
|
| 925 |
+
The following third party components included in the SOFTWARE
|
| 926 |
+
are licensed to Licensee pursuant to the following terms and
|
| 927 |
+
conditions:
|
| 928 |
+
|
| 929 |
+
1. Licensee's use of the GDB third party component is
|
| 930 |
+
subject to the terms and conditions of GNU GPL v3:
|
| 931 |
+
|
| 932 |
+
This product includes copyrighted third-party software licensed
|
| 933 |
+
under the terms of the GNU General Public License v3 ("GPL v3").
|
| 934 |
+
All third-party software packages are copyright by their respective
|
| 935 |
+
authors. GPL v3 terms and conditions are hereby incorporated into
|
| 936 |
+
the Agreement by this reference: http://www.gnu.org/licenses/gpl.txt
|
| 937 |
+
|
| 938 |
+
Consistent with these licensing requirements, the software
|
| 939 |
+
listed below is provided under the terms of the specified
|
| 940 |
+
open source software licenses. To obtain source code for
|
| 941 |
+
software provided under licenses that require
|
| 942 |
+
redistribution of source code, including the GNU General
|
| 943 |
+
Public License (GPL) and GNU Lesser General Public License
|
| 944 |
+
(LGPL), contact oss-requests@nvidia.com. This offer is
|
| 945 |
+
valid for a period of three (3) years from the date of the
|
| 946 |
+
distribution of this product by NVIDIA CORPORATION.
|
| 947 |
+
|
| 948 |
+
Component License
|
| 949 |
+
CUDA-GDB GPL v3
|
| 950 |
+
|
| 951 |
+
2. Licensee represents and warrants that any and all third
|
| 952 |
+
party licensing and/or royalty payment obligations in
|
| 953 |
+
connection with Licensee's use of the H.264 video codecs
|
| 954 |
+
are solely the responsibility of Licensee.
|
| 955 |
+
|
| 956 |
+
3. Licensee's use of the Thrust library is subject to the
|
| 957 |
+
terms and conditions of the Apache License Version 2.0.
|
| 958 |
+
All third-party software packages are copyright by their
|
| 959 |
+
respective authors. Apache License Version 2.0 terms and
|
| 960 |
+
conditions are hereby incorporated into the Agreement by
|
| 961 |
+
this reference.
|
| 962 |
+
http://www.apache.org/licenses/LICENSE-2.0.html
|
| 963 |
+
|
| 964 |
+
In addition, Licensee acknowledges the following notice:
|
| 965 |
+
Thrust includes source code from the Boost Iterator,
|
| 966 |
+
Tuple, System, and Random Number libraries.
|
| 967 |
+
|
| 968 |
+
Boost Software License - Version 1.0 - August 17th, 2003
|
| 969 |
+
. . . .
|
| 970 |
+
|
| 971 |
+
Permission is hereby granted, free of charge, to any person or
|
| 972 |
+
organization obtaining a copy of the software and accompanying
|
| 973 |
+
documentation covered by this license (the "Software") to use,
|
| 974 |
+
reproduce, display, distribute, execute, and transmit the Software,
|
| 975 |
+
and to prepare derivative works of the Software, and to permit
|
| 976 |
+
third-parties to whom the Software is furnished to do so, all
|
| 977 |
+
subject to the following:
|
| 978 |
+
|
| 979 |
+
The copyright notices in the Software and this entire statement,
|
| 980 |
+
including the above license grant, this restriction and the following
|
| 981 |
+
disclaimer, must be included in all copies of the Software, in whole
|
| 982 |
+
or in part, and all derivative works of the Software, unless such
|
| 983 |
+
copies or derivative works are solely in the form of machine-executable
|
| 984 |
+
object code generated by a source language processor.
|
| 985 |
+
|
| 986 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 987 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 988 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
| 989 |
+
NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
| 990 |
+
ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
|
| 991 |
+
OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
|
| 992 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 993 |
+
OTHER DEALINGS IN THE SOFTWARE.
|
| 994 |
+
|
| 995 |
+
4. Licensee's use of the LLVM third party component is
|
| 996 |
+
subject to the following terms and conditions:
|
| 997 |
+
|
| 998 |
+
======================================================
|
| 999 |
+
LLVM Release License
|
| 1000 |
+
======================================================
|
| 1001 |
+
University of Illinois/NCSA
|
| 1002 |
+
Open Source License
|
| 1003 |
+
|
| 1004 |
+
Copyright (c) 2003-2010 University of Illinois at Urbana-Champaign.
|
| 1005 |
+
All rights reserved.
|
| 1006 |
+
|
| 1007 |
+
Developed by:
|
| 1008 |
+
|
| 1009 |
+
LLVM Team
|
| 1010 |
+
|
| 1011 |
+
University of Illinois at Urbana-Champaign
|
| 1012 |
+
|
| 1013 |
+
http://llvm.org
|
| 1014 |
+
|
| 1015 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 1016 |
+
of this software and associated documentation files (the "Software"), to
|
| 1017 |
+
deal with the Software without restriction, including without limitation the
|
| 1018 |
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
| 1019 |
+
sell copies of the Software, and to permit persons to whom the Software is
|
| 1020 |
+
furnished to do so, subject to the following conditions:
|
| 1021 |
+
|
| 1022 |
+
* Redistributions of source code must retain the above copyright notice,
|
| 1023 |
+
this list of conditions and the following disclaimers.
|
| 1024 |
+
|
| 1025 |
+
* Redistributions in binary form must reproduce the above copyright
|
| 1026 |
+
notice, this list of conditions and the following disclaimers in the
|
| 1027 |
+
documentation and/or other materials provided with the distribution.
|
| 1028 |
+
|
| 1029 |
+
* Neither the names of the LLVM Team, University of Illinois at Urbana-
|
| 1030 |
+
Champaign, nor the names of its contributors may be used to endorse or
|
| 1031 |
+
promote products derived from this Software without specific prior
|
| 1032 |
+
written permission.
|
| 1033 |
+
|
| 1034 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 1035 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 1036 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
| 1037 |
+
THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 1038 |
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
| 1039 |
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
| 1040 |
+
DEALINGS WITH THE SOFTWARE.
|
| 1041 |
+
|
| 1042 |
+
5. Licensee's use (e.g. nvprof) of the PCRE third party
|
| 1043 |
+
component is subject to the following terms and
|
| 1044 |
+
conditions:
|
| 1045 |
+
|
| 1046 |
+
------------
|
| 1047 |
+
PCRE LICENCE
|
| 1048 |
+
------------
|
| 1049 |
+
PCRE is a library of functions to support regular expressions whose syntax
|
| 1050 |
+
and semantics are as close as possible to those of the Perl 5 language.
|
| 1051 |
+
Release 8 of PCRE is distributed under the terms of the "BSD" licence, as
|
| 1052 |
+
specified below. The documentation for PCRE, supplied in the "doc"
|
| 1053 |
+
directory, is distributed under the same terms as the software itself. The
|
| 1054 |
+
basic library functions are written in C and are freestanding. Also
|
| 1055 |
+
included in the distribution is a set of C++ wrapper functions, and a just-
|
| 1056 |
+
in-time compiler that can be used to optimize pattern matching. These are
|
| 1057 |
+
both optional features that can be omitted when the library is built.
|
| 1058 |
+
|
| 1059 |
+
THE BASIC LIBRARY FUNCTIONS
|
| 1060 |
+
---------------------------
|
| 1061 |
+
Written by: Philip Hazel
|
| 1062 |
+
Email local part: ph10
|
| 1063 |
+
Email domain: cam.ac.uk
|
| 1064 |
+
University of Cambridge Computing Service,
|
| 1065 |
+
Cambridge, England.
|
| 1066 |
+
Copyright (c) 1997-2012 University of Cambridge
|
| 1067 |
+
All rights reserved.
|
| 1068 |
+
|
| 1069 |
+
PCRE JUST-IN-TIME COMPILATION SUPPORT
|
| 1070 |
+
-------------------------------------
|
| 1071 |
+
Written by: Zoltan Herczeg
|
| 1072 |
+
Email local part: hzmester
|
| 1073 |
+
Emain domain: freemail.hu
|
| 1074 |
+
Copyright(c) 2010-2012 Zoltan Herczeg
|
| 1075 |
+
All rights reserved.
|
| 1076 |
+
|
| 1077 |
+
STACK-LESS JUST-IN-TIME COMPILER
|
| 1078 |
+
--------------------------------
|
| 1079 |
+
Written by: Zoltan Herczeg
|
| 1080 |
+
Email local part: hzmester
|
| 1081 |
+
Emain domain: freemail.hu
|
| 1082 |
+
Copyright(c) 2009-2012 Zoltan Herczeg
|
| 1083 |
+
All rights reserved.
|
| 1084 |
+
|
| 1085 |
+
THE C++ WRAPPER FUNCTIONS
|
| 1086 |
+
-------------------------
|
| 1087 |
+
Contributed by: Google Inc.
|
| 1088 |
+
Copyright (c) 2007-2012, Google Inc.
|
| 1089 |
+
All rights reserved.
|
| 1090 |
+
|
| 1091 |
+
THE "BSD" LICENCE
|
| 1092 |
+
-----------------
|
| 1093 |
+
Redistribution and use in source and binary forms, with or without
|
| 1094 |
+
modification, are permitted provided that the following conditions are met:
|
| 1095 |
+
|
| 1096 |
+
* Redistributions of source code must retain the above copyright notice,
|
| 1097 |
+
this list of conditions and the following disclaimer.
|
| 1098 |
+
|
| 1099 |
+
* Redistributions in binary form must reproduce the above copyright
|
| 1100 |
+
notice, this list of conditions and the following disclaimer in the
|
| 1101 |
+
documentation and/or other materials provided with the distribution.
|
| 1102 |
+
|
| 1103 |
+
* Neither the name of the University of Cambridge nor the name of Google
|
| 1104 |
+
Inc. nor the names of their contributors may be used to endorse or
|
| 1105 |
+
promote products derived from this software without specific prior
|
| 1106 |
+
written permission.
|
| 1107 |
+
|
| 1108 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 1109 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 1110 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
| 1111 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
| 1112 |
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 1113 |
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 1114 |
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| 1115 |
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| 1116 |
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| 1117 |
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 1118 |
+
POSSIBILITY OF SUCH DAMAGE.
|
| 1119 |
+
|
| 1120 |
+
6. Some of the cuBLAS library routines were written by or
|
| 1121 |
+
derived from code written by Vasily Volkov and are subject
|
| 1122 |
+
to the Modified Berkeley Software Distribution License as
|
| 1123 |
+
follows:
|
| 1124 |
+
|
| 1125 |
+
Copyright (c) 2007-2009, Regents of the University of California
|
| 1126 |
+
|
| 1127 |
+
All rights reserved.
|
| 1128 |
+
|
| 1129 |
+
Redistribution and use in source and binary forms, with or without
|
| 1130 |
+
modification, are permitted provided that the following conditions are
|
| 1131 |
+
met:
|
| 1132 |
+
* Redistributions of source code must retain the above copyright
|
| 1133 |
+
notice, this list of conditions and the following disclaimer.
|
| 1134 |
+
* Redistributions in binary form must reproduce the above
|
| 1135 |
+
copyright notice, this list of conditions and the following
|
| 1136 |
+
disclaimer in the documentation and/or other materials provided
|
| 1137 |
+
with the distribution.
|
| 1138 |
+
* Neither the name of the University of California, Berkeley nor
|
| 1139 |
+
the names of its contributors may be used to endorse or promote
|
| 1140 |
+
products derived from this software without specific prior
|
| 1141 |
+
written permission.
|
| 1142 |
+
|
| 1143 |
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
| 1144 |
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| 1145 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| 1146 |
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
| 1147 |
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| 1148 |
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
| 1149 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
| 1150 |
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
| 1151 |
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
| 1152 |
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 1153 |
+
POSSIBILITY OF SUCH DAMAGE.
|
| 1154 |
+
|
| 1155 |
+
7. Some of the cuBLAS library routines were written by or
|
| 1156 |
+
derived from code written by Davide Barbieri and are
|
| 1157 |
+
subject to the Modified Berkeley Software Distribution
|
| 1158 |
+
License as follows:
|
| 1159 |
+
|
| 1160 |
+
Copyright (c) 2008-2009 Davide Barbieri @ University of Rome Tor Vergata.
|
| 1161 |
+
|
| 1162 |
+
All rights reserved.
|
| 1163 |
+
|
| 1164 |
+
Redistribution and use in source and binary forms, with or without
|
| 1165 |
+
modification, are permitted provided that the following conditions are
|
| 1166 |
+
met:
|
| 1167 |
+
* Redistributions of source code must retain the above copyright
|
| 1168 |
+
notice, this list of conditions and the following disclaimer.
|
| 1169 |
+
* Redistributions in binary form must reproduce the above
|
| 1170 |
+
copyright notice, this list of conditions and the following
|
| 1171 |
+
disclaimer in the documentation and/or other materials provided
|
| 1172 |
+
with the distribution.
|
| 1173 |
+
* The name of the author may not be used to endorse or promote
|
| 1174 |
+
products derived from this software without specific prior
|
| 1175 |
+
written permission.
|
| 1176 |
+
|
| 1177 |
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
| 1178 |
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| 1179 |
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| 1180 |
+
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
| 1181 |
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| 1182 |
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
| 1183 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
| 1184 |
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
| 1185 |
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
| 1186 |
+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| 1187 |
+
POSSIBILITY OF SUCH DAMAGE.
|
| 1188 |
+
|
| 1189 |
+
8. Some of the cuBLAS library routines were derived from
|
| 1190 |
+
code developed by the University of Tennessee and are
|
| 1191 |
+
subject to the Modified Berkeley Software Distribution
|
| 1192 |
+
License as follows:
|
| 1193 |
+
|
| 1194 |
+
Copyright (c) 2010 The University of Tennessee.
|
| 1195 |
+
|
| 1196 |
+
All rights reserved.
|
| 1197 |
+
|
| 1198 |
+
Redistribution and use in source and binary forms, with or without
|
| 1199 |
+
modification, are permitted provided that the following conditions are
|
| 1200 |
+
met:
|
| 1201 |
+
* Redistributions of source code must retain the above copyright
|
| 1202 |
+
notice, this list of conditions and the following disclaimer.
|
| 1203 |
+
* Redistributions in binary form must reproduce the above
|
| 1204 |
+
copyright notice, this list of conditions and the following
|
| 1205 |
+
disclaimer listed in this license in the documentation and/or
|
| 1206 |
+
other materials provided with the distribution.
|
| 1207 |
+
* Neither the name of the copyright holders nor the names of its
|
| 1208 |
+
contributors may be used to endorse or promote products derived
|
| 1209 |
+
from this software without specific prior written permission.
|
| 1210 |
+
|
| 1211 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1212 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1213 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1214 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1215 |
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1216 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1217 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1218 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1219 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1220 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1221 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1222 |
+
|
| 1223 |
+
9. Some of the cuBLAS library routines were written by or
|
| 1224 |
+
derived from code written by Jonathan Hogg and are subject
|
| 1225 |
+
to the Modified Berkeley Software Distribution License as
|
| 1226 |
+
follows:
|
| 1227 |
+
|
| 1228 |
+
Copyright (c) 2012, The Science and Technology Facilities Council (STFC).
|
| 1229 |
+
|
| 1230 |
+
All rights reserved.
|
| 1231 |
+
|
| 1232 |
+
Redistribution and use in source and binary forms, with or without
|
| 1233 |
+
modification, are permitted provided that the following conditions are
|
| 1234 |
+
met:
|
| 1235 |
+
* Redistributions of source code must retain the above copyright
|
| 1236 |
+
notice, this list of conditions and the following disclaimer.
|
| 1237 |
+
* Redistributions in binary form must reproduce the above
|
| 1238 |
+
copyright notice, this list of conditions and the following
|
| 1239 |
+
disclaimer in the documentation and/or other materials provided
|
| 1240 |
+
with the distribution.
|
| 1241 |
+
* Neither the name of the STFC nor the names of its contributors
|
| 1242 |
+
may be used to endorse or promote products derived from this
|
| 1243 |
+
software without specific prior written permission.
|
| 1244 |
+
|
| 1245 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1246 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1247 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1248 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE STFC BE
|
| 1249 |
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| 1250 |
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| 1251 |
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
| 1252 |
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
| 1253 |
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
| 1254 |
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
| 1255 |
+
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1256 |
+
|
| 1257 |
+
10. Some of the cuBLAS library routines were written by or
|
| 1258 |
+
derived from code written by Ahmad M. Abdelfattah, David
|
| 1259 |
+
Keyes, and Hatem Ltaief, and are subject to the Apache
|
| 1260 |
+
License, Version 2.0, as follows:
|
| 1261 |
+
|
| 1262 |
+
-- (C) Copyright 2013 King Abdullah University of Science and Technology
|
| 1263 |
+
Authors:
|
| 1264 |
+
Ahmad Abdelfattah (ahmad.ahmad@kaust.edu.sa)
|
| 1265 |
+
David Keyes (david.keyes@kaust.edu.sa)
|
| 1266 |
+
Hatem Ltaief (hatem.ltaief@kaust.edu.sa)
|
| 1267 |
+
|
| 1268 |
+
Redistribution and use in source and binary forms, with or without
|
| 1269 |
+
modification, are permitted provided that the following conditions
|
| 1270 |
+
are met:
|
| 1271 |
+
|
| 1272 |
+
* Redistributions of source code must retain the above copyright
|
| 1273 |
+
notice, this list of conditions and the following disclaimer.
|
| 1274 |
+
* Redistributions in binary form must reproduce the above copyright
|
| 1275 |
+
notice, this list of conditions and the following disclaimer in the
|
| 1276 |
+
documentation and/or other materials provided with the distribution.
|
| 1277 |
+
* Neither the name of the King Abdullah University of Science and
|
| 1278 |
+
Technology nor the names of its contributors may be used to endorse
|
| 1279 |
+
or promote products derived from this software without specific prior
|
| 1280 |
+
written permission.
|
| 1281 |
+
|
| 1282 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1283 |
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1284 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1285 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1286 |
+
HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1287 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1288 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1289 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1290 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1291 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1292 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
| 1293 |
+
|
| 1294 |
+
11. Some of the cuSPARSE library routines were written by or
|
| 1295 |
+
derived from code written by Li-Wen Chang and are subject
|
| 1296 |
+
to the NCSA Open Source License as follows:
|
| 1297 |
+
|
| 1298 |
+
Copyright (c) 2012, University of Illinois.
|
| 1299 |
+
|
| 1300 |
+
All rights reserved.
|
| 1301 |
+
|
| 1302 |
+
Developed by: IMPACT Group, University of Illinois, http://impact.crhc.illinois.edu
|
| 1303 |
+
|
| 1304 |
+
Permission is hereby granted, free of charge, to any person obtaining
|
| 1305 |
+
a copy of this software and associated documentation files (the
|
| 1306 |
+
"Software"), to deal with the Software without restriction, including
|
| 1307 |
+
without limitation the rights to use, copy, modify, merge, publish,
|
| 1308 |
+
distribute, sublicense, and/or sell copies of the Software, and to
|
| 1309 |
+
permit persons to whom the Software is furnished to do so, subject to
|
| 1310 |
+
the following conditions:
|
| 1311 |
+
* Redistributions of source code must retain the above copyright
|
| 1312 |
+
notice, this list of conditions and the following disclaimer.
|
| 1313 |
+
* Redistributions in binary form must reproduce the above
|
| 1314 |
+
copyright notice, this list of conditions and the following
|
| 1315 |
+
disclaimers in the documentation and/or other materials provided
|
| 1316 |
+
with the distribution.
|
| 1317 |
+
* Neither the names of IMPACT Group, University of Illinois, nor
|
| 1318 |
+
the names of its contributors may be used to endorse or promote
|
| 1319 |
+
products derived from this Software without specific prior
|
| 1320 |
+
written permission.
|
| 1321 |
+
|
| 1322 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 1323 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 1324 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
| 1325 |
+
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
|
| 1326 |
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
| 1327 |
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
| 1328 |
+
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
| 1329 |
+
SOFTWARE.
|
| 1330 |
+
|
| 1331 |
+
12. Some of the cuRAND library routines were written by or
|
| 1332 |
+
derived from code written by Mutsuo Saito and Makoto
|
| 1333 |
+
Matsumoto and are subject to the following license:
|
| 1334 |
+
|
| 1335 |
+
Copyright (c) 2009, 2010 Mutsuo Saito, Makoto Matsumoto and Hiroshima
|
| 1336 |
+
University. All rights reserved.
|
| 1337 |
+
|
| 1338 |
+
Copyright (c) 2011 Mutsuo Saito, Makoto Matsumoto, Hiroshima
|
| 1339 |
+
University and University of Tokyo. All rights reserved.
|
| 1340 |
+
|
| 1341 |
+
Redistribution and use in source and binary forms, with or without
|
| 1342 |
+
modification, are permitted provided that the following conditions are
|
| 1343 |
+
met:
|
| 1344 |
+
* Redistributions of source code must retain the above copyright
|
| 1345 |
+
notice, this list of conditions and the following disclaimer.
|
| 1346 |
+
* Redistributions in binary form must reproduce the above
|
| 1347 |
+
copyright notice, this list of conditions and the following
|
| 1348 |
+
disclaimer in the documentation and/or other materials provided
|
| 1349 |
+
with the distribution.
|
| 1350 |
+
* Neither the name of the Hiroshima University nor the names of
|
| 1351 |
+
its contributors may be used to endorse or promote products
|
| 1352 |
+
derived from this software without specific prior written
|
| 1353 |
+
permission.
|
| 1354 |
+
|
| 1355 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1356 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1357 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1358 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1359 |
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1360 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1361 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1362 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1363 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1364 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1365 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1366 |
+
|
| 1367 |
+
13. Some of the cuRAND library routines were derived from
|
| 1368 |
+
code developed by D. E. Shaw Research and are subject to
|
| 1369 |
+
the following license:
|
| 1370 |
+
|
| 1371 |
+
Copyright 2010-2011, D. E. Shaw Research.
|
| 1372 |
+
|
| 1373 |
+
All rights reserved.
|
| 1374 |
+
|
| 1375 |
+
Redistribution and use in source and binary forms, with or without
|
| 1376 |
+
modification, are permitted provided that the following conditions are
|
| 1377 |
+
met:
|
| 1378 |
+
* Redistributions of source code must retain the above copyright
|
| 1379 |
+
notice, this list of conditions, and the following disclaimer.
|
| 1380 |
+
* Redistributions in binary form must reproduce the above
|
| 1381 |
+
copyright notice, this list of conditions, and the following
|
| 1382 |
+
disclaimer in the documentation and/or other materials provided
|
| 1383 |
+
with the distribution.
|
| 1384 |
+
* Neither the name of D. E. Shaw Research nor the names of its
|
| 1385 |
+
contributors may be used to endorse or promote products derived
|
| 1386 |
+
from this software without specific prior written permission.
|
| 1387 |
+
|
| 1388 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1389 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1390 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1391 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1392 |
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1393 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1394 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1395 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1396 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1397 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1398 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1399 |
+
|
| 1400 |
+
14. Some of the Math library routines were written by or
|
| 1401 |
+
derived from code developed by Norbert Juffa and are
|
| 1402 |
+
subject to the following license:
|
| 1403 |
+
|
| 1404 |
+
Copyright (c) 2015-2017, Norbert Juffa
|
| 1405 |
+
All rights reserved.
|
| 1406 |
+
|
| 1407 |
+
Redistribution and use in source and binary forms, with or without
|
| 1408 |
+
modification, are permitted provided that the following conditions
|
| 1409 |
+
are met:
|
| 1410 |
+
|
| 1411 |
+
1. Redistributions of source code must retain the above copyright
|
| 1412 |
+
notice, this list of conditions and the following disclaimer.
|
| 1413 |
+
|
| 1414 |
+
2. Redistributions in binary form must reproduce the above copyright
|
| 1415 |
+
notice, this list of conditions and the following disclaimer in the
|
| 1416 |
+
documentation and/or other materials provided with the distribution.
|
| 1417 |
+
|
| 1418 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1419 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1420 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1421 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1422 |
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1423 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1424 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1425 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1426 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1427 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1428 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1429 |
+
|
| 1430 |
+
15. Licensee's use of the lz4 third party component is
|
| 1431 |
+
subject to the following terms and conditions:
|
| 1432 |
+
|
| 1433 |
+
Copyright (C) 2011-2013, Yann Collet.
|
| 1434 |
+
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
| 1435 |
+
|
| 1436 |
+
Redistribution and use in source and binary forms, with or without
|
| 1437 |
+
modification, are permitted provided that the following conditions are
|
| 1438 |
+
met:
|
| 1439 |
+
|
| 1440 |
+
* Redistributions of source code must retain the above copyright
|
| 1441 |
+
notice, this list of conditions and the following disclaimer.
|
| 1442 |
+
* Redistributions in binary form must reproduce the above
|
| 1443 |
+
copyright notice, this list of conditions and the following disclaimer
|
| 1444 |
+
in the documentation and/or other materials provided with the
|
| 1445 |
+
distribution.
|
| 1446 |
+
|
| 1447 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| 1448 |
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| 1449 |
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| 1450 |
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| 1451 |
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| 1452 |
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| 1453 |
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| 1454 |
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| 1455 |
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| 1456 |
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 1457 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| 1458 |
+
|
| 1459 |
+
16. The NPP library uses code from the Boost Math Toolkit,
|
| 1460 |
+
and is subject to the following license:
|
| 1461 |
+
|
| 1462 |
+
Boost Software License - Version 1.0 - August 17th, 2003
|
| 1463 |
+
. . . .
|
| 1464 |
+
|
| 1465 |
+
Permission is hereby granted, free of charge, to any person or
|
| 1466 |
+
organization obtaining a copy of the software and accompanying
|
| 1467 |
+
documentation covered by this license (the "Software") to use,
|
| 1468 |
+
reproduce, display, distribute, execute, and transmit the Software,
|
| 1469 |
+
and to prepare derivative works of the Software, and to permit
|
| 1470 |
+
third-parties to whom the Software is furnished to do so, all
|
| 1471 |
+
subject to the following:
|
| 1472 |
+
|
| 1473 |
+
The copyright notices in the Software and this entire statement,
|
| 1474 |
+
including the above license grant, this restriction and the following
|
| 1475 |
+
disclaimer, must be included in all copies of the Software, in whole
|
| 1476 |
+
or in part, and all derivative works of the Software, unless such
|
| 1477 |
+
copies or derivative works are solely in the form of machine-executable
|
| 1478 |
+
object code generated by a source language processor.
|
| 1479 |
+
|
| 1480 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
| 1481 |
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
| 1482 |
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
| 1483 |
+
NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
|
| 1484 |
+
ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR
|
| 1485 |
+
OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
|
| 1486 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 1487 |
+
OTHER DEALINGS IN THE SOFTWARE.
|
| 1488 |
+
|
| 1489 |
+
17. Portions of the Nsight Eclipse Edition is subject to the
|
| 1490 |
+
following license:
|
| 1491 |
+
|
| 1492 |
+
The Eclipse Foundation makes available all content in this plug-in
|
| 1493 |
+
("Content"). Unless otherwise indicated below, the Content is provided
|
| 1494 |
+
to you under the terms and conditions of the Eclipse Public License
|
| 1495 |
+
Version 1.0 ("EPL"). A copy of the EPL is available at http://
|
| 1496 |
+
www.eclipse.org/legal/epl-v10.html. For purposes of the EPL, "Program"
|
| 1497 |
+
will mean the Content.
|
| 1498 |
+
|
| 1499 |
+
If you did not receive this Content directly from the Eclipse
|
| 1500 |
+
Foundation, the Content is being redistributed by another party
|
| 1501 |
+
("Redistributor") and different terms and conditions may apply to your
|
| 1502 |
+
use of any object code in the Content. Check the Redistributor's
|
| 1503 |
+
license that was provided with the Content. If no such license exists,
|
| 1504 |
+
contact the Redistributor. Unless otherwise indicated below, the terms
|
| 1505 |
+
and conditions of the EPL still apply to any source code in the
|
| 1506 |
+
Content and such source code may be obtained at http://www.eclipse.org.
|
| 1507 |
+
|
| 1508 |
+
18. Some of the cuBLAS library routines uses code from
|
| 1509 |
+
OpenAI, which is subject to the following license:
|
| 1510 |
+
|
| 1511 |
+
License URL
|
| 1512 |
+
https://github.com/openai/openai-gemm/blob/master/LICENSE
|
| 1513 |
+
|
| 1514 |
+
License Text
|
| 1515 |
+
The MIT License
|
| 1516 |
+
|
| 1517 |
+
Copyright (c) 2016 OpenAI (http://openai.com), 2016 Google Inc.
|
| 1518 |
+
|
| 1519 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 1520 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 1521 |
+
in the Software without restriction, including without limitation the rights
|
| 1522 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 1523 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 1524 |
+
furnished to do so, subject to the following conditions:
|
| 1525 |
+
|
| 1526 |
+
The above copyright notice and this permission notice shall be included in
|
| 1527 |
+
all copies or substantial portions of the Software.
|
| 1528 |
+
|
| 1529 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 1530 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 1531 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 1532 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 1533 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 1534 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
| 1535 |
+
THE SOFTWARE.
|
| 1536 |
+
|
| 1537 |
+
19. Licensee's use of the Visual Studio Setup Configuration
|
| 1538 |
+
Samples is subject to the following license:
|
| 1539 |
+
|
| 1540 |
+
The MIT License (MIT)
|
| 1541 |
+
Copyright (C) Microsoft Corporation. All rights reserved.
|
| 1542 |
+
|
| 1543 |
+
Permission is hereby granted, free of charge, to any person
|
| 1544 |
+
obtaining a copy of this software and associated documentation
|
| 1545 |
+
files (the "Software"), to deal in the Software without restriction,
|
| 1546 |
+
including without limitation the rights to use, copy, modify, merge,
|
| 1547 |
+
publish, distribute, sublicense, and/or sell copies of the Software,
|
| 1548 |
+
and to permit persons to whom the Software is furnished to do so,
|
| 1549 |
+
subject to the following conditions:
|
| 1550 |
+
|
| 1551 |
+
The above copyright notice and this permission notice shall be included
|
| 1552 |
+
in all copies or substantial portions of the Software.
|
| 1553 |
+
|
| 1554 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
| 1555 |
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 1556 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 1557 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 1558 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 1559 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| 1560 |
+
|
| 1561 |
+
20. Licensee's use of linmath.h header for CPU functions for
|
| 1562 |
+
GL vector/matrix operations from lunarG is subject to the
|
| 1563 |
+
Apache License Version 2.0.
|
| 1564 |
+
|
| 1565 |
+
21. The DX12-CUDA sample uses the d3dx12.h header, which is
|
| 1566 |
+
subject to the MIT license .
|
| 1567 |
+
|
| 1568 |
+
-----------------
|
rtme/lib/python3.10/site-packages/pycparser/__init__.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#-----------------------------------------------------------------
|
| 2 |
+
# pycparser: __init__.py
|
| 3 |
+
#
|
| 4 |
+
# This package file exports some convenience functions for
|
| 5 |
+
# interacting with pycparser
|
| 6 |
+
#
|
| 7 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 8 |
+
# License: BSD
|
| 9 |
+
#-----------------------------------------------------------------
|
| 10 |
+
__all__ = ['c_lexer', 'c_parser', 'c_ast']
|
| 11 |
+
__version__ = '2.22'
|
| 12 |
+
|
| 13 |
+
import io
|
| 14 |
+
from subprocess import check_output
|
| 15 |
+
from .c_parser import CParser
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def preprocess_file(filename, cpp_path='cpp', cpp_args=''):
|
| 19 |
+
""" Preprocess a file using cpp.
|
| 20 |
+
|
| 21 |
+
filename:
|
| 22 |
+
Name of the file you want to preprocess.
|
| 23 |
+
|
| 24 |
+
cpp_path:
|
| 25 |
+
cpp_args:
|
| 26 |
+
Refer to the documentation of parse_file for the meaning of these
|
| 27 |
+
arguments.
|
| 28 |
+
|
| 29 |
+
When successful, returns the preprocessed file's contents.
|
| 30 |
+
Errors from cpp will be printed out.
|
| 31 |
+
"""
|
| 32 |
+
path_list = [cpp_path]
|
| 33 |
+
if isinstance(cpp_args, list):
|
| 34 |
+
path_list += cpp_args
|
| 35 |
+
elif cpp_args != '':
|
| 36 |
+
path_list += [cpp_args]
|
| 37 |
+
path_list += [filename]
|
| 38 |
+
|
| 39 |
+
try:
|
| 40 |
+
# Note the use of universal_newlines to treat all newlines
|
| 41 |
+
# as \n for Python's purpose
|
| 42 |
+
text = check_output(path_list, universal_newlines=True)
|
| 43 |
+
except OSError as e:
|
| 44 |
+
raise RuntimeError("Unable to invoke 'cpp'. " +
|
| 45 |
+
'Make sure its path was passed correctly\n' +
|
| 46 |
+
('Original error: %s' % e))
|
| 47 |
+
|
| 48 |
+
return text
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
|
| 52 |
+
parser=None, encoding=None):
|
| 53 |
+
""" Parse a C file using pycparser.
|
| 54 |
+
|
| 55 |
+
filename:
|
| 56 |
+
Name of the file you want to parse.
|
| 57 |
+
|
| 58 |
+
use_cpp:
|
| 59 |
+
Set to True if you want to execute the C pre-processor
|
| 60 |
+
on the file prior to parsing it.
|
| 61 |
+
|
| 62 |
+
cpp_path:
|
| 63 |
+
If use_cpp is True, this is the path to 'cpp' on your
|
| 64 |
+
system. If no path is provided, it attempts to just
|
| 65 |
+
execute 'cpp', so it must be in your PATH.
|
| 66 |
+
|
| 67 |
+
cpp_args:
|
| 68 |
+
If use_cpp is True, set this to the command line arguments strings
|
| 69 |
+
to cpp. Be careful with quotes - it's best to pass a raw string
|
| 70 |
+
(r'') here. For example:
|
| 71 |
+
r'-I../utils/fake_libc_include'
|
| 72 |
+
If several arguments are required, pass a list of strings.
|
| 73 |
+
|
| 74 |
+
encoding:
|
| 75 |
+
Encoding to use for the file to parse
|
| 76 |
+
|
| 77 |
+
parser:
|
| 78 |
+
Optional parser object to be used instead of the default CParser
|
| 79 |
+
|
| 80 |
+
When successful, an AST is returned. ParseError can be
|
| 81 |
+
thrown if the file doesn't parse successfully.
|
| 82 |
+
|
| 83 |
+
Errors from cpp will be printed out.
|
| 84 |
+
"""
|
| 85 |
+
if use_cpp:
|
| 86 |
+
text = preprocess_file(filename, cpp_path, cpp_args)
|
| 87 |
+
else:
|
| 88 |
+
with io.open(filename, encoding=encoding) as f:
|
| 89 |
+
text = f.read()
|
| 90 |
+
|
| 91 |
+
if parser is None:
|
| 92 |
+
parser = CParser()
|
| 93 |
+
return parser.parse(text, filename)
|
rtme/lib/python3.10/site-packages/pycparser/_ast_gen.py
ADDED
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#-----------------------------------------------------------------
|
| 2 |
+
# _ast_gen.py
|
| 3 |
+
#
|
| 4 |
+
# Generates the AST Node classes from a specification given in
|
| 5 |
+
# a configuration file
|
| 6 |
+
#
|
| 7 |
+
# The design of this module was inspired by astgen.py from the
|
| 8 |
+
# Python 2.5 code-base.
|
| 9 |
+
#
|
| 10 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 11 |
+
# License: BSD
|
| 12 |
+
#-----------------------------------------------------------------
|
| 13 |
+
from string import Template
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class ASTCodeGenerator(object):
|
| 17 |
+
def __init__(self, cfg_filename='_c_ast.cfg'):
|
| 18 |
+
""" Initialize the code generator from a configuration
|
| 19 |
+
file.
|
| 20 |
+
"""
|
| 21 |
+
self.cfg_filename = cfg_filename
|
| 22 |
+
self.node_cfg = [NodeCfg(name, contents)
|
| 23 |
+
for (name, contents) in self.parse_cfgfile(cfg_filename)]
|
| 24 |
+
|
| 25 |
+
def generate(self, file=None):
|
| 26 |
+
""" Generates the code into file, an open file buffer.
|
| 27 |
+
"""
|
| 28 |
+
src = Template(_PROLOGUE_COMMENT).substitute(
|
| 29 |
+
cfg_filename=self.cfg_filename)
|
| 30 |
+
|
| 31 |
+
src += _PROLOGUE_CODE
|
| 32 |
+
for node_cfg in self.node_cfg:
|
| 33 |
+
src += node_cfg.generate_source() + '\n\n'
|
| 34 |
+
|
| 35 |
+
file.write(src)
|
| 36 |
+
|
| 37 |
+
def parse_cfgfile(self, filename):
|
| 38 |
+
""" Parse the configuration file and yield pairs of
|
| 39 |
+
(name, contents) for each node.
|
| 40 |
+
"""
|
| 41 |
+
with open(filename, "r") as f:
|
| 42 |
+
for line in f:
|
| 43 |
+
line = line.strip()
|
| 44 |
+
if not line or line.startswith('#'):
|
| 45 |
+
continue
|
| 46 |
+
colon_i = line.find(':')
|
| 47 |
+
lbracket_i = line.find('[')
|
| 48 |
+
rbracket_i = line.find(']')
|
| 49 |
+
if colon_i < 1 or lbracket_i <= colon_i or rbracket_i <= lbracket_i:
|
| 50 |
+
raise RuntimeError("Invalid line in %s:\n%s\n" % (filename, line))
|
| 51 |
+
|
| 52 |
+
name = line[:colon_i]
|
| 53 |
+
val = line[lbracket_i + 1:rbracket_i]
|
| 54 |
+
vallist = [v.strip() for v in val.split(',')] if val else []
|
| 55 |
+
yield name, vallist
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
class NodeCfg(object):
|
| 59 |
+
""" Node configuration.
|
| 60 |
+
|
| 61 |
+
name: node name
|
| 62 |
+
contents: a list of contents - attributes and child nodes
|
| 63 |
+
See comment at the top of the configuration file for details.
|
| 64 |
+
"""
|
| 65 |
+
|
| 66 |
+
def __init__(self, name, contents):
|
| 67 |
+
self.name = name
|
| 68 |
+
self.all_entries = []
|
| 69 |
+
self.attr = []
|
| 70 |
+
self.child = []
|
| 71 |
+
self.seq_child = []
|
| 72 |
+
|
| 73 |
+
for entry in contents:
|
| 74 |
+
clean_entry = entry.rstrip('*')
|
| 75 |
+
self.all_entries.append(clean_entry)
|
| 76 |
+
|
| 77 |
+
if entry.endswith('**'):
|
| 78 |
+
self.seq_child.append(clean_entry)
|
| 79 |
+
elif entry.endswith('*'):
|
| 80 |
+
self.child.append(clean_entry)
|
| 81 |
+
else:
|
| 82 |
+
self.attr.append(entry)
|
| 83 |
+
|
| 84 |
+
def generate_source(self):
|
| 85 |
+
src = self._gen_init()
|
| 86 |
+
src += '\n' + self._gen_children()
|
| 87 |
+
src += '\n' + self._gen_iter()
|
| 88 |
+
src += '\n' + self._gen_attr_names()
|
| 89 |
+
return src
|
| 90 |
+
|
| 91 |
+
def _gen_init(self):
|
| 92 |
+
src = "class %s(Node):\n" % self.name
|
| 93 |
+
|
| 94 |
+
if self.all_entries:
|
| 95 |
+
args = ', '.join(self.all_entries)
|
| 96 |
+
slots = ', '.join("'{0}'".format(e) for e in self.all_entries)
|
| 97 |
+
slots += ", 'coord', '__weakref__'"
|
| 98 |
+
arglist = '(self, %s, coord=None)' % args
|
| 99 |
+
else:
|
| 100 |
+
slots = "'coord', '__weakref__'"
|
| 101 |
+
arglist = '(self, coord=None)'
|
| 102 |
+
|
| 103 |
+
src += " __slots__ = (%s)\n" % slots
|
| 104 |
+
src += " def __init__%s:\n" % arglist
|
| 105 |
+
|
| 106 |
+
for name in self.all_entries + ['coord']:
|
| 107 |
+
src += " self.%s = %s\n" % (name, name)
|
| 108 |
+
|
| 109 |
+
return src
|
| 110 |
+
|
| 111 |
+
def _gen_children(self):
|
| 112 |
+
src = ' def children(self):\n'
|
| 113 |
+
|
| 114 |
+
if self.all_entries:
|
| 115 |
+
src += ' nodelist = []\n'
|
| 116 |
+
|
| 117 |
+
for child in self.child:
|
| 118 |
+
src += (
|
| 119 |
+
' if self.%(child)s is not None:' +
|
| 120 |
+
' nodelist.append(("%(child)s", self.%(child)s))\n') % (
|
| 121 |
+
dict(child=child))
|
| 122 |
+
|
| 123 |
+
for seq_child in self.seq_child:
|
| 124 |
+
src += (
|
| 125 |
+
' for i, child in enumerate(self.%(child)s or []):\n'
|
| 126 |
+
' nodelist.append(("%(child)s[%%d]" %% i, child))\n') % (
|
| 127 |
+
dict(child=seq_child))
|
| 128 |
+
|
| 129 |
+
src += ' return tuple(nodelist)\n'
|
| 130 |
+
else:
|
| 131 |
+
src += ' return ()\n'
|
| 132 |
+
|
| 133 |
+
return src
|
| 134 |
+
|
| 135 |
+
def _gen_iter(self):
|
| 136 |
+
src = ' def __iter__(self):\n'
|
| 137 |
+
|
| 138 |
+
if self.all_entries:
|
| 139 |
+
for child in self.child:
|
| 140 |
+
src += (
|
| 141 |
+
' if self.%(child)s is not None:\n' +
|
| 142 |
+
' yield self.%(child)s\n') % (dict(child=child))
|
| 143 |
+
|
| 144 |
+
for seq_child in self.seq_child:
|
| 145 |
+
src += (
|
| 146 |
+
' for child in (self.%(child)s or []):\n'
|
| 147 |
+
' yield child\n') % (dict(child=seq_child))
|
| 148 |
+
|
| 149 |
+
if not (self.child or self.seq_child):
|
| 150 |
+
# Empty generator
|
| 151 |
+
src += (
|
| 152 |
+
' return\n' +
|
| 153 |
+
' yield\n')
|
| 154 |
+
else:
|
| 155 |
+
# Empty generator
|
| 156 |
+
src += (
|
| 157 |
+
' return\n' +
|
| 158 |
+
' yield\n')
|
| 159 |
+
|
| 160 |
+
return src
|
| 161 |
+
|
| 162 |
+
def _gen_attr_names(self):
|
| 163 |
+
src = " attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')'
|
| 164 |
+
return src
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
_PROLOGUE_COMMENT = \
|
| 168 |
+
r'''#-----------------------------------------------------------------
|
| 169 |
+
# ** ATTENTION **
|
| 170 |
+
# This code was automatically generated from the file:
|
| 171 |
+
# $cfg_filename
|
| 172 |
+
#
|
| 173 |
+
# Do not modify it directly. Modify the configuration file and
|
| 174 |
+
# run the generator again.
|
| 175 |
+
# ** ** *** ** **
|
| 176 |
+
#
|
| 177 |
+
# pycparser: c_ast.py
|
| 178 |
+
#
|
| 179 |
+
# AST Node classes.
|
| 180 |
+
#
|
| 181 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 182 |
+
# License: BSD
|
| 183 |
+
#-----------------------------------------------------------------
|
| 184 |
+
|
| 185 |
+
'''
|
| 186 |
+
|
| 187 |
+
_PROLOGUE_CODE = r'''
|
| 188 |
+
import sys
|
| 189 |
+
|
| 190 |
+
def _repr(obj):
|
| 191 |
+
"""
|
| 192 |
+
Get the representation of an object, with dedicated pprint-like format for lists.
|
| 193 |
+
"""
|
| 194 |
+
if isinstance(obj, list):
|
| 195 |
+
return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]'
|
| 196 |
+
else:
|
| 197 |
+
return repr(obj)
|
| 198 |
+
|
| 199 |
+
class Node(object):
|
| 200 |
+
__slots__ = ()
|
| 201 |
+
""" Abstract base class for AST nodes.
|
| 202 |
+
"""
|
| 203 |
+
def __repr__(self):
|
| 204 |
+
""" Generates a python representation of the current node
|
| 205 |
+
"""
|
| 206 |
+
result = self.__class__.__name__ + '('
|
| 207 |
+
|
| 208 |
+
indent = ''
|
| 209 |
+
separator = ''
|
| 210 |
+
for name in self.__slots__[:-2]:
|
| 211 |
+
result += separator
|
| 212 |
+
result += indent
|
| 213 |
+
result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__)))))
|
| 214 |
+
|
| 215 |
+
separator = ','
|
| 216 |
+
indent = '\n ' + (' ' * len(self.__class__.__name__))
|
| 217 |
+
|
| 218 |
+
result += indent + ')'
|
| 219 |
+
|
| 220 |
+
return result
|
| 221 |
+
|
| 222 |
+
def children(self):
|
| 223 |
+
""" A sequence of all children that are Nodes
|
| 224 |
+
"""
|
| 225 |
+
pass
|
| 226 |
+
|
| 227 |
+
def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
|
| 228 |
+
""" Pretty print the Node and all its attributes and
|
| 229 |
+
children (recursively) to a buffer.
|
| 230 |
+
|
| 231 |
+
buf:
|
| 232 |
+
Open IO buffer into which the Node is printed.
|
| 233 |
+
|
| 234 |
+
offset:
|
| 235 |
+
Initial offset (amount of leading spaces)
|
| 236 |
+
|
| 237 |
+
attrnames:
|
| 238 |
+
True if you want to see the attribute names in
|
| 239 |
+
name=value pairs. False to only see the values.
|
| 240 |
+
|
| 241 |
+
nodenames:
|
| 242 |
+
True if you want to see the actual node names
|
| 243 |
+
within their parents.
|
| 244 |
+
|
| 245 |
+
showcoord:
|
| 246 |
+
Do you want the coordinates of each Node to be
|
| 247 |
+
displayed.
|
| 248 |
+
"""
|
| 249 |
+
lead = ' ' * offset
|
| 250 |
+
if nodenames and _my_node_name is not None:
|
| 251 |
+
buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ')
|
| 252 |
+
else:
|
| 253 |
+
buf.write(lead + self.__class__.__name__+ ': ')
|
| 254 |
+
|
| 255 |
+
if self.attr_names:
|
| 256 |
+
if attrnames:
|
| 257 |
+
nvlist = [(n, getattr(self,n)) for n in self.attr_names]
|
| 258 |
+
attrstr = ', '.join('%s=%s' % nv for nv in nvlist)
|
| 259 |
+
else:
|
| 260 |
+
vlist = [getattr(self, n) for n in self.attr_names]
|
| 261 |
+
attrstr = ', '.join('%s' % v for v in vlist)
|
| 262 |
+
buf.write(attrstr)
|
| 263 |
+
|
| 264 |
+
if showcoord:
|
| 265 |
+
buf.write(' (at %s)' % self.coord)
|
| 266 |
+
buf.write('\n')
|
| 267 |
+
|
| 268 |
+
for (child_name, child) in self.children():
|
| 269 |
+
child.show(
|
| 270 |
+
buf,
|
| 271 |
+
offset=offset + 2,
|
| 272 |
+
attrnames=attrnames,
|
| 273 |
+
nodenames=nodenames,
|
| 274 |
+
showcoord=showcoord,
|
| 275 |
+
_my_node_name=child_name)
|
| 276 |
+
|
| 277 |
+
|
| 278 |
+
class NodeVisitor(object):
|
| 279 |
+
""" A base NodeVisitor class for visiting c_ast nodes.
|
| 280 |
+
Subclass it and define your own visit_XXX methods, where
|
| 281 |
+
XXX is the class name you want to visit with these
|
| 282 |
+
methods.
|
| 283 |
+
|
| 284 |
+
For example:
|
| 285 |
+
|
| 286 |
+
class ConstantVisitor(NodeVisitor):
|
| 287 |
+
def __init__(self):
|
| 288 |
+
self.values = []
|
| 289 |
+
|
| 290 |
+
def visit_Constant(self, node):
|
| 291 |
+
self.values.append(node.value)
|
| 292 |
+
|
| 293 |
+
Creates a list of values of all the constant nodes
|
| 294 |
+
encountered below the given node. To use it:
|
| 295 |
+
|
| 296 |
+
cv = ConstantVisitor()
|
| 297 |
+
cv.visit(node)
|
| 298 |
+
|
| 299 |
+
Notes:
|
| 300 |
+
|
| 301 |
+
* generic_visit() will be called for AST nodes for which
|
| 302 |
+
no visit_XXX method was defined.
|
| 303 |
+
* The children of nodes for which a visit_XXX was
|
| 304 |
+
defined will not be visited - if you need this, call
|
| 305 |
+
generic_visit() on the node.
|
| 306 |
+
You can use:
|
| 307 |
+
NodeVisitor.generic_visit(self, node)
|
| 308 |
+
* Modeled after Python's own AST visiting facilities
|
| 309 |
+
(the ast module of Python 3.0)
|
| 310 |
+
"""
|
| 311 |
+
|
| 312 |
+
_method_cache = None
|
| 313 |
+
|
| 314 |
+
def visit(self, node):
|
| 315 |
+
""" Visit a node.
|
| 316 |
+
"""
|
| 317 |
+
|
| 318 |
+
if self._method_cache is None:
|
| 319 |
+
self._method_cache = {}
|
| 320 |
+
|
| 321 |
+
visitor = self._method_cache.get(node.__class__.__name__, None)
|
| 322 |
+
if visitor is None:
|
| 323 |
+
method = 'visit_' + node.__class__.__name__
|
| 324 |
+
visitor = getattr(self, method, self.generic_visit)
|
| 325 |
+
self._method_cache[node.__class__.__name__] = visitor
|
| 326 |
+
|
| 327 |
+
return visitor(node)
|
| 328 |
+
|
| 329 |
+
def generic_visit(self, node):
|
| 330 |
+
""" Called if no explicit visitor function exists for a
|
| 331 |
+
node. Implements preorder visiting of the node.
|
| 332 |
+
"""
|
| 333 |
+
for c in node:
|
| 334 |
+
self.visit(c)
|
| 335 |
+
|
| 336 |
+
'''
|
rtme/lib/python3.10/site-packages/pycparser/_build_tables.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#-----------------------------------------------------------------
|
| 2 |
+
# pycparser: _build_tables.py
|
| 3 |
+
#
|
| 4 |
+
# A dummy for generating the lexing/parsing tables and and
|
| 5 |
+
# compiling them into .pyc for faster execution in optimized mode.
|
| 6 |
+
# Also generates AST code from the configuration file.
|
| 7 |
+
# Should be called from the pycparser directory.
|
| 8 |
+
#
|
| 9 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 10 |
+
# License: BSD
|
| 11 |
+
#-----------------------------------------------------------------
|
| 12 |
+
|
| 13 |
+
# Insert '.' and '..' as first entries to the search path for modules.
|
| 14 |
+
# Restricted environments like embeddable python do not include the
|
| 15 |
+
# current working directory on startup.
|
| 16 |
+
import importlib
|
| 17 |
+
import sys
|
| 18 |
+
sys.path[0:0] = ['.', '..']
|
| 19 |
+
|
| 20 |
+
# Generate c_ast.py
|
| 21 |
+
from _ast_gen import ASTCodeGenerator
|
| 22 |
+
ast_gen = ASTCodeGenerator('_c_ast.cfg')
|
| 23 |
+
ast_gen.generate(open('c_ast.py', 'w'))
|
| 24 |
+
|
| 25 |
+
from pycparser import c_parser
|
| 26 |
+
|
| 27 |
+
# Generates the tables
|
| 28 |
+
#
|
| 29 |
+
c_parser.CParser(
|
| 30 |
+
lex_optimize=True,
|
| 31 |
+
yacc_debug=False,
|
| 32 |
+
yacc_optimize=True)
|
| 33 |
+
|
| 34 |
+
# Load to compile into .pyc
|
| 35 |
+
#
|
| 36 |
+
importlib.invalidate_caches()
|
| 37 |
+
|
| 38 |
+
import lextab
|
| 39 |
+
import yacctab
|
| 40 |
+
import c_ast
|
rtme/lib/python3.10/site-packages/pycparser/_c_ast.cfg
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#-----------------------------------------------------------------
|
| 2 |
+
# pycparser: _c_ast.cfg
|
| 3 |
+
#
|
| 4 |
+
# Defines the AST Node classes used in pycparser.
|
| 5 |
+
#
|
| 6 |
+
# Each entry is a Node sub-class name, listing the attributes
|
| 7 |
+
# and child nodes of the class:
|
| 8 |
+
# <name>* - a child node
|
| 9 |
+
# <name>** - a sequence of child nodes
|
| 10 |
+
# <name> - an attribute
|
| 11 |
+
#
|
| 12 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 13 |
+
# License: BSD
|
| 14 |
+
#-----------------------------------------------------------------
|
| 15 |
+
|
| 16 |
+
# ArrayDecl is a nested declaration of an array with the given type.
|
| 17 |
+
# dim: the dimension (for example, constant 42)
|
| 18 |
+
# dim_quals: list of dimension qualifiers, to support C99's allowing 'const'
|
| 19 |
+
# and 'static' within the array dimension in function declarations.
|
| 20 |
+
ArrayDecl: [type*, dim*, dim_quals]
|
| 21 |
+
|
| 22 |
+
ArrayRef: [name*, subscript*]
|
| 23 |
+
|
| 24 |
+
# op: =, +=, /= etc.
|
| 25 |
+
#
|
| 26 |
+
Assignment: [op, lvalue*, rvalue*]
|
| 27 |
+
|
| 28 |
+
Alignas: [alignment*]
|
| 29 |
+
|
| 30 |
+
BinaryOp: [op, left*, right*]
|
| 31 |
+
|
| 32 |
+
Break: []
|
| 33 |
+
|
| 34 |
+
Case: [expr*, stmts**]
|
| 35 |
+
|
| 36 |
+
Cast: [to_type*, expr*]
|
| 37 |
+
|
| 38 |
+
# Compound statement in C99 is a list of block items (declarations or
|
| 39 |
+
# statements).
|
| 40 |
+
#
|
| 41 |
+
Compound: [block_items**]
|
| 42 |
+
|
| 43 |
+
# Compound literal (anonymous aggregate) for C99.
|
| 44 |
+
# (type-name) {initializer_list}
|
| 45 |
+
# type: the typename
|
| 46 |
+
# init: InitList for the initializer list
|
| 47 |
+
#
|
| 48 |
+
CompoundLiteral: [type*, init*]
|
| 49 |
+
|
| 50 |
+
# type: int, char, float, string, etc.
|
| 51 |
+
#
|
| 52 |
+
Constant: [type, value]
|
| 53 |
+
|
| 54 |
+
Continue: []
|
| 55 |
+
|
| 56 |
+
# name: the variable being declared
|
| 57 |
+
# quals: list of qualifiers (const, volatile)
|
| 58 |
+
# funcspec: list function specifiers (i.e. inline in C99)
|
| 59 |
+
# storage: list of storage specifiers (extern, register, etc.)
|
| 60 |
+
# type: declaration type (probably nested with all the modifiers)
|
| 61 |
+
# init: initialization value, or None
|
| 62 |
+
# bitsize: bit field size, or None
|
| 63 |
+
#
|
| 64 |
+
Decl: [name, quals, align, storage, funcspec, type*, init*, bitsize*]
|
| 65 |
+
|
| 66 |
+
DeclList: [decls**]
|
| 67 |
+
|
| 68 |
+
Default: [stmts**]
|
| 69 |
+
|
| 70 |
+
DoWhile: [cond*, stmt*]
|
| 71 |
+
|
| 72 |
+
# Represents the ellipsis (...) parameter in a function
|
| 73 |
+
# declaration
|
| 74 |
+
#
|
| 75 |
+
EllipsisParam: []
|
| 76 |
+
|
| 77 |
+
# An empty statement (a semicolon ';' on its own)
|
| 78 |
+
#
|
| 79 |
+
EmptyStatement: []
|
| 80 |
+
|
| 81 |
+
# Enumeration type specifier
|
| 82 |
+
# name: an optional ID
|
| 83 |
+
# values: an EnumeratorList
|
| 84 |
+
#
|
| 85 |
+
Enum: [name, values*]
|
| 86 |
+
|
| 87 |
+
# A name/value pair for enumeration values
|
| 88 |
+
#
|
| 89 |
+
Enumerator: [name, value*]
|
| 90 |
+
|
| 91 |
+
# A list of enumerators
|
| 92 |
+
#
|
| 93 |
+
EnumeratorList: [enumerators**]
|
| 94 |
+
|
| 95 |
+
# A list of expressions separated by the comma operator.
|
| 96 |
+
#
|
| 97 |
+
ExprList: [exprs**]
|
| 98 |
+
|
| 99 |
+
# This is the top of the AST, representing a single C file (a
|
| 100 |
+
# translation unit in K&R jargon). It contains a list of
|
| 101 |
+
# "external-declaration"s, which is either declarations (Decl),
|
| 102 |
+
# Typedef or function definitions (FuncDef).
|
| 103 |
+
#
|
| 104 |
+
FileAST: [ext**]
|
| 105 |
+
|
| 106 |
+
# for (init; cond; next) stmt
|
| 107 |
+
#
|
| 108 |
+
For: [init*, cond*, next*, stmt*]
|
| 109 |
+
|
| 110 |
+
# name: Id
|
| 111 |
+
# args: ExprList
|
| 112 |
+
#
|
| 113 |
+
FuncCall: [name*, args*]
|
| 114 |
+
|
| 115 |
+
# type <decl>(args)
|
| 116 |
+
#
|
| 117 |
+
FuncDecl: [args*, type*]
|
| 118 |
+
|
| 119 |
+
# Function definition: a declarator for the function name and
|
| 120 |
+
# a body, which is a compound statement.
|
| 121 |
+
# There's an optional list of parameter declarations for old
|
| 122 |
+
# K&R-style definitions
|
| 123 |
+
#
|
| 124 |
+
FuncDef: [decl*, param_decls**, body*]
|
| 125 |
+
|
| 126 |
+
Goto: [name]
|
| 127 |
+
|
| 128 |
+
ID: [name]
|
| 129 |
+
|
| 130 |
+
# Holder for types that are a simple identifier (e.g. the built
|
| 131 |
+
# ins void, char etc. and typedef-defined types)
|
| 132 |
+
#
|
| 133 |
+
IdentifierType: [names]
|
| 134 |
+
|
| 135 |
+
If: [cond*, iftrue*, iffalse*]
|
| 136 |
+
|
| 137 |
+
# An initialization list used for compound literals.
|
| 138 |
+
#
|
| 139 |
+
InitList: [exprs**]
|
| 140 |
+
|
| 141 |
+
Label: [name, stmt*]
|
| 142 |
+
|
| 143 |
+
# A named initializer for C99.
|
| 144 |
+
# The name of a NamedInitializer is a sequence of Nodes, because
|
| 145 |
+
# names can be hierarchical and contain constant expressions.
|
| 146 |
+
#
|
| 147 |
+
NamedInitializer: [name**, expr*]
|
| 148 |
+
|
| 149 |
+
# a list of comma separated function parameter declarations
|
| 150 |
+
#
|
| 151 |
+
ParamList: [params**]
|
| 152 |
+
|
| 153 |
+
PtrDecl: [quals, type*]
|
| 154 |
+
|
| 155 |
+
Return: [expr*]
|
| 156 |
+
|
| 157 |
+
StaticAssert: [cond*, message*]
|
| 158 |
+
|
| 159 |
+
# name: struct tag name
|
| 160 |
+
# decls: declaration of members
|
| 161 |
+
#
|
| 162 |
+
Struct: [name, decls**]
|
| 163 |
+
|
| 164 |
+
# type: . or ->
|
| 165 |
+
# name.field or name->field
|
| 166 |
+
#
|
| 167 |
+
StructRef: [name*, type, field*]
|
| 168 |
+
|
| 169 |
+
Switch: [cond*, stmt*]
|
| 170 |
+
|
| 171 |
+
# cond ? iftrue : iffalse
|
| 172 |
+
#
|
| 173 |
+
TernaryOp: [cond*, iftrue*, iffalse*]
|
| 174 |
+
|
| 175 |
+
# A base type declaration
|
| 176 |
+
#
|
| 177 |
+
TypeDecl: [declname, quals, align, type*]
|
| 178 |
+
|
| 179 |
+
# A typedef declaration.
|
| 180 |
+
# Very similar to Decl, but without some attributes
|
| 181 |
+
#
|
| 182 |
+
Typedef: [name, quals, storage, type*]
|
| 183 |
+
|
| 184 |
+
Typename: [name, quals, align, type*]
|
| 185 |
+
|
| 186 |
+
UnaryOp: [op, expr*]
|
| 187 |
+
|
| 188 |
+
# name: union tag name
|
| 189 |
+
# decls: declaration of members
|
| 190 |
+
#
|
| 191 |
+
Union: [name, decls**]
|
| 192 |
+
|
| 193 |
+
While: [cond*, stmt*]
|
| 194 |
+
|
| 195 |
+
Pragma: [string]
|
rtme/lib/python3.10/site-packages/pycparser/ast_transforms.py
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#------------------------------------------------------------------------------
|
| 2 |
+
# pycparser: ast_transforms.py
|
| 3 |
+
#
|
| 4 |
+
# Some utilities used by the parser to create a friendlier AST.
|
| 5 |
+
#
|
| 6 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 7 |
+
# License: BSD
|
| 8 |
+
#------------------------------------------------------------------------------
|
| 9 |
+
|
| 10 |
+
from . import c_ast
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
def fix_switch_cases(switch_node):
|
| 14 |
+
""" The 'case' statements in a 'switch' come out of parsing with one
|
| 15 |
+
child node, so subsequent statements are just tucked to the parent
|
| 16 |
+
Compound. Additionally, consecutive (fall-through) case statements
|
| 17 |
+
come out messy. This is a peculiarity of the C grammar. The following:
|
| 18 |
+
|
| 19 |
+
switch (myvar) {
|
| 20 |
+
case 10:
|
| 21 |
+
k = 10;
|
| 22 |
+
p = k + 1;
|
| 23 |
+
return 10;
|
| 24 |
+
case 20:
|
| 25 |
+
case 30:
|
| 26 |
+
return 20;
|
| 27 |
+
default:
|
| 28 |
+
break;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
Creates this tree (pseudo-dump):
|
| 32 |
+
|
| 33 |
+
Switch
|
| 34 |
+
ID: myvar
|
| 35 |
+
Compound:
|
| 36 |
+
Case 10:
|
| 37 |
+
k = 10
|
| 38 |
+
p = k + 1
|
| 39 |
+
return 10
|
| 40 |
+
Case 20:
|
| 41 |
+
Case 30:
|
| 42 |
+
return 20
|
| 43 |
+
Default:
|
| 44 |
+
break
|
| 45 |
+
|
| 46 |
+
The goal of this transform is to fix this mess, turning it into the
|
| 47 |
+
following:
|
| 48 |
+
|
| 49 |
+
Switch
|
| 50 |
+
ID: myvar
|
| 51 |
+
Compound:
|
| 52 |
+
Case 10:
|
| 53 |
+
k = 10
|
| 54 |
+
p = k + 1
|
| 55 |
+
return 10
|
| 56 |
+
Case 20:
|
| 57 |
+
Case 30:
|
| 58 |
+
return 20
|
| 59 |
+
Default:
|
| 60 |
+
break
|
| 61 |
+
|
| 62 |
+
A fixed AST node is returned. The argument may be modified.
|
| 63 |
+
"""
|
| 64 |
+
assert isinstance(switch_node, c_ast.Switch)
|
| 65 |
+
if not isinstance(switch_node.stmt, c_ast.Compound):
|
| 66 |
+
return switch_node
|
| 67 |
+
|
| 68 |
+
# The new Compound child for the Switch, which will collect children in the
|
| 69 |
+
# correct order
|
| 70 |
+
new_compound = c_ast.Compound([], switch_node.stmt.coord)
|
| 71 |
+
|
| 72 |
+
# The last Case/Default node
|
| 73 |
+
last_case = None
|
| 74 |
+
|
| 75 |
+
# Goes over the children of the Compound below the Switch, adding them
|
| 76 |
+
# either directly below new_compound or below the last Case as appropriate
|
| 77 |
+
# (for `switch(cond) {}`, block_items would have been None)
|
| 78 |
+
for child in (switch_node.stmt.block_items or []):
|
| 79 |
+
if isinstance(child, (c_ast.Case, c_ast.Default)):
|
| 80 |
+
# If it's a Case/Default:
|
| 81 |
+
# 1. Add it to the Compound and mark as "last case"
|
| 82 |
+
# 2. If its immediate child is also a Case or Default, promote it
|
| 83 |
+
# to a sibling.
|
| 84 |
+
new_compound.block_items.append(child)
|
| 85 |
+
_extract_nested_case(child, new_compound.block_items)
|
| 86 |
+
last_case = new_compound.block_items[-1]
|
| 87 |
+
else:
|
| 88 |
+
# Other statements are added as children to the last case, if it
|
| 89 |
+
# exists.
|
| 90 |
+
if last_case is None:
|
| 91 |
+
new_compound.block_items.append(child)
|
| 92 |
+
else:
|
| 93 |
+
last_case.stmts.append(child)
|
| 94 |
+
|
| 95 |
+
switch_node.stmt = new_compound
|
| 96 |
+
return switch_node
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def _extract_nested_case(case_node, stmts_list):
|
| 100 |
+
""" Recursively extract consecutive Case statements that are made nested
|
| 101 |
+
by the parser and add them to the stmts_list.
|
| 102 |
+
"""
|
| 103 |
+
if isinstance(case_node.stmts[0], (c_ast.Case, c_ast.Default)):
|
| 104 |
+
stmts_list.append(case_node.stmts.pop())
|
| 105 |
+
_extract_nested_case(stmts_list[-1], stmts_list)
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
def fix_atomic_specifiers(decl):
|
| 109 |
+
""" Atomic specifiers like _Atomic(type) are unusually structured,
|
| 110 |
+
conferring a qualifier upon the contained type.
|
| 111 |
+
|
| 112 |
+
This function fixes a decl with atomic specifiers to have a sane AST
|
| 113 |
+
structure, by removing spurious Typename->TypeDecl pairs and attaching
|
| 114 |
+
the _Atomic qualifier in the right place.
|
| 115 |
+
"""
|
| 116 |
+
# There can be multiple levels of _Atomic in a decl; fix them until a
|
| 117 |
+
# fixed point is reached.
|
| 118 |
+
while True:
|
| 119 |
+
decl, found = _fix_atomic_specifiers_once(decl)
|
| 120 |
+
if not found:
|
| 121 |
+
break
|
| 122 |
+
|
| 123 |
+
# Make sure to add an _Atomic qual on the topmost decl if needed. Also
|
| 124 |
+
# restore the declname on the innermost TypeDecl (it gets placed in the
|
| 125 |
+
# wrong place during construction).
|
| 126 |
+
typ = decl
|
| 127 |
+
while not isinstance(typ, c_ast.TypeDecl):
|
| 128 |
+
try:
|
| 129 |
+
typ = typ.type
|
| 130 |
+
except AttributeError:
|
| 131 |
+
return decl
|
| 132 |
+
if '_Atomic' in typ.quals and '_Atomic' not in decl.quals:
|
| 133 |
+
decl.quals.append('_Atomic')
|
| 134 |
+
if typ.declname is None:
|
| 135 |
+
typ.declname = decl.name
|
| 136 |
+
|
| 137 |
+
return decl
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
def _fix_atomic_specifiers_once(decl):
|
| 141 |
+
""" Performs one 'fix' round of atomic specifiers.
|
| 142 |
+
Returns (modified_decl, found) where found is True iff a fix was made.
|
| 143 |
+
"""
|
| 144 |
+
parent = decl
|
| 145 |
+
grandparent = None
|
| 146 |
+
node = decl.type
|
| 147 |
+
while node is not None:
|
| 148 |
+
if isinstance(node, c_ast.Typename) and '_Atomic' in node.quals:
|
| 149 |
+
break
|
| 150 |
+
try:
|
| 151 |
+
grandparent = parent
|
| 152 |
+
parent = node
|
| 153 |
+
node = node.type
|
| 154 |
+
except AttributeError:
|
| 155 |
+
# If we've reached a node without a `type` field, it means we won't
|
| 156 |
+
# find what we're looking for at this point; give up the search
|
| 157 |
+
# and return the original decl unmodified.
|
| 158 |
+
return decl, False
|
| 159 |
+
|
| 160 |
+
assert isinstance(parent, c_ast.TypeDecl)
|
| 161 |
+
grandparent.type = node.type
|
| 162 |
+
if '_Atomic' not in node.type.quals:
|
| 163 |
+
node.type.quals.append('_Atomic')
|
| 164 |
+
return decl, True
|
rtme/lib/python3.10/site-packages/pycparser/c_ast.py
ADDED
|
@@ -0,0 +1,1125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#-----------------------------------------------------------------
|
| 2 |
+
# ** ATTENTION **
|
| 3 |
+
# This code was automatically generated from the file:
|
| 4 |
+
# _c_ast.cfg
|
| 5 |
+
#
|
| 6 |
+
# Do not modify it directly. Modify the configuration file and
|
| 7 |
+
# run the generator again.
|
| 8 |
+
# ** ** *** ** **
|
| 9 |
+
#
|
| 10 |
+
# pycparser: c_ast.py
|
| 11 |
+
#
|
| 12 |
+
# AST Node classes.
|
| 13 |
+
#
|
| 14 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 15 |
+
# License: BSD
|
| 16 |
+
#-----------------------------------------------------------------
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
import sys
|
| 20 |
+
|
| 21 |
+
def _repr(obj):
|
| 22 |
+
"""
|
| 23 |
+
Get the representation of an object, with dedicated pprint-like format for lists.
|
| 24 |
+
"""
|
| 25 |
+
if isinstance(obj, list):
|
| 26 |
+
return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]'
|
| 27 |
+
else:
|
| 28 |
+
return repr(obj)
|
| 29 |
+
|
| 30 |
+
class Node(object):
|
| 31 |
+
__slots__ = ()
|
| 32 |
+
""" Abstract base class for AST nodes.
|
| 33 |
+
"""
|
| 34 |
+
def __repr__(self):
|
| 35 |
+
""" Generates a python representation of the current node
|
| 36 |
+
"""
|
| 37 |
+
result = self.__class__.__name__ + '('
|
| 38 |
+
|
| 39 |
+
indent = ''
|
| 40 |
+
separator = ''
|
| 41 |
+
for name in self.__slots__[:-2]:
|
| 42 |
+
result += separator
|
| 43 |
+
result += indent
|
| 44 |
+
result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__)))))
|
| 45 |
+
|
| 46 |
+
separator = ','
|
| 47 |
+
indent = '\n ' + (' ' * len(self.__class__.__name__))
|
| 48 |
+
|
| 49 |
+
result += indent + ')'
|
| 50 |
+
|
| 51 |
+
return result
|
| 52 |
+
|
| 53 |
+
def children(self):
|
| 54 |
+
""" A sequence of all children that are Nodes
|
| 55 |
+
"""
|
| 56 |
+
pass
|
| 57 |
+
|
| 58 |
+
def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
|
| 59 |
+
""" Pretty print the Node and all its attributes and
|
| 60 |
+
children (recursively) to a buffer.
|
| 61 |
+
|
| 62 |
+
buf:
|
| 63 |
+
Open IO buffer into which the Node is printed.
|
| 64 |
+
|
| 65 |
+
offset:
|
| 66 |
+
Initial offset (amount of leading spaces)
|
| 67 |
+
|
| 68 |
+
attrnames:
|
| 69 |
+
True if you want to see the attribute names in
|
| 70 |
+
name=value pairs. False to only see the values.
|
| 71 |
+
|
| 72 |
+
nodenames:
|
| 73 |
+
True if you want to see the actual node names
|
| 74 |
+
within their parents.
|
| 75 |
+
|
| 76 |
+
showcoord:
|
| 77 |
+
Do you want the coordinates of each Node to be
|
| 78 |
+
displayed.
|
| 79 |
+
"""
|
| 80 |
+
lead = ' ' * offset
|
| 81 |
+
if nodenames and _my_node_name is not None:
|
| 82 |
+
buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ')
|
| 83 |
+
else:
|
| 84 |
+
buf.write(lead + self.__class__.__name__+ ': ')
|
| 85 |
+
|
| 86 |
+
if self.attr_names:
|
| 87 |
+
if attrnames:
|
| 88 |
+
nvlist = [(n, getattr(self,n)) for n in self.attr_names]
|
| 89 |
+
attrstr = ', '.join('%s=%s' % nv for nv in nvlist)
|
| 90 |
+
else:
|
| 91 |
+
vlist = [getattr(self, n) for n in self.attr_names]
|
| 92 |
+
attrstr = ', '.join('%s' % v for v in vlist)
|
| 93 |
+
buf.write(attrstr)
|
| 94 |
+
|
| 95 |
+
if showcoord:
|
| 96 |
+
buf.write(' (at %s)' % self.coord)
|
| 97 |
+
buf.write('\n')
|
| 98 |
+
|
| 99 |
+
for (child_name, child) in self.children():
|
| 100 |
+
child.show(
|
| 101 |
+
buf,
|
| 102 |
+
offset=offset + 2,
|
| 103 |
+
attrnames=attrnames,
|
| 104 |
+
nodenames=nodenames,
|
| 105 |
+
showcoord=showcoord,
|
| 106 |
+
_my_node_name=child_name)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
class NodeVisitor(object):
|
| 110 |
+
""" A base NodeVisitor class for visiting c_ast nodes.
|
| 111 |
+
Subclass it and define your own visit_XXX methods, where
|
| 112 |
+
XXX is the class name you want to visit with these
|
| 113 |
+
methods.
|
| 114 |
+
|
| 115 |
+
For example:
|
| 116 |
+
|
| 117 |
+
class ConstantVisitor(NodeVisitor):
|
| 118 |
+
def __init__(self):
|
| 119 |
+
self.values = []
|
| 120 |
+
|
| 121 |
+
def visit_Constant(self, node):
|
| 122 |
+
self.values.append(node.value)
|
| 123 |
+
|
| 124 |
+
Creates a list of values of all the constant nodes
|
| 125 |
+
encountered below the given node. To use it:
|
| 126 |
+
|
| 127 |
+
cv = ConstantVisitor()
|
| 128 |
+
cv.visit(node)
|
| 129 |
+
|
| 130 |
+
Notes:
|
| 131 |
+
|
| 132 |
+
* generic_visit() will be called for AST nodes for which
|
| 133 |
+
no visit_XXX method was defined.
|
| 134 |
+
* The children of nodes for which a visit_XXX was
|
| 135 |
+
defined will not be visited - if you need this, call
|
| 136 |
+
generic_visit() on the node.
|
| 137 |
+
You can use:
|
| 138 |
+
NodeVisitor.generic_visit(self, node)
|
| 139 |
+
* Modeled after Python's own AST visiting facilities
|
| 140 |
+
(the ast module of Python 3.0)
|
| 141 |
+
"""
|
| 142 |
+
|
| 143 |
+
_method_cache = None
|
| 144 |
+
|
| 145 |
+
def visit(self, node):
|
| 146 |
+
""" Visit a node.
|
| 147 |
+
"""
|
| 148 |
+
|
| 149 |
+
if self._method_cache is None:
|
| 150 |
+
self._method_cache = {}
|
| 151 |
+
|
| 152 |
+
visitor = self._method_cache.get(node.__class__.__name__, None)
|
| 153 |
+
if visitor is None:
|
| 154 |
+
method = 'visit_' + node.__class__.__name__
|
| 155 |
+
visitor = getattr(self, method, self.generic_visit)
|
| 156 |
+
self._method_cache[node.__class__.__name__] = visitor
|
| 157 |
+
|
| 158 |
+
return visitor(node)
|
| 159 |
+
|
| 160 |
+
def generic_visit(self, node):
|
| 161 |
+
""" Called if no explicit visitor function exists for a
|
| 162 |
+
node. Implements preorder visiting of the node.
|
| 163 |
+
"""
|
| 164 |
+
for c in node:
|
| 165 |
+
self.visit(c)
|
| 166 |
+
|
| 167 |
+
class ArrayDecl(Node):
|
| 168 |
+
__slots__ = ('type', 'dim', 'dim_quals', 'coord', '__weakref__')
|
| 169 |
+
def __init__(self, type, dim, dim_quals, coord=None):
|
| 170 |
+
self.type = type
|
| 171 |
+
self.dim = dim
|
| 172 |
+
self.dim_quals = dim_quals
|
| 173 |
+
self.coord = coord
|
| 174 |
+
|
| 175 |
+
def children(self):
|
| 176 |
+
nodelist = []
|
| 177 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 178 |
+
if self.dim is not None: nodelist.append(("dim", self.dim))
|
| 179 |
+
return tuple(nodelist)
|
| 180 |
+
|
| 181 |
+
def __iter__(self):
|
| 182 |
+
if self.type is not None:
|
| 183 |
+
yield self.type
|
| 184 |
+
if self.dim is not None:
|
| 185 |
+
yield self.dim
|
| 186 |
+
|
| 187 |
+
attr_names = ('dim_quals', )
|
| 188 |
+
|
| 189 |
+
class ArrayRef(Node):
|
| 190 |
+
__slots__ = ('name', 'subscript', 'coord', '__weakref__')
|
| 191 |
+
def __init__(self, name, subscript, coord=None):
|
| 192 |
+
self.name = name
|
| 193 |
+
self.subscript = subscript
|
| 194 |
+
self.coord = coord
|
| 195 |
+
|
| 196 |
+
def children(self):
|
| 197 |
+
nodelist = []
|
| 198 |
+
if self.name is not None: nodelist.append(("name", self.name))
|
| 199 |
+
if self.subscript is not None: nodelist.append(("subscript", self.subscript))
|
| 200 |
+
return tuple(nodelist)
|
| 201 |
+
|
| 202 |
+
def __iter__(self):
|
| 203 |
+
if self.name is not None:
|
| 204 |
+
yield self.name
|
| 205 |
+
if self.subscript is not None:
|
| 206 |
+
yield self.subscript
|
| 207 |
+
|
| 208 |
+
attr_names = ()
|
| 209 |
+
|
| 210 |
+
class Assignment(Node):
|
| 211 |
+
__slots__ = ('op', 'lvalue', 'rvalue', 'coord', '__weakref__')
|
| 212 |
+
def __init__(self, op, lvalue, rvalue, coord=None):
|
| 213 |
+
self.op = op
|
| 214 |
+
self.lvalue = lvalue
|
| 215 |
+
self.rvalue = rvalue
|
| 216 |
+
self.coord = coord
|
| 217 |
+
|
| 218 |
+
def children(self):
|
| 219 |
+
nodelist = []
|
| 220 |
+
if self.lvalue is not None: nodelist.append(("lvalue", self.lvalue))
|
| 221 |
+
if self.rvalue is not None: nodelist.append(("rvalue", self.rvalue))
|
| 222 |
+
return tuple(nodelist)
|
| 223 |
+
|
| 224 |
+
def __iter__(self):
|
| 225 |
+
if self.lvalue is not None:
|
| 226 |
+
yield self.lvalue
|
| 227 |
+
if self.rvalue is not None:
|
| 228 |
+
yield self.rvalue
|
| 229 |
+
|
| 230 |
+
attr_names = ('op', )
|
| 231 |
+
|
| 232 |
+
class Alignas(Node):
|
| 233 |
+
__slots__ = ('alignment', 'coord', '__weakref__')
|
| 234 |
+
def __init__(self, alignment, coord=None):
|
| 235 |
+
self.alignment = alignment
|
| 236 |
+
self.coord = coord
|
| 237 |
+
|
| 238 |
+
def children(self):
|
| 239 |
+
nodelist = []
|
| 240 |
+
if self.alignment is not None: nodelist.append(("alignment", self.alignment))
|
| 241 |
+
return tuple(nodelist)
|
| 242 |
+
|
| 243 |
+
def __iter__(self):
|
| 244 |
+
if self.alignment is not None:
|
| 245 |
+
yield self.alignment
|
| 246 |
+
|
| 247 |
+
attr_names = ()
|
| 248 |
+
|
| 249 |
+
class BinaryOp(Node):
|
| 250 |
+
__slots__ = ('op', 'left', 'right', 'coord', '__weakref__')
|
| 251 |
+
def __init__(self, op, left, right, coord=None):
|
| 252 |
+
self.op = op
|
| 253 |
+
self.left = left
|
| 254 |
+
self.right = right
|
| 255 |
+
self.coord = coord
|
| 256 |
+
|
| 257 |
+
def children(self):
|
| 258 |
+
nodelist = []
|
| 259 |
+
if self.left is not None: nodelist.append(("left", self.left))
|
| 260 |
+
if self.right is not None: nodelist.append(("right", self.right))
|
| 261 |
+
return tuple(nodelist)
|
| 262 |
+
|
| 263 |
+
def __iter__(self):
|
| 264 |
+
if self.left is not None:
|
| 265 |
+
yield self.left
|
| 266 |
+
if self.right is not None:
|
| 267 |
+
yield self.right
|
| 268 |
+
|
| 269 |
+
attr_names = ('op', )
|
| 270 |
+
|
| 271 |
+
class Break(Node):
|
| 272 |
+
__slots__ = ('coord', '__weakref__')
|
| 273 |
+
def __init__(self, coord=None):
|
| 274 |
+
self.coord = coord
|
| 275 |
+
|
| 276 |
+
def children(self):
|
| 277 |
+
return ()
|
| 278 |
+
|
| 279 |
+
def __iter__(self):
|
| 280 |
+
return
|
| 281 |
+
yield
|
| 282 |
+
|
| 283 |
+
attr_names = ()
|
| 284 |
+
|
| 285 |
+
class Case(Node):
|
| 286 |
+
__slots__ = ('expr', 'stmts', 'coord', '__weakref__')
|
| 287 |
+
def __init__(self, expr, stmts, coord=None):
|
| 288 |
+
self.expr = expr
|
| 289 |
+
self.stmts = stmts
|
| 290 |
+
self.coord = coord
|
| 291 |
+
|
| 292 |
+
def children(self):
|
| 293 |
+
nodelist = []
|
| 294 |
+
if self.expr is not None: nodelist.append(("expr", self.expr))
|
| 295 |
+
for i, child in enumerate(self.stmts or []):
|
| 296 |
+
nodelist.append(("stmts[%d]" % i, child))
|
| 297 |
+
return tuple(nodelist)
|
| 298 |
+
|
| 299 |
+
def __iter__(self):
|
| 300 |
+
if self.expr is not None:
|
| 301 |
+
yield self.expr
|
| 302 |
+
for child in (self.stmts or []):
|
| 303 |
+
yield child
|
| 304 |
+
|
| 305 |
+
attr_names = ()
|
| 306 |
+
|
| 307 |
+
class Cast(Node):
|
| 308 |
+
__slots__ = ('to_type', 'expr', 'coord', '__weakref__')
|
| 309 |
+
def __init__(self, to_type, expr, coord=None):
|
| 310 |
+
self.to_type = to_type
|
| 311 |
+
self.expr = expr
|
| 312 |
+
self.coord = coord
|
| 313 |
+
|
| 314 |
+
def children(self):
|
| 315 |
+
nodelist = []
|
| 316 |
+
if self.to_type is not None: nodelist.append(("to_type", self.to_type))
|
| 317 |
+
if self.expr is not None: nodelist.append(("expr", self.expr))
|
| 318 |
+
return tuple(nodelist)
|
| 319 |
+
|
| 320 |
+
def __iter__(self):
|
| 321 |
+
if self.to_type is not None:
|
| 322 |
+
yield self.to_type
|
| 323 |
+
if self.expr is not None:
|
| 324 |
+
yield self.expr
|
| 325 |
+
|
| 326 |
+
attr_names = ()
|
| 327 |
+
|
| 328 |
+
class Compound(Node):
|
| 329 |
+
__slots__ = ('block_items', 'coord', '__weakref__')
|
| 330 |
+
def __init__(self, block_items, coord=None):
|
| 331 |
+
self.block_items = block_items
|
| 332 |
+
self.coord = coord
|
| 333 |
+
|
| 334 |
+
def children(self):
|
| 335 |
+
nodelist = []
|
| 336 |
+
for i, child in enumerate(self.block_items or []):
|
| 337 |
+
nodelist.append(("block_items[%d]" % i, child))
|
| 338 |
+
return tuple(nodelist)
|
| 339 |
+
|
| 340 |
+
def __iter__(self):
|
| 341 |
+
for child in (self.block_items or []):
|
| 342 |
+
yield child
|
| 343 |
+
|
| 344 |
+
attr_names = ()
|
| 345 |
+
|
| 346 |
+
class CompoundLiteral(Node):
|
| 347 |
+
__slots__ = ('type', 'init', 'coord', '__weakref__')
|
| 348 |
+
def __init__(self, type, init, coord=None):
|
| 349 |
+
self.type = type
|
| 350 |
+
self.init = init
|
| 351 |
+
self.coord = coord
|
| 352 |
+
|
| 353 |
+
def children(self):
|
| 354 |
+
nodelist = []
|
| 355 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 356 |
+
if self.init is not None: nodelist.append(("init", self.init))
|
| 357 |
+
return tuple(nodelist)
|
| 358 |
+
|
| 359 |
+
def __iter__(self):
|
| 360 |
+
if self.type is not None:
|
| 361 |
+
yield self.type
|
| 362 |
+
if self.init is not None:
|
| 363 |
+
yield self.init
|
| 364 |
+
|
| 365 |
+
attr_names = ()
|
| 366 |
+
|
| 367 |
+
class Constant(Node):
|
| 368 |
+
__slots__ = ('type', 'value', 'coord', '__weakref__')
|
| 369 |
+
def __init__(self, type, value, coord=None):
|
| 370 |
+
self.type = type
|
| 371 |
+
self.value = value
|
| 372 |
+
self.coord = coord
|
| 373 |
+
|
| 374 |
+
def children(self):
|
| 375 |
+
nodelist = []
|
| 376 |
+
return tuple(nodelist)
|
| 377 |
+
|
| 378 |
+
def __iter__(self):
|
| 379 |
+
return
|
| 380 |
+
yield
|
| 381 |
+
|
| 382 |
+
attr_names = ('type', 'value', )
|
| 383 |
+
|
| 384 |
+
class Continue(Node):
|
| 385 |
+
__slots__ = ('coord', '__weakref__')
|
| 386 |
+
def __init__(self, coord=None):
|
| 387 |
+
self.coord = coord
|
| 388 |
+
|
| 389 |
+
def children(self):
|
| 390 |
+
return ()
|
| 391 |
+
|
| 392 |
+
def __iter__(self):
|
| 393 |
+
return
|
| 394 |
+
yield
|
| 395 |
+
|
| 396 |
+
attr_names = ()
|
| 397 |
+
|
| 398 |
+
class Decl(Node):
|
| 399 |
+
__slots__ = ('name', 'quals', 'align', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord', '__weakref__')
|
| 400 |
+
def __init__(self, name, quals, align, storage, funcspec, type, init, bitsize, coord=None):
|
| 401 |
+
self.name = name
|
| 402 |
+
self.quals = quals
|
| 403 |
+
self.align = align
|
| 404 |
+
self.storage = storage
|
| 405 |
+
self.funcspec = funcspec
|
| 406 |
+
self.type = type
|
| 407 |
+
self.init = init
|
| 408 |
+
self.bitsize = bitsize
|
| 409 |
+
self.coord = coord
|
| 410 |
+
|
| 411 |
+
def children(self):
|
| 412 |
+
nodelist = []
|
| 413 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 414 |
+
if self.init is not None: nodelist.append(("init", self.init))
|
| 415 |
+
if self.bitsize is not None: nodelist.append(("bitsize", self.bitsize))
|
| 416 |
+
return tuple(nodelist)
|
| 417 |
+
|
| 418 |
+
def __iter__(self):
|
| 419 |
+
if self.type is not None:
|
| 420 |
+
yield self.type
|
| 421 |
+
if self.init is not None:
|
| 422 |
+
yield self.init
|
| 423 |
+
if self.bitsize is not None:
|
| 424 |
+
yield self.bitsize
|
| 425 |
+
|
| 426 |
+
attr_names = ('name', 'quals', 'align', 'storage', 'funcspec', )
|
| 427 |
+
|
| 428 |
+
class DeclList(Node):
|
| 429 |
+
__slots__ = ('decls', 'coord', '__weakref__')
|
| 430 |
+
def __init__(self, decls, coord=None):
|
| 431 |
+
self.decls = decls
|
| 432 |
+
self.coord = coord
|
| 433 |
+
|
| 434 |
+
def children(self):
|
| 435 |
+
nodelist = []
|
| 436 |
+
for i, child in enumerate(self.decls or []):
|
| 437 |
+
nodelist.append(("decls[%d]" % i, child))
|
| 438 |
+
return tuple(nodelist)
|
| 439 |
+
|
| 440 |
+
def __iter__(self):
|
| 441 |
+
for child in (self.decls or []):
|
| 442 |
+
yield child
|
| 443 |
+
|
| 444 |
+
attr_names = ()
|
| 445 |
+
|
| 446 |
+
class Default(Node):
|
| 447 |
+
__slots__ = ('stmts', 'coord', '__weakref__')
|
| 448 |
+
def __init__(self, stmts, coord=None):
|
| 449 |
+
self.stmts = stmts
|
| 450 |
+
self.coord = coord
|
| 451 |
+
|
| 452 |
+
def children(self):
|
| 453 |
+
nodelist = []
|
| 454 |
+
for i, child in enumerate(self.stmts or []):
|
| 455 |
+
nodelist.append(("stmts[%d]" % i, child))
|
| 456 |
+
return tuple(nodelist)
|
| 457 |
+
|
| 458 |
+
def __iter__(self):
|
| 459 |
+
for child in (self.stmts or []):
|
| 460 |
+
yield child
|
| 461 |
+
|
| 462 |
+
attr_names = ()
|
| 463 |
+
|
| 464 |
+
class DoWhile(Node):
|
| 465 |
+
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
| 466 |
+
def __init__(self, cond, stmt, coord=None):
|
| 467 |
+
self.cond = cond
|
| 468 |
+
self.stmt = stmt
|
| 469 |
+
self.coord = coord
|
| 470 |
+
|
| 471 |
+
def children(self):
|
| 472 |
+
nodelist = []
|
| 473 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 474 |
+
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
| 475 |
+
return tuple(nodelist)
|
| 476 |
+
|
| 477 |
+
def __iter__(self):
|
| 478 |
+
if self.cond is not None:
|
| 479 |
+
yield self.cond
|
| 480 |
+
if self.stmt is not None:
|
| 481 |
+
yield self.stmt
|
| 482 |
+
|
| 483 |
+
attr_names = ()
|
| 484 |
+
|
| 485 |
+
class EllipsisParam(Node):
|
| 486 |
+
__slots__ = ('coord', '__weakref__')
|
| 487 |
+
def __init__(self, coord=None):
|
| 488 |
+
self.coord = coord
|
| 489 |
+
|
| 490 |
+
def children(self):
|
| 491 |
+
return ()
|
| 492 |
+
|
| 493 |
+
def __iter__(self):
|
| 494 |
+
return
|
| 495 |
+
yield
|
| 496 |
+
|
| 497 |
+
attr_names = ()
|
| 498 |
+
|
| 499 |
+
class EmptyStatement(Node):
|
| 500 |
+
__slots__ = ('coord', '__weakref__')
|
| 501 |
+
def __init__(self, coord=None):
|
| 502 |
+
self.coord = coord
|
| 503 |
+
|
| 504 |
+
def children(self):
|
| 505 |
+
return ()
|
| 506 |
+
|
| 507 |
+
def __iter__(self):
|
| 508 |
+
return
|
| 509 |
+
yield
|
| 510 |
+
|
| 511 |
+
attr_names = ()
|
| 512 |
+
|
| 513 |
+
class Enum(Node):
|
| 514 |
+
__slots__ = ('name', 'values', 'coord', '__weakref__')
|
| 515 |
+
def __init__(self, name, values, coord=None):
|
| 516 |
+
self.name = name
|
| 517 |
+
self.values = values
|
| 518 |
+
self.coord = coord
|
| 519 |
+
|
| 520 |
+
def children(self):
|
| 521 |
+
nodelist = []
|
| 522 |
+
if self.values is not None: nodelist.append(("values", self.values))
|
| 523 |
+
return tuple(nodelist)
|
| 524 |
+
|
| 525 |
+
def __iter__(self):
|
| 526 |
+
if self.values is not None:
|
| 527 |
+
yield self.values
|
| 528 |
+
|
| 529 |
+
attr_names = ('name', )
|
| 530 |
+
|
| 531 |
+
class Enumerator(Node):
|
| 532 |
+
__slots__ = ('name', 'value', 'coord', '__weakref__')
|
| 533 |
+
def __init__(self, name, value, coord=None):
|
| 534 |
+
self.name = name
|
| 535 |
+
self.value = value
|
| 536 |
+
self.coord = coord
|
| 537 |
+
|
| 538 |
+
def children(self):
|
| 539 |
+
nodelist = []
|
| 540 |
+
if self.value is not None: nodelist.append(("value", self.value))
|
| 541 |
+
return tuple(nodelist)
|
| 542 |
+
|
| 543 |
+
def __iter__(self):
|
| 544 |
+
if self.value is not None:
|
| 545 |
+
yield self.value
|
| 546 |
+
|
| 547 |
+
attr_names = ('name', )
|
| 548 |
+
|
| 549 |
+
class EnumeratorList(Node):
|
| 550 |
+
__slots__ = ('enumerators', 'coord', '__weakref__')
|
| 551 |
+
def __init__(self, enumerators, coord=None):
|
| 552 |
+
self.enumerators = enumerators
|
| 553 |
+
self.coord = coord
|
| 554 |
+
|
| 555 |
+
def children(self):
|
| 556 |
+
nodelist = []
|
| 557 |
+
for i, child in enumerate(self.enumerators or []):
|
| 558 |
+
nodelist.append(("enumerators[%d]" % i, child))
|
| 559 |
+
return tuple(nodelist)
|
| 560 |
+
|
| 561 |
+
def __iter__(self):
|
| 562 |
+
for child in (self.enumerators or []):
|
| 563 |
+
yield child
|
| 564 |
+
|
| 565 |
+
attr_names = ()
|
| 566 |
+
|
| 567 |
+
class ExprList(Node):
|
| 568 |
+
__slots__ = ('exprs', 'coord', '__weakref__')
|
| 569 |
+
def __init__(self, exprs, coord=None):
|
| 570 |
+
self.exprs = exprs
|
| 571 |
+
self.coord = coord
|
| 572 |
+
|
| 573 |
+
def children(self):
|
| 574 |
+
nodelist = []
|
| 575 |
+
for i, child in enumerate(self.exprs or []):
|
| 576 |
+
nodelist.append(("exprs[%d]" % i, child))
|
| 577 |
+
return tuple(nodelist)
|
| 578 |
+
|
| 579 |
+
def __iter__(self):
|
| 580 |
+
for child in (self.exprs or []):
|
| 581 |
+
yield child
|
| 582 |
+
|
| 583 |
+
attr_names = ()
|
| 584 |
+
|
| 585 |
+
class FileAST(Node):
|
| 586 |
+
__slots__ = ('ext', 'coord', '__weakref__')
|
| 587 |
+
def __init__(self, ext, coord=None):
|
| 588 |
+
self.ext = ext
|
| 589 |
+
self.coord = coord
|
| 590 |
+
|
| 591 |
+
def children(self):
|
| 592 |
+
nodelist = []
|
| 593 |
+
for i, child in enumerate(self.ext or []):
|
| 594 |
+
nodelist.append(("ext[%d]" % i, child))
|
| 595 |
+
return tuple(nodelist)
|
| 596 |
+
|
| 597 |
+
def __iter__(self):
|
| 598 |
+
for child in (self.ext or []):
|
| 599 |
+
yield child
|
| 600 |
+
|
| 601 |
+
attr_names = ()
|
| 602 |
+
|
| 603 |
+
class For(Node):
|
| 604 |
+
__slots__ = ('init', 'cond', 'next', 'stmt', 'coord', '__weakref__')
|
| 605 |
+
def __init__(self, init, cond, next, stmt, coord=None):
|
| 606 |
+
self.init = init
|
| 607 |
+
self.cond = cond
|
| 608 |
+
self.next = next
|
| 609 |
+
self.stmt = stmt
|
| 610 |
+
self.coord = coord
|
| 611 |
+
|
| 612 |
+
def children(self):
|
| 613 |
+
nodelist = []
|
| 614 |
+
if self.init is not None: nodelist.append(("init", self.init))
|
| 615 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 616 |
+
if self.next is not None: nodelist.append(("next", self.next))
|
| 617 |
+
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
| 618 |
+
return tuple(nodelist)
|
| 619 |
+
|
| 620 |
+
def __iter__(self):
|
| 621 |
+
if self.init is not None:
|
| 622 |
+
yield self.init
|
| 623 |
+
if self.cond is not None:
|
| 624 |
+
yield self.cond
|
| 625 |
+
if self.next is not None:
|
| 626 |
+
yield self.next
|
| 627 |
+
if self.stmt is not None:
|
| 628 |
+
yield self.stmt
|
| 629 |
+
|
| 630 |
+
attr_names = ()
|
| 631 |
+
|
| 632 |
+
class FuncCall(Node):
|
| 633 |
+
__slots__ = ('name', 'args', 'coord', '__weakref__')
|
| 634 |
+
def __init__(self, name, args, coord=None):
|
| 635 |
+
self.name = name
|
| 636 |
+
self.args = args
|
| 637 |
+
self.coord = coord
|
| 638 |
+
|
| 639 |
+
def children(self):
|
| 640 |
+
nodelist = []
|
| 641 |
+
if self.name is not None: nodelist.append(("name", self.name))
|
| 642 |
+
if self.args is not None: nodelist.append(("args", self.args))
|
| 643 |
+
return tuple(nodelist)
|
| 644 |
+
|
| 645 |
+
def __iter__(self):
|
| 646 |
+
if self.name is not None:
|
| 647 |
+
yield self.name
|
| 648 |
+
if self.args is not None:
|
| 649 |
+
yield self.args
|
| 650 |
+
|
| 651 |
+
attr_names = ()
|
| 652 |
+
|
| 653 |
+
class FuncDecl(Node):
|
| 654 |
+
__slots__ = ('args', 'type', 'coord', '__weakref__')
|
| 655 |
+
def __init__(self, args, type, coord=None):
|
| 656 |
+
self.args = args
|
| 657 |
+
self.type = type
|
| 658 |
+
self.coord = coord
|
| 659 |
+
|
| 660 |
+
def children(self):
|
| 661 |
+
nodelist = []
|
| 662 |
+
if self.args is not None: nodelist.append(("args", self.args))
|
| 663 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 664 |
+
return tuple(nodelist)
|
| 665 |
+
|
| 666 |
+
def __iter__(self):
|
| 667 |
+
if self.args is not None:
|
| 668 |
+
yield self.args
|
| 669 |
+
if self.type is not None:
|
| 670 |
+
yield self.type
|
| 671 |
+
|
| 672 |
+
attr_names = ()
|
| 673 |
+
|
| 674 |
+
class FuncDef(Node):
|
| 675 |
+
__slots__ = ('decl', 'param_decls', 'body', 'coord', '__weakref__')
|
| 676 |
+
def __init__(self, decl, param_decls, body, coord=None):
|
| 677 |
+
self.decl = decl
|
| 678 |
+
self.param_decls = param_decls
|
| 679 |
+
self.body = body
|
| 680 |
+
self.coord = coord
|
| 681 |
+
|
| 682 |
+
def children(self):
|
| 683 |
+
nodelist = []
|
| 684 |
+
if self.decl is not None: nodelist.append(("decl", self.decl))
|
| 685 |
+
if self.body is not None: nodelist.append(("body", self.body))
|
| 686 |
+
for i, child in enumerate(self.param_decls or []):
|
| 687 |
+
nodelist.append(("param_decls[%d]" % i, child))
|
| 688 |
+
return tuple(nodelist)
|
| 689 |
+
|
| 690 |
+
def __iter__(self):
|
| 691 |
+
if self.decl is not None:
|
| 692 |
+
yield self.decl
|
| 693 |
+
if self.body is not None:
|
| 694 |
+
yield self.body
|
| 695 |
+
for child in (self.param_decls or []):
|
| 696 |
+
yield child
|
| 697 |
+
|
| 698 |
+
attr_names = ()
|
| 699 |
+
|
| 700 |
+
class Goto(Node):
|
| 701 |
+
__slots__ = ('name', 'coord', '__weakref__')
|
| 702 |
+
def __init__(self, name, coord=None):
|
| 703 |
+
self.name = name
|
| 704 |
+
self.coord = coord
|
| 705 |
+
|
| 706 |
+
def children(self):
|
| 707 |
+
nodelist = []
|
| 708 |
+
return tuple(nodelist)
|
| 709 |
+
|
| 710 |
+
def __iter__(self):
|
| 711 |
+
return
|
| 712 |
+
yield
|
| 713 |
+
|
| 714 |
+
attr_names = ('name', )
|
| 715 |
+
|
| 716 |
+
class ID(Node):
|
| 717 |
+
__slots__ = ('name', 'coord', '__weakref__')
|
| 718 |
+
def __init__(self, name, coord=None):
|
| 719 |
+
self.name = name
|
| 720 |
+
self.coord = coord
|
| 721 |
+
|
| 722 |
+
def children(self):
|
| 723 |
+
nodelist = []
|
| 724 |
+
return tuple(nodelist)
|
| 725 |
+
|
| 726 |
+
def __iter__(self):
|
| 727 |
+
return
|
| 728 |
+
yield
|
| 729 |
+
|
| 730 |
+
attr_names = ('name', )
|
| 731 |
+
|
| 732 |
+
class IdentifierType(Node):
|
| 733 |
+
__slots__ = ('names', 'coord', '__weakref__')
|
| 734 |
+
def __init__(self, names, coord=None):
|
| 735 |
+
self.names = names
|
| 736 |
+
self.coord = coord
|
| 737 |
+
|
| 738 |
+
def children(self):
|
| 739 |
+
nodelist = []
|
| 740 |
+
return tuple(nodelist)
|
| 741 |
+
|
| 742 |
+
def __iter__(self):
|
| 743 |
+
return
|
| 744 |
+
yield
|
| 745 |
+
|
| 746 |
+
attr_names = ('names', )
|
| 747 |
+
|
| 748 |
+
class If(Node):
|
| 749 |
+
__slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
|
| 750 |
+
def __init__(self, cond, iftrue, iffalse, coord=None):
|
| 751 |
+
self.cond = cond
|
| 752 |
+
self.iftrue = iftrue
|
| 753 |
+
self.iffalse = iffalse
|
| 754 |
+
self.coord = coord
|
| 755 |
+
|
| 756 |
+
def children(self):
|
| 757 |
+
nodelist = []
|
| 758 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 759 |
+
if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue))
|
| 760 |
+
if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse))
|
| 761 |
+
return tuple(nodelist)
|
| 762 |
+
|
| 763 |
+
def __iter__(self):
|
| 764 |
+
if self.cond is not None:
|
| 765 |
+
yield self.cond
|
| 766 |
+
if self.iftrue is not None:
|
| 767 |
+
yield self.iftrue
|
| 768 |
+
if self.iffalse is not None:
|
| 769 |
+
yield self.iffalse
|
| 770 |
+
|
| 771 |
+
attr_names = ()
|
| 772 |
+
|
| 773 |
+
class InitList(Node):
|
| 774 |
+
__slots__ = ('exprs', 'coord', '__weakref__')
|
| 775 |
+
def __init__(self, exprs, coord=None):
|
| 776 |
+
self.exprs = exprs
|
| 777 |
+
self.coord = coord
|
| 778 |
+
|
| 779 |
+
def children(self):
|
| 780 |
+
nodelist = []
|
| 781 |
+
for i, child in enumerate(self.exprs or []):
|
| 782 |
+
nodelist.append(("exprs[%d]" % i, child))
|
| 783 |
+
return tuple(nodelist)
|
| 784 |
+
|
| 785 |
+
def __iter__(self):
|
| 786 |
+
for child in (self.exprs or []):
|
| 787 |
+
yield child
|
| 788 |
+
|
| 789 |
+
attr_names = ()
|
| 790 |
+
|
| 791 |
+
class Label(Node):
|
| 792 |
+
__slots__ = ('name', 'stmt', 'coord', '__weakref__')
|
| 793 |
+
def __init__(self, name, stmt, coord=None):
|
| 794 |
+
self.name = name
|
| 795 |
+
self.stmt = stmt
|
| 796 |
+
self.coord = coord
|
| 797 |
+
|
| 798 |
+
def children(self):
|
| 799 |
+
nodelist = []
|
| 800 |
+
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
| 801 |
+
return tuple(nodelist)
|
| 802 |
+
|
| 803 |
+
def __iter__(self):
|
| 804 |
+
if self.stmt is not None:
|
| 805 |
+
yield self.stmt
|
| 806 |
+
|
| 807 |
+
attr_names = ('name', )
|
| 808 |
+
|
| 809 |
+
class NamedInitializer(Node):
|
| 810 |
+
__slots__ = ('name', 'expr', 'coord', '__weakref__')
|
| 811 |
+
def __init__(self, name, expr, coord=None):
|
| 812 |
+
self.name = name
|
| 813 |
+
self.expr = expr
|
| 814 |
+
self.coord = coord
|
| 815 |
+
|
| 816 |
+
def children(self):
|
| 817 |
+
nodelist = []
|
| 818 |
+
if self.expr is not None: nodelist.append(("expr", self.expr))
|
| 819 |
+
for i, child in enumerate(self.name or []):
|
| 820 |
+
nodelist.append(("name[%d]" % i, child))
|
| 821 |
+
return tuple(nodelist)
|
| 822 |
+
|
| 823 |
+
def __iter__(self):
|
| 824 |
+
if self.expr is not None:
|
| 825 |
+
yield self.expr
|
| 826 |
+
for child in (self.name or []):
|
| 827 |
+
yield child
|
| 828 |
+
|
| 829 |
+
attr_names = ()
|
| 830 |
+
|
| 831 |
+
class ParamList(Node):
|
| 832 |
+
__slots__ = ('params', 'coord', '__weakref__')
|
| 833 |
+
def __init__(self, params, coord=None):
|
| 834 |
+
self.params = params
|
| 835 |
+
self.coord = coord
|
| 836 |
+
|
| 837 |
+
def children(self):
|
| 838 |
+
nodelist = []
|
| 839 |
+
for i, child in enumerate(self.params or []):
|
| 840 |
+
nodelist.append(("params[%d]" % i, child))
|
| 841 |
+
return tuple(nodelist)
|
| 842 |
+
|
| 843 |
+
def __iter__(self):
|
| 844 |
+
for child in (self.params or []):
|
| 845 |
+
yield child
|
| 846 |
+
|
| 847 |
+
attr_names = ()
|
| 848 |
+
|
| 849 |
+
class PtrDecl(Node):
|
| 850 |
+
__slots__ = ('quals', 'type', 'coord', '__weakref__')
|
| 851 |
+
def __init__(self, quals, type, coord=None):
|
| 852 |
+
self.quals = quals
|
| 853 |
+
self.type = type
|
| 854 |
+
self.coord = coord
|
| 855 |
+
|
| 856 |
+
def children(self):
|
| 857 |
+
nodelist = []
|
| 858 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 859 |
+
return tuple(nodelist)
|
| 860 |
+
|
| 861 |
+
def __iter__(self):
|
| 862 |
+
if self.type is not None:
|
| 863 |
+
yield self.type
|
| 864 |
+
|
| 865 |
+
attr_names = ('quals', )
|
| 866 |
+
|
| 867 |
+
class Return(Node):
|
| 868 |
+
__slots__ = ('expr', 'coord', '__weakref__')
|
| 869 |
+
def __init__(self, expr, coord=None):
|
| 870 |
+
self.expr = expr
|
| 871 |
+
self.coord = coord
|
| 872 |
+
|
| 873 |
+
def children(self):
|
| 874 |
+
nodelist = []
|
| 875 |
+
if self.expr is not None: nodelist.append(("expr", self.expr))
|
| 876 |
+
return tuple(nodelist)
|
| 877 |
+
|
| 878 |
+
def __iter__(self):
|
| 879 |
+
if self.expr is not None:
|
| 880 |
+
yield self.expr
|
| 881 |
+
|
| 882 |
+
attr_names = ()
|
| 883 |
+
|
| 884 |
+
class StaticAssert(Node):
|
| 885 |
+
__slots__ = ('cond', 'message', 'coord', '__weakref__')
|
| 886 |
+
def __init__(self, cond, message, coord=None):
|
| 887 |
+
self.cond = cond
|
| 888 |
+
self.message = message
|
| 889 |
+
self.coord = coord
|
| 890 |
+
|
| 891 |
+
def children(self):
|
| 892 |
+
nodelist = []
|
| 893 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 894 |
+
if self.message is not None: nodelist.append(("message", self.message))
|
| 895 |
+
return tuple(nodelist)
|
| 896 |
+
|
| 897 |
+
def __iter__(self):
|
| 898 |
+
if self.cond is not None:
|
| 899 |
+
yield self.cond
|
| 900 |
+
if self.message is not None:
|
| 901 |
+
yield self.message
|
| 902 |
+
|
| 903 |
+
attr_names = ()
|
| 904 |
+
|
| 905 |
+
class Struct(Node):
|
| 906 |
+
__slots__ = ('name', 'decls', 'coord', '__weakref__')
|
| 907 |
+
def __init__(self, name, decls, coord=None):
|
| 908 |
+
self.name = name
|
| 909 |
+
self.decls = decls
|
| 910 |
+
self.coord = coord
|
| 911 |
+
|
| 912 |
+
def children(self):
|
| 913 |
+
nodelist = []
|
| 914 |
+
for i, child in enumerate(self.decls or []):
|
| 915 |
+
nodelist.append(("decls[%d]" % i, child))
|
| 916 |
+
return tuple(nodelist)
|
| 917 |
+
|
| 918 |
+
def __iter__(self):
|
| 919 |
+
for child in (self.decls or []):
|
| 920 |
+
yield child
|
| 921 |
+
|
| 922 |
+
attr_names = ('name', )
|
| 923 |
+
|
| 924 |
+
class StructRef(Node):
|
| 925 |
+
__slots__ = ('name', 'type', 'field', 'coord', '__weakref__')
|
| 926 |
+
def __init__(self, name, type, field, coord=None):
|
| 927 |
+
self.name = name
|
| 928 |
+
self.type = type
|
| 929 |
+
self.field = field
|
| 930 |
+
self.coord = coord
|
| 931 |
+
|
| 932 |
+
def children(self):
|
| 933 |
+
nodelist = []
|
| 934 |
+
if self.name is not None: nodelist.append(("name", self.name))
|
| 935 |
+
if self.field is not None: nodelist.append(("field", self.field))
|
| 936 |
+
return tuple(nodelist)
|
| 937 |
+
|
| 938 |
+
def __iter__(self):
|
| 939 |
+
if self.name is not None:
|
| 940 |
+
yield self.name
|
| 941 |
+
if self.field is not None:
|
| 942 |
+
yield self.field
|
| 943 |
+
|
| 944 |
+
attr_names = ('type', )
|
| 945 |
+
|
| 946 |
+
class Switch(Node):
|
| 947 |
+
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
| 948 |
+
def __init__(self, cond, stmt, coord=None):
|
| 949 |
+
self.cond = cond
|
| 950 |
+
self.stmt = stmt
|
| 951 |
+
self.coord = coord
|
| 952 |
+
|
| 953 |
+
def children(self):
|
| 954 |
+
nodelist = []
|
| 955 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 956 |
+
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
| 957 |
+
return tuple(nodelist)
|
| 958 |
+
|
| 959 |
+
def __iter__(self):
|
| 960 |
+
if self.cond is not None:
|
| 961 |
+
yield self.cond
|
| 962 |
+
if self.stmt is not None:
|
| 963 |
+
yield self.stmt
|
| 964 |
+
|
| 965 |
+
attr_names = ()
|
| 966 |
+
|
| 967 |
+
class TernaryOp(Node):
|
| 968 |
+
__slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
|
| 969 |
+
def __init__(self, cond, iftrue, iffalse, coord=None):
|
| 970 |
+
self.cond = cond
|
| 971 |
+
self.iftrue = iftrue
|
| 972 |
+
self.iffalse = iffalse
|
| 973 |
+
self.coord = coord
|
| 974 |
+
|
| 975 |
+
def children(self):
|
| 976 |
+
nodelist = []
|
| 977 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 978 |
+
if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue))
|
| 979 |
+
if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse))
|
| 980 |
+
return tuple(nodelist)
|
| 981 |
+
|
| 982 |
+
def __iter__(self):
|
| 983 |
+
if self.cond is not None:
|
| 984 |
+
yield self.cond
|
| 985 |
+
if self.iftrue is not None:
|
| 986 |
+
yield self.iftrue
|
| 987 |
+
if self.iffalse is not None:
|
| 988 |
+
yield self.iffalse
|
| 989 |
+
|
| 990 |
+
attr_names = ()
|
| 991 |
+
|
| 992 |
+
class TypeDecl(Node):
|
| 993 |
+
__slots__ = ('declname', 'quals', 'align', 'type', 'coord', '__weakref__')
|
| 994 |
+
def __init__(self, declname, quals, align, type, coord=None):
|
| 995 |
+
self.declname = declname
|
| 996 |
+
self.quals = quals
|
| 997 |
+
self.align = align
|
| 998 |
+
self.type = type
|
| 999 |
+
self.coord = coord
|
| 1000 |
+
|
| 1001 |
+
def children(self):
|
| 1002 |
+
nodelist = []
|
| 1003 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 1004 |
+
return tuple(nodelist)
|
| 1005 |
+
|
| 1006 |
+
def __iter__(self):
|
| 1007 |
+
if self.type is not None:
|
| 1008 |
+
yield self.type
|
| 1009 |
+
|
| 1010 |
+
attr_names = ('declname', 'quals', 'align', )
|
| 1011 |
+
|
| 1012 |
+
class Typedef(Node):
|
| 1013 |
+
__slots__ = ('name', 'quals', 'storage', 'type', 'coord', '__weakref__')
|
| 1014 |
+
def __init__(self, name, quals, storage, type, coord=None):
|
| 1015 |
+
self.name = name
|
| 1016 |
+
self.quals = quals
|
| 1017 |
+
self.storage = storage
|
| 1018 |
+
self.type = type
|
| 1019 |
+
self.coord = coord
|
| 1020 |
+
|
| 1021 |
+
def children(self):
|
| 1022 |
+
nodelist = []
|
| 1023 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 1024 |
+
return tuple(nodelist)
|
| 1025 |
+
|
| 1026 |
+
def __iter__(self):
|
| 1027 |
+
if self.type is not None:
|
| 1028 |
+
yield self.type
|
| 1029 |
+
|
| 1030 |
+
attr_names = ('name', 'quals', 'storage', )
|
| 1031 |
+
|
| 1032 |
+
class Typename(Node):
|
| 1033 |
+
__slots__ = ('name', 'quals', 'align', 'type', 'coord', '__weakref__')
|
| 1034 |
+
def __init__(self, name, quals, align, type, coord=None):
|
| 1035 |
+
self.name = name
|
| 1036 |
+
self.quals = quals
|
| 1037 |
+
self.align = align
|
| 1038 |
+
self.type = type
|
| 1039 |
+
self.coord = coord
|
| 1040 |
+
|
| 1041 |
+
def children(self):
|
| 1042 |
+
nodelist = []
|
| 1043 |
+
if self.type is not None: nodelist.append(("type", self.type))
|
| 1044 |
+
return tuple(nodelist)
|
| 1045 |
+
|
| 1046 |
+
def __iter__(self):
|
| 1047 |
+
if self.type is not None:
|
| 1048 |
+
yield self.type
|
| 1049 |
+
|
| 1050 |
+
attr_names = ('name', 'quals', 'align', )
|
| 1051 |
+
|
| 1052 |
+
class UnaryOp(Node):
|
| 1053 |
+
__slots__ = ('op', 'expr', 'coord', '__weakref__')
|
| 1054 |
+
def __init__(self, op, expr, coord=None):
|
| 1055 |
+
self.op = op
|
| 1056 |
+
self.expr = expr
|
| 1057 |
+
self.coord = coord
|
| 1058 |
+
|
| 1059 |
+
def children(self):
|
| 1060 |
+
nodelist = []
|
| 1061 |
+
if self.expr is not None: nodelist.append(("expr", self.expr))
|
| 1062 |
+
return tuple(nodelist)
|
| 1063 |
+
|
| 1064 |
+
def __iter__(self):
|
| 1065 |
+
if self.expr is not None:
|
| 1066 |
+
yield self.expr
|
| 1067 |
+
|
| 1068 |
+
attr_names = ('op', )
|
| 1069 |
+
|
| 1070 |
+
class Union(Node):
|
| 1071 |
+
__slots__ = ('name', 'decls', 'coord', '__weakref__')
|
| 1072 |
+
def __init__(self, name, decls, coord=None):
|
| 1073 |
+
self.name = name
|
| 1074 |
+
self.decls = decls
|
| 1075 |
+
self.coord = coord
|
| 1076 |
+
|
| 1077 |
+
def children(self):
|
| 1078 |
+
nodelist = []
|
| 1079 |
+
for i, child in enumerate(self.decls or []):
|
| 1080 |
+
nodelist.append(("decls[%d]" % i, child))
|
| 1081 |
+
return tuple(nodelist)
|
| 1082 |
+
|
| 1083 |
+
def __iter__(self):
|
| 1084 |
+
for child in (self.decls or []):
|
| 1085 |
+
yield child
|
| 1086 |
+
|
| 1087 |
+
attr_names = ('name', )
|
| 1088 |
+
|
| 1089 |
+
class While(Node):
|
| 1090 |
+
__slots__ = ('cond', 'stmt', 'coord', '__weakref__')
|
| 1091 |
+
def __init__(self, cond, stmt, coord=None):
|
| 1092 |
+
self.cond = cond
|
| 1093 |
+
self.stmt = stmt
|
| 1094 |
+
self.coord = coord
|
| 1095 |
+
|
| 1096 |
+
def children(self):
|
| 1097 |
+
nodelist = []
|
| 1098 |
+
if self.cond is not None: nodelist.append(("cond", self.cond))
|
| 1099 |
+
if self.stmt is not None: nodelist.append(("stmt", self.stmt))
|
| 1100 |
+
return tuple(nodelist)
|
| 1101 |
+
|
| 1102 |
+
def __iter__(self):
|
| 1103 |
+
if self.cond is not None:
|
| 1104 |
+
yield self.cond
|
| 1105 |
+
if self.stmt is not None:
|
| 1106 |
+
yield self.stmt
|
| 1107 |
+
|
| 1108 |
+
attr_names = ()
|
| 1109 |
+
|
| 1110 |
+
class Pragma(Node):
|
| 1111 |
+
__slots__ = ('string', 'coord', '__weakref__')
|
| 1112 |
+
def __init__(self, string, coord=None):
|
| 1113 |
+
self.string = string
|
| 1114 |
+
self.coord = coord
|
| 1115 |
+
|
| 1116 |
+
def children(self):
|
| 1117 |
+
nodelist = []
|
| 1118 |
+
return tuple(nodelist)
|
| 1119 |
+
|
| 1120 |
+
def __iter__(self):
|
| 1121 |
+
return
|
| 1122 |
+
yield
|
| 1123 |
+
|
| 1124 |
+
attr_names = ('string', )
|
| 1125 |
+
|
rtme/lib/python3.10/site-packages/pycparser/c_generator.py
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#------------------------------------------------------------------------------
|
| 2 |
+
# pycparser: c_generator.py
|
| 3 |
+
#
|
| 4 |
+
# C code generator from pycparser AST nodes.
|
| 5 |
+
#
|
| 6 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 7 |
+
# License: BSD
|
| 8 |
+
#------------------------------------------------------------------------------
|
| 9 |
+
from . import c_ast
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class CGenerator(object):
|
| 13 |
+
""" Uses the same visitor pattern as c_ast.NodeVisitor, but modified to
|
| 14 |
+
return a value from each visit method, using string accumulation in
|
| 15 |
+
generic_visit.
|
| 16 |
+
"""
|
| 17 |
+
def __init__(self, reduce_parentheses=False):
|
| 18 |
+
""" Constructs C-code generator
|
| 19 |
+
|
| 20 |
+
reduce_parentheses:
|
| 21 |
+
if True, eliminates needless parentheses on binary operators
|
| 22 |
+
"""
|
| 23 |
+
# Statements start with indentation of self.indent_level spaces, using
|
| 24 |
+
# the _make_indent method.
|
| 25 |
+
self.indent_level = 0
|
| 26 |
+
self.reduce_parentheses = reduce_parentheses
|
| 27 |
+
|
| 28 |
+
def _make_indent(self):
|
| 29 |
+
return ' ' * self.indent_level
|
| 30 |
+
|
| 31 |
+
def visit(self, node):
|
| 32 |
+
method = 'visit_' + node.__class__.__name__
|
| 33 |
+
return getattr(self, method, self.generic_visit)(node)
|
| 34 |
+
|
| 35 |
+
def generic_visit(self, node):
|
| 36 |
+
if node is None:
|
| 37 |
+
return ''
|
| 38 |
+
else:
|
| 39 |
+
return ''.join(self.visit(c) for c_name, c in node.children())
|
| 40 |
+
|
| 41 |
+
def visit_Constant(self, n):
|
| 42 |
+
return n.value
|
| 43 |
+
|
| 44 |
+
def visit_ID(self, n):
|
| 45 |
+
return n.name
|
| 46 |
+
|
| 47 |
+
def visit_Pragma(self, n):
|
| 48 |
+
ret = '#pragma'
|
| 49 |
+
if n.string:
|
| 50 |
+
ret += ' ' + n.string
|
| 51 |
+
return ret
|
| 52 |
+
|
| 53 |
+
def visit_ArrayRef(self, n):
|
| 54 |
+
arrref = self._parenthesize_unless_simple(n.name)
|
| 55 |
+
return arrref + '[' + self.visit(n.subscript) + ']'
|
| 56 |
+
|
| 57 |
+
def visit_StructRef(self, n):
|
| 58 |
+
sref = self._parenthesize_unless_simple(n.name)
|
| 59 |
+
return sref + n.type + self.visit(n.field)
|
| 60 |
+
|
| 61 |
+
def visit_FuncCall(self, n):
|
| 62 |
+
fref = self._parenthesize_unless_simple(n.name)
|
| 63 |
+
return fref + '(' + self.visit(n.args) + ')'
|
| 64 |
+
|
| 65 |
+
def visit_UnaryOp(self, n):
|
| 66 |
+
if n.op == 'sizeof':
|
| 67 |
+
# Always parenthesize the argument of sizeof since it can be
|
| 68 |
+
# a name.
|
| 69 |
+
return 'sizeof(%s)' % self.visit(n.expr)
|
| 70 |
+
else:
|
| 71 |
+
operand = self._parenthesize_unless_simple(n.expr)
|
| 72 |
+
if n.op == 'p++':
|
| 73 |
+
return '%s++' % operand
|
| 74 |
+
elif n.op == 'p--':
|
| 75 |
+
return '%s--' % operand
|
| 76 |
+
else:
|
| 77 |
+
return '%s%s' % (n.op, operand)
|
| 78 |
+
|
| 79 |
+
# Precedence map of binary operators:
|
| 80 |
+
precedence_map = {
|
| 81 |
+
# Should be in sync with c_parser.CParser.precedence
|
| 82 |
+
# Higher numbers are stronger binding
|
| 83 |
+
'||': 0, # weakest binding
|
| 84 |
+
'&&': 1,
|
| 85 |
+
'|': 2,
|
| 86 |
+
'^': 3,
|
| 87 |
+
'&': 4,
|
| 88 |
+
'==': 5, '!=': 5,
|
| 89 |
+
'>': 6, '>=': 6, '<': 6, '<=': 6,
|
| 90 |
+
'>>': 7, '<<': 7,
|
| 91 |
+
'+': 8, '-': 8,
|
| 92 |
+
'*': 9, '/': 9, '%': 9 # strongest binding
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
def visit_BinaryOp(self, n):
|
| 96 |
+
# Note: all binary operators are left-to-right associative
|
| 97 |
+
#
|
| 98 |
+
# If `n.left.op` has a stronger or equally binding precedence in
|
| 99 |
+
# comparison to `n.op`, no parenthesis are needed for the left:
|
| 100 |
+
# e.g., `(a*b) + c` is equivalent to `a*b + c`, as well as
|
| 101 |
+
# `(a+b) - c` is equivalent to `a+b - c` (same precedence).
|
| 102 |
+
# If the left operator is weaker binding than the current, then
|
| 103 |
+
# parentheses are necessary:
|
| 104 |
+
# e.g., `(a+b) * c` is NOT equivalent to `a+b * c`.
|
| 105 |
+
lval_str = self._parenthesize_if(
|
| 106 |
+
n.left,
|
| 107 |
+
lambda d: not (self._is_simple_node(d) or
|
| 108 |
+
self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and
|
| 109 |
+
self.precedence_map[d.op] >= self.precedence_map[n.op]))
|
| 110 |
+
# If `n.right.op` has a stronger -but not equal- binding precedence,
|
| 111 |
+
# parenthesis can be omitted on the right:
|
| 112 |
+
# e.g., `a + (b*c)` is equivalent to `a + b*c`.
|
| 113 |
+
# If the right operator is weaker or equally binding, then parentheses
|
| 114 |
+
# are necessary:
|
| 115 |
+
# e.g., `a * (b+c)` is NOT equivalent to `a * b+c` and
|
| 116 |
+
# `a - (b+c)` is NOT equivalent to `a - b+c` (same precedence).
|
| 117 |
+
rval_str = self._parenthesize_if(
|
| 118 |
+
n.right,
|
| 119 |
+
lambda d: not (self._is_simple_node(d) or
|
| 120 |
+
self.reduce_parentheses and isinstance(d, c_ast.BinaryOp) and
|
| 121 |
+
self.precedence_map[d.op] > self.precedence_map[n.op]))
|
| 122 |
+
return '%s %s %s' % (lval_str, n.op, rval_str)
|
| 123 |
+
|
| 124 |
+
def visit_Assignment(self, n):
|
| 125 |
+
rval_str = self._parenthesize_if(
|
| 126 |
+
n.rvalue,
|
| 127 |
+
lambda n: isinstance(n, c_ast.Assignment))
|
| 128 |
+
return '%s %s %s' % (self.visit(n.lvalue), n.op, rval_str)
|
| 129 |
+
|
| 130 |
+
def visit_IdentifierType(self, n):
|
| 131 |
+
return ' '.join(n.names)
|
| 132 |
+
|
| 133 |
+
def _visit_expr(self, n):
|
| 134 |
+
if isinstance(n, c_ast.InitList):
|
| 135 |
+
return '{' + self.visit(n) + '}'
|
| 136 |
+
elif isinstance(n, c_ast.ExprList):
|
| 137 |
+
return '(' + self.visit(n) + ')'
|
| 138 |
+
else:
|
| 139 |
+
return self.visit(n)
|
| 140 |
+
|
| 141 |
+
def visit_Decl(self, n, no_type=False):
|
| 142 |
+
# no_type is used when a Decl is part of a DeclList, where the type is
|
| 143 |
+
# explicitly only for the first declaration in a list.
|
| 144 |
+
#
|
| 145 |
+
s = n.name if no_type else self._generate_decl(n)
|
| 146 |
+
if n.bitsize: s += ' : ' + self.visit(n.bitsize)
|
| 147 |
+
if n.init:
|
| 148 |
+
s += ' = ' + self._visit_expr(n.init)
|
| 149 |
+
return s
|
| 150 |
+
|
| 151 |
+
def visit_DeclList(self, n):
|
| 152 |
+
s = self.visit(n.decls[0])
|
| 153 |
+
if len(n.decls) > 1:
|
| 154 |
+
s += ', ' + ', '.join(self.visit_Decl(decl, no_type=True)
|
| 155 |
+
for decl in n.decls[1:])
|
| 156 |
+
return s
|
| 157 |
+
|
| 158 |
+
def visit_Typedef(self, n):
|
| 159 |
+
s = ''
|
| 160 |
+
if n.storage: s += ' '.join(n.storage) + ' '
|
| 161 |
+
s += self._generate_type(n.type)
|
| 162 |
+
return s
|
| 163 |
+
|
| 164 |
+
def visit_Cast(self, n):
|
| 165 |
+
s = '(' + self._generate_type(n.to_type, emit_declname=False) + ')'
|
| 166 |
+
return s + ' ' + self._parenthesize_unless_simple(n.expr)
|
| 167 |
+
|
| 168 |
+
def visit_ExprList(self, n):
|
| 169 |
+
visited_subexprs = []
|
| 170 |
+
for expr in n.exprs:
|
| 171 |
+
visited_subexprs.append(self._visit_expr(expr))
|
| 172 |
+
return ', '.join(visited_subexprs)
|
| 173 |
+
|
| 174 |
+
def visit_InitList(self, n):
|
| 175 |
+
visited_subexprs = []
|
| 176 |
+
for expr in n.exprs:
|
| 177 |
+
visited_subexprs.append(self._visit_expr(expr))
|
| 178 |
+
return ', '.join(visited_subexprs)
|
| 179 |
+
|
| 180 |
+
def visit_Enum(self, n):
|
| 181 |
+
return self._generate_struct_union_enum(n, name='enum')
|
| 182 |
+
|
| 183 |
+
def visit_Alignas(self, n):
|
| 184 |
+
return '_Alignas({})'.format(self.visit(n.alignment))
|
| 185 |
+
|
| 186 |
+
def visit_Enumerator(self, n):
|
| 187 |
+
if not n.value:
|
| 188 |
+
return '{indent}{name},\n'.format(
|
| 189 |
+
indent=self._make_indent(),
|
| 190 |
+
name=n.name,
|
| 191 |
+
)
|
| 192 |
+
else:
|
| 193 |
+
return '{indent}{name} = {value},\n'.format(
|
| 194 |
+
indent=self._make_indent(),
|
| 195 |
+
name=n.name,
|
| 196 |
+
value=self.visit(n.value),
|
| 197 |
+
)
|
| 198 |
+
|
| 199 |
+
def visit_FuncDef(self, n):
|
| 200 |
+
decl = self.visit(n.decl)
|
| 201 |
+
self.indent_level = 0
|
| 202 |
+
body = self.visit(n.body)
|
| 203 |
+
if n.param_decls:
|
| 204 |
+
knrdecls = ';\n'.join(self.visit(p) for p in n.param_decls)
|
| 205 |
+
return decl + '\n' + knrdecls + ';\n' + body + '\n'
|
| 206 |
+
else:
|
| 207 |
+
return decl + '\n' + body + '\n'
|
| 208 |
+
|
| 209 |
+
def visit_FileAST(self, n):
|
| 210 |
+
s = ''
|
| 211 |
+
for ext in n.ext:
|
| 212 |
+
if isinstance(ext, c_ast.FuncDef):
|
| 213 |
+
s += self.visit(ext)
|
| 214 |
+
elif isinstance(ext, c_ast.Pragma):
|
| 215 |
+
s += self.visit(ext) + '\n'
|
| 216 |
+
else:
|
| 217 |
+
s += self.visit(ext) + ';\n'
|
| 218 |
+
return s
|
| 219 |
+
|
| 220 |
+
def visit_Compound(self, n):
|
| 221 |
+
s = self._make_indent() + '{\n'
|
| 222 |
+
self.indent_level += 2
|
| 223 |
+
if n.block_items:
|
| 224 |
+
s += ''.join(self._generate_stmt(stmt) for stmt in n.block_items)
|
| 225 |
+
self.indent_level -= 2
|
| 226 |
+
s += self._make_indent() + '}\n'
|
| 227 |
+
return s
|
| 228 |
+
|
| 229 |
+
def visit_CompoundLiteral(self, n):
|
| 230 |
+
return '(' + self.visit(n.type) + '){' + self.visit(n.init) + '}'
|
| 231 |
+
|
| 232 |
+
|
| 233 |
+
def visit_EmptyStatement(self, n):
|
| 234 |
+
return ';'
|
| 235 |
+
|
| 236 |
+
def visit_ParamList(self, n):
|
| 237 |
+
return ', '.join(self.visit(param) for param in n.params)
|
| 238 |
+
|
| 239 |
+
def visit_Return(self, n):
|
| 240 |
+
s = 'return'
|
| 241 |
+
if n.expr: s += ' ' + self.visit(n.expr)
|
| 242 |
+
return s + ';'
|
| 243 |
+
|
| 244 |
+
def visit_Break(self, n):
|
| 245 |
+
return 'break;'
|
| 246 |
+
|
| 247 |
+
def visit_Continue(self, n):
|
| 248 |
+
return 'continue;'
|
| 249 |
+
|
| 250 |
+
def visit_TernaryOp(self, n):
|
| 251 |
+
s = '(' + self._visit_expr(n.cond) + ') ? '
|
| 252 |
+
s += '(' + self._visit_expr(n.iftrue) + ') : '
|
| 253 |
+
s += '(' + self._visit_expr(n.iffalse) + ')'
|
| 254 |
+
return s
|
| 255 |
+
|
| 256 |
+
def visit_If(self, n):
|
| 257 |
+
s = 'if ('
|
| 258 |
+
if n.cond: s += self.visit(n.cond)
|
| 259 |
+
s += ')\n'
|
| 260 |
+
s += self._generate_stmt(n.iftrue, add_indent=True)
|
| 261 |
+
if n.iffalse:
|
| 262 |
+
s += self._make_indent() + 'else\n'
|
| 263 |
+
s += self._generate_stmt(n.iffalse, add_indent=True)
|
| 264 |
+
return s
|
| 265 |
+
|
| 266 |
+
def visit_For(self, n):
|
| 267 |
+
s = 'for ('
|
| 268 |
+
if n.init: s += self.visit(n.init)
|
| 269 |
+
s += ';'
|
| 270 |
+
if n.cond: s += ' ' + self.visit(n.cond)
|
| 271 |
+
s += ';'
|
| 272 |
+
if n.next: s += ' ' + self.visit(n.next)
|
| 273 |
+
s += ')\n'
|
| 274 |
+
s += self._generate_stmt(n.stmt, add_indent=True)
|
| 275 |
+
return s
|
| 276 |
+
|
| 277 |
+
def visit_While(self, n):
|
| 278 |
+
s = 'while ('
|
| 279 |
+
if n.cond: s += self.visit(n.cond)
|
| 280 |
+
s += ')\n'
|
| 281 |
+
s += self._generate_stmt(n.stmt, add_indent=True)
|
| 282 |
+
return s
|
| 283 |
+
|
| 284 |
+
def visit_DoWhile(self, n):
|
| 285 |
+
s = 'do\n'
|
| 286 |
+
s += self._generate_stmt(n.stmt, add_indent=True)
|
| 287 |
+
s += self._make_indent() + 'while ('
|
| 288 |
+
if n.cond: s += self.visit(n.cond)
|
| 289 |
+
s += ');'
|
| 290 |
+
return s
|
| 291 |
+
|
| 292 |
+
def visit_StaticAssert(self, n):
|
| 293 |
+
s = '_Static_assert('
|
| 294 |
+
s += self.visit(n.cond)
|
| 295 |
+
if n.message:
|
| 296 |
+
s += ','
|
| 297 |
+
s += self.visit(n.message)
|
| 298 |
+
s += ')'
|
| 299 |
+
return s
|
| 300 |
+
|
| 301 |
+
def visit_Switch(self, n):
|
| 302 |
+
s = 'switch (' + self.visit(n.cond) + ')\n'
|
| 303 |
+
s += self._generate_stmt(n.stmt, add_indent=True)
|
| 304 |
+
return s
|
| 305 |
+
|
| 306 |
+
def visit_Case(self, n):
|
| 307 |
+
s = 'case ' + self.visit(n.expr) + ':\n'
|
| 308 |
+
for stmt in n.stmts:
|
| 309 |
+
s += self._generate_stmt(stmt, add_indent=True)
|
| 310 |
+
return s
|
| 311 |
+
|
| 312 |
+
def visit_Default(self, n):
|
| 313 |
+
s = 'default:\n'
|
| 314 |
+
for stmt in n.stmts:
|
| 315 |
+
s += self._generate_stmt(stmt, add_indent=True)
|
| 316 |
+
return s
|
| 317 |
+
|
| 318 |
+
def visit_Label(self, n):
|
| 319 |
+
return n.name + ':\n' + self._generate_stmt(n.stmt)
|
| 320 |
+
|
| 321 |
+
def visit_Goto(self, n):
|
| 322 |
+
return 'goto ' + n.name + ';'
|
| 323 |
+
|
| 324 |
+
def visit_EllipsisParam(self, n):
|
| 325 |
+
return '...'
|
| 326 |
+
|
| 327 |
+
def visit_Struct(self, n):
|
| 328 |
+
return self._generate_struct_union_enum(n, 'struct')
|
| 329 |
+
|
| 330 |
+
def visit_Typename(self, n):
|
| 331 |
+
return self._generate_type(n.type)
|
| 332 |
+
|
| 333 |
+
def visit_Union(self, n):
|
| 334 |
+
return self._generate_struct_union_enum(n, 'union')
|
| 335 |
+
|
| 336 |
+
def visit_NamedInitializer(self, n):
|
| 337 |
+
s = ''
|
| 338 |
+
for name in n.name:
|
| 339 |
+
if isinstance(name, c_ast.ID):
|
| 340 |
+
s += '.' + name.name
|
| 341 |
+
else:
|
| 342 |
+
s += '[' + self.visit(name) + ']'
|
| 343 |
+
s += ' = ' + self._visit_expr(n.expr)
|
| 344 |
+
return s
|
| 345 |
+
|
| 346 |
+
def visit_FuncDecl(self, n):
|
| 347 |
+
return self._generate_type(n)
|
| 348 |
+
|
| 349 |
+
def visit_ArrayDecl(self, n):
|
| 350 |
+
return self._generate_type(n, emit_declname=False)
|
| 351 |
+
|
| 352 |
+
def visit_TypeDecl(self, n):
|
| 353 |
+
return self._generate_type(n, emit_declname=False)
|
| 354 |
+
|
| 355 |
+
def visit_PtrDecl(self, n):
|
| 356 |
+
return self._generate_type(n, emit_declname=False)
|
| 357 |
+
|
| 358 |
+
def _generate_struct_union_enum(self, n, name):
|
| 359 |
+
""" Generates code for structs, unions, and enums. name should be
|
| 360 |
+
'struct', 'union', or 'enum'.
|
| 361 |
+
"""
|
| 362 |
+
if name in ('struct', 'union'):
|
| 363 |
+
members = n.decls
|
| 364 |
+
body_function = self._generate_struct_union_body
|
| 365 |
+
else:
|
| 366 |
+
assert name == 'enum'
|
| 367 |
+
members = None if n.values is None else n.values.enumerators
|
| 368 |
+
body_function = self._generate_enum_body
|
| 369 |
+
s = name + ' ' + (n.name or '')
|
| 370 |
+
if members is not None:
|
| 371 |
+
# None means no members
|
| 372 |
+
# Empty sequence means an empty list of members
|
| 373 |
+
s += '\n'
|
| 374 |
+
s += self._make_indent()
|
| 375 |
+
self.indent_level += 2
|
| 376 |
+
s += '{\n'
|
| 377 |
+
s += body_function(members)
|
| 378 |
+
self.indent_level -= 2
|
| 379 |
+
s += self._make_indent() + '}'
|
| 380 |
+
return s
|
| 381 |
+
|
| 382 |
+
def _generate_struct_union_body(self, members):
|
| 383 |
+
return ''.join(self._generate_stmt(decl) for decl in members)
|
| 384 |
+
|
| 385 |
+
def _generate_enum_body(self, members):
|
| 386 |
+
# `[:-2] + '\n'` removes the final `,` from the enumerator list
|
| 387 |
+
return ''.join(self.visit(value) for value in members)[:-2] + '\n'
|
| 388 |
+
|
| 389 |
+
def _generate_stmt(self, n, add_indent=False):
|
| 390 |
+
""" Generation from a statement node. This method exists as a wrapper
|
| 391 |
+
for individual visit_* methods to handle different treatment of
|
| 392 |
+
some statements in this context.
|
| 393 |
+
"""
|
| 394 |
+
typ = type(n)
|
| 395 |
+
if add_indent: self.indent_level += 2
|
| 396 |
+
indent = self._make_indent()
|
| 397 |
+
if add_indent: self.indent_level -= 2
|
| 398 |
+
|
| 399 |
+
if typ in (
|
| 400 |
+
c_ast.Decl, c_ast.Assignment, c_ast.Cast, c_ast.UnaryOp,
|
| 401 |
+
c_ast.BinaryOp, c_ast.TernaryOp, c_ast.FuncCall, c_ast.ArrayRef,
|
| 402 |
+
c_ast.StructRef, c_ast.Constant, c_ast.ID, c_ast.Typedef,
|
| 403 |
+
c_ast.ExprList):
|
| 404 |
+
# These can also appear in an expression context so no semicolon
|
| 405 |
+
# is added to them automatically
|
| 406 |
+
#
|
| 407 |
+
return indent + self.visit(n) + ';\n'
|
| 408 |
+
elif typ in (c_ast.Compound,):
|
| 409 |
+
# No extra indentation required before the opening brace of a
|
| 410 |
+
# compound - because it consists of multiple lines it has to
|
| 411 |
+
# compute its own indentation.
|
| 412 |
+
#
|
| 413 |
+
return self.visit(n)
|
| 414 |
+
elif typ in (c_ast.If,):
|
| 415 |
+
return indent + self.visit(n)
|
| 416 |
+
else:
|
| 417 |
+
return indent + self.visit(n) + '\n'
|
| 418 |
+
|
| 419 |
+
def _generate_decl(self, n):
|
| 420 |
+
""" Generation from a Decl node.
|
| 421 |
+
"""
|
| 422 |
+
s = ''
|
| 423 |
+
if n.funcspec: s = ' '.join(n.funcspec) + ' '
|
| 424 |
+
if n.storage: s += ' '.join(n.storage) + ' '
|
| 425 |
+
if n.align: s += self.visit(n.align[0]) + ' '
|
| 426 |
+
s += self._generate_type(n.type)
|
| 427 |
+
return s
|
| 428 |
+
|
| 429 |
+
def _generate_type(self, n, modifiers=[], emit_declname = True):
|
| 430 |
+
""" Recursive generation from a type node. n is the type node.
|
| 431 |
+
modifiers collects the PtrDecl, ArrayDecl and FuncDecl modifiers
|
| 432 |
+
encountered on the way down to a TypeDecl, to allow proper
|
| 433 |
+
generation from it.
|
| 434 |
+
"""
|
| 435 |
+
typ = type(n)
|
| 436 |
+
#~ print(n, modifiers)
|
| 437 |
+
|
| 438 |
+
if typ == c_ast.TypeDecl:
|
| 439 |
+
s = ''
|
| 440 |
+
if n.quals: s += ' '.join(n.quals) + ' '
|
| 441 |
+
s += self.visit(n.type)
|
| 442 |
+
|
| 443 |
+
nstr = n.declname if n.declname and emit_declname else ''
|
| 444 |
+
# Resolve modifiers.
|
| 445 |
+
# Wrap in parens to distinguish pointer to array and pointer to
|
| 446 |
+
# function syntax.
|
| 447 |
+
#
|
| 448 |
+
for i, modifier in enumerate(modifiers):
|
| 449 |
+
if isinstance(modifier, c_ast.ArrayDecl):
|
| 450 |
+
if (i != 0 and
|
| 451 |
+
isinstance(modifiers[i - 1], c_ast.PtrDecl)):
|
| 452 |
+
nstr = '(' + nstr + ')'
|
| 453 |
+
nstr += '['
|
| 454 |
+
if modifier.dim_quals:
|
| 455 |
+
nstr += ' '.join(modifier.dim_quals) + ' '
|
| 456 |
+
nstr += self.visit(modifier.dim) + ']'
|
| 457 |
+
elif isinstance(modifier, c_ast.FuncDecl):
|
| 458 |
+
if (i != 0 and
|
| 459 |
+
isinstance(modifiers[i - 1], c_ast.PtrDecl)):
|
| 460 |
+
nstr = '(' + nstr + ')'
|
| 461 |
+
nstr += '(' + self.visit(modifier.args) + ')'
|
| 462 |
+
elif isinstance(modifier, c_ast.PtrDecl):
|
| 463 |
+
if modifier.quals:
|
| 464 |
+
nstr = '* %s%s' % (' '.join(modifier.quals),
|
| 465 |
+
' ' + nstr if nstr else '')
|
| 466 |
+
else:
|
| 467 |
+
nstr = '*' + nstr
|
| 468 |
+
if nstr: s += ' ' + nstr
|
| 469 |
+
return s
|
| 470 |
+
elif typ == c_ast.Decl:
|
| 471 |
+
return self._generate_decl(n.type)
|
| 472 |
+
elif typ == c_ast.Typename:
|
| 473 |
+
return self._generate_type(n.type, emit_declname = emit_declname)
|
| 474 |
+
elif typ == c_ast.IdentifierType:
|
| 475 |
+
return ' '.join(n.names) + ' '
|
| 476 |
+
elif typ in (c_ast.ArrayDecl, c_ast.PtrDecl, c_ast.FuncDecl):
|
| 477 |
+
return self._generate_type(n.type, modifiers + [n],
|
| 478 |
+
emit_declname = emit_declname)
|
| 479 |
+
else:
|
| 480 |
+
return self.visit(n)
|
| 481 |
+
|
| 482 |
+
def _parenthesize_if(self, n, condition):
|
| 483 |
+
""" Visits 'n' and returns its string representation, parenthesized
|
| 484 |
+
if the condition function applied to the node returns True.
|
| 485 |
+
"""
|
| 486 |
+
s = self._visit_expr(n)
|
| 487 |
+
if condition(n):
|
| 488 |
+
return '(' + s + ')'
|
| 489 |
+
else:
|
| 490 |
+
return s
|
| 491 |
+
|
| 492 |
+
def _parenthesize_unless_simple(self, n):
|
| 493 |
+
""" Common use case for _parenthesize_if
|
| 494 |
+
"""
|
| 495 |
+
return self._parenthesize_if(n, lambda d: not self._is_simple_node(d))
|
| 496 |
+
|
| 497 |
+
def _is_simple_node(self, n):
|
| 498 |
+
""" Returns True for nodes that are "simple" - i.e. nodes that always
|
| 499 |
+
have higher precedence than operators.
|
| 500 |
+
"""
|
| 501 |
+
return isinstance(n, (c_ast.Constant, c_ast.ID, c_ast.ArrayRef,
|
| 502 |
+
c_ast.StructRef, c_ast.FuncCall))
|
rtme/lib/python3.10/site-packages/pycparser/c_lexer.py
ADDED
|
@@ -0,0 +1,555 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#------------------------------------------------------------------------------
|
| 2 |
+
# pycparser: c_lexer.py
|
| 3 |
+
#
|
| 4 |
+
# CLexer class: lexer for the C language
|
| 5 |
+
#
|
| 6 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 7 |
+
# License: BSD
|
| 8 |
+
#------------------------------------------------------------------------------
|
| 9 |
+
import re
|
| 10 |
+
|
| 11 |
+
from .ply import lex
|
| 12 |
+
from .ply.lex import TOKEN
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class CLexer(object):
|
| 16 |
+
""" A lexer for the C language. After building it, set the
|
| 17 |
+
input text with input(), and call token() to get new
|
| 18 |
+
tokens.
|
| 19 |
+
|
| 20 |
+
The public attribute filename can be set to an initial
|
| 21 |
+
filename, but the lexer will update it upon #line
|
| 22 |
+
directives.
|
| 23 |
+
"""
|
| 24 |
+
def __init__(self, error_func, on_lbrace_func, on_rbrace_func,
|
| 25 |
+
type_lookup_func):
|
| 26 |
+
""" Create a new Lexer.
|
| 27 |
+
|
| 28 |
+
error_func:
|
| 29 |
+
An error function. Will be called with an error
|
| 30 |
+
message, line and column as arguments, in case of
|
| 31 |
+
an error during lexing.
|
| 32 |
+
|
| 33 |
+
on_lbrace_func, on_rbrace_func:
|
| 34 |
+
Called when an LBRACE or RBRACE is encountered
|
| 35 |
+
(likely to push/pop type_lookup_func's scope)
|
| 36 |
+
|
| 37 |
+
type_lookup_func:
|
| 38 |
+
A type lookup function. Given a string, it must
|
| 39 |
+
return True IFF this string is a name of a type
|
| 40 |
+
that was defined with a typedef earlier.
|
| 41 |
+
"""
|
| 42 |
+
self.error_func = error_func
|
| 43 |
+
self.on_lbrace_func = on_lbrace_func
|
| 44 |
+
self.on_rbrace_func = on_rbrace_func
|
| 45 |
+
self.type_lookup_func = type_lookup_func
|
| 46 |
+
self.filename = ''
|
| 47 |
+
|
| 48 |
+
# Keeps track of the last token returned from self.token()
|
| 49 |
+
self.last_token = None
|
| 50 |
+
|
| 51 |
+
# Allow either "# line" or "# <num>" to support GCC's
|
| 52 |
+
# cpp output
|
| 53 |
+
#
|
| 54 |
+
self.line_pattern = re.compile(r'([ \t]*line\W)|([ \t]*\d+)')
|
| 55 |
+
self.pragma_pattern = re.compile(r'[ \t]*pragma\W')
|
| 56 |
+
|
| 57 |
+
def build(self, **kwargs):
|
| 58 |
+
""" Builds the lexer from the specification. Must be
|
| 59 |
+
called after the lexer object is created.
|
| 60 |
+
|
| 61 |
+
This method exists separately, because the PLY
|
| 62 |
+
manual warns against calling lex.lex inside
|
| 63 |
+
__init__
|
| 64 |
+
"""
|
| 65 |
+
self.lexer = lex.lex(object=self, **kwargs)
|
| 66 |
+
|
| 67 |
+
def reset_lineno(self):
|
| 68 |
+
""" Resets the internal line number counter of the lexer.
|
| 69 |
+
"""
|
| 70 |
+
self.lexer.lineno = 1
|
| 71 |
+
|
| 72 |
+
def input(self, text):
|
| 73 |
+
self.lexer.input(text)
|
| 74 |
+
|
| 75 |
+
def token(self):
|
| 76 |
+
self.last_token = self.lexer.token()
|
| 77 |
+
return self.last_token
|
| 78 |
+
|
| 79 |
+
def find_tok_column(self, token):
|
| 80 |
+
""" Find the column of the token in its line.
|
| 81 |
+
"""
|
| 82 |
+
last_cr = self.lexer.lexdata.rfind('\n', 0, token.lexpos)
|
| 83 |
+
return token.lexpos - last_cr
|
| 84 |
+
|
| 85 |
+
######################-- PRIVATE --######################
|
| 86 |
+
|
| 87 |
+
##
|
| 88 |
+
## Internal auxiliary methods
|
| 89 |
+
##
|
| 90 |
+
def _error(self, msg, token):
|
| 91 |
+
location = self._make_tok_location(token)
|
| 92 |
+
self.error_func(msg, location[0], location[1])
|
| 93 |
+
self.lexer.skip(1)
|
| 94 |
+
|
| 95 |
+
def _make_tok_location(self, token):
|
| 96 |
+
return (token.lineno, self.find_tok_column(token))
|
| 97 |
+
|
| 98 |
+
##
|
| 99 |
+
## Reserved keywords
|
| 100 |
+
##
|
| 101 |
+
keywords = (
|
| 102 |
+
'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST',
|
| 103 |
+
'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN',
|
| 104 |
+
'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG',
|
| 105 |
+
'REGISTER', 'OFFSETOF',
|
| 106 |
+
'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT',
|
| 107 |
+
'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID',
|
| 108 |
+
'VOLATILE', 'WHILE', '__INT128',
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
+
keywords_new = (
|
| 112 |
+
'_BOOL', '_COMPLEX',
|
| 113 |
+
'_NORETURN', '_THREAD_LOCAL', '_STATIC_ASSERT',
|
| 114 |
+
'_ATOMIC', '_ALIGNOF', '_ALIGNAS',
|
| 115 |
+
'_PRAGMA',
|
| 116 |
+
)
|
| 117 |
+
|
| 118 |
+
keyword_map = {}
|
| 119 |
+
|
| 120 |
+
for keyword in keywords:
|
| 121 |
+
keyword_map[keyword.lower()] = keyword
|
| 122 |
+
|
| 123 |
+
for keyword in keywords_new:
|
| 124 |
+
keyword_map[keyword[:2].upper() + keyword[2:].lower()] = keyword
|
| 125 |
+
|
| 126 |
+
##
|
| 127 |
+
## All the tokens recognized by the lexer
|
| 128 |
+
##
|
| 129 |
+
tokens = keywords + keywords_new + (
|
| 130 |
+
# Identifiers
|
| 131 |
+
'ID',
|
| 132 |
+
|
| 133 |
+
# Type identifiers (identifiers previously defined as
|
| 134 |
+
# types with typedef)
|
| 135 |
+
'TYPEID',
|
| 136 |
+
|
| 137 |
+
# constants
|
| 138 |
+
'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX', 'INT_CONST_BIN', 'INT_CONST_CHAR',
|
| 139 |
+
'FLOAT_CONST', 'HEX_FLOAT_CONST',
|
| 140 |
+
'CHAR_CONST',
|
| 141 |
+
'WCHAR_CONST',
|
| 142 |
+
'U8CHAR_CONST',
|
| 143 |
+
'U16CHAR_CONST',
|
| 144 |
+
'U32CHAR_CONST',
|
| 145 |
+
|
| 146 |
+
# String literals
|
| 147 |
+
'STRING_LITERAL',
|
| 148 |
+
'WSTRING_LITERAL',
|
| 149 |
+
'U8STRING_LITERAL',
|
| 150 |
+
'U16STRING_LITERAL',
|
| 151 |
+
'U32STRING_LITERAL',
|
| 152 |
+
|
| 153 |
+
# Operators
|
| 154 |
+
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
|
| 155 |
+
'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
|
| 156 |
+
'LOR', 'LAND', 'LNOT',
|
| 157 |
+
'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
|
| 158 |
+
|
| 159 |
+
# Assignment
|
| 160 |
+
'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL',
|
| 161 |
+
'PLUSEQUAL', 'MINUSEQUAL',
|
| 162 |
+
'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL',
|
| 163 |
+
'OREQUAL',
|
| 164 |
+
|
| 165 |
+
# Increment/decrement
|
| 166 |
+
'PLUSPLUS', 'MINUSMINUS',
|
| 167 |
+
|
| 168 |
+
# Structure dereference (->)
|
| 169 |
+
'ARROW',
|
| 170 |
+
|
| 171 |
+
# Conditional operator (?)
|
| 172 |
+
'CONDOP',
|
| 173 |
+
|
| 174 |
+
# Delimiters
|
| 175 |
+
'LPAREN', 'RPAREN', # ( )
|
| 176 |
+
'LBRACKET', 'RBRACKET', # [ ]
|
| 177 |
+
'LBRACE', 'RBRACE', # { }
|
| 178 |
+
'COMMA', 'PERIOD', # . ,
|
| 179 |
+
'SEMI', 'COLON', # ; :
|
| 180 |
+
|
| 181 |
+
# Ellipsis (...)
|
| 182 |
+
'ELLIPSIS',
|
| 183 |
+
|
| 184 |
+
# pre-processor
|
| 185 |
+
'PPHASH', # '#'
|
| 186 |
+
'PPPRAGMA', # 'pragma'
|
| 187 |
+
'PPPRAGMASTR',
|
| 188 |
+
)
|
| 189 |
+
|
| 190 |
+
##
|
| 191 |
+
## Regexes for use in tokens
|
| 192 |
+
##
|
| 193 |
+
##
|
| 194 |
+
|
| 195 |
+
# valid C identifiers (K&R2: A.2.3), plus '$' (supported by some compilers)
|
| 196 |
+
identifier = r'[a-zA-Z_$][0-9a-zA-Z_$]*'
|
| 197 |
+
|
| 198 |
+
hex_prefix = '0[xX]'
|
| 199 |
+
hex_digits = '[0-9a-fA-F]+'
|
| 200 |
+
bin_prefix = '0[bB]'
|
| 201 |
+
bin_digits = '[01]+'
|
| 202 |
+
|
| 203 |
+
# integer constants (K&R2: A.2.5.1)
|
| 204 |
+
integer_suffix_opt = r'(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?'
|
| 205 |
+
decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')'
|
| 206 |
+
octal_constant = '0[0-7]*'+integer_suffix_opt
|
| 207 |
+
hex_constant = hex_prefix+hex_digits+integer_suffix_opt
|
| 208 |
+
bin_constant = bin_prefix+bin_digits+integer_suffix_opt
|
| 209 |
+
|
| 210 |
+
bad_octal_constant = '0[0-7]*[89]'
|
| 211 |
+
|
| 212 |
+
# character constants (K&R2: A.2.5.2)
|
| 213 |
+
# Note: a-zA-Z and '.-~^_!=&;,' are allowed as escape chars to support #line
|
| 214 |
+
# directives with Windows paths as filenames (..\..\dir\file)
|
| 215 |
+
# For the same reason, decimal_escape allows all digit sequences. We want to
|
| 216 |
+
# parse all correct code, even if it means to sometimes parse incorrect
|
| 217 |
+
# code.
|
| 218 |
+
#
|
| 219 |
+
# The original regexes were taken verbatim from the C syntax definition,
|
| 220 |
+
# and were later modified to avoid worst-case exponential running time.
|
| 221 |
+
#
|
| 222 |
+
# simple_escape = r"""([a-zA-Z._~!=&\^\-\\?'"])"""
|
| 223 |
+
# decimal_escape = r"""(\d+)"""
|
| 224 |
+
# hex_escape = r"""(x[0-9a-fA-F]+)"""
|
| 225 |
+
# bad_escape = r"""([\\][^a-zA-Z._~^!=&\^\-\\?'"x0-7])"""
|
| 226 |
+
#
|
| 227 |
+
# The following modifications were made to avoid the ambiguity that allowed backtracking:
|
| 228 |
+
# (https://github.com/eliben/pycparser/issues/61)
|
| 229 |
+
#
|
| 230 |
+
# - \x was removed from simple_escape, unless it was not followed by a hex digit, to avoid ambiguity with hex_escape.
|
| 231 |
+
# - hex_escape allows one or more hex characters, but requires that the next character(if any) is not hex
|
| 232 |
+
# - decimal_escape allows one or more decimal characters, but requires that the next character(if any) is not a decimal
|
| 233 |
+
# - bad_escape does not allow any decimals (8-9), to avoid conflicting with the permissive decimal_escape.
|
| 234 |
+
#
|
| 235 |
+
# Without this change, python's `re` module would recursively try parsing each ambiguous escape sequence in multiple ways.
|
| 236 |
+
# e.g. `\123` could be parsed as `\1`+`23`, `\12`+`3`, and `\123`.
|
| 237 |
+
|
| 238 |
+
simple_escape = r"""([a-wyzA-Z._~!=&\^\-\\?'"]|x(?![0-9a-fA-F]))"""
|
| 239 |
+
decimal_escape = r"""(\d+)(?!\d)"""
|
| 240 |
+
hex_escape = r"""(x[0-9a-fA-F]+)(?![0-9a-fA-F])"""
|
| 241 |
+
bad_escape = r"""([\\][^a-zA-Z._~^!=&\^\-\\?'"x0-9])"""
|
| 242 |
+
|
| 243 |
+
escape_sequence = r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))'
|
| 244 |
+
|
| 245 |
+
# This complicated regex with lookahead might be slow for strings, so because all of the valid escapes (including \x) allowed
|
| 246 |
+
# 0 or more non-escaped characters after the first character, simple_escape+decimal_escape+hex_escape got simplified to
|
| 247 |
+
|
| 248 |
+
escape_sequence_start_in_string = r"""(\\[0-9a-zA-Z._~!=&\^\-\\?'"])"""
|
| 249 |
+
|
| 250 |
+
cconst_char = r"""([^'\\\n]|"""+escape_sequence+')'
|
| 251 |
+
char_const = "'"+cconst_char+"'"
|
| 252 |
+
wchar_const = 'L'+char_const
|
| 253 |
+
u8char_const = 'u8'+char_const
|
| 254 |
+
u16char_const = 'u'+char_const
|
| 255 |
+
u32char_const = 'U'+char_const
|
| 256 |
+
multicharacter_constant = "'"+cconst_char+"{2,4}'"
|
| 257 |
+
unmatched_quote = "('"+cconst_char+"*\\n)|('"+cconst_char+"*$)"
|
| 258 |
+
bad_char_const = r"""('"""+cconst_char+"""[^'\n]+')|('')|('"""+bad_escape+r"""[^'\n]*')"""
|
| 259 |
+
|
| 260 |
+
# string literals (K&R2: A.2.6)
|
| 261 |
+
string_char = r"""([^"\\\n]|"""+escape_sequence_start_in_string+')'
|
| 262 |
+
string_literal = '"'+string_char+'*"'
|
| 263 |
+
wstring_literal = 'L'+string_literal
|
| 264 |
+
u8string_literal = 'u8'+string_literal
|
| 265 |
+
u16string_literal = 'u'+string_literal
|
| 266 |
+
u32string_literal = 'U'+string_literal
|
| 267 |
+
bad_string_literal = '"'+string_char+'*'+bad_escape+string_char+'*"'
|
| 268 |
+
|
| 269 |
+
# floating constants (K&R2: A.2.5.3)
|
| 270 |
+
exponent_part = r"""([eE][-+]?[0-9]+)"""
|
| 271 |
+
fractional_constant = r"""([0-9]*\.[0-9]+)|([0-9]+\.)"""
|
| 272 |
+
floating_constant = '(((('+fractional_constant+')'+exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)'
|
| 273 |
+
binary_exponent_part = r'''([pP][+-]?[0-9]+)'''
|
| 274 |
+
hex_fractional_constant = '((('+hex_digits+r""")?\."""+hex_digits+')|('+hex_digits+r"""\.))"""
|
| 275 |
+
hex_floating_constant = '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+binary_exponent_part+'[FfLl]?)'
|
| 276 |
+
|
| 277 |
+
##
|
| 278 |
+
## Lexer states: used for preprocessor \n-terminated directives
|
| 279 |
+
##
|
| 280 |
+
states = (
|
| 281 |
+
# ppline: preprocessor line directives
|
| 282 |
+
#
|
| 283 |
+
('ppline', 'exclusive'),
|
| 284 |
+
|
| 285 |
+
# pppragma: pragma
|
| 286 |
+
#
|
| 287 |
+
('pppragma', 'exclusive'),
|
| 288 |
+
)
|
| 289 |
+
|
| 290 |
+
def t_PPHASH(self, t):
|
| 291 |
+
r'[ \t]*\#'
|
| 292 |
+
if self.line_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos):
|
| 293 |
+
t.lexer.begin('ppline')
|
| 294 |
+
self.pp_line = self.pp_filename = None
|
| 295 |
+
elif self.pragma_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos):
|
| 296 |
+
t.lexer.begin('pppragma')
|
| 297 |
+
else:
|
| 298 |
+
t.type = 'PPHASH'
|
| 299 |
+
return t
|
| 300 |
+
|
| 301 |
+
##
|
| 302 |
+
## Rules for the ppline state
|
| 303 |
+
##
|
| 304 |
+
@TOKEN(string_literal)
|
| 305 |
+
def t_ppline_FILENAME(self, t):
|
| 306 |
+
if self.pp_line is None:
|
| 307 |
+
self._error('filename before line number in #line', t)
|
| 308 |
+
else:
|
| 309 |
+
self.pp_filename = t.value.lstrip('"').rstrip('"')
|
| 310 |
+
|
| 311 |
+
@TOKEN(decimal_constant)
|
| 312 |
+
def t_ppline_LINE_NUMBER(self, t):
|
| 313 |
+
if self.pp_line is None:
|
| 314 |
+
self.pp_line = t.value
|
| 315 |
+
else:
|
| 316 |
+
# Ignore: GCC's cpp sometimes inserts a numeric flag
|
| 317 |
+
# after the file name
|
| 318 |
+
pass
|
| 319 |
+
|
| 320 |
+
def t_ppline_NEWLINE(self, t):
|
| 321 |
+
r'\n'
|
| 322 |
+
if self.pp_line is None:
|
| 323 |
+
self._error('line number missing in #line', t)
|
| 324 |
+
else:
|
| 325 |
+
self.lexer.lineno = int(self.pp_line)
|
| 326 |
+
|
| 327 |
+
if self.pp_filename is not None:
|
| 328 |
+
self.filename = self.pp_filename
|
| 329 |
+
|
| 330 |
+
t.lexer.begin('INITIAL')
|
| 331 |
+
|
| 332 |
+
def t_ppline_PPLINE(self, t):
|
| 333 |
+
r'line'
|
| 334 |
+
pass
|
| 335 |
+
|
| 336 |
+
t_ppline_ignore = ' \t'
|
| 337 |
+
|
| 338 |
+
def t_ppline_error(self, t):
|
| 339 |
+
self._error('invalid #line directive', t)
|
| 340 |
+
|
| 341 |
+
##
|
| 342 |
+
## Rules for the pppragma state
|
| 343 |
+
##
|
| 344 |
+
def t_pppragma_NEWLINE(self, t):
|
| 345 |
+
r'\n'
|
| 346 |
+
t.lexer.lineno += 1
|
| 347 |
+
t.lexer.begin('INITIAL')
|
| 348 |
+
|
| 349 |
+
def t_pppragma_PPPRAGMA(self, t):
|
| 350 |
+
r'pragma'
|
| 351 |
+
return t
|
| 352 |
+
|
| 353 |
+
t_pppragma_ignore = ' \t'
|
| 354 |
+
|
| 355 |
+
def t_pppragma_STR(self, t):
|
| 356 |
+
'.+'
|
| 357 |
+
t.type = 'PPPRAGMASTR'
|
| 358 |
+
return t
|
| 359 |
+
|
| 360 |
+
def t_pppragma_error(self, t):
|
| 361 |
+
self._error('invalid #pragma directive', t)
|
| 362 |
+
|
| 363 |
+
##
|
| 364 |
+
## Rules for the normal state
|
| 365 |
+
##
|
| 366 |
+
t_ignore = ' \t'
|
| 367 |
+
|
| 368 |
+
# Newlines
|
| 369 |
+
def t_NEWLINE(self, t):
|
| 370 |
+
r'\n+'
|
| 371 |
+
t.lexer.lineno += t.value.count("\n")
|
| 372 |
+
|
| 373 |
+
# Operators
|
| 374 |
+
t_PLUS = r'\+'
|
| 375 |
+
t_MINUS = r'-'
|
| 376 |
+
t_TIMES = r'\*'
|
| 377 |
+
t_DIVIDE = r'/'
|
| 378 |
+
t_MOD = r'%'
|
| 379 |
+
t_OR = r'\|'
|
| 380 |
+
t_AND = r'&'
|
| 381 |
+
t_NOT = r'~'
|
| 382 |
+
t_XOR = r'\^'
|
| 383 |
+
t_LSHIFT = r'<<'
|
| 384 |
+
t_RSHIFT = r'>>'
|
| 385 |
+
t_LOR = r'\|\|'
|
| 386 |
+
t_LAND = r'&&'
|
| 387 |
+
t_LNOT = r'!'
|
| 388 |
+
t_LT = r'<'
|
| 389 |
+
t_GT = r'>'
|
| 390 |
+
t_LE = r'<='
|
| 391 |
+
t_GE = r'>='
|
| 392 |
+
t_EQ = r'=='
|
| 393 |
+
t_NE = r'!='
|
| 394 |
+
|
| 395 |
+
# Assignment operators
|
| 396 |
+
t_EQUALS = r'='
|
| 397 |
+
t_TIMESEQUAL = r'\*='
|
| 398 |
+
t_DIVEQUAL = r'/='
|
| 399 |
+
t_MODEQUAL = r'%='
|
| 400 |
+
t_PLUSEQUAL = r'\+='
|
| 401 |
+
t_MINUSEQUAL = r'-='
|
| 402 |
+
t_LSHIFTEQUAL = r'<<='
|
| 403 |
+
t_RSHIFTEQUAL = r'>>='
|
| 404 |
+
t_ANDEQUAL = r'&='
|
| 405 |
+
t_OREQUAL = r'\|='
|
| 406 |
+
t_XOREQUAL = r'\^='
|
| 407 |
+
|
| 408 |
+
# Increment/decrement
|
| 409 |
+
t_PLUSPLUS = r'\+\+'
|
| 410 |
+
t_MINUSMINUS = r'--'
|
| 411 |
+
|
| 412 |
+
# ->
|
| 413 |
+
t_ARROW = r'->'
|
| 414 |
+
|
| 415 |
+
# ?
|
| 416 |
+
t_CONDOP = r'\?'
|
| 417 |
+
|
| 418 |
+
# Delimiters
|
| 419 |
+
t_LPAREN = r'\('
|
| 420 |
+
t_RPAREN = r'\)'
|
| 421 |
+
t_LBRACKET = r'\['
|
| 422 |
+
t_RBRACKET = r'\]'
|
| 423 |
+
t_COMMA = r','
|
| 424 |
+
t_PERIOD = r'\.'
|
| 425 |
+
t_SEMI = r';'
|
| 426 |
+
t_COLON = r':'
|
| 427 |
+
t_ELLIPSIS = r'\.\.\.'
|
| 428 |
+
|
| 429 |
+
# Scope delimiters
|
| 430 |
+
# To see why on_lbrace_func is needed, consider:
|
| 431 |
+
# typedef char TT;
|
| 432 |
+
# void foo(int TT) { TT = 10; }
|
| 433 |
+
# TT x = 5;
|
| 434 |
+
# Outside the function, TT is a typedef, but inside (starting and ending
|
| 435 |
+
# with the braces) it's a parameter. The trouble begins with yacc's
|
| 436 |
+
# lookahead token. If we open a new scope in brace_open, then TT has
|
| 437 |
+
# already been read and incorrectly interpreted as TYPEID. So, we need
|
| 438 |
+
# to open and close scopes from within the lexer.
|
| 439 |
+
# Similar for the TT immediately outside the end of the function.
|
| 440 |
+
#
|
| 441 |
+
@TOKEN(r'\{')
|
| 442 |
+
def t_LBRACE(self, t):
|
| 443 |
+
self.on_lbrace_func()
|
| 444 |
+
return t
|
| 445 |
+
@TOKEN(r'\}')
|
| 446 |
+
def t_RBRACE(self, t):
|
| 447 |
+
self.on_rbrace_func()
|
| 448 |
+
return t
|
| 449 |
+
|
| 450 |
+
t_STRING_LITERAL = string_literal
|
| 451 |
+
|
| 452 |
+
# The following floating and integer constants are defined as
|
| 453 |
+
# functions to impose a strict order (otherwise, decimal
|
| 454 |
+
# is placed before the others because its regex is longer,
|
| 455 |
+
# and this is bad)
|
| 456 |
+
#
|
| 457 |
+
@TOKEN(floating_constant)
|
| 458 |
+
def t_FLOAT_CONST(self, t):
|
| 459 |
+
return t
|
| 460 |
+
|
| 461 |
+
@TOKEN(hex_floating_constant)
|
| 462 |
+
def t_HEX_FLOAT_CONST(self, t):
|
| 463 |
+
return t
|
| 464 |
+
|
| 465 |
+
@TOKEN(hex_constant)
|
| 466 |
+
def t_INT_CONST_HEX(self, t):
|
| 467 |
+
return t
|
| 468 |
+
|
| 469 |
+
@TOKEN(bin_constant)
|
| 470 |
+
def t_INT_CONST_BIN(self, t):
|
| 471 |
+
return t
|
| 472 |
+
|
| 473 |
+
@TOKEN(bad_octal_constant)
|
| 474 |
+
def t_BAD_CONST_OCT(self, t):
|
| 475 |
+
msg = "Invalid octal constant"
|
| 476 |
+
self._error(msg, t)
|
| 477 |
+
|
| 478 |
+
@TOKEN(octal_constant)
|
| 479 |
+
def t_INT_CONST_OCT(self, t):
|
| 480 |
+
return t
|
| 481 |
+
|
| 482 |
+
@TOKEN(decimal_constant)
|
| 483 |
+
def t_INT_CONST_DEC(self, t):
|
| 484 |
+
return t
|
| 485 |
+
|
| 486 |
+
# Must come before bad_char_const, to prevent it from
|
| 487 |
+
# catching valid char constants as invalid
|
| 488 |
+
#
|
| 489 |
+
@TOKEN(multicharacter_constant)
|
| 490 |
+
def t_INT_CONST_CHAR(self, t):
|
| 491 |
+
return t
|
| 492 |
+
|
| 493 |
+
@TOKEN(char_const)
|
| 494 |
+
def t_CHAR_CONST(self, t):
|
| 495 |
+
return t
|
| 496 |
+
|
| 497 |
+
@TOKEN(wchar_const)
|
| 498 |
+
def t_WCHAR_CONST(self, t):
|
| 499 |
+
return t
|
| 500 |
+
|
| 501 |
+
@TOKEN(u8char_const)
|
| 502 |
+
def t_U8CHAR_CONST(self, t):
|
| 503 |
+
return t
|
| 504 |
+
|
| 505 |
+
@TOKEN(u16char_const)
|
| 506 |
+
def t_U16CHAR_CONST(self, t):
|
| 507 |
+
return t
|
| 508 |
+
|
| 509 |
+
@TOKEN(u32char_const)
|
| 510 |
+
def t_U32CHAR_CONST(self, t):
|
| 511 |
+
return t
|
| 512 |
+
|
| 513 |
+
@TOKEN(unmatched_quote)
|
| 514 |
+
def t_UNMATCHED_QUOTE(self, t):
|
| 515 |
+
msg = "Unmatched '"
|
| 516 |
+
self._error(msg, t)
|
| 517 |
+
|
| 518 |
+
@TOKEN(bad_char_const)
|
| 519 |
+
def t_BAD_CHAR_CONST(self, t):
|
| 520 |
+
msg = "Invalid char constant %s" % t.value
|
| 521 |
+
self._error(msg, t)
|
| 522 |
+
|
| 523 |
+
@TOKEN(wstring_literal)
|
| 524 |
+
def t_WSTRING_LITERAL(self, t):
|
| 525 |
+
return t
|
| 526 |
+
|
| 527 |
+
@TOKEN(u8string_literal)
|
| 528 |
+
def t_U8STRING_LITERAL(self, t):
|
| 529 |
+
return t
|
| 530 |
+
|
| 531 |
+
@TOKEN(u16string_literal)
|
| 532 |
+
def t_U16STRING_LITERAL(self, t):
|
| 533 |
+
return t
|
| 534 |
+
|
| 535 |
+
@TOKEN(u32string_literal)
|
| 536 |
+
def t_U32STRING_LITERAL(self, t):
|
| 537 |
+
return t
|
| 538 |
+
|
| 539 |
+
# unmatched string literals are caught by the preprocessor
|
| 540 |
+
|
| 541 |
+
@TOKEN(bad_string_literal)
|
| 542 |
+
def t_BAD_STRING_LITERAL(self, t):
|
| 543 |
+
msg = "String contains invalid escape code"
|
| 544 |
+
self._error(msg, t)
|
| 545 |
+
|
| 546 |
+
@TOKEN(identifier)
|
| 547 |
+
def t_ID(self, t):
|
| 548 |
+
t.type = self.keyword_map.get(t.value, "ID")
|
| 549 |
+
if t.type == 'ID' and self.type_lookup_func(t.value):
|
| 550 |
+
t.type = "TYPEID"
|
| 551 |
+
return t
|
| 552 |
+
|
| 553 |
+
def t_error(self, t):
|
| 554 |
+
msg = 'Illegal character %s' % repr(t.value[0])
|
| 555 |
+
self._error(msg, t)
|
rtme/lib/python3.10/site-packages/pycparser/c_parser.py
ADDED
|
@@ -0,0 +1,1950 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#------------------------------------------------------------------------------
|
| 2 |
+
# pycparser: c_parser.py
|
| 3 |
+
#
|
| 4 |
+
# CParser class: Parser and AST builder for the C language
|
| 5 |
+
#
|
| 6 |
+
# Eli Bendersky [https://eli.thegreenplace.net/]
|
| 7 |
+
# License: BSD
|
| 8 |
+
#------------------------------------------------------------------------------
|
| 9 |
+
from .ply import yacc
|
| 10 |
+
|
| 11 |
+
from . import c_ast
|
| 12 |
+
from .c_lexer import CLexer
|
| 13 |
+
from .plyparser import PLYParser, ParseError, parameterized, template
|
| 14 |
+
from .ast_transforms import fix_switch_cases, fix_atomic_specifiers
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
@template
|
| 18 |
+
class CParser(PLYParser):
|
| 19 |
+
def __init__(
|
| 20 |
+
self,
|
| 21 |
+
lex_optimize=True,
|
| 22 |
+
lexer=CLexer,
|
| 23 |
+
lextab='pycparser.lextab',
|
| 24 |
+
yacc_optimize=True,
|
| 25 |
+
yacctab='pycparser.yacctab',
|
| 26 |
+
yacc_debug=False,
|
| 27 |
+
taboutputdir=''):
|
| 28 |
+
""" Create a new CParser.
|
| 29 |
+
|
| 30 |
+
Some arguments for controlling the debug/optimization
|
| 31 |
+
level of the parser are provided. The defaults are
|
| 32 |
+
tuned for release/performance mode.
|
| 33 |
+
The simple rules for using them are:
|
| 34 |
+
*) When tweaking CParser/CLexer, set these to False
|
| 35 |
+
*) When releasing a stable parser, set to True
|
| 36 |
+
|
| 37 |
+
lex_optimize:
|
| 38 |
+
Set to False when you're modifying the lexer.
|
| 39 |
+
Otherwise, changes in the lexer won't be used, if
|
| 40 |
+
some lextab.py file exists.
|
| 41 |
+
When releasing with a stable lexer, set to True
|
| 42 |
+
to save the re-generation of the lexer table on
|
| 43 |
+
each run.
|
| 44 |
+
|
| 45 |
+
lexer:
|
| 46 |
+
Set this parameter to define the lexer to use if
|
| 47 |
+
you're not using the default CLexer.
|
| 48 |
+
|
| 49 |
+
lextab:
|
| 50 |
+
Points to the lex table that's used for optimized
|
| 51 |
+
mode. Only if you're modifying the lexer and want
|
| 52 |
+
some tests to avoid re-generating the table, make
|
| 53 |
+
this point to a local lex table file (that's been
|
| 54 |
+
earlier generated with lex_optimize=True)
|
| 55 |
+
|
| 56 |
+
yacc_optimize:
|
| 57 |
+
Set to False when you're modifying the parser.
|
| 58 |
+
Otherwise, changes in the parser won't be used, if
|
| 59 |
+
some parsetab.py file exists.
|
| 60 |
+
When releasing with a stable parser, set to True
|
| 61 |
+
to save the re-generation of the parser table on
|
| 62 |
+
each run.
|
| 63 |
+
|
| 64 |
+
yacctab:
|
| 65 |
+
Points to the yacc table that's used for optimized
|
| 66 |
+
mode. Only if you're modifying the parser, make
|
| 67 |
+
this point to a local yacc table file
|
| 68 |
+
|
| 69 |
+
yacc_debug:
|
| 70 |
+
Generate a parser.out file that explains how yacc
|
| 71 |
+
built the parsing table from the grammar.
|
| 72 |
+
|
| 73 |
+
taboutputdir:
|
| 74 |
+
Set this parameter to control the location of generated
|
| 75 |
+
lextab and yacctab files.
|
| 76 |
+
"""
|
| 77 |
+
self.clex = lexer(
|
| 78 |
+
error_func=self._lex_error_func,
|
| 79 |
+
on_lbrace_func=self._lex_on_lbrace_func,
|
| 80 |
+
on_rbrace_func=self._lex_on_rbrace_func,
|
| 81 |
+
type_lookup_func=self._lex_type_lookup_func)
|
| 82 |
+
|
| 83 |
+
self.clex.build(
|
| 84 |
+
optimize=lex_optimize,
|
| 85 |
+
lextab=lextab,
|
| 86 |
+
outputdir=taboutputdir)
|
| 87 |
+
self.tokens = self.clex.tokens
|
| 88 |
+
|
| 89 |
+
rules_with_opt = [
|
| 90 |
+
'abstract_declarator',
|
| 91 |
+
'assignment_expression',
|
| 92 |
+
'declaration_list',
|
| 93 |
+
'declaration_specifiers_no_type',
|
| 94 |
+
'designation',
|
| 95 |
+
'expression',
|
| 96 |
+
'identifier_list',
|
| 97 |
+
'init_declarator_list',
|
| 98 |
+
'id_init_declarator_list',
|
| 99 |
+
'initializer_list',
|
| 100 |
+
'parameter_type_list',
|
| 101 |
+
'block_item_list',
|
| 102 |
+
'type_qualifier_list',
|
| 103 |
+
'struct_declarator_list'
|
| 104 |
+
]
|
| 105 |
+
|
| 106 |
+
for rule in rules_with_opt:
|
| 107 |
+
self._create_opt_rule(rule)
|
| 108 |
+
|
| 109 |
+
self.cparser = yacc.yacc(
|
| 110 |
+
module=self,
|
| 111 |
+
start='translation_unit_or_empty',
|
| 112 |
+
debug=yacc_debug,
|
| 113 |
+
optimize=yacc_optimize,
|
| 114 |
+
tabmodule=yacctab,
|
| 115 |
+
outputdir=taboutputdir)
|
| 116 |
+
|
| 117 |
+
# Stack of scopes for keeping track of symbols. _scope_stack[-1] is
|
| 118 |
+
# the current (topmost) scope. Each scope is a dictionary that
|
| 119 |
+
# specifies whether a name is a type. If _scope_stack[n][name] is
|
| 120 |
+
# True, 'name' is currently a type in the scope. If it's False,
|
| 121 |
+
# 'name' is used in the scope but not as a type (for instance, if we
|
| 122 |
+
# saw: int name;
|
| 123 |
+
# If 'name' is not a key in _scope_stack[n] then 'name' was not defined
|
| 124 |
+
# in this scope at all.
|
| 125 |
+
self._scope_stack = [dict()]
|
| 126 |
+
|
| 127 |
+
# Keeps track of the last token given to yacc (the lookahead token)
|
| 128 |
+
self._last_yielded_token = None
|
| 129 |
+
|
| 130 |
+
def parse(self, text, filename='', debug=False):
|
| 131 |
+
""" Parses C code and returns an AST.
|
| 132 |
+
|
| 133 |
+
text:
|
| 134 |
+
A string containing the C source code
|
| 135 |
+
|
| 136 |
+
filename:
|
| 137 |
+
Name of the file being parsed (for meaningful
|
| 138 |
+
error messages)
|
| 139 |
+
|
| 140 |
+
debug:
|
| 141 |
+
Debug flag to YACC
|
| 142 |
+
"""
|
| 143 |
+
self.clex.filename = filename
|
| 144 |
+
self.clex.reset_lineno()
|
| 145 |
+
self._scope_stack = [dict()]
|
| 146 |
+
self._last_yielded_token = None
|
| 147 |
+
return self.cparser.parse(
|
| 148 |
+
input=text,
|
| 149 |
+
lexer=self.clex,
|
| 150 |
+
debug=debug)
|
| 151 |
+
|
| 152 |
+
######################-- PRIVATE --######################
|
| 153 |
+
|
| 154 |
+
def _push_scope(self):
|
| 155 |
+
self._scope_stack.append(dict())
|
| 156 |
+
|
| 157 |
+
def _pop_scope(self):
|
| 158 |
+
assert len(self._scope_stack) > 1
|
| 159 |
+
self._scope_stack.pop()
|
| 160 |
+
|
| 161 |
+
def _add_typedef_name(self, name, coord):
|
| 162 |
+
""" Add a new typedef name (ie a TYPEID) to the current scope
|
| 163 |
+
"""
|
| 164 |
+
if not self._scope_stack[-1].get(name, True):
|
| 165 |
+
self._parse_error(
|
| 166 |
+
"Typedef %r previously declared as non-typedef "
|
| 167 |
+
"in this scope" % name, coord)
|
| 168 |
+
self._scope_stack[-1][name] = True
|
| 169 |
+
|
| 170 |
+
def _add_identifier(self, name, coord):
|
| 171 |
+
""" Add a new object, function, or enum member name (ie an ID) to the
|
| 172 |
+
current scope
|
| 173 |
+
"""
|
| 174 |
+
if self._scope_stack[-1].get(name, False):
|
| 175 |
+
self._parse_error(
|
| 176 |
+
"Non-typedef %r previously declared as typedef "
|
| 177 |
+
"in this scope" % name, coord)
|
| 178 |
+
self._scope_stack[-1][name] = False
|
| 179 |
+
|
| 180 |
+
def _is_type_in_scope(self, name):
|
| 181 |
+
""" Is *name* a typedef-name in the current scope?
|
| 182 |
+
"""
|
| 183 |
+
for scope in reversed(self._scope_stack):
|
| 184 |
+
# If name is an identifier in this scope it shadows typedefs in
|
| 185 |
+
# higher scopes.
|
| 186 |
+
in_scope = scope.get(name)
|
| 187 |
+
if in_scope is not None: return in_scope
|
| 188 |
+
return False
|
| 189 |
+
|
| 190 |
+
def _lex_error_func(self, msg, line, column):
|
| 191 |
+
self._parse_error(msg, self._coord(line, column))
|
| 192 |
+
|
| 193 |
+
def _lex_on_lbrace_func(self):
|
| 194 |
+
self._push_scope()
|
| 195 |
+
|
| 196 |
+
def _lex_on_rbrace_func(self):
|
| 197 |
+
self._pop_scope()
|
| 198 |
+
|
| 199 |
+
def _lex_type_lookup_func(self, name):
|
| 200 |
+
""" Looks up types that were previously defined with
|
| 201 |
+
typedef.
|
| 202 |
+
Passed to the lexer for recognizing identifiers that
|
| 203 |
+
are types.
|
| 204 |
+
"""
|
| 205 |
+
is_type = self._is_type_in_scope(name)
|
| 206 |
+
return is_type
|
| 207 |
+
|
| 208 |
+
def _get_yacc_lookahead_token(self):
|
| 209 |
+
""" We need access to yacc's lookahead token in certain cases.
|
| 210 |
+
This is the last token yacc requested from the lexer, so we
|
| 211 |
+
ask the lexer.
|
| 212 |
+
"""
|
| 213 |
+
return self.clex.last_token
|
| 214 |
+
|
| 215 |
+
# To understand what's going on here, read sections A.8.5 and
|
| 216 |
+
# A.8.6 of K&R2 very carefully.
|
| 217 |
+
#
|
| 218 |
+
# A C type consists of a basic type declaration, with a list
|
| 219 |
+
# of modifiers. For example:
|
| 220 |
+
#
|
| 221 |
+
# int *c[5];
|
| 222 |
+
#
|
| 223 |
+
# The basic declaration here is 'int c', and the pointer and
|
| 224 |
+
# the array are the modifiers.
|
| 225 |
+
#
|
| 226 |
+
# Basic declarations are represented by TypeDecl (from module c_ast) and the
|
| 227 |
+
# modifiers are FuncDecl, PtrDecl and ArrayDecl.
|
| 228 |
+
#
|
| 229 |
+
# The standard states that whenever a new modifier is parsed, it should be
|
| 230 |
+
# added to the end of the list of modifiers. For example:
|
| 231 |
+
#
|
| 232 |
+
# K&R2 A.8.6.2: Array Declarators
|
| 233 |
+
#
|
| 234 |
+
# In a declaration T D where D has the form
|
| 235 |
+
# D1 [constant-expression-opt]
|
| 236 |
+
# and the type of the identifier in the declaration T D1 is
|
| 237 |
+
# "type-modifier T", the type of the
|
| 238 |
+
# identifier of D is "type-modifier array of T"
|
| 239 |
+
#
|
| 240 |
+
# This is what this method does. The declarator it receives
|
| 241 |
+
# can be a list of declarators ending with TypeDecl. It
|
| 242 |
+
# tacks the modifier to the end of this list, just before
|
| 243 |
+
# the TypeDecl.
|
| 244 |
+
#
|
| 245 |
+
# Additionally, the modifier may be a list itself. This is
|
| 246 |
+
# useful for pointers, that can come as a chain from the rule
|
| 247 |
+
# p_pointer. In this case, the whole modifier list is spliced
|
| 248 |
+
# into the new location.
|
| 249 |
+
def _type_modify_decl(self, decl, modifier):
|
| 250 |
+
""" Tacks a type modifier on a declarator, and returns
|
| 251 |
+
the modified declarator.
|
| 252 |
+
|
| 253 |
+
Note: the declarator and modifier may be modified
|
| 254 |
+
"""
|
| 255 |
+
#~ print '****'
|
| 256 |
+
#~ decl.show(offset=3)
|
| 257 |
+
#~ modifier.show(offset=3)
|
| 258 |
+
#~ print '****'
|
| 259 |
+
|
| 260 |
+
modifier_head = modifier
|
| 261 |
+
modifier_tail = modifier
|
| 262 |
+
|
| 263 |
+
# The modifier may be a nested list. Reach its tail.
|
| 264 |
+
while modifier_tail.type:
|
| 265 |
+
modifier_tail = modifier_tail.type
|
| 266 |
+
|
| 267 |
+
# If the decl is a basic type, just tack the modifier onto it.
|
| 268 |
+
if isinstance(decl, c_ast.TypeDecl):
|
| 269 |
+
modifier_tail.type = decl
|
| 270 |
+
return modifier
|
| 271 |
+
else:
|
| 272 |
+
# Otherwise, the decl is a list of modifiers. Reach
|
| 273 |
+
# its tail and splice the modifier onto the tail,
|
| 274 |
+
# pointing to the underlying basic type.
|
| 275 |
+
decl_tail = decl
|
| 276 |
+
|
| 277 |
+
while not isinstance(decl_tail.type, c_ast.TypeDecl):
|
| 278 |
+
decl_tail = decl_tail.type
|
| 279 |
+
|
| 280 |
+
modifier_tail.type = decl_tail.type
|
| 281 |
+
decl_tail.type = modifier_head
|
| 282 |
+
return decl
|
| 283 |
+
|
| 284 |
+
# Due to the order in which declarators are constructed,
|
| 285 |
+
# they have to be fixed in order to look like a normal AST.
|
| 286 |
+
#
|
| 287 |
+
# When a declaration arrives from syntax construction, it has
|
| 288 |
+
# these problems:
|
| 289 |
+
# * The innermost TypeDecl has no type (because the basic
|
| 290 |
+
# type is only known at the uppermost declaration level)
|
| 291 |
+
# * The declaration has no variable name, since that is saved
|
| 292 |
+
# in the innermost TypeDecl
|
| 293 |
+
# * The typename of the declaration is a list of type
|
| 294 |
+
# specifiers, and not a node. Here, basic identifier types
|
| 295 |
+
# should be separated from more complex types like enums
|
| 296 |
+
# and structs.
|
| 297 |
+
#
|
| 298 |
+
# This method fixes these problems.
|
| 299 |
+
def _fix_decl_name_type(self, decl, typename):
|
| 300 |
+
""" Fixes a declaration. Modifies decl.
|
| 301 |
+
"""
|
| 302 |
+
# Reach the underlying basic type
|
| 303 |
+
#
|
| 304 |
+
type = decl
|
| 305 |
+
while not isinstance(type, c_ast.TypeDecl):
|
| 306 |
+
type = type.type
|
| 307 |
+
|
| 308 |
+
decl.name = type.declname
|
| 309 |
+
type.quals = decl.quals[:]
|
| 310 |
+
|
| 311 |
+
# The typename is a list of types. If any type in this
|
| 312 |
+
# list isn't an IdentifierType, it must be the only
|
| 313 |
+
# type in the list (it's illegal to declare "int enum ..")
|
| 314 |
+
# If all the types are basic, they're collected in the
|
| 315 |
+
# IdentifierType holder.
|
| 316 |
+
for tn in typename:
|
| 317 |
+
if not isinstance(tn, c_ast.IdentifierType):
|
| 318 |
+
if len(typename) > 1:
|
| 319 |
+
self._parse_error(
|
| 320 |
+
"Invalid multiple types specified", tn.coord)
|
| 321 |
+
else:
|
| 322 |
+
type.type = tn
|
| 323 |
+
return decl
|
| 324 |
+
|
| 325 |
+
if not typename:
|
| 326 |
+
# Functions default to returning int
|
| 327 |
+
#
|
| 328 |
+
if not isinstance(decl.type, c_ast.FuncDecl):
|
| 329 |
+
self._parse_error(
|
| 330 |
+
"Missing type in declaration", decl.coord)
|
| 331 |
+
type.type = c_ast.IdentifierType(
|
| 332 |
+
['int'],
|
| 333 |
+
coord=decl.coord)
|
| 334 |
+
else:
|
| 335 |
+
# At this point, we know that typename is a list of IdentifierType
|
| 336 |
+
# nodes. Concatenate all the names into a single list.
|
| 337 |
+
#
|
| 338 |
+
type.type = c_ast.IdentifierType(
|
| 339 |
+
[name for id in typename for name in id.names],
|
| 340 |
+
coord=typename[0].coord)
|
| 341 |
+
return decl
|
| 342 |
+
|
| 343 |
+
def _add_declaration_specifier(self, declspec, newspec, kind, append=False):
|
| 344 |
+
""" Declaration specifiers are represented by a dictionary
|
| 345 |
+
with the entries:
|
| 346 |
+
* qual: a list of type qualifiers
|
| 347 |
+
* storage: a list of storage type qualifiers
|
| 348 |
+
* type: a list of type specifiers
|
| 349 |
+
* function: a list of function specifiers
|
| 350 |
+
* alignment: a list of alignment specifiers
|
| 351 |
+
|
| 352 |
+
This method is given a declaration specifier, and a
|
| 353 |
+
new specifier of a given kind.
|
| 354 |
+
If `append` is True, the new specifier is added to the end of
|
| 355 |
+
the specifiers list, otherwise it's added at the beginning.
|
| 356 |
+
Returns the declaration specifier, with the new
|
| 357 |
+
specifier incorporated.
|
| 358 |
+
"""
|
| 359 |
+
spec = declspec or dict(qual=[], storage=[], type=[], function=[], alignment=[])
|
| 360 |
+
|
| 361 |
+
if append:
|
| 362 |
+
spec[kind].append(newspec)
|
| 363 |
+
else:
|
| 364 |
+
spec[kind].insert(0, newspec)
|
| 365 |
+
|
| 366 |
+
return spec
|
| 367 |
+
|
| 368 |
+
def _build_declarations(self, spec, decls, typedef_namespace=False):
|
| 369 |
+
""" Builds a list of declarations all sharing the given specifiers.
|
| 370 |
+
If typedef_namespace is true, each declared name is added
|
| 371 |
+
to the "typedef namespace", which also includes objects,
|
| 372 |
+
functions, and enum constants.
|
| 373 |
+
"""
|
| 374 |
+
is_typedef = 'typedef' in spec['storage']
|
| 375 |
+
declarations = []
|
| 376 |
+
|
| 377 |
+
# Bit-fields are allowed to be unnamed.
|
| 378 |
+
if decls[0].get('bitsize') is not None:
|
| 379 |
+
pass
|
| 380 |
+
|
| 381 |
+
# When redeclaring typedef names as identifiers in inner scopes, a
|
| 382 |
+
# problem can occur where the identifier gets grouped into
|
| 383 |
+
# spec['type'], leaving decl as None. This can only occur for the
|
| 384 |
+
# first declarator.
|
| 385 |
+
elif decls[0]['decl'] is None:
|
| 386 |
+
if len(spec['type']) < 2 or len(spec['type'][-1].names) != 1 or \
|
| 387 |
+
not self._is_type_in_scope(spec['type'][-1].names[0]):
|
| 388 |
+
coord = '?'
|
| 389 |
+
for t in spec['type']:
|
| 390 |
+
if hasattr(t, 'coord'):
|
| 391 |
+
coord = t.coord
|
| 392 |
+
break
|
| 393 |
+
self._parse_error('Invalid declaration', coord)
|
| 394 |
+
|
| 395 |
+
# Make this look as if it came from "direct_declarator:ID"
|
| 396 |
+
decls[0]['decl'] = c_ast.TypeDecl(
|
| 397 |
+
declname=spec['type'][-1].names[0],
|
| 398 |
+
type=None,
|
| 399 |
+
quals=None,
|
| 400 |
+
align=spec['alignment'],
|
| 401 |
+
coord=spec['type'][-1].coord)
|
| 402 |
+
# Remove the "new" type's name from the end of spec['type']
|
| 403 |
+
del spec['type'][-1]
|
| 404 |
+
|
| 405 |
+
# A similar problem can occur where the declaration ends up looking
|
| 406 |
+
# like an abstract declarator. Give it a name if this is the case.
|
| 407 |
+
elif not isinstance(decls[0]['decl'], (
|
| 408 |
+
c_ast.Enum, c_ast.Struct, c_ast.Union, c_ast.IdentifierType)):
|
| 409 |
+
decls_0_tail = decls[0]['decl']
|
| 410 |
+
while not isinstance(decls_0_tail, c_ast.TypeDecl):
|
| 411 |
+
decls_0_tail = decls_0_tail.type
|
| 412 |
+
if decls_0_tail.declname is None:
|
| 413 |
+
decls_0_tail.declname = spec['type'][-1].names[0]
|
| 414 |
+
del spec['type'][-1]
|
| 415 |
+
|
| 416 |
+
for decl in decls:
|
| 417 |
+
assert decl['decl'] is not None
|
| 418 |
+
if is_typedef:
|
| 419 |
+
declaration = c_ast.Typedef(
|
| 420 |
+
name=None,
|
| 421 |
+
quals=spec['qual'],
|
| 422 |
+
storage=spec['storage'],
|
| 423 |
+
type=decl['decl'],
|
| 424 |
+
coord=decl['decl'].coord)
|
| 425 |
+
else:
|
| 426 |
+
declaration = c_ast.Decl(
|
| 427 |
+
name=None,
|
| 428 |
+
quals=spec['qual'],
|
| 429 |
+
align=spec['alignment'],
|
| 430 |
+
storage=spec['storage'],
|
| 431 |
+
funcspec=spec['function'],
|
| 432 |
+
type=decl['decl'],
|
| 433 |
+
init=decl.get('init'),
|
| 434 |
+
bitsize=decl.get('bitsize'),
|
| 435 |
+
coord=decl['decl'].coord)
|
| 436 |
+
|
| 437 |
+
if isinstance(declaration.type, (
|
| 438 |
+
c_ast.Enum, c_ast.Struct, c_ast.Union,
|
| 439 |
+
c_ast.IdentifierType)):
|
| 440 |
+
fixed_decl = declaration
|
| 441 |
+
else:
|
| 442 |
+
fixed_decl = self._fix_decl_name_type(declaration, spec['type'])
|
| 443 |
+
|
| 444 |
+
# Add the type name defined by typedef to a
|
| 445 |
+
# symbol table (for usage in the lexer)
|
| 446 |
+
if typedef_namespace:
|
| 447 |
+
if is_typedef:
|
| 448 |
+
self._add_typedef_name(fixed_decl.name, fixed_decl.coord)
|
| 449 |
+
else:
|
| 450 |
+
self._add_identifier(fixed_decl.name, fixed_decl.coord)
|
| 451 |
+
|
| 452 |
+
fixed_decl = fix_atomic_specifiers(fixed_decl)
|
| 453 |
+
declarations.append(fixed_decl)
|
| 454 |
+
|
| 455 |
+
return declarations
|
| 456 |
+
|
| 457 |
+
def _build_function_definition(self, spec, decl, param_decls, body):
|
| 458 |
+
""" Builds a function definition.
|
| 459 |
+
"""
|
| 460 |
+
if 'typedef' in spec['storage']:
|
| 461 |
+
self._parse_error("Invalid typedef", decl.coord)
|
| 462 |
+
|
| 463 |
+
declaration = self._build_declarations(
|
| 464 |
+
spec=spec,
|
| 465 |
+
decls=[dict(decl=decl, init=None)],
|
| 466 |
+
typedef_namespace=True)[0]
|
| 467 |
+
|
| 468 |
+
return c_ast.FuncDef(
|
| 469 |
+
decl=declaration,
|
| 470 |
+
param_decls=param_decls,
|
| 471 |
+
body=body,
|
| 472 |
+
coord=decl.coord)
|
| 473 |
+
|
| 474 |
+
def _select_struct_union_class(self, token):
|
| 475 |
+
""" Given a token (either STRUCT or UNION), selects the
|
| 476 |
+
appropriate AST class.
|
| 477 |
+
"""
|
| 478 |
+
if token == 'struct':
|
| 479 |
+
return c_ast.Struct
|
| 480 |
+
else:
|
| 481 |
+
return c_ast.Union
|
| 482 |
+
|
| 483 |
+
##
|
| 484 |
+
## Precedence and associativity of operators
|
| 485 |
+
##
|
| 486 |
+
# If this changes, c_generator.CGenerator.precedence_map needs to change as
|
| 487 |
+
# well
|
| 488 |
+
precedence = (
|
| 489 |
+
('left', 'LOR'),
|
| 490 |
+
('left', 'LAND'),
|
| 491 |
+
('left', 'OR'),
|
| 492 |
+
('left', 'XOR'),
|
| 493 |
+
('left', 'AND'),
|
| 494 |
+
('left', 'EQ', 'NE'),
|
| 495 |
+
('left', 'GT', 'GE', 'LT', 'LE'),
|
| 496 |
+
('left', 'RSHIFT', 'LSHIFT'),
|
| 497 |
+
('left', 'PLUS', 'MINUS'),
|
| 498 |
+
('left', 'TIMES', 'DIVIDE', 'MOD')
|
| 499 |
+
)
|
| 500 |
+
|
| 501 |
+
##
|
| 502 |
+
## Grammar productions
|
| 503 |
+
## Implementation of the BNF defined in K&R2 A.13
|
| 504 |
+
##
|
| 505 |
+
|
| 506 |
+
# Wrapper around a translation unit, to allow for empty input.
|
| 507 |
+
# Not strictly part of the C99 Grammar, but useful in practice.
|
| 508 |
+
def p_translation_unit_or_empty(self, p):
|
| 509 |
+
""" translation_unit_or_empty : translation_unit
|
| 510 |
+
| empty
|
| 511 |
+
"""
|
| 512 |
+
if p[1] is None:
|
| 513 |
+
p[0] = c_ast.FileAST([])
|
| 514 |
+
else:
|
| 515 |
+
p[0] = c_ast.FileAST(p[1])
|
| 516 |
+
|
| 517 |
+
def p_translation_unit_1(self, p):
|
| 518 |
+
""" translation_unit : external_declaration
|
| 519 |
+
"""
|
| 520 |
+
# Note: external_declaration is already a list
|
| 521 |
+
p[0] = p[1]
|
| 522 |
+
|
| 523 |
+
def p_translation_unit_2(self, p):
|
| 524 |
+
""" translation_unit : translation_unit external_declaration
|
| 525 |
+
"""
|
| 526 |
+
p[1].extend(p[2])
|
| 527 |
+
p[0] = p[1]
|
| 528 |
+
|
| 529 |
+
# Declarations always come as lists (because they can be
|
| 530 |
+
# several in one line), so we wrap the function definition
|
| 531 |
+
# into a list as well, to make the return value of
|
| 532 |
+
# external_declaration homogeneous.
|
| 533 |
+
def p_external_declaration_1(self, p):
|
| 534 |
+
""" external_declaration : function_definition
|
| 535 |
+
"""
|
| 536 |
+
p[0] = [p[1]]
|
| 537 |
+
|
| 538 |
+
def p_external_declaration_2(self, p):
|
| 539 |
+
""" external_declaration : declaration
|
| 540 |
+
"""
|
| 541 |
+
p[0] = p[1]
|
| 542 |
+
|
| 543 |
+
def p_external_declaration_3(self, p):
|
| 544 |
+
""" external_declaration : pp_directive
|
| 545 |
+
| pppragma_directive
|
| 546 |
+
"""
|
| 547 |
+
p[0] = [p[1]]
|
| 548 |
+
|
| 549 |
+
def p_external_declaration_4(self, p):
|
| 550 |
+
""" external_declaration : SEMI
|
| 551 |
+
"""
|
| 552 |
+
p[0] = []
|
| 553 |
+
|
| 554 |
+
def p_external_declaration_5(self, p):
|
| 555 |
+
""" external_declaration : static_assert
|
| 556 |
+
"""
|
| 557 |
+
p[0] = p[1]
|
| 558 |
+
|
| 559 |
+
def p_static_assert_declaration(self, p):
|
| 560 |
+
""" static_assert : _STATIC_ASSERT LPAREN constant_expression COMMA unified_string_literal RPAREN
|
| 561 |
+
| _STATIC_ASSERT LPAREN constant_expression RPAREN
|
| 562 |
+
"""
|
| 563 |
+
if len(p) == 5:
|
| 564 |
+
p[0] = [c_ast.StaticAssert(p[3], None, self._token_coord(p, 1))]
|
| 565 |
+
else:
|
| 566 |
+
p[0] = [c_ast.StaticAssert(p[3], p[5], self._token_coord(p, 1))]
|
| 567 |
+
|
| 568 |
+
def p_pp_directive(self, p):
|
| 569 |
+
""" pp_directive : PPHASH
|
| 570 |
+
"""
|
| 571 |
+
self._parse_error('Directives not supported yet',
|
| 572 |
+
self._token_coord(p, 1))
|
| 573 |
+
|
| 574 |
+
# This encompasses two types of C99-compatible pragmas:
|
| 575 |
+
# - The #pragma directive:
|
| 576 |
+
# # pragma character_sequence
|
| 577 |
+
# - The _Pragma unary operator:
|
| 578 |
+
# _Pragma ( " string_literal " )
|
| 579 |
+
def p_pppragma_directive(self, p):
|
| 580 |
+
""" pppragma_directive : PPPRAGMA
|
| 581 |
+
| PPPRAGMA PPPRAGMASTR
|
| 582 |
+
| _PRAGMA LPAREN unified_string_literal RPAREN
|
| 583 |
+
"""
|
| 584 |
+
if len(p) == 5:
|
| 585 |
+
p[0] = c_ast.Pragma(p[3], self._token_coord(p, 2))
|
| 586 |
+
elif len(p) == 3:
|
| 587 |
+
p[0] = c_ast.Pragma(p[2], self._token_coord(p, 2))
|
| 588 |
+
else:
|
| 589 |
+
p[0] = c_ast.Pragma("", self._token_coord(p, 1))
|
| 590 |
+
|
| 591 |
+
def p_pppragma_directive_list(self, p):
|
| 592 |
+
""" pppragma_directive_list : pppragma_directive
|
| 593 |
+
| pppragma_directive_list pppragma_directive
|
| 594 |
+
"""
|
| 595 |
+
p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]
|
| 596 |
+
|
| 597 |
+
# In function definitions, the declarator can be followed by
|
| 598 |
+
# a declaration list, for old "K&R style" function definitios.
|
| 599 |
+
def p_function_definition_1(self, p):
|
| 600 |
+
""" function_definition : id_declarator declaration_list_opt compound_statement
|
| 601 |
+
"""
|
| 602 |
+
# no declaration specifiers - 'int' becomes the default type
|
| 603 |
+
spec = dict(
|
| 604 |
+
qual=[],
|
| 605 |
+
alignment=[],
|
| 606 |
+
storage=[],
|
| 607 |
+
type=[c_ast.IdentifierType(['int'],
|
| 608 |
+
coord=self._token_coord(p, 1))],
|
| 609 |
+
function=[])
|
| 610 |
+
|
| 611 |
+
p[0] = self._build_function_definition(
|
| 612 |
+
spec=spec,
|
| 613 |
+
decl=p[1],
|
| 614 |
+
param_decls=p[2],
|
| 615 |
+
body=p[3])
|
| 616 |
+
|
| 617 |
+
def p_function_definition_2(self, p):
|
| 618 |
+
""" function_definition : declaration_specifiers id_declarator declaration_list_opt compound_statement
|
| 619 |
+
"""
|
| 620 |
+
spec = p[1]
|
| 621 |
+
|
| 622 |
+
p[0] = self._build_function_definition(
|
| 623 |
+
spec=spec,
|
| 624 |
+
decl=p[2],
|
| 625 |
+
param_decls=p[3],
|
| 626 |
+
body=p[4])
|
| 627 |
+
|
| 628 |
+
# Note, according to C18 A.2.2 6.7.10 static_assert-declaration _Static_assert
|
| 629 |
+
# is a declaration, not a statement. We additionally recognise it as a statement
|
| 630 |
+
# to fix parsing of _Static_assert inside the functions.
|
| 631 |
+
#
|
| 632 |
+
def p_statement(self, p):
|
| 633 |
+
""" statement : labeled_statement
|
| 634 |
+
| expression_statement
|
| 635 |
+
| compound_statement
|
| 636 |
+
| selection_statement
|
| 637 |
+
| iteration_statement
|
| 638 |
+
| jump_statement
|
| 639 |
+
| pppragma_directive
|
| 640 |
+
| static_assert
|
| 641 |
+
"""
|
| 642 |
+
p[0] = p[1]
|
| 643 |
+
|
| 644 |
+
# A pragma is generally considered a decorator rather than an actual
|
| 645 |
+
# statement. Still, for the purposes of analyzing an abstract syntax tree of
|
| 646 |
+
# C code, pragma's should not be ignored and were previously treated as a
|
| 647 |
+
# statement. This presents a problem for constructs that take a statement
|
| 648 |
+
# such as labeled_statements, selection_statements, and
|
| 649 |
+
# iteration_statements, causing a misleading structure in the AST. For
|
| 650 |
+
# example, consider the following C code.
|
| 651 |
+
#
|
| 652 |
+
# for (int i = 0; i < 3; i++)
|
| 653 |
+
# #pragma omp critical
|
| 654 |
+
# sum += 1;
|
| 655 |
+
#
|
| 656 |
+
# This code will compile and execute "sum += 1;" as the body of the for
|
| 657 |
+
# loop. Previous implementations of PyCParser would render the AST for this
|
| 658 |
+
# block of code as follows:
|
| 659 |
+
#
|
| 660 |
+
# For:
|
| 661 |
+
# DeclList:
|
| 662 |
+
# Decl: i, [], [], []
|
| 663 |
+
# TypeDecl: i, []
|
| 664 |
+
# IdentifierType: ['int']
|
| 665 |
+
# Constant: int, 0
|
| 666 |
+
# BinaryOp: <
|
| 667 |
+
# ID: i
|
| 668 |
+
# Constant: int, 3
|
| 669 |
+
# UnaryOp: p++
|
| 670 |
+
# ID: i
|
| 671 |
+
# Pragma: omp critical
|
| 672 |
+
# Assignment: +=
|
| 673 |
+
# ID: sum
|
| 674 |
+
# Constant: int, 1
|
| 675 |
+
#
|
| 676 |
+
# This AST misleadingly takes the Pragma as the body of the loop and the
|
| 677 |
+
# assignment then becomes a sibling of the loop.
|
| 678 |
+
#
|
| 679 |
+
# To solve edge cases like these, the pragmacomp_or_statement rule groups
|
| 680 |
+
# a pragma and its following statement (which would otherwise be orphaned)
|
| 681 |
+
# using a compound block, effectively turning the above code into:
|
| 682 |
+
#
|
| 683 |
+
# for (int i = 0; i < 3; i++) {
|
| 684 |
+
# #pragma omp critical
|
| 685 |
+
# sum += 1;
|
| 686 |
+
# }
|
| 687 |
+
def p_pragmacomp_or_statement(self, p):
|
| 688 |
+
""" pragmacomp_or_statement : pppragma_directive_list statement
|
| 689 |
+
| statement
|
| 690 |
+
"""
|
| 691 |
+
if len(p) == 3:
|
| 692 |
+
p[0] = c_ast.Compound(
|
| 693 |
+
block_items=p[1]+[p[2]],
|
| 694 |
+
coord=self._token_coord(p, 1))
|
| 695 |
+
else:
|
| 696 |
+
p[0] = p[1]
|
| 697 |
+
|
| 698 |
+
# In C, declarations can come several in a line:
|
| 699 |
+
# int x, *px, romulo = 5;
|
| 700 |
+
#
|
| 701 |
+
# However, for the AST, we will split them to separate Decl
|
| 702 |
+
# nodes.
|
| 703 |
+
#
|
| 704 |
+
# This rule splits its declarations and always returns a list
|
| 705 |
+
# of Decl nodes, even if it's one element long.
|
| 706 |
+
#
|
| 707 |
+
def p_decl_body(self, p):
|
| 708 |
+
""" decl_body : declaration_specifiers init_declarator_list_opt
|
| 709 |
+
| declaration_specifiers_no_type id_init_declarator_list_opt
|
| 710 |
+
"""
|
| 711 |
+
spec = p[1]
|
| 712 |
+
|
| 713 |
+
# p[2] (init_declarator_list_opt) is either a list or None
|
| 714 |
+
#
|
| 715 |
+
if p[2] is None:
|
| 716 |
+
# By the standard, you must have at least one declarator unless
|
| 717 |
+
# declaring a structure tag, a union tag, or the members of an
|
| 718 |
+
# enumeration.
|
| 719 |
+
#
|
| 720 |
+
ty = spec['type']
|
| 721 |
+
s_u_or_e = (c_ast.Struct, c_ast.Union, c_ast.Enum)
|
| 722 |
+
if len(ty) == 1 and isinstance(ty[0], s_u_or_e):
|
| 723 |
+
decls = [c_ast.Decl(
|
| 724 |
+
name=None,
|
| 725 |
+
quals=spec['qual'],
|
| 726 |
+
align=spec['alignment'],
|
| 727 |
+
storage=spec['storage'],
|
| 728 |
+
funcspec=spec['function'],
|
| 729 |
+
type=ty[0],
|
| 730 |
+
init=None,
|
| 731 |
+
bitsize=None,
|
| 732 |
+
coord=ty[0].coord)]
|
| 733 |
+
|
| 734 |
+
# However, this case can also occur on redeclared identifiers in
|
| 735 |
+
# an inner scope. The trouble is that the redeclared type's name
|
| 736 |
+
# gets grouped into declaration_specifiers; _build_declarations
|
| 737 |
+
# compensates for this.
|
| 738 |
+
#
|
| 739 |
+
else:
|
| 740 |
+
decls = self._build_declarations(
|
| 741 |
+
spec=spec,
|
| 742 |
+
decls=[dict(decl=None, init=None)],
|
| 743 |
+
typedef_namespace=True)
|
| 744 |
+
|
| 745 |
+
else:
|
| 746 |
+
decls = self._build_declarations(
|
| 747 |
+
spec=spec,
|
| 748 |
+
decls=p[2],
|
| 749 |
+
typedef_namespace=True)
|
| 750 |
+
|
| 751 |
+
p[0] = decls
|
| 752 |
+
|
| 753 |
+
# The declaration has been split to a decl_body sub-rule and
|
| 754 |
+
# SEMI, because having them in a single rule created a problem
|
| 755 |
+
# for defining typedefs.
|
| 756 |
+
#
|
| 757 |
+
# If a typedef line was directly followed by a line using the
|
| 758 |
+
# type defined with the typedef, the type would not be
|
| 759 |
+
# recognized. This is because to reduce the declaration rule,
|
| 760 |
+
# the parser's lookahead asked for the token after SEMI, which
|
| 761 |
+
# was the type from the next line, and the lexer had no chance
|
| 762 |
+
# to see the updated type symbol table.
|
| 763 |
+
#
|
| 764 |
+
# Splitting solves this problem, because after seeing SEMI,
|
| 765 |
+
# the parser reduces decl_body, which actually adds the new
|
| 766 |
+
# type into the table to be seen by the lexer before the next
|
| 767 |
+
# line is reached.
|
| 768 |
+
def p_declaration(self, p):
|
| 769 |
+
""" declaration : decl_body SEMI
|
| 770 |
+
"""
|
| 771 |
+
p[0] = p[1]
|
| 772 |
+
|
| 773 |
+
# Since each declaration is a list of declarations, this
|
| 774 |
+
# rule will combine all the declarations and return a single
|
| 775 |
+
# list
|
| 776 |
+
#
|
| 777 |
+
def p_declaration_list(self, p):
|
| 778 |
+
""" declaration_list : declaration
|
| 779 |
+
| declaration_list declaration
|
| 780 |
+
"""
|
| 781 |
+
p[0] = p[1] if len(p) == 2 else p[1] + p[2]
|
| 782 |
+
|
| 783 |
+
# To know when declaration-specifiers end and declarators begin,
|
| 784 |
+
# we require declaration-specifiers to have at least one
|
| 785 |
+
# type-specifier, and disallow typedef-names after we've seen any
|
| 786 |
+
# type-specifier. These are both required by the spec.
|
| 787 |
+
#
|
| 788 |
+
def p_declaration_specifiers_no_type_1(self, p):
|
| 789 |
+
""" declaration_specifiers_no_type : type_qualifier declaration_specifiers_no_type_opt
|
| 790 |
+
"""
|
| 791 |
+
p[0] = self._add_declaration_specifier(p[2], p[1], 'qual')
|
| 792 |
+
|
| 793 |
+
def p_declaration_specifiers_no_type_2(self, p):
|
| 794 |
+
""" declaration_specifiers_no_type : storage_class_specifier declaration_specifiers_no_type_opt
|
| 795 |
+
"""
|
| 796 |
+
p[0] = self._add_declaration_specifier(p[2], p[1], 'storage')
|
| 797 |
+
|
| 798 |
+
def p_declaration_specifiers_no_type_3(self, p):
|
| 799 |
+
""" declaration_specifiers_no_type : function_specifier declaration_specifiers_no_type_opt
|
| 800 |
+
"""
|
| 801 |
+
p[0] = self._add_declaration_specifier(p[2], p[1], 'function')
|
| 802 |
+
|
| 803 |
+
# Without this, `typedef _Atomic(T) U` will parse incorrectly because the
|
| 804 |
+
# _Atomic qualifier will match, instead of the specifier.
|
| 805 |
+
def p_declaration_specifiers_no_type_4(self, p):
|
| 806 |
+
""" declaration_specifiers_no_type : atomic_specifier declaration_specifiers_no_type_opt
|
| 807 |
+
"""
|
| 808 |
+
p[0] = self._add_declaration_specifier(p[2], p[1], 'type')
|
| 809 |
+
|
| 810 |
+
def p_declaration_specifiers_no_type_5(self, p):
|
| 811 |
+
""" declaration_specifiers_no_type : alignment_specifier declaration_specifiers_no_type_opt
|
| 812 |
+
"""
|
| 813 |
+
p[0] = self._add_declaration_specifier(p[2], p[1], 'alignment')
|
| 814 |
+
|
| 815 |
+
def p_declaration_specifiers_1(self, p):
|
| 816 |
+
""" declaration_specifiers : declaration_specifiers type_qualifier
|
| 817 |
+
"""
|
| 818 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True)
|
| 819 |
+
|
| 820 |
+
def p_declaration_specifiers_2(self, p):
|
| 821 |
+
""" declaration_specifiers : declaration_specifiers storage_class_specifier
|
| 822 |
+
"""
|
| 823 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'storage', append=True)
|
| 824 |
+
|
| 825 |
+
def p_declaration_specifiers_3(self, p):
|
| 826 |
+
""" declaration_specifiers : declaration_specifiers function_specifier
|
| 827 |
+
"""
|
| 828 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'function', append=True)
|
| 829 |
+
|
| 830 |
+
def p_declaration_specifiers_4(self, p):
|
| 831 |
+
""" declaration_specifiers : declaration_specifiers type_specifier_no_typeid
|
| 832 |
+
"""
|
| 833 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
|
| 834 |
+
|
| 835 |
+
def p_declaration_specifiers_5(self, p):
|
| 836 |
+
""" declaration_specifiers : type_specifier
|
| 837 |
+
"""
|
| 838 |
+
p[0] = self._add_declaration_specifier(None, p[1], 'type')
|
| 839 |
+
|
| 840 |
+
def p_declaration_specifiers_6(self, p):
|
| 841 |
+
""" declaration_specifiers : declaration_specifiers_no_type type_specifier
|
| 842 |
+
"""
|
| 843 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
|
| 844 |
+
|
| 845 |
+
def p_declaration_specifiers_7(self, p):
|
| 846 |
+
""" declaration_specifiers : declaration_specifiers alignment_specifier
|
| 847 |
+
"""
|
| 848 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'alignment', append=True)
|
| 849 |
+
|
| 850 |
+
def p_storage_class_specifier(self, p):
|
| 851 |
+
""" storage_class_specifier : AUTO
|
| 852 |
+
| REGISTER
|
| 853 |
+
| STATIC
|
| 854 |
+
| EXTERN
|
| 855 |
+
| TYPEDEF
|
| 856 |
+
| _THREAD_LOCAL
|
| 857 |
+
"""
|
| 858 |
+
p[0] = p[1]
|
| 859 |
+
|
| 860 |
+
def p_function_specifier(self, p):
|
| 861 |
+
""" function_specifier : INLINE
|
| 862 |
+
| _NORETURN
|
| 863 |
+
"""
|
| 864 |
+
p[0] = p[1]
|
| 865 |
+
|
| 866 |
+
def p_type_specifier_no_typeid(self, p):
|
| 867 |
+
""" type_specifier_no_typeid : VOID
|
| 868 |
+
| _BOOL
|
| 869 |
+
| CHAR
|
| 870 |
+
| SHORT
|
| 871 |
+
| INT
|
| 872 |
+
| LONG
|
| 873 |
+
| FLOAT
|
| 874 |
+
| DOUBLE
|
| 875 |
+
| _COMPLEX
|
| 876 |
+
| SIGNED
|
| 877 |
+
| UNSIGNED
|
| 878 |
+
| __INT128
|
| 879 |
+
"""
|
| 880 |
+
p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1))
|
| 881 |
+
|
| 882 |
+
def p_type_specifier(self, p):
|
| 883 |
+
""" type_specifier : typedef_name
|
| 884 |
+
| enum_specifier
|
| 885 |
+
| struct_or_union_specifier
|
| 886 |
+
| type_specifier_no_typeid
|
| 887 |
+
| atomic_specifier
|
| 888 |
+
"""
|
| 889 |
+
p[0] = p[1]
|
| 890 |
+
|
| 891 |
+
# See section 6.7.2.4 of the C11 standard.
|
| 892 |
+
def p_atomic_specifier(self, p):
|
| 893 |
+
""" atomic_specifier : _ATOMIC LPAREN type_name RPAREN
|
| 894 |
+
"""
|
| 895 |
+
typ = p[3]
|
| 896 |
+
typ.quals.append('_Atomic')
|
| 897 |
+
p[0] = typ
|
| 898 |
+
|
| 899 |
+
def p_type_qualifier(self, p):
|
| 900 |
+
""" type_qualifier : CONST
|
| 901 |
+
| RESTRICT
|
| 902 |
+
| VOLATILE
|
| 903 |
+
| _ATOMIC
|
| 904 |
+
"""
|
| 905 |
+
p[0] = p[1]
|
| 906 |
+
|
| 907 |
+
def p_init_declarator_list(self, p):
|
| 908 |
+
""" init_declarator_list : init_declarator
|
| 909 |
+
| init_declarator_list COMMA init_declarator
|
| 910 |
+
"""
|
| 911 |
+
p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
|
| 912 |
+
|
| 913 |
+
# Returns a {decl=<declarator> : init=<initializer>} dictionary
|
| 914 |
+
# If there's no initializer, uses None
|
| 915 |
+
#
|
| 916 |
+
def p_init_declarator(self, p):
|
| 917 |
+
""" init_declarator : declarator
|
| 918 |
+
| declarator EQUALS initializer
|
| 919 |
+
"""
|
| 920 |
+
p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None))
|
| 921 |
+
|
| 922 |
+
def p_id_init_declarator_list(self, p):
|
| 923 |
+
""" id_init_declarator_list : id_init_declarator
|
| 924 |
+
| id_init_declarator_list COMMA init_declarator
|
| 925 |
+
"""
|
| 926 |
+
p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
|
| 927 |
+
|
| 928 |
+
def p_id_init_declarator(self, p):
|
| 929 |
+
""" id_init_declarator : id_declarator
|
| 930 |
+
| id_declarator EQUALS initializer
|
| 931 |
+
"""
|
| 932 |
+
p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None))
|
| 933 |
+
|
| 934 |
+
# Require at least one type specifier in a specifier-qualifier-list
|
| 935 |
+
#
|
| 936 |
+
def p_specifier_qualifier_list_1(self, p):
|
| 937 |
+
""" specifier_qualifier_list : specifier_qualifier_list type_specifier_no_typeid
|
| 938 |
+
"""
|
| 939 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
|
| 940 |
+
|
| 941 |
+
def p_specifier_qualifier_list_2(self, p):
|
| 942 |
+
""" specifier_qualifier_list : specifier_qualifier_list type_qualifier
|
| 943 |
+
"""
|
| 944 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True)
|
| 945 |
+
|
| 946 |
+
def p_specifier_qualifier_list_3(self, p):
|
| 947 |
+
""" specifier_qualifier_list : type_specifier
|
| 948 |
+
"""
|
| 949 |
+
p[0] = self._add_declaration_specifier(None, p[1], 'type')
|
| 950 |
+
|
| 951 |
+
def p_specifier_qualifier_list_4(self, p):
|
| 952 |
+
""" specifier_qualifier_list : type_qualifier_list type_specifier
|
| 953 |
+
"""
|
| 954 |
+
p[0] = dict(qual=p[1], alignment=[], storage=[], type=[p[2]], function=[])
|
| 955 |
+
|
| 956 |
+
def p_specifier_qualifier_list_5(self, p):
|
| 957 |
+
""" specifier_qualifier_list : alignment_specifier
|
| 958 |
+
"""
|
| 959 |
+
p[0] = dict(qual=[], alignment=[p[1]], storage=[], type=[], function=[])
|
| 960 |
+
|
| 961 |
+
def p_specifier_qualifier_list_6(self, p):
|
| 962 |
+
""" specifier_qualifier_list : specifier_qualifier_list alignment_specifier
|
| 963 |
+
"""
|
| 964 |
+
p[0] = self._add_declaration_specifier(p[1], p[2], 'alignment')
|
| 965 |
+
|
| 966 |
+
# TYPEID is allowed here (and in other struct/enum related tag names), because
|
| 967 |
+
# struct/enum tags reside in their own namespace and can be named the same as types
|
| 968 |
+
#
|
| 969 |
+
def p_struct_or_union_specifier_1(self, p):
|
| 970 |
+
""" struct_or_union_specifier : struct_or_union ID
|
| 971 |
+
| struct_or_union TYPEID
|
| 972 |
+
"""
|
| 973 |
+
klass = self._select_struct_union_class(p[1])
|
| 974 |
+
# None means no list of members
|
| 975 |
+
p[0] = klass(
|
| 976 |
+
name=p[2],
|
| 977 |
+
decls=None,
|
| 978 |
+
coord=self._token_coord(p, 2))
|
| 979 |
+
|
| 980 |
+
def p_struct_or_union_specifier_2(self, p):
|
| 981 |
+
""" struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close
|
| 982 |
+
| struct_or_union brace_open brace_close
|
| 983 |
+
"""
|
| 984 |
+
klass = self._select_struct_union_class(p[1])
|
| 985 |
+
if len(p) == 4:
|
| 986 |
+
# Empty sequence means an empty list of members
|
| 987 |
+
p[0] = klass(
|
| 988 |
+
name=None,
|
| 989 |
+
decls=[],
|
| 990 |
+
coord=self._token_coord(p, 2))
|
| 991 |
+
else:
|
| 992 |
+
p[0] = klass(
|
| 993 |
+
name=None,
|
| 994 |
+
decls=p[3],
|
| 995 |
+
coord=self._token_coord(p, 2))
|
| 996 |
+
|
| 997 |
+
|
| 998 |
+
def p_struct_or_union_specifier_3(self, p):
|
| 999 |
+
""" struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close
|
| 1000 |
+
| struct_or_union ID brace_open brace_close
|
| 1001 |
+
| struct_or_union TYPEID brace_open struct_declaration_list brace_close
|
| 1002 |
+
| struct_or_union TYPEID brace_open brace_close
|
| 1003 |
+
"""
|
| 1004 |
+
klass = self._select_struct_union_class(p[1])
|
| 1005 |
+
if len(p) == 5:
|
| 1006 |
+
# Empty sequence means an empty list of members
|
| 1007 |
+
p[0] = klass(
|
| 1008 |
+
name=p[2],
|
| 1009 |
+
decls=[],
|
| 1010 |
+
coord=self._token_coord(p, 2))
|
| 1011 |
+
else:
|
| 1012 |
+
p[0] = klass(
|
| 1013 |
+
name=p[2],
|
| 1014 |
+
decls=p[4],
|
| 1015 |
+
coord=self._token_coord(p, 2))
|
| 1016 |
+
|
| 1017 |
+
def p_struct_or_union(self, p):
|
| 1018 |
+
""" struct_or_union : STRUCT
|
| 1019 |
+
| UNION
|
| 1020 |
+
"""
|
| 1021 |
+
p[0] = p[1]
|
| 1022 |
+
|
| 1023 |
+
# Combine all declarations into a single list
|
| 1024 |
+
#
|
| 1025 |
+
def p_struct_declaration_list(self, p):
|
| 1026 |
+
""" struct_declaration_list : struct_declaration
|
| 1027 |
+
| struct_declaration_list struct_declaration
|
| 1028 |
+
"""
|
| 1029 |
+
if len(p) == 2:
|
| 1030 |
+
p[0] = p[1] or []
|
| 1031 |
+
else:
|
| 1032 |
+
p[0] = p[1] + (p[2] or [])
|
| 1033 |
+
|
| 1034 |
+
def p_struct_declaration_1(self, p):
|
| 1035 |
+
""" struct_declaration : specifier_qualifier_list struct_declarator_list_opt SEMI
|
| 1036 |
+
"""
|
| 1037 |
+
spec = p[1]
|
| 1038 |
+
assert 'typedef' not in spec['storage']
|
| 1039 |
+
|
| 1040 |
+
if p[2] is not None:
|
| 1041 |
+
decls = self._build_declarations(
|
| 1042 |
+
spec=spec,
|
| 1043 |
+
decls=p[2])
|
| 1044 |
+
|
| 1045 |
+
elif len(spec['type']) == 1:
|
| 1046 |
+
# Anonymous struct/union, gcc extension, C1x feature.
|
| 1047 |
+
# Although the standard only allows structs/unions here, I see no
|
| 1048 |
+
# reason to disallow other types since some compilers have typedefs
|
| 1049 |
+
# here, and pycparser isn't about rejecting all invalid code.
|
| 1050 |
+
#
|
| 1051 |
+
node = spec['type'][0]
|
| 1052 |
+
if isinstance(node, c_ast.Node):
|
| 1053 |
+
decl_type = node
|
| 1054 |
+
else:
|
| 1055 |
+
decl_type = c_ast.IdentifierType(node)
|
| 1056 |
+
|
| 1057 |
+
decls = self._build_declarations(
|
| 1058 |
+
spec=spec,
|
| 1059 |
+
decls=[dict(decl=decl_type)])
|
| 1060 |
+
|
| 1061 |
+
else:
|
| 1062 |
+
# Structure/union members can have the same names as typedefs.
|
| 1063 |
+
# The trouble is that the member's name gets grouped into
|
| 1064 |
+
# specifier_qualifier_list; _build_declarations compensates.
|
| 1065 |
+
#
|
| 1066 |
+
decls = self._build_declarations(
|
| 1067 |
+
spec=spec,
|
| 1068 |
+
decls=[dict(decl=None, init=None)])
|
| 1069 |
+
|
| 1070 |
+
p[0] = decls
|
| 1071 |
+
|
| 1072 |
+
def p_struct_declaration_2(self, p):
|
| 1073 |
+
""" struct_declaration : SEMI
|
| 1074 |
+
"""
|
| 1075 |
+
p[0] = None
|
| 1076 |
+
|
| 1077 |
+
def p_struct_declaration_3(self, p):
|
| 1078 |
+
""" struct_declaration : pppragma_directive
|
| 1079 |
+
"""
|
| 1080 |
+
p[0] = [p[1]]
|
| 1081 |
+
|
| 1082 |
+
def p_struct_declarator_list(self, p):
|
| 1083 |
+
""" struct_declarator_list : struct_declarator
|
| 1084 |
+
| struct_declarator_list COMMA struct_declarator
|
| 1085 |
+
"""
|
| 1086 |
+
p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
|
| 1087 |
+
|
| 1088 |
+
# struct_declarator passes up a dict with the keys: decl (for
|
| 1089 |
+
# the underlying declarator) and bitsize (for the bitsize)
|
| 1090 |
+
#
|
| 1091 |
+
def p_struct_declarator_1(self, p):
|
| 1092 |
+
""" struct_declarator : declarator
|
| 1093 |
+
"""
|
| 1094 |
+
p[0] = {'decl': p[1], 'bitsize': None}
|
| 1095 |
+
|
| 1096 |
+
def p_struct_declarator_2(self, p):
|
| 1097 |
+
""" struct_declarator : declarator COLON constant_expression
|
| 1098 |
+
| COLON constant_expression
|
| 1099 |
+
"""
|
| 1100 |
+
if len(p) > 3:
|
| 1101 |
+
p[0] = {'decl': p[1], 'bitsize': p[3]}
|
| 1102 |
+
else:
|
| 1103 |
+
p[0] = {'decl': c_ast.TypeDecl(None, None, None, None), 'bitsize': p[2]}
|
| 1104 |
+
|
| 1105 |
+
def p_enum_specifier_1(self, p):
|
| 1106 |
+
""" enum_specifier : ENUM ID
|
| 1107 |
+
| ENUM TYPEID
|
| 1108 |
+
"""
|
| 1109 |
+
p[0] = c_ast.Enum(p[2], None, self._token_coord(p, 1))
|
| 1110 |
+
|
| 1111 |
+
def p_enum_specifier_2(self, p):
|
| 1112 |
+
""" enum_specifier : ENUM brace_open enumerator_list brace_close
|
| 1113 |
+
"""
|
| 1114 |
+
p[0] = c_ast.Enum(None, p[3], self._token_coord(p, 1))
|
| 1115 |
+
|
| 1116 |
+
def p_enum_specifier_3(self, p):
|
| 1117 |
+
""" enum_specifier : ENUM ID brace_open enumerator_list brace_close
|
| 1118 |
+
| ENUM TYPEID brace_open enumerator_list brace_close
|
| 1119 |
+
"""
|
| 1120 |
+
p[0] = c_ast.Enum(p[2], p[4], self._token_coord(p, 1))
|
| 1121 |
+
|
| 1122 |
+
def p_enumerator_list(self, p):
|
| 1123 |
+
""" enumerator_list : enumerator
|
| 1124 |
+
| enumerator_list COMMA
|
| 1125 |
+
| enumerator_list COMMA enumerator
|
| 1126 |
+
"""
|
| 1127 |
+
if len(p) == 2:
|
| 1128 |
+
p[0] = c_ast.EnumeratorList([p[1]], p[1].coord)
|
| 1129 |
+
elif len(p) == 3:
|
| 1130 |
+
p[0] = p[1]
|
| 1131 |
+
else:
|
| 1132 |
+
p[1].enumerators.append(p[3])
|
| 1133 |
+
p[0] = p[1]
|
| 1134 |
+
|
| 1135 |
+
def p_alignment_specifier(self, p):
|
| 1136 |
+
""" alignment_specifier : _ALIGNAS LPAREN type_name RPAREN
|
| 1137 |
+
| _ALIGNAS LPAREN constant_expression RPAREN
|
| 1138 |
+
"""
|
| 1139 |
+
p[0] = c_ast.Alignas(p[3], self._token_coord(p, 1))
|
| 1140 |
+
|
| 1141 |
+
def p_enumerator(self, p):
|
| 1142 |
+
""" enumerator : ID
|
| 1143 |
+
| ID EQUALS constant_expression
|
| 1144 |
+
"""
|
| 1145 |
+
if len(p) == 2:
|
| 1146 |
+
enumerator = c_ast.Enumerator(
|
| 1147 |
+
p[1], None,
|
| 1148 |
+
self._token_coord(p, 1))
|
| 1149 |
+
else:
|
| 1150 |
+
enumerator = c_ast.Enumerator(
|
| 1151 |
+
p[1], p[3],
|
| 1152 |
+
self._token_coord(p, 1))
|
| 1153 |
+
self._add_identifier(enumerator.name, enumerator.coord)
|
| 1154 |
+
|
| 1155 |
+
p[0] = enumerator
|
| 1156 |
+
|
| 1157 |
+
def p_declarator(self, p):
|
| 1158 |
+
""" declarator : id_declarator
|
| 1159 |
+
| typeid_declarator
|
| 1160 |
+
"""
|
| 1161 |
+
p[0] = p[1]
|
| 1162 |
+
|
| 1163 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1164 |
+
def p_xxx_declarator_1(self, p):
|
| 1165 |
+
""" xxx_declarator : direct_xxx_declarator
|
| 1166 |
+
"""
|
| 1167 |
+
p[0] = p[1]
|
| 1168 |
+
|
| 1169 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1170 |
+
def p_xxx_declarator_2(self, p):
|
| 1171 |
+
""" xxx_declarator : pointer direct_xxx_declarator
|
| 1172 |
+
"""
|
| 1173 |
+
p[0] = self._type_modify_decl(p[2], p[1])
|
| 1174 |
+
|
| 1175 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1176 |
+
def p_direct_xxx_declarator_1(self, p):
|
| 1177 |
+
""" direct_xxx_declarator : yyy
|
| 1178 |
+
"""
|
| 1179 |
+
p[0] = c_ast.TypeDecl(
|
| 1180 |
+
declname=p[1],
|
| 1181 |
+
type=None,
|
| 1182 |
+
quals=None,
|
| 1183 |
+
align=None,
|
| 1184 |
+
coord=self._token_coord(p, 1))
|
| 1185 |
+
|
| 1186 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'))
|
| 1187 |
+
def p_direct_xxx_declarator_2(self, p):
|
| 1188 |
+
""" direct_xxx_declarator : LPAREN xxx_declarator RPAREN
|
| 1189 |
+
"""
|
| 1190 |
+
p[0] = p[2]
|
| 1191 |
+
|
| 1192 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1193 |
+
def p_direct_xxx_declarator_3(self, p):
|
| 1194 |
+
""" direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET
|
| 1195 |
+
"""
|
| 1196 |
+
quals = (p[3] if len(p) > 5 else []) or []
|
| 1197 |
+
# Accept dimension qualifiers
|
| 1198 |
+
# Per C99 6.7.5.3 p7
|
| 1199 |
+
arr = c_ast.ArrayDecl(
|
| 1200 |
+
type=None,
|
| 1201 |
+
dim=p[4] if len(p) > 5 else p[3],
|
| 1202 |
+
dim_quals=quals,
|
| 1203 |
+
coord=p[1].coord)
|
| 1204 |
+
|
| 1205 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
| 1206 |
+
|
| 1207 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1208 |
+
def p_direct_xxx_declarator_4(self, p):
|
| 1209 |
+
""" direct_xxx_declarator : direct_xxx_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET
|
| 1210 |
+
| direct_xxx_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET
|
| 1211 |
+
"""
|
| 1212 |
+
# Using slice notation for PLY objects doesn't work in Python 3 for the
|
| 1213 |
+
# version of PLY embedded with pycparser; see PLY Google Code issue 30.
|
| 1214 |
+
# Work around that here by listing the two elements separately.
|
| 1215 |
+
listed_quals = [item if isinstance(item, list) else [item]
|
| 1216 |
+
for item in [p[3],p[4]]]
|
| 1217 |
+
dim_quals = [qual for sublist in listed_quals for qual in sublist
|
| 1218 |
+
if qual is not None]
|
| 1219 |
+
arr = c_ast.ArrayDecl(
|
| 1220 |
+
type=None,
|
| 1221 |
+
dim=p[5],
|
| 1222 |
+
dim_quals=dim_quals,
|
| 1223 |
+
coord=p[1].coord)
|
| 1224 |
+
|
| 1225 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
| 1226 |
+
|
| 1227 |
+
# Special for VLAs
|
| 1228 |
+
#
|
| 1229 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1230 |
+
def p_direct_xxx_declarator_5(self, p):
|
| 1231 |
+
""" direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET
|
| 1232 |
+
"""
|
| 1233 |
+
arr = c_ast.ArrayDecl(
|
| 1234 |
+
type=None,
|
| 1235 |
+
dim=c_ast.ID(p[4], self._token_coord(p, 4)),
|
| 1236 |
+
dim_quals=p[3] if p[3] is not None else [],
|
| 1237 |
+
coord=p[1].coord)
|
| 1238 |
+
|
| 1239 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
| 1240 |
+
|
| 1241 |
+
@parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
|
| 1242 |
+
def p_direct_xxx_declarator_6(self, p):
|
| 1243 |
+
""" direct_xxx_declarator : direct_xxx_declarator LPAREN parameter_type_list RPAREN
|
| 1244 |
+
| direct_xxx_declarator LPAREN identifier_list_opt RPAREN
|
| 1245 |
+
"""
|
| 1246 |
+
func = c_ast.FuncDecl(
|
| 1247 |
+
args=p[3],
|
| 1248 |
+
type=None,
|
| 1249 |
+
coord=p[1].coord)
|
| 1250 |
+
|
| 1251 |
+
# To see why _get_yacc_lookahead_token is needed, consider:
|
| 1252 |
+
# typedef char TT;
|
| 1253 |
+
# void foo(int TT) { TT = 10; }
|
| 1254 |
+
# Outside the function, TT is a typedef, but inside (starting and
|
| 1255 |
+
# ending with the braces) it's a parameter. The trouble begins with
|
| 1256 |
+
# yacc's lookahead token. We don't know if we're declaring or
|
| 1257 |
+
# defining a function until we see LBRACE, but if we wait for yacc to
|
| 1258 |
+
# trigger a rule on that token, then TT will have already been read
|
| 1259 |
+
# and incorrectly interpreted as TYPEID. We need to add the
|
| 1260 |
+
# parameters to the scope the moment the lexer sees LBRACE.
|
| 1261 |
+
#
|
| 1262 |
+
if self._get_yacc_lookahead_token().type == "LBRACE":
|
| 1263 |
+
if func.args is not None:
|
| 1264 |
+
for param in func.args.params:
|
| 1265 |
+
if isinstance(param, c_ast.EllipsisParam): break
|
| 1266 |
+
self._add_identifier(param.name, param.coord)
|
| 1267 |
+
|
| 1268 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=func)
|
| 1269 |
+
|
| 1270 |
+
def p_pointer(self, p):
|
| 1271 |
+
""" pointer : TIMES type_qualifier_list_opt
|
| 1272 |
+
| TIMES type_qualifier_list_opt pointer
|
| 1273 |
+
"""
|
| 1274 |
+
coord = self._token_coord(p, 1)
|
| 1275 |
+
# Pointer decls nest from inside out. This is important when different
|
| 1276 |
+
# levels have different qualifiers. For example:
|
| 1277 |
+
#
|
| 1278 |
+
# char * const * p;
|
| 1279 |
+
#
|
| 1280 |
+
# Means "pointer to const pointer to char"
|
| 1281 |
+
#
|
| 1282 |
+
# While:
|
| 1283 |
+
#
|
| 1284 |
+
# char ** const p;
|
| 1285 |
+
#
|
| 1286 |
+
# Means "const pointer to pointer to char"
|
| 1287 |
+
#
|
| 1288 |
+
# So when we construct PtrDecl nestings, the leftmost pointer goes in
|
| 1289 |
+
# as the most nested type.
|
| 1290 |
+
nested_type = c_ast.PtrDecl(quals=p[2] or [], type=None, coord=coord)
|
| 1291 |
+
if len(p) > 3:
|
| 1292 |
+
tail_type = p[3]
|
| 1293 |
+
while tail_type.type is not None:
|
| 1294 |
+
tail_type = tail_type.type
|
| 1295 |
+
tail_type.type = nested_type
|
| 1296 |
+
p[0] = p[3]
|
| 1297 |
+
else:
|
| 1298 |
+
p[0] = nested_type
|
| 1299 |
+
|
| 1300 |
+
def p_type_qualifier_list(self, p):
|
| 1301 |
+
""" type_qualifier_list : type_qualifier
|
| 1302 |
+
| type_qualifier_list type_qualifier
|
| 1303 |
+
"""
|
| 1304 |
+
p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]
|
| 1305 |
+
|
| 1306 |
+
def p_parameter_type_list(self, p):
|
| 1307 |
+
""" parameter_type_list : parameter_list
|
| 1308 |
+
| parameter_list COMMA ELLIPSIS
|
| 1309 |
+
"""
|
| 1310 |
+
if len(p) > 2:
|
| 1311 |
+
p[1].params.append(c_ast.EllipsisParam(self._token_coord(p, 3)))
|
| 1312 |
+
|
| 1313 |
+
p[0] = p[1]
|
| 1314 |
+
|
| 1315 |
+
def p_parameter_list(self, p):
|
| 1316 |
+
""" parameter_list : parameter_declaration
|
| 1317 |
+
| parameter_list COMMA parameter_declaration
|
| 1318 |
+
"""
|
| 1319 |
+
if len(p) == 2: # single parameter
|
| 1320 |
+
p[0] = c_ast.ParamList([p[1]], p[1].coord)
|
| 1321 |
+
else:
|
| 1322 |
+
p[1].params.append(p[3])
|
| 1323 |
+
p[0] = p[1]
|
| 1324 |
+
|
| 1325 |
+
# From ISO/IEC 9899:TC2, 6.7.5.3.11:
|
| 1326 |
+
# "If, in a parameter declaration, an identifier can be treated either
|
| 1327 |
+
# as a typedef name or as a parameter name, it shall be taken as a
|
| 1328 |
+
# typedef name."
|
| 1329 |
+
#
|
| 1330 |
+
# Inside a parameter declaration, once we've reduced declaration specifiers,
|
| 1331 |
+
# if we shift in an LPAREN and see a TYPEID, it could be either an abstract
|
| 1332 |
+
# declarator or a declarator nested inside parens. This rule tells us to
|
| 1333 |
+
# always treat it as an abstract declarator. Therefore, we only accept
|
| 1334 |
+
# `id_declarator`s and `typeid_noparen_declarator`s.
|
| 1335 |
+
def p_parameter_declaration_1(self, p):
|
| 1336 |
+
""" parameter_declaration : declaration_specifiers id_declarator
|
| 1337 |
+
| declaration_specifiers typeid_noparen_declarator
|
| 1338 |
+
"""
|
| 1339 |
+
spec = p[1]
|
| 1340 |
+
if not spec['type']:
|
| 1341 |
+
spec['type'] = [c_ast.IdentifierType(['int'],
|
| 1342 |
+
coord=self._token_coord(p, 1))]
|
| 1343 |
+
p[0] = self._build_declarations(
|
| 1344 |
+
spec=spec,
|
| 1345 |
+
decls=[dict(decl=p[2])])[0]
|
| 1346 |
+
|
| 1347 |
+
def p_parameter_declaration_2(self, p):
|
| 1348 |
+
""" parameter_declaration : declaration_specifiers abstract_declarator_opt
|
| 1349 |
+
"""
|
| 1350 |
+
spec = p[1]
|
| 1351 |
+
if not spec['type']:
|
| 1352 |
+
spec['type'] = [c_ast.IdentifierType(['int'],
|
| 1353 |
+
coord=self._token_coord(p, 1))]
|
| 1354 |
+
|
| 1355 |
+
# Parameters can have the same names as typedefs. The trouble is that
|
| 1356 |
+
# the parameter's name gets grouped into declaration_specifiers, making
|
| 1357 |
+
# it look like an old-style declaration; compensate.
|
| 1358 |
+
#
|
| 1359 |
+
if len(spec['type']) > 1 and len(spec['type'][-1].names) == 1 and \
|
| 1360 |
+
self._is_type_in_scope(spec['type'][-1].names[0]):
|
| 1361 |
+
decl = self._build_declarations(
|
| 1362 |
+
spec=spec,
|
| 1363 |
+
decls=[dict(decl=p[2], init=None)])[0]
|
| 1364 |
+
|
| 1365 |
+
# This truly is an old-style parameter declaration
|
| 1366 |
+
#
|
| 1367 |
+
else:
|
| 1368 |
+
decl = c_ast.Typename(
|
| 1369 |
+
name='',
|
| 1370 |
+
quals=spec['qual'],
|
| 1371 |
+
align=None,
|
| 1372 |
+
type=p[2] or c_ast.TypeDecl(None, None, None, None),
|
| 1373 |
+
coord=self._token_coord(p, 2))
|
| 1374 |
+
typename = spec['type']
|
| 1375 |
+
decl = self._fix_decl_name_type(decl, typename)
|
| 1376 |
+
|
| 1377 |
+
p[0] = decl
|
| 1378 |
+
|
| 1379 |
+
def p_identifier_list(self, p):
|
| 1380 |
+
""" identifier_list : identifier
|
| 1381 |
+
| identifier_list COMMA identifier
|
| 1382 |
+
"""
|
| 1383 |
+
if len(p) == 2: # single parameter
|
| 1384 |
+
p[0] = c_ast.ParamList([p[1]], p[1].coord)
|
| 1385 |
+
else:
|
| 1386 |
+
p[1].params.append(p[3])
|
| 1387 |
+
p[0] = p[1]
|
| 1388 |
+
|
| 1389 |
+
def p_initializer_1(self, p):
|
| 1390 |
+
""" initializer : assignment_expression
|
| 1391 |
+
"""
|
| 1392 |
+
p[0] = p[1]
|
| 1393 |
+
|
| 1394 |
+
def p_initializer_2(self, p):
|
| 1395 |
+
""" initializer : brace_open initializer_list_opt brace_close
|
| 1396 |
+
| brace_open initializer_list COMMA brace_close
|
| 1397 |
+
"""
|
| 1398 |
+
if p[2] is None:
|
| 1399 |
+
p[0] = c_ast.InitList([], self._token_coord(p, 1))
|
| 1400 |
+
else:
|
| 1401 |
+
p[0] = p[2]
|
| 1402 |
+
|
| 1403 |
+
def p_initializer_list(self, p):
|
| 1404 |
+
""" initializer_list : designation_opt initializer
|
| 1405 |
+
| initializer_list COMMA designation_opt initializer
|
| 1406 |
+
"""
|
| 1407 |
+
if len(p) == 3: # single initializer
|
| 1408 |
+
init = p[2] if p[1] is None else c_ast.NamedInitializer(p[1], p[2])
|
| 1409 |
+
p[0] = c_ast.InitList([init], p[2].coord)
|
| 1410 |
+
else:
|
| 1411 |
+
init = p[4] if p[3] is None else c_ast.NamedInitializer(p[3], p[4])
|
| 1412 |
+
p[1].exprs.append(init)
|
| 1413 |
+
p[0] = p[1]
|
| 1414 |
+
|
| 1415 |
+
def p_designation(self, p):
|
| 1416 |
+
""" designation : designator_list EQUALS
|
| 1417 |
+
"""
|
| 1418 |
+
p[0] = p[1]
|
| 1419 |
+
|
| 1420 |
+
# Designators are represented as a list of nodes, in the order in which
|
| 1421 |
+
# they're written in the code.
|
| 1422 |
+
#
|
| 1423 |
+
def p_designator_list(self, p):
|
| 1424 |
+
""" designator_list : designator
|
| 1425 |
+
| designator_list designator
|
| 1426 |
+
"""
|
| 1427 |
+
p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]
|
| 1428 |
+
|
| 1429 |
+
def p_designator(self, p):
|
| 1430 |
+
""" designator : LBRACKET constant_expression RBRACKET
|
| 1431 |
+
| PERIOD identifier
|
| 1432 |
+
"""
|
| 1433 |
+
p[0] = p[2]
|
| 1434 |
+
|
| 1435 |
+
def p_type_name(self, p):
|
| 1436 |
+
""" type_name : specifier_qualifier_list abstract_declarator_opt
|
| 1437 |
+
"""
|
| 1438 |
+
typename = c_ast.Typename(
|
| 1439 |
+
name='',
|
| 1440 |
+
quals=p[1]['qual'][:],
|
| 1441 |
+
align=None,
|
| 1442 |
+
type=p[2] or c_ast.TypeDecl(None, None, None, None),
|
| 1443 |
+
coord=self._token_coord(p, 2))
|
| 1444 |
+
|
| 1445 |
+
p[0] = self._fix_decl_name_type(typename, p[1]['type'])
|
| 1446 |
+
|
| 1447 |
+
def p_abstract_declarator_1(self, p):
|
| 1448 |
+
""" abstract_declarator : pointer
|
| 1449 |
+
"""
|
| 1450 |
+
dummytype = c_ast.TypeDecl(None, None, None, None)
|
| 1451 |
+
p[0] = self._type_modify_decl(
|
| 1452 |
+
decl=dummytype,
|
| 1453 |
+
modifier=p[1])
|
| 1454 |
+
|
| 1455 |
+
def p_abstract_declarator_2(self, p):
|
| 1456 |
+
""" abstract_declarator : pointer direct_abstract_declarator
|
| 1457 |
+
"""
|
| 1458 |
+
p[0] = self._type_modify_decl(p[2], p[1])
|
| 1459 |
+
|
| 1460 |
+
def p_abstract_declarator_3(self, p):
|
| 1461 |
+
""" abstract_declarator : direct_abstract_declarator
|
| 1462 |
+
"""
|
| 1463 |
+
p[0] = p[1]
|
| 1464 |
+
|
| 1465 |
+
# Creating and using direct_abstract_declarator_opt here
|
| 1466 |
+
# instead of listing both direct_abstract_declarator and the
|
| 1467 |
+
# lack of it in the beginning of _1 and _2 caused two
|
| 1468 |
+
# shift/reduce errors.
|
| 1469 |
+
#
|
| 1470 |
+
def p_direct_abstract_declarator_1(self, p):
|
| 1471 |
+
""" direct_abstract_declarator : LPAREN abstract_declarator RPAREN """
|
| 1472 |
+
p[0] = p[2]
|
| 1473 |
+
|
| 1474 |
+
def p_direct_abstract_declarator_2(self, p):
|
| 1475 |
+
""" direct_abstract_declarator : direct_abstract_declarator LBRACKET assignment_expression_opt RBRACKET
|
| 1476 |
+
"""
|
| 1477 |
+
arr = c_ast.ArrayDecl(
|
| 1478 |
+
type=None,
|
| 1479 |
+
dim=p[3],
|
| 1480 |
+
dim_quals=[],
|
| 1481 |
+
coord=p[1].coord)
|
| 1482 |
+
|
| 1483 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
| 1484 |
+
|
| 1485 |
+
def p_direct_abstract_declarator_3(self, p):
|
| 1486 |
+
""" direct_abstract_declarator : LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET
|
| 1487 |
+
"""
|
| 1488 |
+
quals = (p[2] if len(p) > 4 else []) or []
|
| 1489 |
+
p[0] = c_ast.ArrayDecl(
|
| 1490 |
+
type=c_ast.TypeDecl(None, None, None, None),
|
| 1491 |
+
dim=p[3] if len(p) > 4 else p[2],
|
| 1492 |
+
dim_quals=quals,
|
| 1493 |
+
coord=self._token_coord(p, 1))
|
| 1494 |
+
|
| 1495 |
+
def p_direct_abstract_declarator_4(self, p):
|
| 1496 |
+
""" direct_abstract_declarator : direct_abstract_declarator LBRACKET TIMES RBRACKET
|
| 1497 |
+
"""
|
| 1498 |
+
arr = c_ast.ArrayDecl(
|
| 1499 |
+
type=None,
|
| 1500 |
+
dim=c_ast.ID(p[3], self._token_coord(p, 3)),
|
| 1501 |
+
dim_quals=[],
|
| 1502 |
+
coord=p[1].coord)
|
| 1503 |
+
|
| 1504 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
|
| 1505 |
+
|
| 1506 |
+
def p_direct_abstract_declarator_5(self, p):
|
| 1507 |
+
""" direct_abstract_declarator : LBRACKET TIMES RBRACKET
|
| 1508 |
+
"""
|
| 1509 |
+
p[0] = c_ast.ArrayDecl(
|
| 1510 |
+
type=c_ast.TypeDecl(None, None, None, None),
|
| 1511 |
+
dim=c_ast.ID(p[3], self._token_coord(p, 3)),
|
| 1512 |
+
dim_quals=[],
|
| 1513 |
+
coord=self._token_coord(p, 1))
|
| 1514 |
+
|
| 1515 |
+
def p_direct_abstract_declarator_6(self, p):
|
| 1516 |
+
""" direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN
|
| 1517 |
+
"""
|
| 1518 |
+
func = c_ast.FuncDecl(
|
| 1519 |
+
args=p[3],
|
| 1520 |
+
type=None,
|
| 1521 |
+
coord=p[1].coord)
|
| 1522 |
+
|
| 1523 |
+
p[0] = self._type_modify_decl(decl=p[1], modifier=func)
|
| 1524 |
+
|
| 1525 |
+
def p_direct_abstract_declarator_7(self, p):
|
| 1526 |
+
""" direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN
|
| 1527 |
+
"""
|
| 1528 |
+
p[0] = c_ast.FuncDecl(
|
| 1529 |
+
args=p[2],
|
| 1530 |
+
type=c_ast.TypeDecl(None, None, None, None),
|
| 1531 |
+
coord=self._token_coord(p, 1))
|
| 1532 |
+
|
| 1533 |
+
# declaration is a list, statement isn't. To make it consistent, block_item
|
| 1534 |
+
# will always be a list
|
| 1535 |
+
#
|
| 1536 |
+
def p_block_item(self, p):
|
| 1537 |
+
""" block_item : declaration
|
| 1538 |
+
| statement
|
| 1539 |
+
"""
|
| 1540 |
+
p[0] = p[1] if isinstance(p[1], list) else [p[1]]
|
| 1541 |
+
|
| 1542 |
+
# Since we made block_item a list, this just combines lists
|
| 1543 |
+
#
|
| 1544 |
+
def p_block_item_list(self, p):
|
| 1545 |
+
""" block_item_list : block_item
|
| 1546 |
+
| block_item_list block_item
|
| 1547 |
+
"""
|
| 1548 |
+
# Empty block items (plain ';') produce [None], so ignore them
|
| 1549 |
+
p[0] = p[1] if (len(p) == 2 or p[2] == [None]) else p[1] + p[2]
|
| 1550 |
+
|
| 1551 |
+
def p_compound_statement_1(self, p):
|
| 1552 |
+
""" compound_statement : brace_open block_item_list_opt brace_close """
|
| 1553 |
+
p[0] = c_ast.Compound(
|
| 1554 |
+
block_items=p[2],
|
| 1555 |
+
coord=self._token_coord(p, 1))
|
| 1556 |
+
|
| 1557 |
+
def p_labeled_statement_1(self, p):
|
| 1558 |
+
""" labeled_statement : ID COLON pragmacomp_or_statement """
|
| 1559 |
+
p[0] = c_ast.Label(p[1], p[3], self._token_coord(p, 1))
|
| 1560 |
+
|
| 1561 |
+
def p_labeled_statement_2(self, p):
|
| 1562 |
+
""" labeled_statement : CASE constant_expression COLON pragmacomp_or_statement """
|
| 1563 |
+
p[0] = c_ast.Case(p[2], [p[4]], self._token_coord(p, 1))
|
| 1564 |
+
|
| 1565 |
+
def p_labeled_statement_3(self, p):
|
| 1566 |
+
""" labeled_statement : DEFAULT COLON pragmacomp_or_statement """
|
| 1567 |
+
p[0] = c_ast.Default([p[3]], self._token_coord(p, 1))
|
| 1568 |
+
|
| 1569 |
+
def p_selection_statement_1(self, p):
|
| 1570 |
+
""" selection_statement : IF LPAREN expression RPAREN pragmacomp_or_statement """
|
| 1571 |
+
p[0] = c_ast.If(p[3], p[5], None, self._token_coord(p, 1))
|
| 1572 |
+
|
| 1573 |
+
def p_selection_statement_2(self, p):
|
| 1574 |
+
""" selection_statement : IF LPAREN expression RPAREN statement ELSE pragmacomp_or_statement """
|
| 1575 |
+
p[0] = c_ast.If(p[3], p[5], p[7], self._token_coord(p, 1))
|
| 1576 |
+
|
| 1577 |
+
def p_selection_statement_3(self, p):
|
| 1578 |
+
""" selection_statement : SWITCH LPAREN expression RPAREN pragmacomp_or_statement """
|
| 1579 |
+
p[0] = fix_switch_cases(
|
| 1580 |
+
c_ast.Switch(p[3], p[5], self._token_coord(p, 1)))
|
| 1581 |
+
|
| 1582 |
+
def p_iteration_statement_1(self, p):
|
| 1583 |
+
""" iteration_statement : WHILE LPAREN expression RPAREN pragmacomp_or_statement """
|
| 1584 |
+
p[0] = c_ast.While(p[3], p[5], self._token_coord(p, 1))
|
| 1585 |
+
|
| 1586 |
+
def p_iteration_statement_2(self, p):
|
| 1587 |
+
""" iteration_statement : DO pragmacomp_or_statement WHILE LPAREN expression RPAREN SEMI """
|
| 1588 |
+
p[0] = c_ast.DoWhile(p[5], p[2], self._token_coord(p, 1))
|
| 1589 |
+
|
| 1590 |
+
def p_iteration_statement_3(self, p):
|
| 1591 |
+
""" iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """
|
| 1592 |
+
p[0] = c_ast.For(p[3], p[5], p[7], p[9], self._token_coord(p, 1))
|
| 1593 |
+
|
| 1594 |
+
def p_iteration_statement_4(self, p):
|
| 1595 |
+
""" iteration_statement : FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """
|
| 1596 |
+
p[0] = c_ast.For(c_ast.DeclList(p[3], self._token_coord(p, 1)),
|
| 1597 |
+
p[4], p[6], p[8], self._token_coord(p, 1))
|
| 1598 |
+
|
| 1599 |
+
def p_jump_statement_1(self, p):
|
| 1600 |
+
""" jump_statement : GOTO ID SEMI """
|
| 1601 |
+
p[0] = c_ast.Goto(p[2], self._token_coord(p, 1))
|
| 1602 |
+
|
| 1603 |
+
def p_jump_statement_2(self, p):
|
| 1604 |
+
""" jump_statement : BREAK SEMI """
|
| 1605 |
+
p[0] = c_ast.Break(self._token_coord(p, 1))
|
| 1606 |
+
|
| 1607 |
+
def p_jump_statement_3(self, p):
|
| 1608 |
+
""" jump_statement : CONTINUE SEMI """
|
| 1609 |
+
p[0] = c_ast.Continue(self._token_coord(p, 1))
|
| 1610 |
+
|
| 1611 |
+
def p_jump_statement_4(self, p):
|
| 1612 |
+
""" jump_statement : RETURN expression SEMI
|
| 1613 |
+
| RETURN SEMI
|
| 1614 |
+
"""
|
| 1615 |
+
p[0] = c_ast.Return(p[2] if len(p) == 4 else None, self._token_coord(p, 1))
|
| 1616 |
+
|
| 1617 |
+
def p_expression_statement(self, p):
|
| 1618 |
+
""" expression_statement : expression_opt SEMI """
|
| 1619 |
+
if p[1] is None:
|
| 1620 |
+
p[0] = c_ast.EmptyStatement(self._token_coord(p, 2))
|
| 1621 |
+
else:
|
| 1622 |
+
p[0] = p[1]
|
| 1623 |
+
|
| 1624 |
+
def p_expression(self, p):
|
| 1625 |
+
""" expression : assignment_expression
|
| 1626 |
+
| expression COMMA assignment_expression
|
| 1627 |
+
"""
|
| 1628 |
+
if len(p) == 2:
|
| 1629 |
+
p[0] = p[1]
|
| 1630 |
+
else:
|
| 1631 |
+
if not isinstance(p[1], c_ast.ExprList):
|
| 1632 |
+
p[1] = c_ast.ExprList([p[1]], p[1].coord)
|
| 1633 |
+
|
| 1634 |
+
p[1].exprs.append(p[3])
|
| 1635 |
+
p[0] = p[1]
|
| 1636 |
+
|
| 1637 |
+
def p_parenthesized_compound_expression(self, p):
|
| 1638 |
+
""" assignment_expression : LPAREN compound_statement RPAREN """
|
| 1639 |
+
p[0] = p[2]
|
| 1640 |
+
|
| 1641 |
+
def p_typedef_name(self, p):
|
| 1642 |
+
""" typedef_name : TYPEID """
|
| 1643 |
+
p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1))
|
| 1644 |
+
|
| 1645 |
+
def p_assignment_expression(self, p):
|
| 1646 |
+
""" assignment_expression : conditional_expression
|
| 1647 |
+
| unary_expression assignment_operator assignment_expression
|
| 1648 |
+
"""
|
| 1649 |
+
if len(p) == 2:
|
| 1650 |
+
p[0] = p[1]
|
| 1651 |
+
else:
|
| 1652 |
+
p[0] = c_ast.Assignment(p[2], p[1], p[3], p[1].coord)
|
| 1653 |
+
|
| 1654 |
+
# K&R2 defines these as many separate rules, to encode
|
| 1655 |
+
# precedence and associativity. Why work hard ? I'll just use
|
| 1656 |
+
# the built in precedence/associativity specification feature
|
| 1657 |
+
# of PLY. (see precedence declaration above)
|
| 1658 |
+
#
|
| 1659 |
+
def p_assignment_operator(self, p):
|
| 1660 |
+
""" assignment_operator : EQUALS
|
| 1661 |
+
| XOREQUAL
|
| 1662 |
+
| TIMESEQUAL
|
| 1663 |
+
| DIVEQUAL
|
| 1664 |
+
| MODEQUAL
|
| 1665 |
+
| PLUSEQUAL
|
| 1666 |
+
| MINUSEQUAL
|
| 1667 |
+
| LSHIFTEQUAL
|
| 1668 |
+
| RSHIFTEQUAL
|
| 1669 |
+
| ANDEQUAL
|
| 1670 |
+
| OREQUAL
|
| 1671 |
+
"""
|
| 1672 |
+
p[0] = p[1]
|
| 1673 |
+
|
| 1674 |
+
def p_constant_expression(self, p):
|
| 1675 |
+
""" constant_expression : conditional_expression """
|
| 1676 |
+
p[0] = p[1]
|
| 1677 |
+
|
| 1678 |
+
def p_conditional_expression(self, p):
|
| 1679 |
+
""" conditional_expression : binary_expression
|
| 1680 |
+
| binary_expression CONDOP expression COLON conditional_expression
|
| 1681 |
+
"""
|
| 1682 |
+
if len(p) == 2:
|
| 1683 |
+
p[0] = p[1]
|
| 1684 |
+
else:
|
| 1685 |
+
p[0] = c_ast.TernaryOp(p[1], p[3], p[5], p[1].coord)
|
| 1686 |
+
|
| 1687 |
+
def p_binary_expression(self, p):
|
| 1688 |
+
""" binary_expression : cast_expression
|
| 1689 |
+
| binary_expression TIMES binary_expression
|
| 1690 |
+
| binary_expression DIVIDE binary_expression
|
| 1691 |
+
| binary_expression MOD binary_expression
|
| 1692 |
+
| binary_expression PLUS binary_expression
|
| 1693 |
+
| binary_expression MINUS binary_expression
|
| 1694 |
+
| binary_expression RSHIFT binary_expression
|
| 1695 |
+
| binary_expression LSHIFT binary_expression
|
| 1696 |
+
| binary_expression LT binary_expression
|
| 1697 |
+
| binary_expression LE binary_expression
|
| 1698 |
+
| binary_expression GE binary_expression
|
| 1699 |
+
| binary_expression GT binary_expression
|
| 1700 |
+
| binary_expression EQ binary_expression
|
| 1701 |
+
| binary_expression NE binary_expression
|
| 1702 |
+
| binary_expression AND binary_expression
|
| 1703 |
+
| binary_expression OR binary_expression
|
| 1704 |
+
| binary_expression XOR binary_expression
|
| 1705 |
+
| binary_expression LAND binary_expression
|
| 1706 |
+
| binary_expression LOR binary_expression
|
| 1707 |
+
"""
|
| 1708 |
+
if len(p) == 2:
|
| 1709 |
+
p[0] = p[1]
|
| 1710 |
+
else:
|
| 1711 |
+
p[0] = c_ast.BinaryOp(p[2], p[1], p[3], p[1].coord)
|
| 1712 |
+
|
| 1713 |
+
def p_cast_expression_1(self, p):
|
| 1714 |
+
""" cast_expression : unary_expression """
|
| 1715 |
+
p[0] = p[1]
|
| 1716 |
+
|
| 1717 |
+
def p_cast_expression_2(self, p):
|
| 1718 |
+
""" cast_expression : LPAREN type_name RPAREN cast_expression """
|
| 1719 |
+
p[0] = c_ast.Cast(p[2], p[4], self._token_coord(p, 1))
|
| 1720 |
+
|
| 1721 |
+
def p_unary_expression_1(self, p):
|
| 1722 |
+
""" unary_expression : postfix_expression """
|
| 1723 |
+
p[0] = p[1]
|
| 1724 |
+
|
| 1725 |
+
def p_unary_expression_2(self, p):
|
| 1726 |
+
""" unary_expression : PLUSPLUS unary_expression
|
| 1727 |
+
| MINUSMINUS unary_expression
|
| 1728 |
+
| unary_operator cast_expression
|
| 1729 |
+
"""
|
| 1730 |
+
p[0] = c_ast.UnaryOp(p[1], p[2], p[2].coord)
|
| 1731 |
+
|
| 1732 |
+
def p_unary_expression_3(self, p):
|
| 1733 |
+
""" unary_expression : SIZEOF unary_expression
|
| 1734 |
+
| SIZEOF LPAREN type_name RPAREN
|
| 1735 |
+
| _ALIGNOF LPAREN type_name RPAREN
|
| 1736 |
+
"""
|
| 1737 |
+
p[0] = c_ast.UnaryOp(
|
| 1738 |
+
p[1],
|
| 1739 |
+
p[2] if len(p) == 3 else p[3],
|
| 1740 |
+
self._token_coord(p, 1))
|
| 1741 |
+
|
| 1742 |
+
def p_unary_operator(self, p):
|
| 1743 |
+
""" unary_operator : AND
|
| 1744 |
+
| TIMES
|
| 1745 |
+
| PLUS
|
| 1746 |
+
| MINUS
|
| 1747 |
+
| NOT
|
| 1748 |
+
| LNOT
|
| 1749 |
+
"""
|
| 1750 |
+
p[0] = p[1]
|
| 1751 |
+
|
| 1752 |
+
def p_postfix_expression_1(self, p):
|
| 1753 |
+
""" postfix_expression : primary_expression """
|
| 1754 |
+
p[0] = p[1]
|
| 1755 |
+
|
| 1756 |
+
def p_postfix_expression_2(self, p):
|
| 1757 |
+
""" postfix_expression : postfix_expression LBRACKET expression RBRACKET """
|
| 1758 |
+
p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord)
|
| 1759 |
+
|
| 1760 |
+
def p_postfix_expression_3(self, p):
|
| 1761 |
+
""" postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN
|
| 1762 |
+
| postfix_expression LPAREN RPAREN
|
| 1763 |
+
"""
|
| 1764 |
+
p[0] = c_ast.FuncCall(p[1], p[3] if len(p) == 5 else None, p[1].coord)
|
| 1765 |
+
|
| 1766 |
+
def p_postfix_expression_4(self, p):
|
| 1767 |
+
""" postfix_expression : postfix_expression PERIOD ID
|
| 1768 |
+
| postfix_expression PERIOD TYPEID
|
| 1769 |
+
| postfix_expression ARROW ID
|
| 1770 |
+
| postfix_expression ARROW TYPEID
|
| 1771 |
+
"""
|
| 1772 |
+
field = c_ast.ID(p[3], self._token_coord(p, 3))
|
| 1773 |
+
p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord)
|
| 1774 |
+
|
| 1775 |
+
def p_postfix_expression_5(self, p):
|
| 1776 |
+
""" postfix_expression : postfix_expression PLUSPLUS
|
| 1777 |
+
| postfix_expression MINUSMINUS
|
| 1778 |
+
"""
|
| 1779 |
+
p[0] = c_ast.UnaryOp('p' + p[2], p[1], p[1].coord)
|
| 1780 |
+
|
| 1781 |
+
def p_postfix_expression_6(self, p):
|
| 1782 |
+
""" postfix_expression : LPAREN type_name RPAREN brace_open initializer_list brace_close
|
| 1783 |
+
| LPAREN type_name RPAREN brace_open initializer_list COMMA brace_close
|
| 1784 |
+
"""
|
| 1785 |
+
p[0] = c_ast.CompoundLiteral(p[2], p[5])
|
| 1786 |
+
|
| 1787 |
+
def p_primary_expression_1(self, p):
|
| 1788 |
+
""" primary_expression : identifier """
|
| 1789 |
+
p[0] = p[1]
|
| 1790 |
+
|
| 1791 |
+
def p_primary_expression_2(self, p):
|
| 1792 |
+
""" primary_expression : constant """
|
| 1793 |
+
p[0] = p[1]
|
| 1794 |
+
|
| 1795 |
+
def p_primary_expression_3(self, p):
|
| 1796 |
+
""" primary_expression : unified_string_literal
|
| 1797 |
+
| unified_wstring_literal
|
| 1798 |
+
"""
|
| 1799 |
+
p[0] = p[1]
|
| 1800 |
+
|
| 1801 |
+
def p_primary_expression_4(self, p):
|
| 1802 |
+
""" primary_expression : LPAREN expression RPAREN """
|
| 1803 |
+
p[0] = p[2]
|
| 1804 |
+
|
| 1805 |
+
def p_primary_expression_5(self, p):
|
| 1806 |
+
""" primary_expression : OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN
|
| 1807 |
+
"""
|
| 1808 |
+
coord = self._token_coord(p, 1)
|
| 1809 |
+
p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord),
|
| 1810 |
+
c_ast.ExprList([p[3], p[5]], coord),
|
| 1811 |
+
coord)
|
| 1812 |
+
|
| 1813 |
+
def p_offsetof_member_designator(self, p):
|
| 1814 |
+
""" offsetof_member_designator : identifier
|
| 1815 |
+
| offsetof_member_designator PERIOD identifier
|
| 1816 |
+
| offsetof_member_designator LBRACKET expression RBRACKET
|
| 1817 |
+
"""
|
| 1818 |
+
if len(p) == 2:
|
| 1819 |
+
p[0] = p[1]
|
| 1820 |
+
elif len(p) == 4:
|
| 1821 |
+
p[0] = c_ast.StructRef(p[1], p[2], p[3], p[1].coord)
|
| 1822 |
+
elif len(p) == 5:
|
| 1823 |
+
p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord)
|
| 1824 |
+
else:
|
| 1825 |
+
raise NotImplementedError("Unexpected parsing state. len(p): %u" % len(p))
|
| 1826 |
+
|
| 1827 |
+
def p_argument_expression_list(self, p):
|
| 1828 |
+
""" argument_expression_list : assignment_expression
|
| 1829 |
+
| argument_expression_list COMMA assignment_expression
|
| 1830 |
+
"""
|
| 1831 |
+
if len(p) == 2: # single expr
|
| 1832 |
+
p[0] = c_ast.ExprList([p[1]], p[1].coord)
|
| 1833 |
+
else:
|
| 1834 |
+
p[1].exprs.append(p[3])
|
| 1835 |
+
p[0] = p[1]
|
| 1836 |
+
|
| 1837 |
+
def p_identifier(self, p):
|
| 1838 |
+
""" identifier : ID """
|
| 1839 |
+
p[0] = c_ast.ID(p[1], self._token_coord(p, 1))
|
| 1840 |
+
|
| 1841 |
+
def p_constant_1(self, p):
|
| 1842 |
+
""" constant : INT_CONST_DEC
|
| 1843 |
+
| INT_CONST_OCT
|
| 1844 |
+
| INT_CONST_HEX
|
| 1845 |
+
| INT_CONST_BIN
|
| 1846 |
+
| INT_CONST_CHAR
|
| 1847 |
+
"""
|
| 1848 |
+
uCount = 0
|
| 1849 |
+
lCount = 0
|
| 1850 |
+
for x in p[1][-3:]:
|
| 1851 |
+
if x in ('l', 'L'):
|
| 1852 |
+
lCount += 1
|
| 1853 |
+
elif x in ('u', 'U'):
|
| 1854 |
+
uCount += 1
|
| 1855 |
+
t = ''
|
| 1856 |
+
if uCount > 1:
|
| 1857 |
+
raise ValueError('Constant cannot have more than one u/U suffix.')
|
| 1858 |
+
elif lCount > 2:
|
| 1859 |
+
raise ValueError('Constant cannot have more than two l/L suffix.')
|
| 1860 |
+
prefix = 'unsigned ' * uCount + 'long ' * lCount
|
| 1861 |
+
p[0] = c_ast.Constant(
|
| 1862 |
+
prefix + 'int', p[1], self._token_coord(p, 1))
|
| 1863 |
+
|
| 1864 |
+
def p_constant_2(self, p):
|
| 1865 |
+
""" constant : FLOAT_CONST
|
| 1866 |
+
| HEX_FLOAT_CONST
|
| 1867 |
+
"""
|
| 1868 |
+
if 'x' in p[1].lower():
|
| 1869 |
+
t = 'float'
|
| 1870 |
+
else:
|
| 1871 |
+
if p[1][-1] in ('f', 'F'):
|
| 1872 |
+
t = 'float'
|
| 1873 |
+
elif p[1][-1] in ('l', 'L'):
|
| 1874 |
+
t = 'long double'
|
| 1875 |
+
else:
|
| 1876 |
+
t = 'double'
|
| 1877 |
+
|
| 1878 |
+
p[0] = c_ast.Constant(
|
| 1879 |
+
t, p[1], self._token_coord(p, 1))
|
| 1880 |
+
|
| 1881 |
+
def p_constant_3(self, p):
|
| 1882 |
+
""" constant : CHAR_CONST
|
| 1883 |
+
| WCHAR_CONST
|
| 1884 |
+
| U8CHAR_CONST
|
| 1885 |
+
| U16CHAR_CONST
|
| 1886 |
+
| U32CHAR_CONST
|
| 1887 |
+
"""
|
| 1888 |
+
p[0] = c_ast.Constant(
|
| 1889 |
+
'char', p[1], self._token_coord(p, 1))
|
| 1890 |
+
|
| 1891 |
+
# The "unified" string and wstring literal rules are for supporting
|
| 1892 |
+
# concatenation of adjacent string literals.
|
| 1893 |
+
# I.e. "hello " "world" is seen by the C compiler as a single string literal
|
| 1894 |
+
# with the value "hello world"
|
| 1895 |
+
#
|
| 1896 |
+
def p_unified_string_literal(self, p):
|
| 1897 |
+
""" unified_string_literal : STRING_LITERAL
|
| 1898 |
+
| unified_string_literal STRING_LITERAL
|
| 1899 |
+
"""
|
| 1900 |
+
if len(p) == 2: # single literal
|
| 1901 |
+
p[0] = c_ast.Constant(
|
| 1902 |
+
'string', p[1], self._token_coord(p, 1))
|
| 1903 |
+
else:
|
| 1904 |
+
p[1].value = p[1].value[:-1] + p[2][1:]
|
| 1905 |
+
p[0] = p[1]
|
| 1906 |
+
|
| 1907 |
+
def p_unified_wstring_literal(self, p):
|
| 1908 |
+
""" unified_wstring_literal : WSTRING_LITERAL
|
| 1909 |
+
| U8STRING_LITERAL
|
| 1910 |
+
| U16STRING_LITERAL
|
| 1911 |
+
| U32STRING_LITERAL
|
| 1912 |
+
| unified_wstring_literal WSTRING_LITERAL
|
| 1913 |
+
| unified_wstring_literal U8STRING_LITERAL
|
| 1914 |
+
| unified_wstring_literal U16STRING_LITERAL
|
| 1915 |
+
| unified_wstring_literal U32STRING_LITERAL
|
| 1916 |
+
"""
|
| 1917 |
+
if len(p) == 2: # single literal
|
| 1918 |
+
p[0] = c_ast.Constant(
|
| 1919 |
+
'string', p[1], self._token_coord(p, 1))
|
| 1920 |
+
else:
|
| 1921 |
+
p[1].value = p[1].value.rstrip()[:-1] + p[2][2:]
|
| 1922 |
+
p[0] = p[1]
|
| 1923 |
+
|
| 1924 |
+
def p_brace_open(self, p):
|
| 1925 |
+
""" brace_open : LBRACE
|
| 1926 |
+
"""
|
| 1927 |
+
p[0] = p[1]
|
| 1928 |
+
p.set_lineno(0, p.lineno(1))
|
| 1929 |
+
|
| 1930 |
+
def p_brace_close(self, p):
|
| 1931 |
+
""" brace_close : RBRACE
|
| 1932 |
+
"""
|
| 1933 |
+
p[0] = p[1]
|
| 1934 |
+
p.set_lineno(0, p.lineno(1))
|
| 1935 |
+
|
| 1936 |
+
def p_empty(self, p):
|
| 1937 |
+
'empty : '
|
| 1938 |
+
p[0] = None
|
| 1939 |
+
|
| 1940 |
+
def p_error(self, p):
|
| 1941 |
+
# If error recovery is added here in the future, make sure
|
| 1942 |
+
# _get_yacc_lookahead_token still works!
|
| 1943 |
+
#
|
| 1944 |
+
if p:
|
| 1945 |
+
self._parse_error(
|
| 1946 |
+
'before: %s' % p.value,
|
| 1947 |
+
self._coord(lineno=p.lineno,
|
| 1948 |
+
column=self.clex.find_tok_column(p)))
|
| 1949 |
+
else:
|
| 1950 |
+
self._parse_error('At end of input', self.clex.filename)
|
rtme/lib/python3.10/site-packages/pycparser/lextab.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# lextab.py. This file automatically created by PLY (version 3.10). Don't edit!
|
| 2 |
+
_tabversion = '3.10'
|
| 3 |
+
_lextokens = set(('AND', 'ANDEQUAL', 'ARROW', 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CHAR_CONST', 'COLON', 'COMMA', 'CONDOP', 'CONST', 'CONTINUE', 'DEFAULT', 'DIVEQUAL', 'DIVIDE', 'DO', 'DOUBLE', 'ELLIPSIS', 'ELSE', 'ENUM', 'EQ', 'EQUALS', 'EXTERN', 'FLOAT', 'FLOAT_CONST', 'FOR', 'GE', 'GOTO', 'GT', 'HEX_FLOAT_CONST', 'ID', 'IF', 'INLINE', 'INT', 'INT_CONST_BIN', 'INT_CONST_CHAR', 'INT_CONST_DEC', 'INT_CONST_HEX', 'INT_CONST_OCT', 'LAND', 'LBRACE', 'LBRACKET', 'LE', 'LNOT', 'LONG', 'LOR', 'LPAREN', 'LSHIFT', 'LSHIFTEQUAL', 'LT', 'MINUS', 'MINUSEQUAL', 'MINUSMINUS', 'MOD', 'MODEQUAL', 'NE', 'NOT', 'OFFSETOF', 'OR', 'OREQUAL', 'PERIOD', 'PLUS', 'PLUSEQUAL', 'PLUSPLUS', 'PPHASH', 'PPPRAGMA', 'PPPRAGMASTR', 'RBRACE', 'RBRACKET', 'REGISTER', 'RESTRICT', 'RETURN', 'RPAREN', 'RSHIFT', 'RSHIFTEQUAL', 'SEMI', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRING_LITERAL', 'STRUCT', 'SWITCH', 'TIMES', 'TIMESEQUAL', 'TYPEDEF', 'TYPEID', 'U16CHAR_CONST', 'U16STRING_LITERAL', 'U32CHAR_CONST', 'U32STRING_LITERAL', 'U8CHAR_CONST', 'U8STRING_LITERAL', 'UNION', 'UNSIGNED', 'VOID', 'VOLATILE', 'WCHAR_CONST', 'WHILE', 'WSTRING_LITERAL', 'XOR', 'XOREQUAL', '_ALIGNAS', '_ALIGNOF', '_ATOMIC', '_BOOL', '_COMPLEX', '_NORETURN', '_PRAGMA', '_STATIC_ASSERT', '_THREAD_LOCAL', '__INT128'))
|
| 4 |
+
_lexreflags = 64
|
| 5 |
+
_lexliterals = ''
|
| 6 |
+
_lexstateinfo = {'INITIAL': 'inclusive', 'ppline': 'exclusive', 'pppragma': 'exclusive'}
|
| 7 |
+
_lexstatere = {'INITIAL': [('(?P<t_PPHASH>[ \\t]*\\#)|(?P<t_NEWLINE>\\n+)|(?P<t_LBRACE>\\{)|(?P<t_RBRACE>\\})|(?P<t_FLOAT_CONST>((((([0-9]*\\.[0-9]+)|([0-9]+\\.))([eE][-+]?[0-9]+)?)|([0-9]+([eE][-+]?[0-9]+)))[FfLl]?))|(?P<t_HEX_FLOAT_CONST>(0[xX]([0-9a-fA-F]+|((([0-9a-fA-F]+)?\\.[0-9a-fA-F]+)|([0-9a-fA-F]+\\.)))([pP][+-]?[0-9]+)[FfLl]?))|(?P<t_INT_CONST_HEX>0[xX][0-9a-fA-F]+(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|(?P<t_INT_CONST_BIN>0[bB][01]+(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|(?P<t_BAD_CONST_OCT>0[0-7]*[89])|(?P<t_INT_CONST_OCT>0[0-7]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|(?P<t_INT_CONST_DEC>(0(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|([1-9][0-9]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?))|(?P<t_INT_CONST_CHAR>\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F])))){2,4}\')|(?P<t_CHAR_CONST>\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?P<t_WCHAR_CONST>L\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?P<t_U8CHAR_CONST>u8\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?P<t_U16CHAR_CONST>u\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?P<t_U32CHAR_CONST>U\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))\')|(?P<t_UNMATCHED_QUOTE>(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))*\\n)|(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))*$))|(?P<t_BAD_CHAR_CONST>(\'([^\'\\\\\\n]|(\\\\(([a-wyzA-Z._~!=&\\^\\-\\\\?\'"]|x(?![0-9a-fA-F]))|(\\d+)(?!\\d)|(x[0-9a-fA-F]+)(?![0-9a-fA-F]))))[^\'\n]+\')|(\'\')|(\'([\\\\][^a-zA-Z._~^!=&\\^\\-\\\\?\'"x0-9])[^\'\\n]*\'))|(?P<t_WSTRING_LITERAL>L"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_U8STRING_LITERAL>u8"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_U16STRING_LITERAL>u"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_U32STRING_LITERAL>U"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_BAD_STRING_LITERAL>"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*([\\\\][^a-zA-Z._~^!=&\\^\\-\\\\?\'"x0-9])([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_ID>[a-zA-Z_$][0-9a-zA-Z_$]*)|(?P<t_STRING_LITERAL>"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_ELLIPSIS>\\.\\.\\.)|(?P<t_LOR>\\|\\|)|(?P<t_PLUSPLUS>\\+\\+)|(?P<t_LSHIFTEQUAL><<=)|(?P<t_OREQUAL>\\|=)|(?P<t_PLUSEQUAL>\\+=)|(?P<t_RSHIFTEQUAL>>>=)|(?P<t_TIMESEQUAL>\\*=)|(?P<t_XOREQUAL>\\^=)|(?P<t_ANDEQUAL>&=)|(?P<t_ARROW>->)|(?P<t_CONDOP>\\?)|(?P<t_DIVEQUAL>/=)|(?P<t_EQ>==)|(?P<t_GE>>=)|(?P<t_LAND>&&)|(?P<t_LBRACKET>\\[)|(?P<t_LE><=)|(?P<t_LPAREN>\\()|(?P<t_LSHIFT><<)|(?P<t_MINUSEQUAL>-=)|(?P<t_MINUSMINUS>--)|(?P<t_MODEQUAL>%=)|(?P<t_NE>!=)|(?P<t_OR>\\|)|(?P<t_PERIOD>\\.)|(?P<t_PLUS>\\+)|(?P<t_RBRACKET>\\])|(?P<t_RPAREN>\\))|(?P<t_RSHIFT>>>)|(?P<t_TIMES>\\*)|(?P<t_XOR>\\^)|(?P<t_AND>&)|(?P<t_COLON>:)|(?P<t_COMMA>,)|(?P<t_DIVIDE>/)|(?P<t_EQUALS>=)|(?P<t_GT>>)|(?P<t_LNOT>!)|(?P<t_LT><)|(?P<t_MINUS>-)|(?P<t_MOD>%)|(?P<t_NOT>~)|(?P<t_SEMI>;)', [None, ('t_PPHASH', 'PPHASH'), ('t_NEWLINE', 'NEWLINE'), ('t_LBRACE', 'LBRACE'), ('t_RBRACE', 'RBRACE'), ('t_FLOAT_CONST', 'FLOAT_CONST'), None, None, None, None, None, None, None, None, None, ('t_HEX_FLOAT_CONST', 'HEX_FLOAT_CONST'), None, None, None, None, None, None, None, ('t_INT_CONST_HEX', 'INT_CONST_HEX'), None, None, None, None, None, None, None, ('t_INT_CONST_BIN', 'INT_CONST_BIN'), None, None, None, None, None, None, None, ('t_BAD_CONST_OCT', 'BAD_CONST_OCT'), ('t_INT_CONST_OCT', 'INT_CONST_OCT'), None, None, None, None, None, None, None, ('t_INT_CONST_DEC', 'INT_CONST_DEC'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_INT_CONST_CHAR', 'INT_CONST_CHAR'), None, None, None, None, None, None, ('t_CHAR_CONST', 'CHAR_CONST'), None, None, None, None, None, None, ('t_WCHAR_CONST', 'WCHAR_CONST'), None, None, None, None, None, None, ('t_U8CHAR_CONST', 'U8CHAR_CONST'), None, None, None, None, None, None, ('t_U16CHAR_CONST', 'U16CHAR_CONST'), None, None, None, None, None, None, ('t_U32CHAR_CONST', 'U32CHAR_CONST'), None, None, None, None, None, None, ('t_UNMATCHED_QUOTE', 'UNMATCHED_QUOTE'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_BAD_CHAR_CONST', 'BAD_CHAR_CONST'), None, None, None, None, None, None, None, None, None, None, ('t_WSTRING_LITERAL', 'WSTRING_LITERAL'), None, None, ('t_U8STRING_LITERAL', 'U8STRING_LITERAL'), None, None, ('t_U16STRING_LITERAL', 'U16STRING_LITERAL'), None, None, ('t_U32STRING_LITERAL', 'U32STRING_LITERAL'), None, None, ('t_BAD_STRING_LITERAL', 'BAD_STRING_LITERAL'), None, None, None, None, None, ('t_ID', 'ID'), (None, 'STRING_LITERAL'), None, None, (None, 'ELLIPSIS'), (None, 'LOR'), (None, 'PLUSPLUS'), (None, 'LSHIFTEQUAL'), (None, 'OREQUAL'), (None, 'PLUSEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'TIMESEQUAL'), (None, 'XOREQUAL'), (None, 'ANDEQUAL'), (None, 'ARROW'), (None, 'CONDOP'), (None, 'DIVEQUAL'), (None, 'EQ'), (None, 'GE'), (None, 'LAND'), (None, 'LBRACKET'), (None, 'LE'), (None, 'LPAREN'), (None, 'LSHIFT'), (None, 'MINUSEQUAL'), (None, 'MINUSMINUS'), (None, 'MODEQUAL'), (None, 'NE'), (None, 'OR'), (None, 'PERIOD'), (None, 'PLUS'), (None, 'RBRACKET'), (None, 'RPAREN'), (None, 'RSHIFT'), (None, 'TIMES'), (None, 'XOR'), (None, 'AND'), (None, 'COLON'), (None, 'COMMA'), (None, 'DIVIDE'), (None, 'EQUALS'), (None, 'GT'), (None, 'LNOT'), (None, 'LT'), (None, 'MINUS'), (None, 'MOD'), (None, 'NOT'), (None, 'SEMI')])], 'ppline': [('(?P<t_ppline_FILENAME>"([^"\\\\\\n]|(\\\\[0-9a-zA-Z._~!=&\\^\\-\\\\?\'"]))*")|(?P<t_ppline_LINE_NUMBER>(0(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?)|([1-9][0-9]*(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?))|(?P<t_ppline_NEWLINE>\\n)|(?P<t_ppline_PPLINE>line)', [None, ('t_ppline_FILENAME', 'FILENAME'), None, None, ('t_ppline_LINE_NUMBER', 'LINE_NUMBER'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_ppline_NEWLINE', 'NEWLINE'), ('t_ppline_PPLINE', 'PPLINE')])], 'pppragma': [('(?P<t_pppragma_NEWLINE>\\n)|(?P<t_pppragma_PPPRAGMA>pragma)|(?P<t_pppragma_STR>.+)', [None, ('t_pppragma_NEWLINE', 'NEWLINE'), ('t_pppragma_PPPRAGMA', 'PPPRAGMA'), ('t_pppragma_STR', 'STR')])]}
|
| 8 |
+
_lexstateignore = {'INITIAL': ' \t', 'ppline': ' \t', 'pppragma': ' \t'}
|
| 9 |
+
_lexstateerrorf = {'INITIAL': 't_error', 'ppline': 't_ppline_error', 'pppragma': 't_pppragma_error'}
|
| 10 |
+
_lexstateeoff = {}
|
rtme/lib/python3.10/site-packages/pycparser/ply/__init__.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PLY package
|
| 2 |
+
# Author: David Beazley (dave@dabeaz.com)
|
| 3 |
+
|
| 4 |
+
__version__ = '3.9'
|
| 5 |
+
__all__ = ['lex','yacc']
|
rtme/lib/python3.10/site-packages/pycparser/ply/cpp.py
ADDED
|
@@ -0,0 +1,905 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# -----------------------------------------------------------------------------
|
| 2 |
+
# cpp.py
|
| 3 |
+
#
|
| 4 |
+
# Author: David Beazley (http://www.dabeaz.com)
|
| 5 |
+
# Copyright (C) 2017
|
| 6 |
+
# All rights reserved
|
| 7 |
+
#
|
| 8 |
+
# This module implements an ANSI-C style lexical preprocessor for PLY.
|
| 9 |
+
# -----------------------------------------------------------------------------
|
| 10 |
+
import sys
|
| 11 |
+
|
| 12 |
+
# Some Python 3 compatibility shims
|
| 13 |
+
if sys.version_info.major < 3:
|
| 14 |
+
STRING_TYPES = (str, unicode)
|
| 15 |
+
else:
|
| 16 |
+
STRING_TYPES = str
|
| 17 |
+
xrange = range
|
| 18 |
+
|
| 19 |
+
# -----------------------------------------------------------------------------
|
| 20 |
+
# Default preprocessor lexer definitions. These tokens are enough to get
|
| 21 |
+
# a basic preprocessor working. Other modules may import these if they want
|
| 22 |
+
# -----------------------------------------------------------------------------
|
| 23 |
+
|
| 24 |
+
tokens = (
|
| 25 |
+
'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT1', 'CPP_COMMENT2', 'CPP_POUND','CPP_DPOUND'
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
literals = "+-*/%|&~^<>=!?()[]{}.,;:\\\'\""
|
| 29 |
+
|
| 30 |
+
# Whitespace
|
| 31 |
+
def t_CPP_WS(t):
|
| 32 |
+
r'\s+'
|
| 33 |
+
t.lexer.lineno += t.value.count("\n")
|
| 34 |
+
return t
|
| 35 |
+
|
| 36 |
+
t_CPP_POUND = r'\#'
|
| 37 |
+
t_CPP_DPOUND = r'\#\#'
|
| 38 |
+
|
| 39 |
+
# Identifier
|
| 40 |
+
t_CPP_ID = r'[A-Za-z_][\w_]*'
|
| 41 |
+
|
| 42 |
+
# Integer literal
|
| 43 |
+
def CPP_INTEGER(t):
|
| 44 |
+
r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)'
|
| 45 |
+
return t
|
| 46 |
+
|
| 47 |
+
t_CPP_INTEGER = CPP_INTEGER
|
| 48 |
+
|
| 49 |
+
# Floating literal
|
| 50 |
+
t_CPP_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
|
| 51 |
+
|
| 52 |
+
# String literal
|
| 53 |
+
def t_CPP_STRING(t):
|
| 54 |
+
r'\"([^\\\n]|(\\(.|\n)))*?\"'
|
| 55 |
+
t.lexer.lineno += t.value.count("\n")
|
| 56 |
+
return t
|
| 57 |
+
|
| 58 |
+
# Character constant 'c' or L'c'
|
| 59 |
+
def t_CPP_CHAR(t):
|
| 60 |
+
r'(L)?\'([^\\\n]|(\\(.|\n)))*?\''
|
| 61 |
+
t.lexer.lineno += t.value.count("\n")
|
| 62 |
+
return t
|
| 63 |
+
|
| 64 |
+
# Comment
|
| 65 |
+
def t_CPP_COMMENT1(t):
|
| 66 |
+
r'(/\*(.|\n)*?\*/)'
|
| 67 |
+
ncr = t.value.count("\n")
|
| 68 |
+
t.lexer.lineno += ncr
|
| 69 |
+
# replace with one space or a number of '\n'
|
| 70 |
+
t.type = 'CPP_WS'; t.value = '\n' * ncr if ncr else ' '
|
| 71 |
+
return t
|
| 72 |
+
|
| 73 |
+
# Line comment
|
| 74 |
+
def t_CPP_COMMENT2(t):
|
| 75 |
+
r'(//.*?(\n|$))'
|
| 76 |
+
# replace with '/n'
|
| 77 |
+
t.type = 'CPP_WS'; t.value = '\n'
|
| 78 |
+
return t
|
| 79 |
+
|
| 80 |
+
def t_error(t):
|
| 81 |
+
t.type = t.value[0]
|
| 82 |
+
t.value = t.value[0]
|
| 83 |
+
t.lexer.skip(1)
|
| 84 |
+
return t
|
| 85 |
+
|
| 86 |
+
import re
|
| 87 |
+
import copy
|
| 88 |
+
import time
|
| 89 |
+
import os.path
|
| 90 |
+
|
| 91 |
+
# -----------------------------------------------------------------------------
|
| 92 |
+
# trigraph()
|
| 93 |
+
#
|
| 94 |
+
# Given an input string, this function replaces all trigraph sequences.
|
| 95 |
+
# The following mapping is used:
|
| 96 |
+
#
|
| 97 |
+
# ??= #
|
| 98 |
+
# ??/ \
|
| 99 |
+
# ??' ^
|
| 100 |
+
# ??( [
|
| 101 |
+
# ??) ]
|
| 102 |
+
# ??! |
|
| 103 |
+
# ??< {
|
| 104 |
+
# ??> }
|
| 105 |
+
# ??- ~
|
| 106 |
+
# -----------------------------------------------------------------------------
|
| 107 |
+
|
| 108 |
+
_trigraph_pat = re.compile(r'''\?\?[=/\'\(\)\!<>\-]''')
|
| 109 |
+
_trigraph_rep = {
|
| 110 |
+
'=':'#',
|
| 111 |
+
'/':'\\',
|
| 112 |
+
"'":'^',
|
| 113 |
+
'(':'[',
|
| 114 |
+
')':']',
|
| 115 |
+
'!':'|',
|
| 116 |
+
'<':'{',
|
| 117 |
+
'>':'}',
|
| 118 |
+
'-':'~'
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
def trigraph(input):
|
| 122 |
+
return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input)
|
| 123 |
+
|
| 124 |
+
# ------------------------------------------------------------------
|
| 125 |
+
# Macro object
|
| 126 |
+
#
|
| 127 |
+
# This object holds information about preprocessor macros
|
| 128 |
+
#
|
| 129 |
+
# .name - Macro name (string)
|
| 130 |
+
# .value - Macro value (a list of tokens)
|
| 131 |
+
# .arglist - List of argument names
|
| 132 |
+
# .variadic - Boolean indicating whether or not variadic macro
|
| 133 |
+
# .vararg - Name of the variadic parameter
|
| 134 |
+
#
|
| 135 |
+
# When a macro is created, the macro replacement token sequence is
|
| 136 |
+
# pre-scanned and used to create patch lists that are later used
|
| 137 |
+
# during macro expansion
|
| 138 |
+
# ------------------------------------------------------------------
|
| 139 |
+
|
| 140 |
+
class Macro(object):
|
| 141 |
+
def __init__(self,name,value,arglist=None,variadic=False):
|
| 142 |
+
self.name = name
|
| 143 |
+
self.value = value
|
| 144 |
+
self.arglist = arglist
|
| 145 |
+
self.variadic = variadic
|
| 146 |
+
if variadic:
|
| 147 |
+
self.vararg = arglist[-1]
|
| 148 |
+
self.source = None
|
| 149 |
+
|
| 150 |
+
# ------------------------------------------------------------------
|
| 151 |
+
# Preprocessor object
|
| 152 |
+
#
|
| 153 |
+
# Object representing a preprocessor. Contains macro definitions,
|
| 154 |
+
# include directories, and other information
|
| 155 |
+
# ------------------------------------------------------------------
|
| 156 |
+
|
| 157 |
+
class Preprocessor(object):
|
| 158 |
+
def __init__(self,lexer=None):
|
| 159 |
+
if lexer is None:
|
| 160 |
+
lexer = lex.lexer
|
| 161 |
+
self.lexer = lexer
|
| 162 |
+
self.macros = { }
|
| 163 |
+
self.path = []
|
| 164 |
+
self.temp_path = []
|
| 165 |
+
|
| 166 |
+
# Probe the lexer for selected tokens
|
| 167 |
+
self.lexprobe()
|
| 168 |
+
|
| 169 |
+
tm = time.localtime()
|
| 170 |
+
self.define("__DATE__ \"%s\"" % time.strftime("%b %d %Y",tm))
|
| 171 |
+
self.define("__TIME__ \"%s\"" % time.strftime("%H:%M:%S",tm))
|
| 172 |
+
self.parser = None
|
| 173 |
+
|
| 174 |
+
# -----------------------------------------------------------------------------
|
| 175 |
+
# tokenize()
|
| 176 |
+
#
|
| 177 |
+
# Utility function. Given a string of text, tokenize into a list of tokens
|
| 178 |
+
# -----------------------------------------------------------------------------
|
| 179 |
+
|
| 180 |
+
def tokenize(self,text):
|
| 181 |
+
tokens = []
|
| 182 |
+
self.lexer.input(text)
|
| 183 |
+
while True:
|
| 184 |
+
tok = self.lexer.token()
|
| 185 |
+
if not tok: break
|
| 186 |
+
tokens.append(tok)
|
| 187 |
+
return tokens
|
| 188 |
+
|
| 189 |
+
# ---------------------------------------------------------------------
|
| 190 |
+
# error()
|
| 191 |
+
#
|
| 192 |
+
# Report a preprocessor error/warning of some kind
|
| 193 |
+
# ----------------------------------------------------------------------
|
| 194 |
+
|
| 195 |
+
def error(self,file,line,msg):
|
| 196 |
+
print("%s:%d %s" % (file,line,msg))
|
| 197 |
+
|
| 198 |
+
# ----------------------------------------------------------------------
|
| 199 |
+
# lexprobe()
|
| 200 |
+
#
|
| 201 |
+
# This method probes the preprocessor lexer object to discover
|
| 202 |
+
# the token types of symbols that are important to the preprocessor.
|
| 203 |
+
# If this works right, the preprocessor will simply "work"
|
| 204 |
+
# with any suitable lexer regardless of how tokens have been named.
|
| 205 |
+
# ----------------------------------------------------------------------
|
| 206 |
+
|
| 207 |
+
def lexprobe(self):
|
| 208 |
+
|
| 209 |
+
# Determine the token type for identifiers
|
| 210 |
+
self.lexer.input("identifier")
|
| 211 |
+
tok = self.lexer.token()
|
| 212 |
+
if not tok or tok.value != "identifier":
|
| 213 |
+
print("Couldn't determine identifier type")
|
| 214 |
+
else:
|
| 215 |
+
self.t_ID = tok.type
|
| 216 |
+
|
| 217 |
+
# Determine the token type for integers
|
| 218 |
+
self.lexer.input("12345")
|
| 219 |
+
tok = self.lexer.token()
|
| 220 |
+
if not tok or int(tok.value) != 12345:
|
| 221 |
+
print("Couldn't determine integer type")
|
| 222 |
+
else:
|
| 223 |
+
self.t_INTEGER = tok.type
|
| 224 |
+
self.t_INTEGER_TYPE = type(tok.value)
|
| 225 |
+
|
| 226 |
+
# Determine the token type for strings enclosed in double quotes
|
| 227 |
+
self.lexer.input("\"filename\"")
|
| 228 |
+
tok = self.lexer.token()
|
| 229 |
+
if not tok or tok.value != "\"filename\"":
|
| 230 |
+
print("Couldn't determine string type")
|
| 231 |
+
else:
|
| 232 |
+
self.t_STRING = tok.type
|
| 233 |
+
|
| 234 |
+
# Determine the token type for whitespace--if any
|
| 235 |
+
self.lexer.input(" ")
|
| 236 |
+
tok = self.lexer.token()
|
| 237 |
+
if not tok or tok.value != " ":
|
| 238 |
+
self.t_SPACE = None
|
| 239 |
+
else:
|
| 240 |
+
self.t_SPACE = tok.type
|
| 241 |
+
|
| 242 |
+
# Determine the token type for newlines
|
| 243 |
+
self.lexer.input("\n")
|
| 244 |
+
tok = self.lexer.token()
|
| 245 |
+
if not tok or tok.value != "\n":
|
| 246 |
+
self.t_NEWLINE = None
|
| 247 |
+
print("Couldn't determine token for newlines")
|
| 248 |
+
else:
|
| 249 |
+
self.t_NEWLINE = tok.type
|
| 250 |
+
|
| 251 |
+
self.t_WS = (self.t_SPACE, self.t_NEWLINE)
|
| 252 |
+
|
| 253 |
+
# Check for other characters used by the preprocessor
|
| 254 |
+
chars = [ '<','>','#','##','\\','(',')',',','.']
|
| 255 |
+
for c in chars:
|
| 256 |
+
self.lexer.input(c)
|
| 257 |
+
tok = self.lexer.token()
|
| 258 |
+
if not tok or tok.value != c:
|
| 259 |
+
print("Unable to lex '%s' required for preprocessor" % c)
|
| 260 |
+
|
| 261 |
+
# ----------------------------------------------------------------------
|
| 262 |
+
# add_path()
|
| 263 |
+
#
|
| 264 |
+
# Adds a search path to the preprocessor.
|
| 265 |
+
# ----------------------------------------------------------------------
|
| 266 |
+
|
| 267 |
+
def add_path(self,path):
|
| 268 |
+
self.path.append(path)
|
| 269 |
+
|
| 270 |
+
# ----------------------------------------------------------------------
|
| 271 |
+
# group_lines()
|
| 272 |
+
#
|
| 273 |
+
# Given an input string, this function splits it into lines. Trailing whitespace
|
| 274 |
+
# is removed. Any line ending with \ is grouped with the next line. This
|
| 275 |
+
# function forms the lowest level of the preprocessor---grouping into text into
|
| 276 |
+
# a line-by-line format.
|
| 277 |
+
# ----------------------------------------------------------------------
|
| 278 |
+
|
| 279 |
+
def group_lines(self,input):
|
| 280 |
+
lex = self.lexer.clone()
|
| 281 |
+
lines = [x.rstrip() for x in input.splitlines()]
|
| 282 |
+
for i in xrange(len(lines)):
|
| 283 |
+
j = i+1
|
| 284 |
+
while lines[i].endswith('\\') and (j < len(lines)):
|
| 285 |
+
lines[i] = lines[i][:-1]+lines[j]
|
| 286 |
+
lines[j] = ""
|
| 287 |
+
j += 1
|
| 288 |
+
|
| 289 |
+
input = "\n".join(lines)
|
| 290 |
+
lex.input(input)
|
| 291 |
+
lex.lineno = 1
|
| 292 |
+
|
| 293 |
+
current_line = []
|
| 294 |
+
while True:
|
| 295 |
+
tok = lex.token()
|
| 296 |
+
if not tok:
|
| 297 |
+
break
|
| 298 |
+
current_line.append(tok)
|
| 299 |
+
if tok.type in self.t_WS and '\n' in tok.value:
|
| 300 |
+
yield current_line
|
| 301 |
+
current_line = []
|
| 302 |
+
|
| 303 |
+
if current_line:
|
| 304 |
+
yield current_line
|
| 305 |
+
|
| 306 |
+
# ----------------------------------------------------------------------
|
| 307 |
+
# tokenstrip()
|
| 308 |
+
#
|
| 309 |
+
# Remove leading/trailing whitespace tokens from a token list
|
| 310 |
+
# ----------------------------------------------------------------------
|
| 311 |
+
|
| 312 |
+
def tokenstrip(self,tokens):
|
| 313 |
+
i = 0
|
| 314 |
+
while i < len(tokens) and tokens[i].type in self.t_WS:
|
| 315 |
+
i += 1
|
| 316 |
+
del tokens[:i]
|
| 317 |
+
i = len(tokens)-1
|
| 318 |
+
while i >= 0 and tokens[i].type in self.t_WS:
|
| 319 |
+
i -= 1
|
| 320 |
+
del tokens[i+1:]
|
| 321 |
+
return tokens
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
# ----------------------------------------------------------------------
|
| 325 |
+
# collect_args()
|
| 326 |
+
#
|
| 327 |
+
# Collects comma separated arguments from a list of tokens. The arguments
|
| 328 |
+
# must be enclosed in parenthesis. Returns a tuple (tokencount,args,positions)
|
| 329 |
+
# where tokencount is the number of tokens consumed, args is a list of arguments,
|
| 330 |
+
# and positions is a list of integers containing the starting index of each
|
| 331 |
+
# argument. Each argument is represented by a list of tokens.
|
| 332 |
+
#
|
| 333 |
+
# When collecting arguments, leading and trailing whitespace is removed
|
| 334 |
+
# from each argument.
|
| 335 |
+
#
|
| 336 |
+
# This function properly handles nested parenthesis and commas---these do not
|
| 337 |
+
# define new arguments.
|
| 338 |
+
# ----------------------------------------------------------------------
|
| 339 |
+
|
| 340 |
+
def collect_args(self,tokenlist):
|
| 341 |
+
args = []
|
| 342 |
+
positions = []
|
| 343 |
+
current_arg = []
|
| 344 |
+
nesting = 1
|
| 345 |
+
tokenlen = len(tokenlist)
|
| 346 |
+
|
| 347 |
+
# Search for the opening '('.
|
| 348 |
+
i = 0
|
| 349 |
+
while (i < tokenlen) and (tokenlist[i].type in self.t_WS):
|
| 350 |
+
i += 1
|
| 351 |
+
|
| 352 |
+
if (i < tokenlen) and (tokenlist[i].value == '('):
|
| 353 |
+
positions.append(i+1)
|
| 354 |
+
else:
|
| 355 |
+
self.error(self.source,tokenlist[0].lineno,"Missing '(' in macro arguments")
|
| 356 |
+
return 0, [], []
|
| 357 |
+
|
| 358 |
+
i += 1
|
| 359 |
+
|
| 360 |
+
while i < tokenlen:
|
| 361 |
+
t = tokenlist[i]
|
| 362 |
+
if t.value == '(':
|
| 363 |
+
current_arg.append(t)
|
| 364 |
+
nesting += 1
|
| 365 |
+
elif t.value == ')':
|
| 366 |
+
nesting -= 1
|
| 367 |
+
if nesting == 0:
|
| 368 |
+
if current_arg:
|
| 369 |
+
args.append(self.tokenstrip(current_arg))
|
| 370 |
+
positions.append(i)
|
| 371 |
+
return i+1,args,positions
|
| 372 |
+
current_arg.append(t)
|
| 373 |
+
elif t.value == ',' and nesting == 1:
|
| 374 |
+
args.append(self.tokenstrip(current_arg))
|
| 375 |
+
positions.append(i+1)
|
| 376 |
+
current_arg = []
|
| 377 |
+
else:
|
| 378 |
+
current_arg.append(t)
|
| 379 |
+
i += 1
|
| 380 |
+
|
| 381 |
+
# Missing end argument
|
| 382 |
+
self.error(self.source,tokenlist[-1].lineno,"Missing ')' in macro arguments")
|
| 383 |
+
return 0, [],[]
|
| 384 |
+
|
| 385 |
+
# ----------------------------------------------------------------------
|
| 386 |
+
# macro_prescan()
|
| 387 |
+
#
|
| 388 |
+
# Examine the macro value (token sequence) and identify patch points
|
| 389 |
+
# This is used to speed up macro expansion later on---we'll know
|
| 390 |
+
# right away where to apply patches to the value to form the expansion
|
| 391 |
+
# ----------------------------------------------------------------------
|
| 392 |
+
|
| 393 |
+
def macro_prescan(self,macro):
|
| 394 |
+
macro.patch = [] # Standard macro arguments
|
| 395 |
+
macro.str_patch = [] # String conversion expansion
|
| 396 |
+
macro.var_comma_patch = [] # Variadic macro comma patch
|
| 397 |
+
i = 0
|
| 398 |
+
while i < len(macro.value):
|
| 399 |
+
if macro.value[i].type == self.t_ID and macro.value[i].value in macro.arglist:
|
| 400 |
+
argnum = macro.arglist.index(macro.value[i].value)
|
| 401 |
+
# Conversion of argument to a string
|
| 402 |
+
if i > 0 and macro.value[i-1].value == '#':
|
| 403 |
+
macro.value[i] = copy.copy(macro.value[i])
|
| 404 |
+
macro.value[i].type = self.t_STRING
|
| 405 |
+
del macro.value[i-1]
|
| 406 |
+
macro.str_patch.append((argnum,i-1))
|
| 407 |
+
continue
|
| 408 |
+
# Concatenation
|
| 409 |
+
elif (i > 0 and macro.value[i-1].value == '##'):
|
| 410 |
+
macro.patch.append(('c',argnum,i-1))
|
| 411 |
+
del macro.value[i-1]
|
| 412 |
+
continue
|
| 413 |
+
elif ((i+1) < len(macro.value) and macro.value[i+1].value == '##'):
|
| 414 |
+
macro.patch.append(('c',argnum,i))
|
| 415 |
+
i += 1
|
| 416 |
+
continue
|
| 417 |
+
# Standard expansion
|
| 418 |
+
else:
|
| 419 |
+
macro.patch.append(('e',argnum,i))
|
| 420 |
+
elif macro.value[i].value == '##':
|
| 421 |
+
if macro.variadic and (i > 0) and (macro.value[i-1].value == ',') and \
|
| 422 |
+
((i+1) < len(macro.value)) and (macro.value[i+1].type == self.t_ID) and \
|
| 423 |
+
(macro.value[i+1].value == macro.vararg):
|
| 424 |
+
macro.var_comma_patch.append(i-1)
|
| 425 |
+
i += 1
|
| 426 |
+
macro.patch.sort(key=lambda x: x[2],reverse=True)
|
| 427 |
+
|
| 428 |
+
# ----------------------------------------------------------------------
|
| 429 |
+
# macro_expand_args()
|
| 430 |
+
#
|
| 431 |
+
# Given a Macro and list of arguments (each a token list), this method
|
| 432 |
+
# returns an expanded version of a macro. The return value is a token sequence
|
| 433 |
+
# representing the replacement macro tokens
|
| 434 |
+
# ----------------------------------------------------------------------
|
| 435 |
+
|
| 436 |
+
def macro_expand_args(self,macro,args):
|
| 437 |
+
# Make a copy of the macro token sequence
|
| 438 |
+
rep = [copy.copy(_x) for _x in macro.value]
|
| 439 |
+
|
| 440 |
+
# Make string expansion patches. These do not alter the length of the replacement sequence
|
| 441 |
+
|
| 442 |
+
str_expansion = {}
|
| 443 |
+
for argnum, i in macro.str_patch:
|
| 444 |
+
if argnum not in str_expansion:
|
| 445 |
+
str_expansion[argnum] = ('"%s"' % "".join([x.value for x in args[argnum]])).replace("\\","\\\\")
|
| 446 |
+
rep[i] = copy.copy(rep[i])
|
| 447 |
+
rep[i].value = str_expansion[argnum]
|
| 448 |
+
|
| 449 |
+
# Make the variadic macro comma patch. If the variadic macro argument is empty, we get rid
|
| 450 |
+
comma_patch = False
|
| 451 |
+
if macro.variadic and not args[-1]:
|
| 452 |
+
for i in macro.var_comma_patch:
|
| 453 |
+
rep[i] = None
|
| 454 |
+
comma_patch = True
|
| 455 |
+
|
| 456 |
+
# Make all other patches. The order of these matters. It is assumed that the patch list
|
| 457 |
+
# has been sorted in reverse order of patch location since replacements will cause the
|
| 458 |
+
# size of the replacement sequence to expand from the patch point.
|
| 459 |
+
|
| 460 |
+
expanded = { }
|
| 461 |
+
for ptype, argnum, i in macro.patch:
|
| 462 |
+
# Concatenation. Argument is left unexpanded
|
| 463 |
+
if ptype == 'c':
|
| 464 |
+
rep[i:i+1] = args[argnum]
|
| 465 |
+
# Normal expansion. Argument is macro expanded first
|
| 466 |
+
elif ptype == 'e':
|
| 467 |
+
if argnum not in expanded:
|
| 468 |
+
expanded[argnum] = self.expand_macros(args[argnum])
|
| 469 |
+
rep[i:i+1] = expanded[argnum]
|
| 470 |
+
|
| 471 |
+
# Get rid of removed comma if necessary
|
| 472 |
+
if comma_patch:
|
| 473 |
+
rep = [_i for _i in rep if _i]
|
| 474 |
+
|
| 475 |
+
return rep
|
| 476 |
+
|
| 477 |
+
|
| 478 |
+
# ----------------------------------------------------------------------
|
| 479 |
+
# expand_macros()
|
| 480 |
+
#
|
| 481 |
+
# Given a list of tokens, this function performs macro expansion.
|
| 482 |
+
# The expanded argument is a dictionary that contains macros already
|
| 483 |
+
# expanded. This is used to prevent infinite recursion.
|
| 484 |
+
# ----------------------------------------------------------------------
|
| 485 |
+
|
| 486 |
+
def expand_macros(self,tokens,expanded=None):
|
| 487 |
+
if expanded is None:
|
| 488 |
+
expanded = {}
|
| 489 |
+
i = 0
|
| 490 |
+
while i < len(tokens):
|
| 491 |
+
t = tokens[i]
|
| 492 |
+
if t.type == self.t_ID:
|
| 493 |
+
if t.value in self.macros and t.value not in expanded:
|
| 494 |
+
# Yes, we found a macro match
|
| 495 |
+
expanded[t.value] = True
|
| 496 |
+
|
| 497 |
+
m = self.macros[t.value]
|
| 498 |
+
if not m.arglist:
|
| 499 |
+
# A simple macro
|
| 500 |
+
ex = self.expand_macros([copy.copy(_x) for _x in m.value],expanded)
|
| 501 |
+
for e in ex:
|
| 502 |
+
e.lineno = t.lineno
|
| 503 |
+
tokens[i:i+1] = ex
|
| 504 |
+
i += len(ex)
|
| 505 |
+
else:
|
| 506 |
+
# A macro with arguments
|
| 507 |
+
j = i + 1
|
| 508 |
+
while j < len(tokens) and tokens[j].type in self.t_WS:
|
| 509 |
+
j += 1
|
| 510 |
+
if tokens[j].value == '(':
|
| 511 |
+
tokcount,args,positions = self.collect_args(tokens[j:])
|
| 512 |
+
if not m.variadic and len(args) != len(m.arglist):
|
| 513 |
+
self.error(self.source,t.lineno,"Macro %s requires %d arguments" % (t.value,len(m.arglist)))
|
| 514 |
+
i = j + tokcount
|
| 515 |
+
elif m.variadic and len(args) < len(m.arglist)-1:
|
| 516 |
+
if len(m.arglist) > 2:
|
| 517 |
+
self.error(self.source,t.lineno,"Macro %s must have at least %d arguments" % (t.value, len(m.arglist)-1))
|
| 518 |
+
else:
|
| 519 |
+
self.error(self.source,t.lineno,"Macro %s must have at least %d argument" % (t.value, len(m.arglist)-1))
|
| 520 |
+
i = j + tokcount
|
| 521 |
+
else:
|
| 522 |
+
if m.variadic:
|
| 523 |
+
if len(args) == len(m.arglist)-1:
|
| 524 |
+
args.append([])
|
| 525 |
+
else:
|
| 526 |
+
args[len(m.arglist)-1] = tokens[j+positions[len(m.arglist)-1]:j+tokcount-1]
|
| 527 |
+
del args[len(m.arglist):]
|
| 528 |
+
|
| 529 |
+
# Get macro replacement text
|
| 530 |
+
rep = self.macro_expand_args(m,args)
|
| 531 |
+
rep = self.expand_macros(rep,expanded)
|
| 532 |
+
for r in rep:
|
| 533 |
+
r.lineno = t.lineno
|
| 534 |
+
tokens[i:j+tokcount] = rep
|
| 535 |
+
i += len(rep)
|
| 536 |
+
del expanded[t.value]
|
| 537 |
+
continue
|
| 538 |
+
elif t.value == '__LINE__':
|
| 539 |
+
t.type = self.t_INTEGER
|
| 540 |
+
t.value = self.t_INTEGER_TYPE(t.lineno)
|
| 541 |
+
|
| 542 |
+
i += 1
|
| 543 |
+
return tokens
|
| 544 |
+
|
| 545 |
+
# ----------------------------------------------------------------------
|
| 546 |
+
# evalexpr()
|
| 547 |
+
#
|
| 548 |
+
# Evaluate an expression token sequence for the purposes of evaluating
|
| 549 |
+
# integral expressions.
|
| 550 |
+
# ----------------------------------------------------------------------
|
| 551 |
+
|
| 552 |
+
def evalexpr(self,tokens):
|
| 553 |
+
# tokens = tokenize(line)
|
| 554 |
+
# Search for defined macros
|
| 555 |
+
i = 0
|
| 556 |
+
while i < len(tokens):
|
| 557 |
+
if tokens[i].type == self.t_ID and tokens[i].value == 'defined':
|
| 558 |
+
j = i + 1
|
| 559 |
+
needparen = False
|
| 560 |
+
result = "0L"
|
| 561 |
+
while j < len(tokens):
|
| 562 |
+
if tokens[j].type in self.t_WS:
|
| 563 |
+
j += 1
|
| 564 |
+
continue
|
| 565 |
+
elif tokens[j].type == self.t_ID:
|
| 566 |
+
if tokens[j].value in self.macros:
|
| 567 |
+
result = "1L"
|
| 568 |
+
else:
|
| 569 |
+
result = "0L"
|
| 570 |
+
if not needparen: break
|
| 571 |
+
elif tokens[j].value == '(':
|
| 572 |
+
needparen = True
|
| 573 |
+
elif tokens[j].value == ')':
|
| 574 |
+
break
|
| 575 |
+
else:
|
| 576 |
+
self.error(self.source,tokens[i].lineno,"Malformed defined()")
|
| 577 |
+
j += 1
|
| 578 |
+
tokens[i].type = self.t_INTEGER
|
| 579 |
+
tokens[i].value = self.t_INTEGER_TYPE(result)
|
| 580 |
+
del tokens[i+1:j+1]
|
| 581 |
+
i += 1
|
| 582 |
+
tokens = self.expand_macros(tokens)
|
| 583 |
+
for i,t in enumerate(tokens):
|
| 584 |
+
if t.type == self.t_ID:
|
| 585 |
+
tokens[i] = copy.copy(t)
|
| 586 |
+
tokens[i].type = self.t_INTEGER
|
| 587 |
+
tokens[i].value = self.t_INTEGER_TYPE("0L")
|
| 588 |
+
elif t.type == self.t_INTEGER:
|
| 589 |
+
tokens[i] = copy.copy(t)
|
| 590 |
+
# Strip off any trailing suffixes
|
| 591 |
+
tokens[i].value = str(tokens[i].value)
|
| 592 |
+
while tokens[i].value[-1] not in "0123456789abcdefABCDEF":
|
| 593 |
+
tokens[i].value = tokens[i].value[:-1]
|
| 594 |
+
|
| 595 |
+
expr = "".join([str(x.value) for x in tokens])
|
| 596 |
+
expr = expr.replace("&&"," and ")
|
| 597 |
+
expr = expr.replace("||"," or ")
|
| 598 |
+
expr = expr.replace("!"," not ")
|
| 599 |
+
try:
|
| 600 |
+
result = eval(expr)
|
| 601 |
+
except Exception:
|
| 602 |
+
self.error(self.source,tokens[0].lineno,"Couldn't evaluate expression")
|
| 603 |
+
result = 0
|
| 604 |
+
return result
|
| 605 |
+
|
| 606 |
+
# ----------------------------------------------------------------------
|
| 607 |
+
# parsegen()
|
| 608 |
+
#
|
| 609 |
+
# Parse an input string/
|
| 610 |
+
# ----------------------------------------------------------------------
|
| 611 |
+
def parsegen(self,input,source=None):
|
| 612 |
+
|
| 613 |
+
# Replace trigraph sequences
|
| 614 |
+
t = trigraph(input)
|
| 615 |
+
lines = self.group_lines(t)
|
| 616 |
+
|
| 617 |
+
if not source:
|
| 618 |
+
source = ""
|
| 619 |
+
|
| 620 |
+
self.define("__FILE__ \"%s\"" % source)
|
| 621 |
+
|
| 622 |
+
self.source = source
|
| 623 |
+
chunk = []
|
| 624 |
+
enable = True
|
| 625 |
+
iftrigger = False
|
| 626 |
+
ifstack = []
|
| 627 |
+
|
| 628 |
+
for x in lines:
|
| 629 |
+
for i,tok in enumerate(x):
|
| 630 |
+
if tok.type not in self.t_WS: break
|
| 631 |
+
if tok.value == '#':
|
| 632 |
+
# Preprocessor directive
|
| 633 |
+
|
| 634 |
+
# insert necessary whitespace instead of eaten tokens
|
| 635 |
+
for tok in x:
|
| 636 |
+
if tok.type in self.t_WS and '\n' in tok.value:
|
| 637 |
+
chunk.append(tok)
|
| 638 |
+
|
| 639 |
+
dirtokens = self.tokenstrip(x[i+1:])
|
| 640 |
+
if dirtokens:
|
| 641 |
+
name = dirtokens[0].value
|
| 642 |
+
args = self.tokenstrip(dirtokens[1:])
|
| 643 |
+
else:
|
| 644 |
+
name = ""
|
| 645 |
+
args = []
|
| 646 |
+
|
| 647 |
+
if name == 'define':
|
| 648 |
+
if enable:
|
| 649 |
+
for tok in self.expand_macros(chunk):
|
| 650 |
+
yield tok
|
| 651 |
+
chunk = []
|
| 652 |
+
self.define(args)
|
| 653 |
+
elif name == 'include':
|
| 654 |
+
if enable:
|
| 655 |
+
for tok in self.expand_macros(chunk):
|
| 656 |
+
yield tok
|
| 657 |
+
chunk = []
|
| 658 |
+
oldfile = self.macros['__FILE__']
|
| 659 |
+
for tok in self.include(args):
|
| 660 |
+
yield tok
|
| 661 |
+
self.macros['__FILE__'] = oldfile
|
| 662 |
+
self.source = source
|
| 663 |
+
elif name == 'undef':
|
| 664 |
+
if enable:
|
| 665 |
+
for tok in self.expand_macros(chunk):
|
| 666 |
+
yield tok
|
| 667 |
+
chunk = []
|
| 668 |
+
self.undef(args)
|
| 669 |
+
elif name == 'ifdef':
|
| 670 |
+
ifstack.append((enable,iftrigger))
|
| 671 |
+
if enable:
|
| 672 |
+
if not args[0].value in self.macros:
|
| 673 |
+
enable = False
|
| 674 |
+
iftrigger = False
|
| 675 |
+
else:
|
| 676 |
+
iftrigger = True
|
| 677 |
+
elif name == 'ifndef':
|
| 678 |
+
ifstack.append((enable,iftrigger))
|
| 679 |
+
if enable:
|
| 680 |
+
if args[0].value in self.macros:
|
| 681 |
+
enable = False
|
| 682 |
+
iftrigger = False
|
| 683 |
+
else:
|
| 684 |
+
iftrigger = True
|
| 685 |
+
elif name == 'if':
|
| 686 |
+
ifstack.append((enable,iftrigger))
|
| 687 |
+
if enable:
|
| 688 |
+
result = self.evalexpr(args)
|
| 689 |
+
if not result:
|
| 690 |
+
enable = False
|
| 691 |
+
iftrigger = False
|
| 692 |
+
else:
|
| 693 |
+
iftrigger = True
|
| 694 |
+
elif name == 'elif':
|
| 695 |
+
if ifstack:
|
| 696 |
+
if ifstack[-1][0]: # We only pay attention if outer "if" allows this
|
| 697 |
+
if enable: # If already true, we flip enable False
|
| 698 |
+
enable = False
|
| 699 |
+
elif not iftrigger: # If False, but not triggered yet, we'll check expression
|
| 700 |
+
result = self.evalexpr(args)
|
| 701 |
+
if result:
|
| 702 |
+
enable = True
|
| 703 |
+
iftrigger = True
|
| 704 |
+
else:
|
| 705 |
+
self.error(self.source,dirtokens[0].lineno,"Misplaced #elif")
|
| 706 |
+
|
| 707 |
+
elif name == 'else':
|
| 708 |
+
if ifstack:
|
| 709 |
+
if ifstack[-1][0]:
|
| 710 |
+
if enable:
|
| 711 |
+
enable = False
|
| 712 |
+
elif not iftrigger:
|
| 713 |
+
enable = True
|
| 714 |
+
iftrigger = True
|
| 715 |
+
else:
|
| 716 |
+
self.error(self.source,dirtokens[0].lineno,"Misplaced #else")
|
| 717 |
+
|
| 718 |
+
elif name == 'endif':
|
| 719 |
+
if ifstack:
|
| 720 |
+
enable,iftrigger = ifstack.pop()
|
| 721 |
+
else:
|
| 722 |
+
self.error(self.source,dirtokens[0].lineno,"Misplaced #endif")
|
| 723 |
+
else:
|
| 724 |
+
# Unknown preprocessor directive
|
| 725 |
+
pass
|
| 726 |
+
|
| 727 |
+
else:
|
| 728 |
+
# Normal text
|
| 729 |
+
if enable:
|
| 730 |
+
chunk.extend(x)
|
| 731 |
+
|
| 732 |
+
for tok in self.expand_macros(chunk):
|
| 733 |
+
yield tok
|
| 734 |
+
chunk = []
|
| 735 |
+
|
| 736 |
+
# ----------------------------------------------------------------------
|
| 737 |
+
# include()
|
| 738 |
+
#
|
| 739 |
+
# Implementation of file-inclusion
|
| 740 |
+
# ----------------------------------------------------------------------
|
| 741 |
+
|
| 742 |
+
def include(self,tokens):
|
| 743 |
+
# Try to extract the filename and then process an include file
|
| 744 |
+
if not tokens:
|
| 745 |
+
return
|
| 746 |
+
if tokens:
|
| 747 |
+
if tokens[0].value != '<' and tokens[0].type != self.t_STRING:
|
| 748 |
+
tokens = self.expand_macros(tokens)
|
| 749 |
+
|
| 750 |
+
if tokens[0].value == '<':
|
| 751 |
+
# Include <...>
|
| 752 |
+
i = 1
|
| 753 |
+
while i < len(tokens):
|
| 754 |
+
if tokens[i].value == '>':
|
| 755 |
+
break
|
| 756 |
+
i += 1
|
| 757 |
+
else:
|
| 758 |
+
print("Malformed #include <...>")
|
| 759 |
+
return
|
| 760 |
+
filename = "".join([x.value for x in tokens[1:i]])
|
| 761 |
+
path = self.path + [""] + self.temp_path
|
| 762 |
+
elif tokens[0].type == self.t_STRING:
|
| 763 |
+
filename = tokens[0].value[1:-1]
|
| 764 |
+
path = self.temp_path + [""] + self.path
|
| 765 |
+
else:
|
| 766 |
+
print("Malformed #include statement")
|
| 767 |
+
return
|
| 768 |
+
for p in path:
|
| 769 |
+
iname = os.path.join(p,filename)
|
| 770 |
+
try:
|
| 771 |
+
data = open(iname,"r").read()
|
| 772 |
+
dname = os.path.dirname(iname)
|
| 773 |
+
if dname:
|
| 774 |
+
self.temp_path.insert(0,dname)
|
| 775 |
+
for tok in self.parsegen(data,filename):
|
| 776 |
+
yield tok
|
| 777 |
+
if dname:
|
| 778 |
+
del self.temp_path[0]
|
| 779 |
+
break
|
| 780 |
+
except IOError:
|
| 781 |
+
pass
|
| 782 |
+
else:
|
| 783 |
+
print("Couldn't find '%s'" % filename)
|
| 784 |
+
|
| 785 |
+
# ----------------------------------------------------------------------
|
| 786 |
+
# define()
|
| 787 |
+
#
|
| 788 |
+
# Define a new macro
|
| 789 |
+
# ----------------------------------------------------------------------
|
| 790 |
+
|
| 791 |
+
def define(self,tokens):
|
| 792 |
+
if isinstance(tokens,STRING_TYPES):
|
| 793 |
+
tokens = self.tokenize(tokens)
|
| 794 |
+
|
| 795 |
+
linetok = tokens
|
| 796 |
+
try:
|
| 797 |
+
name = linetok[0]
|
| 798 |
+
if len(linetok) > 1:
|
| 799 |
+
mtype = linetok[1]
|
| 800 |
+
else:
|
| 801 |
+
mtype = None
|
| 802 |
+
if not mtype:
|
| 803 |
+
m = Macro(name.value,[])
|
| 804 |
+
self.macros[name.value] = m
|
| 805 |
+
elif mtype.type in self.t_WS:
|
| 806 |
+
# A normal macro
|
| 807 |
+
m = Macro(name.value,self.tokenstrip(linetok[2:]))
|
| 808 |
+
self.macros[name.value] = m
|
| 809 |
+
elif mtype.value == '(':
|
| 810 |
+
# A macro with arguments
|
| 811 |
+
tokcount, args, positions = self.collect_args(linetok[1:])
|
| 812 |
+
variadic = False
|
| 813 |
+
for a in args:
|
| 814 |
+
if variadic:
|
| 815 |
+
print("No more arguments may follow a variadic argument")
|
| 816 |
+
break
|
| 817 |
+
astr = "".join([str(_i.value) for _i in a])
|
| 818 |
+
if astr == "...":
|
| 819 |
+
variadic = True
|
| 820 |
+
a[0].type = self.t_ID
|
| 821 |
+
a[0].value = '__VA_ARGS__'
|
| 822 |
+
variadic = True
|
| 823 |
+
del a[1:]
|
| 824 |
+
continue
|
| 825 |
+
elif astr[-3:] == "..." and a[0].type == self.t_ID:
|
| 826 |
+
variadic = True
|
| 827 |
+
del a[1:]
|
| 828 |
+
# If, for some reason, "." is part of the identifier, strip off the name for the purposes
|
| 829 |
+
# of macro expansion
|
| 830 |
+
if a[0].value[-3:] == '...':
|
| 831 |
+
a[0].value = a[0].value[:-3]
|
| 832 |
+
continue
|
| 833 |
+
if len(a) > 1 or a[0].type != self.t_ID:
|
| 834 |
+
print("Invalid macro argument")
|
| 835 |
+
break
|
| 836 |
+
else:
|
| 837 |
+
mvalue = self.tokenstrip(linetok[1+tokcount:])
|
| 838 |
+
i = 0
|
| 839 |
+
while i < len(mvalue):
|
| 840 |
+
if i+1 < len(mvalue):
|
| 841 |
+
if mvalue[i].type in self.t_WS and mvalue[i+1].value == '##':
|
| 842 |
+
del mvalue[i]
|
| 843 |
+
continue
|
| 844 |
+
elif mvalue[i].value == '##' and mvalue[i+1].type in self.t_WS:
|
| 845 |
+
del mvalue[i+1]
|
| 846 |
+
i += 1
|
| 847 |
+
m = Macro(name.value,mvalue,[x[0].value for x in args],variadic)
|
| 848 |
+
self.macro_prescan(m)
|
| 849 |
+
self.macros[name.value] = m
|
| 850 |
+
else:
|
| 851 |
+
print("Bad macro definition")
|
| 852 |
+
except LookupError:
|
| 853 |
+
print("Bad macro definition")
|
| 854 |
+
|
| 855 |
+
# ----------------------------------------------------------------------
|
| 856 |
+
# undef()
|
| 857 |
+
#
|
| 858 |
+
# Undefine a macro
|
| 859 |
+
# ----------------------------------------------------------------------
|
| 860 |
+
|
| 861 |
+
def undef(self,tokens):
|
| 862 |
+
id = tokens[0].value
|
| 863 |
+
try:
|
| 864 |
+
del self.macros[id]
|
| 865 |
+
except LookupError:
|
| 866 |
+
pass
|
| 867 |
+
|
| 868 |
+
# ----------------------------------------------------------------------
|
| 869 |
+
# parse()
|
| 870 |
+
#
|
| 871 |
+
# Parse input text.
|
| 872 |
+
# ----------------------------------------------------------------------
|
| 873 |
+
def parse(self,input,source=None,ignore={}):
|
| 874 |
+
self.ignore = ignore
|
| 875 |
+
self.parser = self.parsegen(input,source)
|
| 876 |
+
|
| 877 |
+
# ----------------------------------------------------------------------
|
| 878 |
+
# token()
|
| 879 |
+
#
|
| 880 |
+
# Method to return individual tokens
|
| 881 |
+
# ----------------------------------------------------------------------
|
| 882 |
+
def token(self):
|
| 883 |
+
try:
|
| 884 |
+
while True:
|
| 885 |
+
tok = next(self.parser)
|
| 886 |
+
if tok.type not in self.ignore: return tok
|
| 887 |
+
except StopIteration:
|
| 888 |
+
self.parser = None
|
| 889 |
+
return None
|
| 890 |
+
|
| 891 |
+
if __name__ == '__main__':
|
| 892 |
+
import ply.lex as lex
|
| 893 |
+
lexer = lex.lex()
|
| 894 |
+
|
| 895 |
+
# Run a preprocessor
|
| 896 |
+
import sys
|
| 897 |
+
f = open(sys.argv[1])
|
| 898 |
+
input = f.read()
|
| 899 |
+
|
| 900 |
+
p = Preprocessor(lexer)
|
| 901 |
+
p.parse(input,sys.argv[1])
|
| 902 |
+
while True:
|
| 903 |
+
tok = p.token()
|
| 904 |
+
if not tok: break
|
| 905 |
+
print(p.source, tok)
|