Skip to content

Commit e04a4e7

Browse files
committed
Add command-line options to accept paths of headers as a list of multiple file paths
1 parent bb4044d commit e04a4e7

1 file changed

Lines changed: 85 additions & 73 deletions

File tree

ci/generate_checked_functions.py

Lines changed: 85 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from pycparser import c_parser, c_ast, parse_file
22
import os
3+
import argparse
34

45

56
def collect_typedefs(ast):
@@ -172,10 +173,23 @@ def generate_checked_function(func, typedefs):
172173
return "\n".join(new_func)
173174

174175

176+
def parse_arguments():
177+
parser = argparse.ArgumentParser(
178+
description="Generate checked functions from header files."
179+
)
180+
parser.add_argument(
181+
"--headers",
182+
nargs="+",
183+
required=True,
184+
help="List of header file paths to process.",
185+
)
186+
return parser.parse_args()
187+
188+
175189
# Updated process_header to scan all return types and create a proper Result type
176190

177191

178-
def process_header():
192+
def process_headers(header_paths):
179193
# Define the Result struct as a string
180194
RESULT_STRUCT = """
181195
typedef struct {
@@ -186,84 +200,82 @@ def process_header():
186200
} Result;
187201
"""
188202

189-
# Based on current file location, adjust the path to the header file
190-
input_header = os.path.join(
191-
os.path.dirname(__file__), "../core/iwasm/include/wasm_export.h"
192-
)
193-
output_header = input_header.replace("wasm_export.h", "wasm_export_checked.h")
194-
195-
# Parse the header file with preprocessing
196-
ast = parse_file(
197-
input_header,
198-
use_cpp=True,
199-
cpp_path="gcc",
200-
cpp_args=[
201-
"-E",
202-
"-D__attribute__(x)=",
203-
"-D__asm__(x)=",
204-
"-D__asm(x)=",
205-
"-D__builtin_va_list=int",
206-
"-D__extension__=",
207-
"-D__inline__=",
208-
"-D__restrict=",
209-
"-D__restrict__=",
210-
"-D_Static_assert(x, y)=",
211-
"-D__signed=",
212-
"-D__volatile__(x)=",
213-
"-Dstatic_assert(x, y)=",
214-
],
215-
)
216-
217-
# Collect all typedefs
218-
typedefs = collect_typedefs(ast)
219-
220-
# Collect all function declarations
221-
functions = [
222-
node
223-
for node in ast.ext
224-
if isinstance(node, c_ast.Decl) and isinstance(node.type, c_ast.FuncDecl)
225-
]
226-
227-
# Scan all return types and update Result struct
228-
return_types = set()
229-
for func in functions:
230-
if isinstance(func.type.type, c_ast.TypeDecl):
231-
return_type = " ".join(func.type.type.type.names)
232-
# resolved_type = resolve_typedef(typedefs, return_type)
233-
return_types.add(return_type)
234-
235-
# Update the Result struct with all return types
236-
for return_type in return_types:
237-
if return_type == "void":
238-
continue # No need to add void type
239-
240-
RESULT_STRUCT = RESULT_STRUCT.replace(
241-
"// Add other types as needed",
242-
f" {return_type} {return_type}_value;\n // Add other types as needed",
203+
for input_header in header_paths:
204+
output_header = input_header.replace(".h", "_checked.h")
205+
206+
# Parse the header file with preprocessing
207+
ast = parse_file(
208+
input_header,
209+
use_cpp=True,
210+
cpp_path="gcc",
211+
cpp_args=[
212+
"-E",
213+
"-D__attribute__(x)=",
214+
"-D__asm__(x)=",
215+
"-D__asm(x)=",
216+
"-D__builtin_va_list=int",
217+
"-D__extension__=",
218+
"-D__inline__=",
219+
"-D__restrict=",
220+
"-D__restrict__=",
221+
"-D_Static_assert(x, y)=",
222+
"-D__signed=",
223+
"-D__volatile__(x)=",
224+
"-Dstatic_assert(x, y)=",
225+
],
243226
)
244227

245-
# Generate the new header file
246-
with open(output_header, "w") as f:
247-
f.write("#ifndef WASM_EXPORT_CHECKED_H\n#define WASM_EXPORT_CHECKED_H\n\n")
228+
# Collect all typedefs
229+
typedefs = collect_typedefs(ast)
248230

249-
# necessary headers
250-
f.write("#include <stdbool.h>\n")
251-
f.write("#include <stdint.h>\n")
252-
f.write("#include <stdlib.h>\n")
253-
f.write("\n")
254-
f.write('#include "wasm_export.h"\n')
255-
f.write('#include "lib_export.h"\n')
256-
f.write("\n")
257-
258-
# Write the updated Result struct
259-
f.write(RESULT_STRUCT + "\n")
231+
# Collect all function declarations
232+
functions = [
233+
node
234+
for node in ast.ext
235+
if isinstance(node, c_ast.Decl) and isinstance(node.type, c_ast.FuncDecl)
236+
]
260237

238+
# Scan all return types and update Result struct
239+
return_types = set()
261240
for func in functions:
262-
new_func = generate_checked_function(func, typedefs)
263-
f.write(new_func + "\n\n")
241+
if isinstance(func.type.type, c_ast.TypeDecl):
242+
return_type = " ".join(func.type.type.type.names)
243+
# resolved_type = resolve_typedef(typedefs, return_type)
244+
return_types.add(return_type)
245+
246+
# Update the Result struct with all return types
247+
for return_type in return_types:
248+
if return_type == "void":
249+
continue # No need to add void type
250+
251+
RESULT_STRUCT = RESULT_STRUCT.replace(
252+
"// Add other types as needed",
253+
f" {return_type} {return_type}_value;\n // Add other types as needed",
254+
)
255+
256+
# Generate the new header file
257+
with open(output_header, "w") as f:
258+
f.write("#ifndef WASM_EXPORT_CHECKED_H\n#define WASM_EXPORT_CHECKED_H\n\n")
259+
260+
# necessary headers
261+
f.write("#include <stdbool.h>\n")
262+
f.write("#include <stdint.h>\n")
263+
f.write("#include <stdlib.h>\n")
264+
f.write("\n")
265+
f.write('#include "wasm_export.h"\n')
266+
f.write('#include "lib_export.h"\n')
267+
f.write("\n")
268+
269+
# Write the updated Result struct
270+
f.write(RESULT_STRUCT + "\n")
271+
272+
for func in functions:
273+
new_func = generate_checked_function(func, typedefs)
274+
f.write(new_func + "\n\n")
264275

265-
f.write("#endif // WASM_EXPORT_CHECKED_H\n")
276+
f.write("#endif // WASM_EXPORT_CHECKED_H\n")
266277

267278

268279
if __name__ == "__main__":
269-
process_header()
280+
args = parse_arguments()
281+
process_headers(args.headers)

0 commit comments

Comments
 (0)