11from pycparser import c_parser , c_ast , parse_file
22import os
3+ import argparse
34
45
56def 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
268279if __name__ == "__main__" :
269- process_header ()
280+ args = parse_arguments ()
281+ process_headers (args .headers )
0 commit comments