@@ -202,6 +202,19 @@ def read_file(filename):
202
202
return assign_ids (unique_messages , unique_modules , stable_data )
203
203
204
204
205
+ def make_cpp_scoped_enum_decl (e : str , ut : str ) -> str :
206
+ parts = e .split ("::" )
207
+ enum = parts [- 1 ]
208
+ if "(anonymous namespace)" in parts or "{anonymous}" in parts :
209
+ raise Exception (
210
+ f"Scoped enum { e } is inside an anonymous namespace and cannot be forward declared."
211
+ )
212
+ if len (parts ) > 1 :
213
+ ns = "::" .join (parts [:- 1 ])
214
+ return f"namespace { ns } {{ enum struct { enum } : { ut } ; }}"
215
+ return f"enum struct { enum } : { ut } ;"
216
+
217
+
205
218
def make_cpp_catalog_defn (m : Message ) -> str :
206
219
return f"""/*
207
220
"{ m .text } "
@@ -221,11 +234,16 @@ def make_cpp_module_defn(m: Module) -> str:
221
234
}}"""
222
235
223
236
224
- def write_cpp (messages , modules , extra_headers : list [str ], filename : str ):
237
+ def write_cpp (messages , modules , scoped_enums , extra_headers : list [str ], filename : str ):
225
238
with open (filename , "w" ) as f :
226
239
f .write ("\n " .join (f'#include "{ h } "' for h in extra_headers ))
227
240
f .write ("\n #include <log/catalog/arguments.hpp>\n " )
228
241
f .write ("\n #include <log/catalog/catalog.hpp>\n \n " )
242
+ scoped_enum_decls = [
243
+ make_cpp_scoped_enum_decl (e , ut ) for e , ut in scoped_enums .items ()
244
+ ]
245
+ f .write ("\n " .join (scoped_enum_decls ))
246
+ f .write ("\n \n " )
229
247
cpp_catalog_defns = [make_cpp_catalog_defn (m ) for m in messages ]
230
248
f .write ("\n " .join (cpp_catalog_defns ))
231
249
f .write ("\n \n " )
@@ -254,15 +272,12 @@ def fq_name(node):
254
272
enums = {}
255
273
for node in translation_unit .cursor .walk_preorder ():
256
274
if node .kind == CursorKind .ENUM_DECL :
257
- enums .update (
258
- {
259
- fq_name (node ): {
260
- e .spelling : e .enum_value
261
- for e in node .walk_preorder ()
262
- if e .kind == CursorKind .ENUM_CONSTANT_DECL
263
- }
264
- }
265
- )
275
+ new_decl = {
276
+ e .spelling : e .enum_value
277
+ for e in node .walk_preorder ()
278
+ if e .kind == CursorKind .ENUM_CONSTANT_DECL
279
+ }
280
+ enums [fq_name (node )] = enums .get (fq_name (node ), {}) | new_decl
266
281
return enums
267
282
268
283
@@ -274,11 +289,11 @@ def write_json(
274
289
)
275
290
for m in stable_data .get ("messages" ):
276
291
j = m .to_json ()
277
- if not j in d ["messages" ]:
292
+ if j not in d ["messages" ]:
278
293
d ["messages" ].append (j )
279
294
for m in stable_data .get ("modules" ):
280
295
j = m .to_json ()
281
- if not j in d ["modules" ]:
296
+ if j not in d ["modules" ]:
282
297
d ["modules" ].append (j )
283
298
284
299
str_catalog = dict (** d , enums = dict ())
@@ -347,9 +362,13 @@ def serialize_modules(client_node: et.Element, modules: list[Module]):
347
362
348
363
349
364
def arg_type_encoding (arg ):
350
- string_re = re .compile (r"encode_(32|u32|64|u64)<(.*)>" )
365
+ string_re = re .compile (r"encode_(32|u32|64|u64|enum )<(.*)>" )
351
366
m = string_re .match (arg )
352
- return (f"encode_{ m .group (1 )} " , m .group (2 ))
367
+ if "enum" in m .group (1 ):
368
+ args_re = re .compile (r"(.*), (.*)" )
369
+ args_m = args_re .match (m .group (2 ))
370
+ return (f"encode_{ m .group (1 )} " , args_m .group (1 ), args_m .group (2 ))
371
+ return (f"encode_{ m .group (1 )} " , m .group (2 ), m .group (2 ))
353
372
354
373
355
374
def arg_printf_spec (arg : str ):
@@ -360,9 +379,20 @@ def arg_printf_spec(arg: str):
360
379
"encode_u64" : "%llu" ,
361
380
"float" : "%f" ,
362
381
"double" : "%f" ,
382
+ "int" : "%d" ,
383
+ "unsigned int" : "%u" ,
384
+ "short" : "%d" ,
385
+ "unsigned short" : "%u" ,
386
+ "signed char" : "%d" ,
387
+ "unsigned char" : "%u" ,
388
+ "char" : "%c" ,
389
+ "long" : "%ld" ,
390
+ "unsigned long" : "%lu" ,
391
+ "long long" : "%lld" ,
392
+ "unsigned long long" : "%llu" ,
363
393
}
364
- enc , t = arg_type_encoding (arg )
365
- return printf_dict .get (t , printf_dict .get (enc , "%d" ))
394
+ enc , _ , ut = arg_type_encoding (arg )
395
+ return printf_dict .get (ut , printf_dict .get (enc , "%d" ))
366
396
367
397
368
398
def serialize_messages (
@@ -539,8 +569,15 @@ def main():
539
569
except Exception as e :
540
570
raise Exception (f"{ str (e )} from file { args .input } " )
541
571
572
+ scoped_enums = {}
542
573
if args .cpp_output is not None :
543
- write_cpp (messages , modules , args .cpp_headers , args .cpp_output )
574
+ for m in messages :
575
+ for i , arg_type in enumerate (m .args ):
576
+ enc , enum , ut = arg_type_encoding (arg_type )
577
+ if "enum" in enc :
578
+ scoped_enums .update ({enum : ut })
579
+
580
+ write_cpp (messages , modules , scoped_enums , args .cpp_headers , args .cpp_output )
544
581
545
582
stable_output = dict (messages = [], modules = [])
546
583
if not args .forget_old_ids :
@@ -563,14 +600,13 @@ def main():
563
600
}
564
601
for m in messages :
565
602
for i , arg_type in enumerate (m .args ):
566
- _ , enum = arg_type_encoding (arg_type )
603
+ _ , enum , _ = arg_type_encoding (arg_type )
567
604
if enum in enums :
568
605
m .enum_lookup = (i + 1 , enums [enum ][0 ])
569
606
except Exception as e :
570
607
print (
571
608
f"Couldn't extract enum info ({ str (e )} ), enum lookup will not be available"
572
609
)
573
-
574
610
else :
575
611
print ("XML output without C++ output: enum lookup will not be available" )
576
612
0 commit comments