diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 004e6af..8701889 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,6 +32,9 @@ jobs: - name: Run unit tests run: make test-unit + - name: Run unit tests with bounded parser cache + run: + make test-cache-size-bound - name: Run integration tests run: make test-integration diff --git a/Makefile b/Makefile index 7d9a39e..74676ca 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,11 @@ test-unit: venv/bin/activate $(UNIT_TESTS) . $< && python3 -m unittest $(UNIT_TESTS) test: test-unit +.PHONY: test-cache-size-bound +test-cache-size-bound: venv/bin/activate $(UNIT_TESTS) + PYDEVICETREE_CACHE_SIZE_BOUND=128 . $< && python3 -m unittest $(UNIT_TESTS) +test: test-cache-size-bound + INTEGRATION_TESTS = tests/test_full_trees.py .PHONY: test-integration diff --git a/pydevicetree/source/grammar.py b/pydevicetree/source/grammar.py index 7768439..cabf917 100644 --- a/pydevicetree/source/grammar.py +++ b/pydevicetree/source/grammar.py @@ -2,9 +2,22 @@ # Copyright (c) 2019 SiFive Inc. # SPDX-License-Identifier: Apache-2.0 +import os +import sys + import pyparsing as p # type: ignore -p.ParserElement.enablePackrat() +ENV_CACHE_OPTION = "PYDEVICETREE_CACHE_SIZE_BOUND" + +cache_bound = None +if ENV_CACHE_OPTION in os.environ: + option = os.environ[ENV_CACHE_OPTION] + if option != "None": + try: + cache_bound = int(option) + except ValueError: + print("%s requires a valid integer" % ENV_CACHE_OPTION, file=sys.stderr) +p.ParserElement.enablePackrat(cache_bound) node_name = p.Word(p.alphanums + ",.-+_") ^ p.Literal("/") integer = p.pyparsing_common.integer ^ (p.Literal("0x").suppress() + p.pyparsing_common.hex_integer) @@ -59,6 +72,5 @@ devicetree.ignore("//" + p.SkipTo(p.lineEnd)) if __name__ == "__main__": - import sys if len(sys.argv) > 1: devicetree.parseFile(sys.argv[1]).pprint()