Skip to content

Commit 5960119

Browse files
Andrew Boiecarlescufi
authored andcommitted
scripts: parse_syscalls: generalize struct tags
Now we can build up lists of data structures matching a list of particular tags, with __subsystem being just one case. Relax searches to also look inside C files, since struct prototypes may be declared there as well. Signed-off-by: Andrew Boie <[email protected]>
1 parent 455e178 commit 5960119

File tree

3 files changed

+47
-28
lines changed

3 files changed

+47
-28
lines changed

CMakeLists.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,9 @@ if(EXISTS ${CMAKE_BINARY_DIR}/zephyr_modules.txt)
495495
set(ZEPHYR_CURRENT_MODULE_DIR)
496496
endif()
497497

498-
set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h)
499-
set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json)
500-
set(subsys_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/subsystems.json)
498+
set(syscall_list_h ${CMAKE_CURRENT_BINARY_DIR}/include/generated/syscall_list.h)
499+
set(syscalls_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/syscalls.json)
500+
set(struct_tags_json ${CMAKE_CURRENT_BINARY_DIR}/misc/generated/struct_tags.json)
501501

502502
# The syscalls subdirs txt file is constructed by python containing a list of folders to use for
503503
# dependency handling, including empty folders.
@@ -589,20 +589,20 @@ endforeach()
589589
add_custom_command(
590590
OUTPUT
591591
${syscalls_json}
592-
${subsys_json}
592+
${struct_tags_json}
593593
COMMAND
594594
${PYTHON_EXECUTABLE}
595595
${ZEPHYR_BASE}/scripts/parse_syscalls.py
596596
--include ${ZEPHYR_BASE}/include # Read files from this dir
597597
${parse_syscalls_include_args} # Read files from these dirs also
598598
--json-file ${syscalls_json} # Write this file
599-
--subsystem-file ${subsys_json} # Write subsystem list to this file
599+
--tag-struct-file ${struct_tags_json} # Write subsystem list to this file
600600
DEPENDS ${syscalls_subdirs_trigger} ${PARSE_SYSCALLS_HEADER_DEPENDS}
601601
)
602602

603603
add_custom_target(${SYSCALL_LIST_H_TARGET} DEPENDS ${syscall_list_h})
604604
add_custom_target(${PARSE_SYSCALLS_TARGET}
605-
DEPENDS ${syscalls_json} ${subsys_json})
605+
DEPENDS ${syscalls_json} ${struct_tags_json})
606606

607607
# 64-bit systems do not require special handling of 64-bit system call
608608
# parameters or return values, indicate this to the system call boilerplate
@@ -632,7 +632,7 @@ add_custom_command(OUTPUT include/generated/syscall_dispatch.c ${syscall_list_h}
632632
)
633633

634634
# This is passed into all calls to the gen_kobject_list.py script.
635-
set(gen_kobject_list_include_args --include ${subsys_json})
635+
set(gen_kobject_list_include_args --include ${struct_tags_json})
636636

