Skip to content

Commit 9a97490

Browse files
committed
[UR] Add script to strip guarded lines from file
In order to pre-process files which don't support conditional inclusion of line blocks, such as linker scripts, we can use this script to remove lines which should not be included unless specified.
1 parent 707093d commit 9a97490

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright (C) 2025 Intel Corporation
4+
#
5+
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
6+
# See LICENSE.TXT
7+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
9+
10+
"""
11+
This script is a basic pre-processor which deals with conditionally excluding
12+
blocks of lines based on pre and post guard marker lines, a list of guard
13+
names to include in the output, and an input file.
14+
15+
- Pre and post guard marker lines are always removed weather the are guards
16+
are specified for inclusion or not.
17+
- Lines within guard blocks which are not specified for inclusion are always
18+
removed.
19+
- Lines within guard blocks which are specified for inclusion will be always be
20+
included in the output file.
21+
- All other lines not within guard blocks are always included in the output
22+
file.
23+
"""
24+
25+
from argparse import ArgumentParser, FileType, RawDescriptionHelpFormatter
26+
import re
27+
from sys import stdout
28+
from typing import List, Tuple, Union
29+
30+
31+
def _create_guards(pre: str, post: str, names: List[str]) -> List[Tuple[str, str]]:
32+
guards = []
33+
for name in names:
34+
guards.append(
35+
(
36+
pre % name if "%s" in pre else pre,
37+
post % name if "%s" in post else post,
38+
)
39+
)
40+
return guards
41+
42+
43+
def _is_guard(marker: str, line: str) -> bool:
44+
line = line.strip()
45+
marker = marker.replace("%s", r"[A-Za-z0-9][A-Za-z0-9_]+")
46+
if re.match(marker, line):
47+
return True
48+
return False
49+
50+
51+
def _find_guard(
52+
line: str, guards: List[Tuple[str, str]]
53+
) -> Union[Tuple[str, str], None]:
54+
line = line.strip()
55+
for guard in guards:
56+
if guard[0] in line or guard[1] in line:
57+
return guard
58+
return None
59+
60+
61+
def strip_guarded_lines(
62+
inlines: List[str],
63+
pre: str,
64+
post: str,
65+
names: List[str],
66+
) -> List[str]:
67+
guards = _create_guards(pre, post, names)
68+
stack = []
69+
outlines = []
70+
for line in inlines:
71+
if _is_guard(pre, line):
72+
stack.append(_find_guard(line, guards))
73+
continue
74+
elif _is_guard(post, line):
75+
guard = stack.pop()
76+
if guard:
77+
assert _is_guard(
78+
guard[1], line
79+
), f'interleaved guard found: "{guard[1]}" before "{line.strip()}"'
80+
continue
81+
else:
82+
if not all(stack):
83+
continue
84+
outlines.append(line)
85+
return outlines
86+
87+
88+
def main():
89+
parser = ArgumentParser(
90+
description=__doc__, formatter_class=RawDescriptionHelpFormatter
91+
)
92+
parser.add_argument(
93+
"infile", type=FileType("r"), help="input file to strip guarded lines from"
94+
)
95+
group = parser.add_mutually_exclusive_group()
96+
group.add_argument(
97+
"-o",
98+
"--outfile",
99+
type=FileType("w"),
100+
default=stdout,
101+
help="file to write to stripped output to, default: stdout",
102+
)
103+
group.add_argument(
104+
"-i", "--in-place", action="store_true", help="write to input file in-place"
105+
)
106+
parser.add_argument("--encoding", help="encoding to be used for the outfile")
107+
parser.add_argument(
108+
"--pre",
109+
default="#if %s",
110+
help='pre-guard marker where %%s is the guard name, default: "#if %%s"',
111+
)
112+
parser.add_argument(
113+
"--post",
114+
default="#endif",
115+
help='post-guard market where %%s is the guard name, default: "#endif"',
116+
)
117+
parser.add_argument("guards", nargs="*", help="names of guards to strip lines of")
118+
args = parser.parse_args()
119+
120+
inlines = args.infile.readlines()
121+
if args.in_place:
122+
args.infile.close()
123+
args.outfile = open(args.infile.name, "w")
124+
if args.encoding:
125+
args.outfile.reconfigure(encoding=args.encoding)
126+
127+
outlines = strip_guarded_lines(inlines, args.pre, args.post, args.guards)
128+
args.outfile.writelines(outlines)
129+
130+
131+
if __name__ == "__main__":
132+
try:
133+
main()
134+
except KeyboardInterrupt:
135+
exit(130)

0 commit comments

Comments
 (0)