@@ -231,15 +231,15 @@ def is_array(cls, name):
231
231
return True if re .match (cls .RE_ARRAY , name ) else False
232
232
except :
233
233
return False
234
-
234
+
235
235
@classmethod
236
236
def get_array_length (cls , name ):
237
237
if not cls .is_array (name ):
238
238
raise Exception ("Cannot find array length of non-array type." )
239
239
240
240
match = re .match (cls .RE_ARRAY , name )
241
241
return match .groups ()[1 ]
242
-
242
+
243
243
@classmethod
244
244
def get_array_element_type (cls , name ):
245
245
if not cls .is_array (name ):
@@ -427,7 +427,7 @@ def is_bounds(cls, item):
427
427
return True if re .match (cls .RE_BOUNDS , item ['desc' ]) else False
428
428
except :
429
429
return False
430
-
430
+
431
431
@classmethod
432
432
def tagged_member (cls , item ):
433
433
try :
@@ -1266,6 +1266,122 @@ def get_loader_prologue(namespace, tags, obj, meta):
1266
1266
1267
1267
return prologue
1268
1268
1269
+
1270
+ """
1271
+ Private:
1272
+ Takes a list of struct members and recursively searches for class handles.
1273
+ Returns a list of class handles with access chains to reach them (e.g.
1274
+ "struct_a->struct_b.handle"). Also handles ranges of class handles and
1275
+ ranges of structs with class handle members, although the latter only works
1276
+ to one level of recursion i.e. a range of structs with a range of structs
1277
+ with a handle member will not work.
1278
+ """
1279
+ def get_struct_handle_members (namespace ,
1280
+ tags ,
1281
+ meta ,
1282
+ members ,
1283
+ parent = '' ,
1284
+ is_struct_range = False ):
1285
+ handle_members = []
1286
+ for m in members :
1287
+ if type_traits .is_class_handle (m ['type' ], meta ):
1288
+ m_tname = _remove_const_ptr (subt (namespace , tags , m ['type' ]))
1289
+ m_objname = re .sub (r"(\w+)_handle_t" , r"\1_object_t" , m_tname )
1290
+ # We can deal with a range of handles, but not if it's in a range of structs
1291
+ if param_traits .is_range (m ) and not is_struct_range :
1292
+ handle_members .append ({
1293
+ 'parent' : parent ,
1294
+ 'name' : m ['name' ],
1295
+ 'obj_name' : m_objname ,
1296
+ 'type' : m_tname ,
1297
+ 'range_start' : param_traits .range_start (m ),
1298
+ 'range_end' : param_traits .range_end (m )
1299
+ })
1300
+ else :
1301
+ handle_members .append ({
1302
+ 'parent' : parent ,
1303
+ 'name' : m ['name' ],
1304
+ 'obj_name' : m_objname ,
1305
+ 'optional' : param_traits .is_optional (m )
1306
+ })
1307
+ elif type_traits .is_struct (m ['type' ], meta ):
1308
+ member_struct_type = _remove_const_ptr (m ['type' ])
1309
+ member_struct_members = meta ['struct' ][member_struct_type ][
1310
+ 'members' ]
1311
+ if param_traits .is_range (m ):
1312
+ # If we've hit a range of structs we need to start a new recursion looking
1313
+ # for handle members. We do not support range within range, so skip that
1314
+ if is_struct_range :
1315
+ continue
1316
+ range_handle_members = get_struct_handle_members (
1317
+ namespace , tags , meta , member_struct_members , '' , True )
1318
+ if range_handle_members :
1319
+ handle_members .append ({
1320
+ 'parent' : parent ,
1321
+ 'name' : m ['name' ],
1322
+ 'type' : subt (namespace , tags , member_struct_type ),
1323
+ 'range_start' : param_traits .range_start (m ),
1324
+ 'range_end' : param_traits .range_end (m ),
1325
+ 'handle_members' : range_handle_members
1326
+ })
1327
+ else :
1328
+ # If it's just a struct we can keep recursing in search of handles
1329
+ m_is_pointer = type_traits .is_pointer (m ['type' ])
1330
+ new_parent_deref = '->' if m_is_pointer else '.'
1331
+ new_parent = m ['name' ] + new_parent_deref
1332
+ handle_members += get_struct_handle_members (
1333
+ namespace , tags , meta , member_struct_members , new_parent ,
1334
+ is_struct_range )
1335
+
1336
+ return handle_members
1337
+
1338
+
1339
+ """
1340
+ Public:
1341
+ Strips a string of all dereferences.
1342
+
1343
+ This is useful in layer templates for creating unique variable names. For
1344
+ instance if we need to copy pMyStruct->member.hObject out of a function
1345
+ parameter into a local variable we use this to get the unique (or at least
1346
+ distinct from any other parameter we might copy) variable name
1347
+ pMyStructmemberhObject.
1348
+ """
1349
+ def strip_deref (string_to_strip ):
1350
+ string_to_strip = string_to_strip .replace ('.' , '' )
1351
+ return string_to_strip .replace ('->' , '' )
1352
+
1353
+
1354
+ """
1355
+ Public:
1356
+ Takes a function object and recurses through its struct parameters to return
1357
+ a list of structs that have handle object members the loader will need to
1358
+ convert.
1359
+ """
1360
+ def get_object_handle_structs_to_convert (namespace , tags , obj , meta ):
1361
+ structs = []
1362
+ params = _filter_param_list (obj ['params' ], ["[in]" ])
1363
+
1364
+ for item in params :
1365
+ if type_traits .is_struct (item ['type' ], meta ):
1366
+ members = meta ['struct' ][_remove_const_ptr (
1367
+ item ['type' ])]['members' ]
1368
+ handle_members = get_struct_handle_members (namespace , tags , meta ,
1369
+ members )
1370
+ if handle_members :
1371
+ name = subt (namespace , tags , item ['name' ])
1372
+ tname = _remove_const_ptr (subt (namespace , tags , item ['type' ]))
1373
+ struct = {
1374
+ 'name' : name ,
1375
+ 'type' : tname ,
1376
+ 'optional' : param_traits .is_optional (item ),
1377
+ 'members' : handle_members
1378
+ }
1379
+
1380
+ structs .append (struct )
1381
+
1382
+ return structs
1383
+
1384
+
1269
1385
"""
1270
1386
Public:
1271
1387
returns an enum object with the given name
0 commit comments