637637
set(DRV_VALIDATION ${PROJECT_BINARY_DIR}/include/generated/driver-validation.h)
638638
add_custom_command(
@@ -646,7 +646,7 @@ add_custom_command(
646646
DEPENDS
647647
${ZEPHYR_BASE}/scripts/gen_kobject_list.py
648648
${PARSE_SYSCALLS_TARGET}
649-
${subsys_json}
649+
${struct_tags_json}
650650
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
651651
)
652652
add_custom_target(${DRIVER_VALIDATION_H_TARGET} DEPENDS ${DRV_VALIDATION})

scripts/gen_kobject_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ def write_kobj_size_output(fp):
918918
def parse_subsystems_list_file(path):
919919
with open(path, "r") as fp:
920920
subsys_list = json.load(fp)
921-
subsystems.extend(subsys_list)
921+
subsystems.extend(subsys_list["__subsystem"])
922922

923923
def parse_args():
924924
global args

scripts/parse_syscalls.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
System calls require a great deal of boilerplate code in order to implement
1111
completely. This script is the first step in the build system's process of
1212
auto-generating this code by doing a text scan of directories containing
13-
header files, and building up a database of system calls and their
13+
C or header files, and building up a database of system calls and their
1414
function call prototypes. This information is emitted to a generated
1515
JSON file for further processing.
1616
17+
This script also scans for struct definitions such as __subsystem and
18+
__net_socket, emitting a JSON dictionary mapping tags to all the struct
19+
declarations found that were tagged with them.
20+
1721
If the output JSON file already exists, its contents are checked against
1822
what information this script would have outputted; if the result is that the
1923
file would be unchanged, it is not modified to prevent unnecessary
@@ -26,35 +30,50 @@
2630
import os
2731
import json
2832

33+
regex_flags = re.MULTILINE | re.VERBOSE
34+
2935
syscall_regex = re.compile(r'''
3036
__syscall\s+ # __syscall attribute, must be first
3137
([^(]+) # type and name of system call (split later)
3238
[(] # Function opening parenthesis
3339
([^)]*) # Arg list (split later)
3440
[)] # Closing parenthesis
35-
''', re.MULTILINE | re.VERBOSE)
41+
''', regex_flags)
3642

37-
subsys_regex = re.compile(r'''
38-
__subsystem\s+ # __subsystem attribute, must be first
43+
struct_tags = ["__subsystem"]
44+
45+
tagged_struct_decl_template = r'''
46+
%s\s+ # tag, must be first
3947
struct\s+ # struct keyword is next
4048
([^{]+) # name of subsystem
4149
[{] # Open curly bracket
42-
''', re.MULTILINE | re.VERBOSE)
50+
'''
51+
52+
def tagged_struct_update(target_list, tag, contents):
53+
regex = re.compile(tagged_struct_decl_template % tag, regex_flags)
54+
items = [mo.groups()[0].strip() for mo in regex.finditer(contents)]
55+
target_list.extend(items)
56+
4357

4458
def analyze_headers(multiple_directories):
4559
syscall_ret = []
46-
subsys_ret = []
60+
tagged_ret = {}
61+
62+
for tag in struct_tags:
63+
tagged_ret[tag] = []
4764

4865
for base_path in multiple_directories:
4966
for root, dirs, files in os.walk(base_path, topdown=True):
5067
dirs.sort()
5168
files.sort()
5269
for fn in files:
5370

54-
# toolchain/common.h has the definitions of __syscall and __subsystem which we
71+
# toolchain/common.h has the definitions of these tagswhich we
5572
# don't want to trip over
5673
path = os.path.join(root, fn)
57-
if not fn.endswith(".h") or path.endswith(os.path.join(os.sep, 'toolchain', 'common.h')):
74+
if (not (path.endswith(".h") or path.endswith(".c")) or
75+
path.endswith(os.path.join(os.sep, 'toolchain',
76+
'common.h'))):
5877
continue
5978

6079
with open(path, "r", encoding="utf-8") as fp:
@@ -63,16 +82,15 @@ def analyze_headers(multiple_directories):
6382
try:
6483
syscall_result = [(mo.groups(), fn)
6584
for mo in syscall_regex.finditer(contents)]
66-
subsys_result = [mo.groups()[0].strip()
67-
for mo in subsys_regex.finditer(contents)]
85+
for tag in struct_tags:
86+
tagged_struct_update(tagged_ret[tag], tag, contents)
6887
except Exception:
6988
sys.stderr.write("While parsing %s\n" % fn)
7089
raise
7190

7291
syscall_ret.extend(syscall_result)
73-
subsys_ret.extend(subsys_result)
7492

75-
return syscall_ret, subsys_ret
93+
return syscall_ret, tagged_ret
7694

7795

7896
def update_file_if_changed(path, new):
@@ -102,18 +120,19 @@ def parse_args():
102120
"-j", "--json-file", required=True,
103121
help="Write system call prototype information as json to file")
104122
parser.add_argument(
105-
"-s", "--subsystem-file", required=True,
106-
help="Write subsystem name information as json to file")
123+
"-t", "--tag-struct-file", required=True,
124+
help="Write tagged struct name information as json to file")
125+
107126
args = parser.parse_args()
108127

109128

110129
def main():
111130
parse_args()
112131

113-
syscalls, subsys = analyze_headers(args.include)
132+
syscalls, tagged = analyze_headers(args.include)
114133

115134
# Only write json files if they don't exist or have changes since
116-
# they will force and incremental rebuild.
135+
# they will force an incremental rebuild.
117136

118137
syscalls_in_json = json.dumps(
119138
syscalls,
@@ -122,12 +141,12 @@ def main():
122141
)
123142
update_file_if_changed(args.json_file, syscalls_in_json)
124143

125-
subsys_in_json = json.dumps(
126-
subsys,
144+
tagged_struct_in_json = json.dumps(
145+
tagged,
127146
indent=4,
128147
sort_keys=True
129148
)
130-
update_file_if_changed(args.subsystem_file, subsys_in_json)
149+
update_file_if_changed(args.tag_struct_file, tagged_struct_in_json)
131150

132151

133152
if __name__ == "__main__":

0 commit comments

Comments
 (0)