11from pycparser import c_parser , c_ast , parse_file
22import os
3+ from pprint import pprint
34
45
56# Updated generate_checked_function to dynamically update Result definition for new return types
67
78
8- def generate_checked_function (func ):
9+ def collect_typedefs (ast ):
10+ typedefs = {}
11+ for node in ast .ext :
12+ if isinstance (node , c_ast .Typedef ):
13+ typedefs [node .name ] = node .type
14+ return typedefs
15+
16+ def resolve_typedef (typedefs , type_name ):
17+ resolved_type = typedefs .get (type_name )
18+
19+ # Return the original type name if not a typedef
20+ if not resolved_type :
21+ return type_name
22+
23+ print (f"Resolving typedef for { type_name } : { resolved_type } \n " )
24+
25+ if isinstance (resolved_type , c_ast .TypeDecl ):
26+ # Base case: Return the type name
27+ return " " .join (resolved_type .declname )
28+ elif isinstance (resolved_type , c_ast .PtrDecl ):
29+ # Handle pointer typedefs
30+ resolved_type .show ()
31+ base_type = " " .join (resolved_type .type .type .name )
32+ return f"{ base_type } *"
33+ elif isinstance (resolved_type , c_ast .ArrayDecl ):
34+ # Handle array typedefs
35+ base_type = resolve_typedef (resolved_type .type .declname , typedefs )
36+ return f"{ base_type } *"
37+
38+
39+ def generate_checked_function (func , typedefs ):
940 func_name = func .name # Access the name directly from Decl
1041 new_func_name = f"{ func_name } _checked"
1142
@@ -16,6 +47,8 @@ def generate_checked_function(func):
1647 return_type = "void" # Default to void if no return type is specified
1748 if isinstance (func .type .type , c_ast .TypeDecl ):
1849 return_type = " " .join (func .type .type .type .names )
50+ resolved_type = resolve_typedef (typedefs , return_type )
51+ return_type = resolved_type
1952
2053 # Start building the new function
2154 new_func = [f"static inline Result { new_func_name } (" ]
@@ -55,32 +88,41 @@ def generate_checked_function(func):
5588 # Call the original function
5689 if return_type == "void" :
5790 new_func .append (f" { func_name } ({ ', ' .join (param_list )} );" )
58- new_func .append (f" Result res = {{ .error_code = 0 }};" )
5991 elif has_variadic :
6092 new_func .append (" va_start(args, " + param_list [- 2 ] + ");" )
6193 new_func .append (
6294 f" { return_type } original_result = { func_name } ({ ', ' .join (param_list [:- 1 ])} , args);"
6395 )
6496 new_func .append (" va_end(args);" )
65- new_func .append (f" Result res;" )
66- new_func .append (f" if (original_result == 0) {{" )
67- new_func .append (f" res.error_code = 0;" )
68- new_func .append (f" res.value.{ return_type } _value = original_result;" )
69- new_func .append (f" }} else {{" )
70- new_func .append (f" res.error_code = -2;" )
71- new_func .append (f" }}" )
7297 else :
7398 new_func .append (
7499 f" { return_type } original_result = { func_name } ({ ', ' .join (param_list )} );"
75100 )
76- new_func .append (f" Result res;" )
77- new_func .append (f" if (original_result == 0) {{" )
78- new_func .append (f" res.error_code = 0;" )
79101
80- new_func .append (f" res.value.{ return_type } _value = original_result;" )
102+ # Handle result return from the original function
103+ new_func .append (f" Result res;" )
104+ # if it is bool type
105+ if return_type == "_Bool" :
106+ new_func .append (f" if (original_result == 1) {{" )
107+ new_func .append (f" res.error_code = 0;" )
108+ new_func .append (f" res.value._Bool_value = original_result;" )
81109 new_func .append (f" }} else {{" )
82- new_func .append (f" res.error_code = -2 ;" )
110+ new_func .append (f" res.error_code = -1 ;" )
83111 new_func .append (f" }}" )
112+ # if it is void type
113+ elif return_type == "void" :
114+ new_func .append (f" res.error_code = 0;" )
115+ else :
116+ if isinstance (func .type .type , c_ast .PtrDecl ):
117+ new_func .append (f" if (original_result != NULL) {{" )
118+ new_func .append (f" res.error_code = 0;" )
119+ new_func .append (f" res.value.{ return_type } _value = original_result;" )
120+ new_func .append (f" }} else {{" )
121+ new_func .append (f" res.error_code = -1;" )
122+ new_func .append (f" }}" )
123+ else :
124+ new_func .append (f" res.error_code = 0;" )
125+ new_func .append (f" res.value.{ return_type } _value = original_result;" )
84126
85127 new_func .append (f" return res;" )
86128 new_func .append ("}" )
@@ -130,6 +172,10 @@ def process_header():
130172 ],
131173 )
132174
175+ # Collect typedefs
176+ typedefs = collect_typedefs (ast )
177+ # pprint(typedefs)
178+
133179 # Collect all function declarations
134180 functions = [
135181 node
@@ -142,7 +188,8 @@ def process_header():
142188 for func in functions :
143189 if isinstance (func .type .type , c_ast .TypeDecl ):
144190 return_type = " " .join (func .type .type .type .names )
145- return_types .add (return_type )
191+ resolved_type = resolve_typedef (typedefs , return_type )
192+ return_types .add (resolved_type )
146193
147194 # Update the Result struct with all return types
148195 for return_type in return_types :
@@ -171,7 +218,7 @@ def process_header():
171218 f .write (RESULT_STRUCT + "\n " )
172219
173220 for func in functions :
174- new_func = generate_checked_function (func )
221+ new_func = generate_checked_function (func , typedefs )
175222 f .write (new_func + "\n \n " )
176223
177224 f .write ("#endif // WASM_EXPORT_CHECKED_H\n " )
0 commit comments