kconfig-preprocessor-parser 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kconfig_preprocessor_parser-0.1.0/LICENSE +21 -0
- kconfig_preprocessor_parser-0.1.0/PKG-INFO +155 -0
- kconfig_preprocessor_parser-0.1.0/README.md +126 -0
- kconfig_preprocessor_parser-0.1.0/pyproject.toml +62 -0
- kconfig_preprocessor_parser-0.1.0/pyproject.toml.orig +54 -0
- kconfig_preprocessor_parser-0.1.0/src/kconfig_preprocessor_parser/__init__.py +33 -0
- kconfig_preprocessor_parser-0.1.0/src/kconfig_preprocessor_parser/parser.py +1130 -0
- kconfig_preprocessor_parser-0.1.0/src/kconfig_preprocessor_parser/py.typed +0 -0
- kconfig_preprocessor_parser-0.1.0/tests/unit/test_parser.py +492 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 s4nsec
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kconfig-preprocessor-parser
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Extract C preprocessor conditionals and resolve each branch to its effective CONFIG_* condition
|
|
5
|
+
Keywords: c,preprocessor,tree-sitter,kconfig,linux-kernel,ifdef
|
|
6
|
+
Author: s4nsec
|
|
7
|
+
Author-email: s4nsec <s4nsec@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: C
|
|
19
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
20
|
+
Classifier: Topic :: Software Development :: Pre-processors
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Dist: tree-sitter>=0.23
|
|
23
|
+
Requires-Dist: tree-sitter-c>=0.23
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Project-URL: Homepage, https://github.com/appleseedlab/kconfig-preprocessor-parser
|
|
26
|
+
Project-URL: Repository, https://github.com/appleseedlab/kconfig-preprocessor-parser
|
|
27
|
+
Project-URL: Issues, https://github.com/appleseedlab/kconfig-preprocessor-parser/issues
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# kconfig-preprocessor-parser
|
|
31
|
+
|
|
32
|
+
Extract C preprocessor conditional blocks (`#ifdef` / `#if` / `#elif` / `#else`)
|
|
33
|
+
from source files using [tree-sitter](https://tree-sitter.github.io/), and
|
|
34
|
+
resolve each branch to the **effective condition** that must hold for its lines
|
|
35
|
+
to compile.
|
|
36
|
+
|
|
37
|
+
Built for Linux kernel configuration analysis, where knowing *which* `CONFIG_*`
|
|
38
|
+
symbols guard a given line matters. Scope is deliberately narrow: only
|
|
39
|
+
`CONFIG_*` symbols are resolved (see [Limitations](#limitations)).
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
uv add kconfig-preprocessor-parser
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Requires Python 3.10+.
|
|
48
|
+
|
|
49
|
+
## Quick start
|
|
50
|
+
|
|
51
|
+
Given `s.c`:
|
|
52
|
+
|
|
53
|
+
```c
|
|
54
|
+
int fn(void) {
|
|
55
|
+
#ifdef CONFIG_A
|
|
56
|
+
a();
|
|
57
|
+
#elif defined(CONFIG_B)
|
|
58
|
+
b();
|
|
59
|
+
#else
|
|
60
|
+
c();
|
|
61
|
+
#endif
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Each branch resolves to the full condition, including the negated preceding
|
|
67
|
+
branches:
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from pathlib import Path
|
|
71
|
+
from kconfig_preprocessor_parser import extract_preproc_branch_blocks_from_file
|
|
72
|
+
|
|
73
|
+
for block, cond in extract_preproc_branch_blocks_from_file(
|
|
74
|
+
kernel_src=Path("."), c_file_path=Path("s.c")
|
|
75
|
+
):
|
|
76
|
+
print(block.type, block.body_lines, "->", cond.raw_expression)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
preproc_ifdef [3] -> CONFIG_A
|
|
81
|
+
preproc_elif [5] -> not CONFIG_A and CONFIG_B
|
|
82
|
+
preproc_else [7] -> not CONFIG_A and not CONFIG_B
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Note `raw_expression` for the `#elif` and `#else` branches: the parser carries
|
|
86
|
+
the negation of every earlier branch in the chain, so the expression is the
|
|
87
|
+
complete guard for those lines, not just the local directive.
|
|
88
|
+
|
|
89
|
+
Nested blocks compose the same way — a `#ifdef CONFIG_B` inside a
|
|
90
|
+
`#ifdef CONFIG_A` yields `CONFIG_A and CONFIG_B`.
|
|
91
|
+
|
|
92
|
+
Boolean operators are supported: `defined(A) && defined(B)` resolves to
|
|
93
|
+
`((A) and (B))`, and `||` resolves to `or`.
|
|
94
|
+
|
|
95
|
+
## Limitations
|
|
96
|
+
|
|
97
|
+
**Value comparisons are not resolved.** Conditions are reduced in terms of
|
|
98
|
+
whether a symbol is defined, so any comparison against a value fails:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
#if LINUX_VERSION_CODE > 100 -> parseable=False, "unsupported_condition_expression"
|
|
102
|
+
#if CONFIG_NR_CPUS > 4 -> parseable=False, "unsupported_condition_expression"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Unresolved conditions are never silently dropped. They come back with
|
|
106
|
+
`parseable=False`, a `failure_reason`, and the original text in
|
|
107
|
+
`raw_expression`, so you can filter or handle them yourself.
|
|
108
|
+
|
|
109
|
+
**Only `CONFIG_*` symbols are resolved.** Any other identifier is reported with
|
|
110
|
+
`parseable=False` and `failure_reason="non_config_symbol"`:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
#ifdef CONFIG_A -> parseable=True
|
|
114
|
+
#ifdef __KERNEL__ -> parseable=False, "non_config_symbol"
|
|
115
|
+
#ifdef DEBUG -> parseable=False, "non_config_symbol"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Conditions are read syntactically from one file.** Macros are not expanded and
|
|
119
|
+
`#include` is not followed, so `#define MY_FLAG CONFIG_A` followed by
|
|
120
|
+
`#ifdef MY_FLAG` reports `MY_FLAG`, not `CONFIG_A`. Symbols are reported as
|
|
121
|
+
guards regardless of whether they are actually defined — resolve them against a
|
|
122
|
+
real config with `parse_enabled_configs`.
|
|
123
|
+
|
|
124
|
+
**C only.** Backed by `tree-sitter-c`; C++ is not supported.
|
|
125
|
+
|
|
126
|
+
## Coverage reports
|
|
127
|
+
|
|
128
|
+
`get_all_lines_in_preproc` and
|
|
129
|
+
`get_all_parseable_preproc_lines_in_covered_functions` read syzkaller coverage
|
|
130
|
+
JSON. Reports record absolute paths from the machine the kernel was built on,
|
|
131
|
+
which rarely match the tree you are analyzing, so paths are mapped onto
|
|
132
|
+
`kernel_src` by longest matching suffix:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
get_all_parseable_preproc_lines_in_covered_functions(
|
|
136
|
+
coverage_file=Path("coverage.json"),
|
|
137
|
+
kernel_src=Path("/src/linux"),
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Pass `strip_prefix` to map them explicitly instead:
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
get_all_parseable_preproc_lines_in_covered_functions(
|
|
145
|
+
coverage_file=Path("coverage.json"),
|
|
146
|
+
kernel_src=Path("/src/linux"),
|
|
147
|
+
strip_prefix="/build/ci/kernel-6.1",
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Files that cannot be mapped onto `kernel_src` are skipped, not fatal.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
MIT
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# kconfig-preprocessor-parser
|
|
2
|
+
|
|
3
|
+
Extract C preprocessor conditional blocks (`#ifdef` / `#if` / `#elif` / `#else`)
|
|
4
|
+
from source files using [tree-sitter](https://tree-sitter.github.io/), and
|
|
5
|
+
resolve each branch to the **effective condition** that must hold for its lines
|
|
6
|
+
to compile.
|
|
7
|
+
|
|
8
|
+
Built for Linux kernel configuration analysis, where knowing *which* `CONFIG_*`
|
|
9
|
+
symbols guard a given line matters. Scope is deliberately narrow: only
|
|
10
|
+
`CONFIG_*` symbols are resolved (see [Limitations](#limitations)).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
uv add kconfig-preprocessor-parser
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Python 3.10+.
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
Given `s.c`:
|
|
23
|
+
|
|
24
|
+
```c
|
|
25
|
+
int fn(void) {
|
|
26
|
+
#ifdef CONFIG_A
|
|
27
|
+
a();
|
|
28
|
+
#elif defined(CONFIG_B)
|
|
29
|
+
b();
|
|
30
|
+
#else
|
|
31
|
+
c();
|
|
32
|
+
#endif
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Each branch resolves to the full condition, including the negated preceding
|
|
38
|
+
branches:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from kconfig_preprocessor_parser import extract_preproc_branch_blocks_from_file
|
|
43
|
+
|
|
44
|
+
for block, cond in extract_preproc_branch_blocks_from_file(
|
|
45
|
+
kernel_src=Path("."), c_file_path=Path("s.c")
|
|
46
|
+
):
|
|
47
|
+
print(block.type, block.body_lines, "->", cond.raw_expression)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
preproc_ifdef [3] -> CONFIG_A
|
|
52
|
+
preproc_elif [5] -> not CONFIG_A and CONFIG_B
|
|
53
|
+
preproc_else [7] -> not CONFIG_A and not CONFIG_B
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Note `raw_expression` for the `#elif` and `#else` branches: the parser carries
|
|
57
|
+
the negation of every earlier branch in the chain, so the expression is the
|
|
58
|
+
complete guard for those lines, not just the local directive.
|
|
59
|
+
|
|
60
|
+
Nested blocks compose the same way — a `#ifdef CONFIG_B` inside a
|
|
61
|
+
`#ifdef CONFIG_A` yields `CONFIG_A and CONFIG_B`.
|
|
62
|
+
|
|
63
|
+
Boolean operators are supported: `defined(A) && defined(B)` resolves to
|
|
64
|
+
`((A) and (B))`, and `||` resolves to `or`.
|
|
65
|
+
|
|
66
|
+
## Limitations
|
|
67
|
+
|
|
68
|
+
**Value comparisons are not resolved.** Conditions are reduced in terms of
|
|
69
|
+
whether a symbol is defined, so any comparison against a value fails:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
#if LINUX_VERSION_CODE > 100 -> parseable=False, "unsupported_condition_expression"
|
|
73
|
+
#if CONFIG_NR_CPUS > 4 -> parseable=False, "unsupported_condition_expression"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Unresolved conditions are never silently dropped. They come back with
|
|
77
|
+
`parseable=False`, a `failure_reason`, and the original text in
|
|
78
|
+
`raw_expression`, so you can filter or handle them yourself.
|
|
79
|
+
|
|
80
|
+
**Only `CONFIG_*` symbols are resolved.** Any other identifier is reported with
|
|
81
|
+
`parseable=False` and `failure_reason="non_config_symbol"`:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
#ifdef CONFIG_A -> parseable=True
|
|
85
|
+
#ifdef __KERNEL__ -> parseable=False, "non_config_symbol"
|
|
86
|
+
#ifdef DEBUG -> parseable=False, "non_config_symbol"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Conditions are read syntactically from one file.** Macros are not expanded and
|
|
90
|
+
`#include` is not followed, so `#define MY_FLAG CONFIG_A` followed by
|
|
91
|
+
`#ifdef MY_FLAG` reports `MY_FLAG`, not `CONFIG_A`. Symbols are reported as
|
|
92
|
+
guards regardless of whether they are actually defined — resolve them against a
|
|
93
|
+
real config with `parse_enabled_configs`.
|
|
94
|
+
|
|
95
|
+
**C only.** Backed by `tree-sitter-c`; C++ is not supported.
|
|
96
|
+
|
|
97
|
+
## Coverage reports
|
|
98
|
+
|
|
99
|
+
`get_all_lines_in_preproc` and
|
|
100
|
+
`get_all_parseable_preproc_lines_in_covered_functions` read syzkaller coverage
|
|
101
|
+
JSON. Reports record absolute paths from the machine the kernel was built on,
|
|
102
|
+
which rarely match the tree you are analyzing, so paths are mapped onto
|
|
103
|
+
`kernel_src` by longest matching suffix:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
get_all_parseable_preproc_lines_in_covered_functions(
|
|
107
|
+
coverage_file=Path("coverage.json"),
|
|
108
|
+
kernel_src=Path("/src/linux"),
|
|
109
|
+
)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Pass `strip_prefix` to map them explicitly instead:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
get_all_parseable_preproc_lines_in_covered_functions(
|
|
116
|
+
coverage_file=Path("coverage.json"),
|
|
117
|
+
kernel_src=Path("/src/linux"),
|
|
118
|
+
strip_prefix="/build/ci/kernel-6.1",
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Files that cannot be mapped onto `kernel_src` are skipped, not fatal.
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
MIT
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "kconfig-preprocessor-parser"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Extract C preprocessor conditionals and resolve each branch to its effective CONFIG_* condition"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"tree-sitter>=0.23",
|
|
11
|
+
"tree-sitter-c>=0.23",
|
|
12
|
+
]
|
|
13
|
+
keywords = [
|
|
14
|
+
"c",
|
|
15
|
+
"preprocessor",
|
|
16
|
+
"tree-sitter",
|
|
17
|
+
"kconfig",
|
|
18
|
+
"linux-kernel",
|
|
19
|
+
"ifdef",
|
|
20
|
+
]
|
|
21
|
+
classifiers = [
|
|
22
|
+
"Development Status :: 3 - Alpha",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3.10",
|
|
27
|
+
"Programming Language :: Python :: 3.11",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: C",
|
|
31
|
+
"Topic :: Software Development :: Compilers",
|
|
32
|
+
"Topic :: Software Development :: Pre-processors",
|
|
33
|
+
"Typing :: Typed",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[[project.authors]]
|
|
37
|
+
name = "s4nsec"
|
|
38
|
+
email = "s4nsec@gmail.com"
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
Homepage = "https://github.com/appleseedlab/kconfig-preprocessor-parser"
|
|
42
|
+
Repository = "https://github.com/appleseedlab/kconfig-preprocessor-parser"
|
|
43
|
+
Issues = "https://github.com/appleseedlab/kconfig-preprocessor-parser/issues"
|
|
44
|
+
|
|
45
|
+
[dependency-groups]
|
|
46
|
+
dev = ["pytest>=8"]
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = ["tests"]
|
|
50
|
+
|
|
51
|
+
[tool.uv.build-backend]
|
|
52
|
+
source-include = ["tests/**"]
|
|
53
|
+
|
|
54
|
+
[[tool.uv.index]]
|
|
55
|
+
name = "testpypi"
|
|
56
|
+
url = "https://test.pypi.org/simple/"
|
|
57
|
+
publish-url = "https://test.pypi.org/legacy/"
|
|
58
|
+
explicit = true
|
|
59
|
+
|
|
60
|
+
[build-system]
|
|
61
|
+
requires = ["uv_build>=0.12.7,<0.13"]
|
|
62
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "kconfig-preprocessor-parser"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Extract C preprocessor conditionals and resolve each branch to its effective CONFIG_* condition"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "s4nsec", email = "s4nsec@gmail.com" }
|
|
10
|
+
]
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"tree-sitter>=0.23",
|
|
14
|
+
"tree-sitter-c>=0.23",
|
|
15
|
+
]
|
|
16
|
+
keywords = ["c", "preprocessor", "tree-sitter", "kconfig", "linux-kernel", "ifdef"]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: C",
|
|
27
|
+
"Topic :: Software Development :: Compilers",
|
|
28
|
+
"Topic :: Software Development :: Pre-processors",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/appleseedlab/kconfig-preprocessor-parser"
|
|
34
|
+
Repository = "https://github.com/appleseedlab/kconfig-preprocessor-parser"
|
|
35
|
+
Issues = "https://github.com/appleseedlab/kconfig-preprocessor-parser/issues"
|
|
36
|
+
|
|
37
|
+
[dependency-groups]
|
|
38
|
+
dev = ["pytest>=8"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
testpaths = ["tests"]
|
|
42
|
+
|
|
43
|
+
[tool.uv.build-backend]
|
|
44
|
+
source-include = ["tests/**"]
|
|
45
|
+
|
|
46
|
+
[[tool.uv.index]]
|
|
47
|
+
name = "testpypi"
|
|
48
|
+
url = "https://test.pypi.org/simple/"
|
|
49
|
+
publish-url = "https://test.pypi.org/legacy/"
|
|
50
|
+
explicit = true
|
|
51
|
+
|
|
52
|
+
[build-system]
|
|
53
|
+
requires = ["uv_build>=0.12.7,<0.13"]
|
|
54
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from kconfig_preprocessor_parser.parser import (
|
|
2
|
+
ConditionInfo,
|
|
3
|
+
EffectiveConditionInfo,
|
|
4
|
+
PreprocBlock,
|
|
5
|
+
extract_all_tracked_lines,
|
|
6
|
+
extract_preproc_branch_blocks_from_file,
|
|
7
|
+
extract_preproc_blocks_from_file,
|
|
8
|
+
extract_preproc_blocks_from_covered_functions,
|
|
9
|
+
find_function_for_line,
|
|
10
|
+
get_all_parseable_preproc_lines_in_covered_functions,
|
|
11
|
+
get_all_lines_in_preproc,
|
|
12
|
+
get_function_name,
|
|
13
|
+
parse_enabled_configs,
|
|
14
|
+
parse_function_spans,
|
|
15
|
+
write_effective_conditions_for_requested_lines,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"ConditionInfo",
|
|
20
|
+
"EffectiveConditionInfo",
|
|
21
|
+
"PreprocBlock",
|
|
22
|
+
"extract_all_tracked_lines",
|
|
23
|
+
"extract_preproc_branch_blocks_from_file",
|
|
24
|
+
"extract_preproc_blocks_from_file",
|
|
25
|
+
"extract_preproc_blocks_from_covered_functions",
|
|
26
|
+
"find_function_for_line",
|
|
27
|
+
"get_all_parseable_preproc_lines_in_covered_functions",
|
|
28
|
+
"get_all_lines_in_preproc",
|
|
29
|
+
"get_function_name",
|
|
30
|
+
"parse_enabled_configs",
|
|
31
|
+
"parse_function_spans",
|
|
32
|
+
"write_effective_conditions_for_requested_lines",
|
|
33
|
+
]
|