@@ -48,6 +48,58 @@ def eprint(*args, **kwargs):
4848
4949fake_libc_path = os .path .join (script_path , 'fake_libc' )
5050
51+
52+ # ---------------- monkey patch code for pycparser -------------------------
53+ # this code cleans up the output when logging the objects created by pycparser
54+ # It makes it easier to read
55+
56+ def _repr (obj ):
57+ if isinstance (obj , list ):
58+ if len (obj ) >= 1 :
59+ if isinstance (obj [0 ], str ):
60+ res = ', ' .join (repr (item ) for item in obj )
61+ else :
62+ res = [
63+ '\n ' .join (f' { line } ' for line in _repr (e ).split ('\n ' ))
64+ for e in obj
65+ ]
66+ res = ',\n ' .join (res )
67+ res = f'\n { res } \n '
68+ else :
69+ res = ''
70+
71+ return f'[{ res } ]'
72+ else :
73+ return repr (obj )
74+
75+
76+ def Node__repr__ (self ):
77+ """ Generates a python representation of the current node
78+ """
79+ result = f'{ self .__class__ .__name__ } ('
80+ res = []
81+
82+ for name in self .__slots__ [:- 2 ]:
83+ dta = f'{ name } ={ _repr (getattr (self , name ))} '
84+ res .append (dta )
85+
86+ res = ',\n ' .join (res )
87+
88+ if isinstance (self , c_ast .FileAST ) or len (
89+ self .__slots__ [:- 2 ]
90+ ) > 1 or res .count ('\n ' ):
91+ res = '\n ' .join (f' { line } ' for line in res .split ('\n ' ))
92+ result += f'\n { res } \n )'
93+ else :
94+ result += f'{ res } )'
95+
96+ return result
97+
98+
99+ c_ast ._repr = _repr
100+ setattr (c_ast .Node , '__repr__' , Node__repr__ )
101+
102+
51103#
52104# Argument parsing
53105#
@@ -523,9 +575,42 @@ def is_struct(type):
523575)
524576
525577
526- ast_file = open (os .path .join (os .path .dirname (__file__ ), 'ast.txt' ), 'w' )
527- ast_file .write (str (ast ))
528- ast_file .close ()
578+ forward_struct_decls = {}
579+
580+ for item in ast .ext [:]:
581+ if (
582+ isinstance (item , c_ast .Decl ) and
583+ item .name is None and
584+ isinstance (item .type , c_ast .Struct ) and
585+ item .type .name is not None
586+ ):
587+ if item .type .decls is None :
588+ forward_struct_decls [item .type .name ] = [item ]
589+ else :
590+ if item .type .name in forward_struct_decls :
591+ decs = forward_struct_decls [item .type .name ]
592+ if len (decs ) == 2 :
593+ decl , td = decs
594+
595+ td .type .type .decls = item .type .decls [:]
596+
597+ ast .ext .remove (decl )
598+ ast .ext .remove (item )
599+ elif (
600+ isinstance (item , c_ast .Typedef ) and
601+ isinstance (item .type , c_ast .TypeDecl ) and
602+ item .name and item .type .declname and item .name == item .type .declname and
603+ isinstance (item .type .type , c_ast .Struct ) and
604+ item .type .type .decls is None
605+ ):
606+ if item .type .type .name in forward_struct_decls :
607+ forward_struct_decls [item .type .type .name ].append (item )
608+
609+
610+
611+ # ast_file = open(os.path.join(os.path.dirname(__file__), 'ast.txt'), 'w')
612+ # ast_file.write(str(ast))
613+ # ast_file.close()
529614
530615pp_cmd = cpp_path + (' ' .join (cpp_args ))
531616
0 commit comments