@@ -293,6 +293,58 @@ def is_struct(type):
293
293
gen = c_generator .CGenerator ()
294
294
ast = parser .parse (s , filename = '<none>' )
295
295
296
+
297
+ # *************** Fix ***********************************
298
+ # this is a fix for structures not getting populated properly from
299
+ # forward declarations. pycparser doesn't make the connection between
300
+ # a forwrd declaration and the actual declaration so the structures get created
301
+ # without any fields. Since there are no fields things like callbacks break
302
+ # because the generation code looks for specific field names
303
+ # to know if it is valid to be used as a callback.
304
+ forward_struct_decls = {}
305
+
306
+ for item in ast .ext [:]:
307
+ # Locate a forward declaration
308
+ if (
309
+ isinstance (item , c_ast .Decl ) and
310
+ item .name is None and
311
+ isinstance (item .type , c_ast .Struct ) and
312
+ item .type .name is not None
313
+ ):
314
+ # check to see if there are no fields , and of not store the structure
315
+ # as a foward declaration. If it does have fields then build a single
316
+ # object that represents the structure with the fiels.
317
+ if item .type .decls is None :
318
+ forward_struct_decls [item .type .name ] = [item ]
319
+ else :
320
+ if item .type .name in forward_struct_decls :
321
+ decs = forward_struct_decls [item .type .name ]
322
+ if len (decs ) == 2 :
323
+ decl , td = decs
324
+
325
+ td .type .type .decls = item .type .decls [:]
326
+
327
+ ast .ext .remove (decl )
328
+ ast .ext .remove (item )
329
+ # there are 3 objects that get created for a formard declaration.
330
+ # a structure without any fields, a typedef pointing to that structure.
331
+ # and the last is another structure that has fields. So we need to capture
332
+ # all 3 parts to build a single object that represents a structure.
333
+ elif (
334
+ isinstance (item , c_ast .Typedef ) and
335
+ isinstance (item .type , c_ast .TypeDecl ) and
336
+ item .name and
337
+ item .type .declname and
338
+ item .name == item .type .declname and
339
+ isinstance (item .type .type , c_ast .Struct ) and
340
+ item .type .type .decls is None
341
+ ):
342
+ if item .type .type .name in forward_struct_decls :
343
+ forward_struct_decls [item .type .type .name ].append (item )
344
+
345
+ # ********************************************************************
346
+
347
+
296
348
# Types and structs
297
349
298
350
typedefs = [x .type for x in ast .ext if isinstance (x , c_ast .Typedef )] # and not (hasattr(x.type, 'declname') and lv_base_obj_pattern.match(x.type.declname))]
0 commit comments