Mercurial > games > semicongine
comparison fuhtark_test/Vulkan-Headers-1.4.334/registry/cgenerator.py @ 1501:f40d9d814c08 default tip main
did: correct vulkan-api generator
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 26 Nov 2025 23:34:29 +0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1500:91c8c3b7cbf0 | 1501:f40d9d814c08 |
|---|---|
| 1 #!/usr/bin/env python3 -i | |
| 2 # | |
| 3 # Copyright 2013-2025 The Khronos Group Inc. | |
| 4 # | |
| 5 # SPDX-License-Identifier: Apache-2.0 | |
| 6 | |
| 7 import os | |
| 8 import re | |
| 9 | |
| 10 from generator import (GeneratorOptions, | |
| 11 MissingGeneratorOptionsConventionsError, | |
| 12 MissingGeneratorOptionsError, MissingRegistryError, | |
| 13 OutputGenerator, noneStr, regSortFeatures, write) | |
| 14 | |
| 15 class CGeneratorOptions(GeneratorOptions): | |
| 16 """CGeneratorOptions - subclass of GeneratorOptions. | |
| 17 | |
| 18 Adds options used by COutputGenerator objects during C language header | |
| 19 generation.""" | |
| 20 | |
| 21 def __init__(self, | |
| 22 prefixText='', | |
| 23 genFuncPointers=True, | |
| 24 protectFile=True, | |
| 25 protectFeature=True, | |
| 26 protectProto=None, | |
| 27 protectProtoStr=None, | |
| 28 protectExtensionProto=None, | |
| 29 protectExtensionProtoStr=None, | |
| 30 protectExportName=None, | |
| 31 protectExportProtoStr=None, | |
| 32 apicall='', | |
| 33 apientry='', | |
| 34 apientryp='', | |
| 35 indentFuncProto=True, | |
| 36 indentFuncPointer=False, | |
| 37 alignFuncParam=0, | |
| 38 genEnumBeginEndRange=False, | |
| 39 genAliasMacro=False, | |
| 40 genStructExtendsComment=False, | |
| 41 aliasMacro='', | |
| 42 misracstyle=False, | |
| 43 misracppstyle=False, | |
| 44 **kwargs | |
| 45 ): | |
| 46 """Constructor. | |
| 47 Additional parameters beyond parent class: | |
| 48 | |
| 49 - prefixText - list of strings to prefix generated header with | |
| 50 (usually a copyright statement + calling convention macros) | |
| 51 - protectFile - True if multiple inclusion protection should be | |
| 52 generated (based on the filename) around the entire header | |
| 53 - protectFeature - True if #ifndef..#endif protection should be | |
| 54 generated around a feature interface in the header file | |
| 55 - genFuncPointers - True if function pointer typedefs should be | |
| 56 generated | |
| 57 - protectProto - If conditional protection should be generated | |
| 58 around prototype declarations, set to either '#ifdef' | |
| 59 to require opt-in (#ifdef protectProtoStr) or '#ifndef' | |
| 60 to require opt-out (#ifndef protectProtoStr). Otherwise | |
| 61 set to None. | |
| 62 - protectProtoStr - #ifdef/#ifndef symbol to use around prototype | |
| 63 declarations, if protectProto is set | |
| 64 - protectExtensionProto - If conditional protection should be generated | |
| 65 around extension prototype declarations, set to either '#ifdef' | |
| 66 to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' | |
| 67 to require opt-out (#ifndef protectExtensionProtoStr). Otherwise | |
| 68 set to None | |
| 69 - protectExtensionProtoStr - #ifdef/#ifndef symbol to use around | |
| 70 extension prototype declarations, if protectExtensionProto is set | |
| 71 - protectExportName - name used to determine if a command is | |
| 72 exported matching an entry in the XML 'export' attribute. | |
| 73 Set to None if no matching should be done. | |
| 74 - protectExportProtoStr - #ifndef symbol to use around prototypes | |
| 75 for commands that are not exported. | |
| 76 Set to None if no protection is wanted. | |
| 77 - apicall - string to use for the function declaration prefix, | |
| 78 such as APICALL on Windows | |
| 79 - apientry - string to use for the calling convention macro, | |
| 80 in typedefs, such as APIENTRY | |
| 81 - apientryp - string to use for the calling convention macro | |
| 82 in function pointer typedefs, such as APIENTRYP | |
| 83 - indentFuncProto - True if prototype declarations should put each | |
| 84 parameter on a separate line | |
| 85 - indentFuncPointer - True if typedefed function pointers should put each | |
| 86 parameter on a separate line | |
| 87 - alignFuncParam - if nonzero and parameters are being put on a | |
| 88 separate line, align parameter names at the specified column | |
| 89 - genEnumBeginEndRange - True if BEGIN_RANGE / END_RANGE macros should | |
| 90 be generated for enumerated types | |
| 91 - genAliasMacro - True if the OpenXR alias macro should be generated | |
| 92 for aliased types (unclear what other circumstances this is useful) | |
| 93 - genStructExtendsComment - True if comments showing the structures | |
| 94 whose pNext chain a structure extends are included before its | |
| 95 definition | |
| 96 - aliasMacro - alias macro to inject when genAliasMacro is True | |
| 97 - misracstyle - generate MISRA C-friendly headers | |
| 98 - misracppstyle - generate MISRA C++-friendly headers""" | |
| 99 | |
| 100 GeneratorOptions.__init__(self, **kwargs) | |
| 101 | |
| 102 self.prefixText = prefixText | |
| 103 """list of strings to prefix generated header with (usually a copyright statement + calling convention macros).""" | |
| 104 | |
| 105 self.genFuncPointers = genFuncPointers | |
| 106 """True if function pointer typedefs should be generated""" | |
| 107 | |
| 108 self.protectFile = protectFile | |
| 109 """True if multiple inclusion protection should be generated (based on the filename) around the entire header.""" | |
| 110 | |
| 111 self.protectFeature = protectFeature | |
| 112 """True if #ifndef..#endif protection should be generated around a feature interface in the header file.""" | |
| 113 | |
| 114 self.protectProto = protectProto | |
| 115 """If conditional protection should be generated around prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectProtoStr) or '#ifndef' to require opt-out (#ifndef protectProtoStr). Otherwise set to None.""" | |
| 116 | |
| 117 self.protectProtoStr = protectProtoStr | |
| 118 """#ifdef/#ifndef symbol to use around prototype declarations, if protectProto is set""" | |
| 119 | |
| 120 self.protectExtensionProto = protectExtensionProto | |
| 121 """If conditional protection should be generated around extension prototype declarations, set to either '#ifdef' to require opt-in (#ifdef protectExtensionProtoStr) or '#ifndef' to require opt-out (#ifndef protectExtensionProtoStr). Otherwise set to None.""" | |
| 122 | |
| 123 self.protectExtensionProtoStr = protectExtensionProtoStr | |
| 124 """#ifdef/#ifndef symbol to use around extension prototype declarations, if protectExtensionProto is set""" | |
| 125 | |
| 126 self.protectExportName = protectExportName | |
| 127 """Export name for commands which are exported""" | |
| 128 | |
| 129 self.protectExportProtoStr = protectExportProtoStr | |
| 130 """#ifndef symbol to use around prototypes for commands which are not exported""" | |
| 131 | |
| 132 self.apicall = apicall | |
| 133 """string to use for the function declaration prefix, such as APICALL on Windows.""" | |
| 134 | |
| 135 self.apientry = apientry | |
| 136 """string to use for the calling convention macro, in typedefs, such as APIENTRY.""" | |
| 137 | |
| 138 self.apientryp = apientryp | |
| 139 """string to use for the calling convention macro in function pointer typedefs, such as APIENTRYP.""" | |
| 140 | |
| 141 self.indentFuncProto = indentFuncProto | |
| 142 """True if prototype declarations should put each parameter on a separate line""" | |
| 143 | |
| 144 self.indentFuncPointer = indentFuncPointer | |
| 145 """True if typedefed function pointers should put each parameter on a separate line""" | |
| 146 | |
| 147 self.alignFuncParam = alignFuncParam | |
| 148 """if nonzero and parameters are being put on a separate line, align parameter names at the specified column""" | |
| 149 | |
| 150 self.genEnumBeginEndRange = genEnumBeginEndRange | |
| 151 """True if BEGIN_RANGE / END_RANGE macros should be generated for enumerated types""" | |
| 152 | |
| 153 self.genAliasMacro = genAliasMacro | |
| 154 """True if the OpenXR alias macro should be generated for aliased types (unclear what other circumstances this is useful)""" | |
| 155 | |
| 156 self.genStructExtendsComment = genStructExtendsComment | |
| 157 """True if comments showing the structures whose pNext chain a structure extends are included before its definition""" | |
| 158 | |
| 159 self.aliasMacro = aliasMacro | |
| 160 """alias macro to inject when genAliasMacro is True""" | |
| 161 | |
| 162 self.misracstyle = misracstyle | |
| 163 """generate MISRA C-friendly headers""" | |
| 164 | |
| 165 self.misracppstyle = misracppstyle | |
| 166 """generate MISRA C++-friendly headers""" | |
| 167 | |
| 168 self.codeGenerator = True | |
| 169 """True if this generator makes compilable code""" | |
| 170 | |
| 171 | |
| 172 class COutputGenerator(OutputGenerator): | |
| 173 """Generates C-language API interfaces.""" | |
| 174 | |
| 175 # This is an ordered list of sections in the header file. | |
| 176 TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum', | |
| 177 'group', 'bitmask', 'funcpointer', 'struct'] | |
| 178 ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command'] | |
| 179 | |
| 180 def __init__(self, *args, **kwargs): | |
| 181 super().__init__(*args, **kwargs) | |
| 182 # Internal state - accumulators for different inner block text | |
| 183 self.sections = {section: [] for section in self.ALL_SECTIONS} | |
| 184 self.feature_not_empty = False | |
| 185 self.may_alias = None | |
| 186 | |
| 187 def beginFile(self, genOpts): | |
| 188 OutputGenerator.beginFile(self, genOpts) | |
| 189 if self.genOpts is None: | |
| 190 raise MissingGeneratorOptionsError() | |
| 191 # C-specific | |
| 192 # | |
| 193 # Multiple inclusion protection & C++ wrappers. | |
| 194 if self.genOpts.protectFile and self.genOpts.filename: | |
| 195 headerSym = re.sub(r'\.h', '_h_', | |
| 196 os.path.basename(self.genOpts.filename)).upper() | |
| 197 write('#ifndef', headerSym, file=self.outFile) | |
| 198 write('#define', headerSym, '1', file=self.outFile) | |
| 199 self.newline() | |
| 200 | |
| 201 # User-supplied prefix text, if any (list of strings) | |
| 202 if genOpts.prefixText: | |
| 203 for s in genOpts.prefixText: | |
| 204 write(s, file=self.outFile) | |
| 205 | |
| 206 # C++ extern wrapper - after prefix lines so they can add includes. | |
| 207 self.newline() | |
| 208 write('#ifdef __cplusplus', file=self.outFile) | |
| 209 write('extern "C" {', file=self.outFile) | |
| 210 write('#endif', file=self.outFile) | |
| 211 self.newline() | |
| 212 | |
| 213 def endFile(self): | |
| 214 # C-specific | |
| 215 # Finish C++ wrapper and multiple inclusion protection | |
| 216 if self.genOpts is None: | |
| 217 raise MissingGeneratorOptionsError() | |
| 218 self.newline() | |
| 219 write('#ifdef __cplusplus', file=self.outFile) | |
| 220 write('}', file=self.outFile) | |
| 221 write('#endif', file=self.outFile) | |
| 222 if self.genOpts.protectFile and self.genOpts.filename: | |
| 223 self.newline() | |
| 224 write('#endif', file=self.outFile) | |
| 225 # Finish processing in superclass | |
| 226 OutputGenerator.endFile(self) | |
| 227 | |
| 228 def beginFeature(self, interface, emit): | |
| 229 # Start processing in superclass | |
| 230 OutputGenerator.beginFeature(self, interface, emit) | |
| 231 # C-specific | |
| 232 # Accumulate includes, defines, types, enums, function pointer typedefs, | |
| 233 # end function prototypes separately for this feature. They are only | |
| 234 # printed in endFeature(). | |
| 235 self.sections = {section: [] for section in self.ALL_SECTIONS} | |
| 236 self.feature_not_empty = False | |
| 237 | |
| 238 def _endProtectComment(self, protect_str, protect_directive='#ifdef'): | |
| 239 if protect_directive is None or protect_str is None: | |
| 240 raise RuntimeError('Should not call in here without something to protect') | |
| 241 | |
| 242 # Do not put comments after #endif closing blocks if this is not set | |
| 243 if not self.genOpts.conventions.protectProtoComment: | |
| 244 return '' | |
| 245 elif 'ifdef' in protect_directive: | |
| 246 return f' /* {protect_str} */' | |
| 247 else: | |
| 248 return f' /* !{protect_str} */' | |
| 249 | |
| 250 def endFeature(self): | |
| 251 "Actually write the interface to the output file." | |
| 252 # C-specific | |
| 253 if self.emit: | |
| 254 if self.feature_not_empty: | |
| 255 if self.genOpts is None: | |
| 256 raise MissingGeneratorOptionsError() | |
| 257 if self.genOpts.conventions is None: | |
| 258 raise MissingGeneratorOptionsConventionsError() | |
| 259 is_core = self.featureName and self.featureName.startswith(f"{self.conventions.api_prefix}VERSION_") | |
| 260 if self.genOpts.conventions.writeFeature(self.featureName, self.featureExtraProtect, self.genOpts.filename): | |
| 261 self.newline() | |
| 262 if self.genOpts.protectFeature: | |
| 263 write('#ifndef', self.featureName, file=self.outFile) | |
| 264 | |
| 265 # If type declarations are needed by other features based on | |
| 266 # this one, it may be necessary to suppress the ExtraProtect, | |
| 267 # or move it below the 'for section...' loop. | |
| 268 if self.featureExtraProtect is not None: | |
| 269 write('#ifdef', self.featureExtraProtect, file=self.outFile) | |
| 270 self.newline() | |
| 271 | |
| 272 # Generate warning of possible use in IDEs | |
| 273 write(f'// {self.featureName} is a preprocessor guard. Do not pass it to API calls.', file=self.outFile) | |
| 274 write('#define', self.featureName, '1', file=self.outFile) | |
| 275 for section in self.TYPE_SECTIONS: | |
| 276 contents = self.sections[section] | |
| 277 if contents: | |
| 278 write('\n'.join(contents), file=self.outFile) | |
| 279 | |
| 280 if self.genOpts.genFuncPointers and self.sections['commandPointer']: | |
| 281 write('\n'.join(self.sections['commandPointer']), file=self.outFile) | |
| 282 self.newline() | |
| 283 | |
| 284 if self.sections['command']: | |
| 285 if self.genOpts.protectProto: | |
| 286 write(self.genOpts.protectProto, | |
| 287 self.genOpts.protectProtoStr, file=self.outFile) | |
| 288 if self.genOpts.protectExtensionProto and not is_core: | |
| 289 write(self.genOpts.protectExtensionProto, | |
| 290 self.genOpts.protectExtensionProtoStr, file=self.outFile) | |
| 291 write('\n'.join(self.sections['command']), end='', file=self.outFile) | |
| 292 if self.genOpts.protectExtensionProto and not is_core: | |
| 293 write('#endif' + | |
| 294 self._endProtectComment(protect_directive=self.genOpts.protectExtensionProto, | |
| 295 protect_str=self.genOpts.protectExtensionProtoStr), | |
| 296 file=self.outFile) | |
| 297 if self.genOpts.protectProto: | |
| 298 write('#endif' + | |
| 299 self._endProtectComment(protect_directive=self.genOpts.protectProto, | |
| 300 protect_str=self.genOpts.protectProtoStr), | |
| 301 file=self.outFile) | |
| 302 else: | |
| 303 self.newline() | |
| 304 | |
| 305 if self.featureExtraProtect is not None: | |
| 306 write('#endif' + | |
| 307 self._endProtectComment(protect_str=self.featureExtraProtect), | |
| 308 file=self.outFile) | |
| 309 | |
| 310 if self.genOpts.protectFeature: | |
| 311 write('#endif' + | |
| 312 self._endProtectComment(protect_str=self.featureName), | |
| 313 file=self.outFile) | |
| 314 # Finish processing in superclass | |
| 315 OutputGenerator.endFeature(self) | |
| 316 | |
| 317 def appendSection(self, section, text): | |
| 318 "Append a definition to the specified section" | |
| 319 | |
| 320 if section is None: | |
| 321 self.logMsg('error', 'Missing section in appendSection (probably a <type> element missing its \'category\' attribute. Text:', text) | |
| 322 exit(1) | |
| 323 | |
| 324 self.sections[section].append(text) | |
| 325 self.feature_not_empty = True | |
| 326 | |
| 327 def genType(self, typeinfo, name, alias): | |
| 328 "Generate type." | |
| 329 OutputGenerator.genType(self, typeinfo, name, alias) | |
| 330 typeElem = typeinfo.elem | |
| 331 | |
| 332 # Vulkan: | |
| 333 # Determine the category of the type, and the type section to add | |
| 334 # its definition to. | |
| 335 # 'funcpointer' is added to the 'struct' section as a workaround for | |
| 336 # internal issue #877, since structures and function pointer types | |
| 337 # can have cross-dependencies. | |
| 338 category = typeElem.get('category') | |
| 339 if category == 'funcpointer': | |
| 340 section = 'struct' | |
| 341 else: | |
| 342 section = category | |
| 343 | |
| 344 if category in ('struct', 'union'): | |
| 345 # If the type is a struct type, generate it using the | |
| 346 # special-purpose generator. | |
| 347 self.genStruct(typeinfo, name, alias) | |
| 348 else: | |
| 349 if self.genOpts is None: | |
| 350 raise MissingGeneratorOptionsError() | |
| 351 | |
| 352 body = self.deprecationComment(typeElem) | |
| 353 | |
| 354 # OpenXR: this section was not under 'else:' previously, just fell through | |
| 355 if alias: | |
| 356 # If the type is an alias, just emit a typedef declaration | |
| 357 body += f"typedef {alias} {name};\n" | |
| 358 else: | |
| 359 # Replace <apientry /> tags with an APIENTRY-style string | |
| 360 # (from self.genOpts). Copy other text through unchanged. | |
| 361 # If the resulting text is an empty string, do not emit it. | |
| 362 body += noneStr(typeElem.text) | |
| 363 for elem in typeElem: | |
| 364 if elem.tag == 'apientry': | |
| 365 body += self.genOpts.apientry + noneStr(elem.tail) | |
| 366 else: | |
| 367 body += noneStr(elem.text) + noneStr(elem.tail) | |
| 368 if category == 'define' and self.misracppstyle(): | |
| 369 body = body.replace("(uint32_t)", "static_cast<uint32_t>") | |
| 370 if body: | |
| 371 # Add extra newline after multi-line entries. | |
| 372 if '\n' in body[0:-1]: | |
| 373 body += '\n' | |
| 374 self.appendSection(section, body) | |
| 375 | |
| 376 def genProtectString(self, protect_str): | |
| 377 """Generate protection string. | |
| 378 | |
| 379 Protection strings are the strings defining the OS/Platform/Graphics | |
| 380 requirements for a given API command. When generating the | |
| 381 language header files, we need to make sure the items specific to a | |
| 382 graphics API or OS platform are properly wrapped in #ifs.""" | |
| 383 protect_if_str = '' | |
| 384 protect_end_str = '' | |
| 385 if not protect_str: | |
| 386 return (protect_if_str, protect_end_str) | |
| 387 | |
| 388 if ',' in protect_str: | |
| 389 protect_list = protect_str.split(',') | |
| 390 protect_defs = (f'defined({d})' for d in protect_list) | |
| 391 protect_def_str = ' && '.join(protect_defs) | |
| 392 protect_if_str = f'#if {protect_def_str}\n' | |
| 393 protect_end_str = f'#endif // {protect_def_str}\n' | |
| 394 else: | |
| 395 protect_if_str = f'#ifdef {protect_str}\n' | |
| 396 protect_end_str = f'#endif // {protect_str}\n' | |
| 397 | |
| 398 return (protect_if_str, protect_end_str) | |
| 399 | |
| 400 def typeMayAlias(self, typeName): | |
| 401 if not self.may_alias: | |
| 402 if self.registry is None: | |
| 403 raise MissingRegistryError() | |
| 404 # First time we have asked if a type may alias. | |
| 405 # So, populate the set of all names of types that may. | |
| 406 | |
| 407 # Everyone with an explicit mayalias="true" | |
| 408 self.may_alias = set(typeName | |
| 409 for typeName, data in self.registry.typedict.items() | |
| 410 if data.elem.get('mayalias') == 'true') | |
| 411 | |
| 412 # Every type mentioned in some other type's parentstruct attribute. | |
| 413 polymorphic_bases = (otherType.elem.get('parentstruct') | |
| 414 for otherType in self.registry.typedict.values()) | |
| 415 self.may_alias.update(set(x for x in polymorphic_bases | |
| 416 if x is not None)) | |
| 417 return typeName in self.may_alias | |
| 418 | |
| 419 def genStruct(self, typeinfo, typeName, alias): | |
| 420 """Generate struct (e.g. C "struct" type). | |
| 421 | |
| 422 This is a special case of the <type> tag where the contents are | |
| 423 interpreted as a set of <member> tags instead of freeform C | |
| 424 C type declarations. The <member> tags are just like <param> | |
| 425 tags - they are a declaration of a struct or union member. | |
| 426 Only simple member declarations are supported (no nested | |
| 427 structs etc.) | |
| 428 | |
| 429 If alias is not None, then this struct aliases another; just | |
| 430 generate a typedef of that alias.""" | |
| 431 OutputGenerator.genStruct(self, typeinfo, typeName, alias) | |
| 432 | |
| 433 if self.genOpts is None: | |
| 434 raise MissingGeneratorOptionsError() | |
| 435 | |
| 436 typeElem = typeinfo.elem | |
| 437 body = self.deprecationComment(typeElem) | |
| 438 | |
| 439 if alias: | |
| 440 body += f"typedef {alias} {typeName};\n" | |
| 441 else: | |
| 442 (protect_begin, protect_end) = self.genProtectString(typeElem.get('protect')) | |
| 443 if protect_begin: | |
| 444 body += protect_begin | |
| 445 | |
| 446 if self.genOpts.genStructExtendsComment: | |
| 447 structextends = typeElem.get('structextends') | |
| 448 body += f"// {typeName} extends {structextends}\n" if structextends else '' | |
| 449 | |
| 450 body += f"typedef {typeElem.get('category')}" | |
| 451 | |
| 452 # This is an OpenXR-specific alternative where aliasing refers | |
| 453 # to an inheritance hierarchy of types rather than C-level type | |
| 454 # aliases. | |
| 455 if self.genOpts.genAliasMacro and self.typeMayAlias(typeName): | |
| 456 body += f" {self.genOpts.aliasMacro}" | |
| 457 | |
| 458 body += f" {typeName} {{\n" | |
| 459 | |
| 460 targetLen = self.getMaxCParamTypeLength(typeinfo) | |
| 461 for member in typeElem.findall('.//member'): | |
| 462 body += self.deprecationComment(member, indent = 4) | |
| 463 body += self.makeCParamDecl(member, targetLen + 4) | |
| 464 body += ';\n' | |
| 465 body += f"}} {typeName};\n" | |
| 466 if protect_end: | |
| 467 body += protect_end | |
| 468 | |
| 469 self.appendSection('struct', body) | |
| 470 | |
| 471 def genGroup(self, groupinfo, groupName, alias=None): | |
| 472 """Generate groups (e.g. C "enum" type). | |
| 473 | |
| 474 These are concatenated together with other types. | |
| 475 | |
| 476 If alias is not None, it is the name of another group type | |
| 477 which aliases this type; just generate that alias.""" | |
| 478 OutputGenerator.genGroup(self, groupinfo, groupName, alias) | |
| 479 groupElem = groupinfo.elem | |
| 480 | |
| 481 # After either enumerated type or alias paths, add the declaration | |
| 482 # to the appropriate section for the group being defined. | |
| 483 if groupElem.get('type') == 'bitmask': | |
| 484 section = 'bitmask' | |
| 485 else: | |
| 486 section = 'group' | |
| 487 | |
| 488 if alias: | |
| 489 # If the group name is aliased, just emit a typedef declaration | |
| 490 # for the alias. | |
| 491 body = f"typedef {alias} {groupName};\n" | |
| 492 self.appendSection(section, body) | |
| 493 else: | |
| 494 if self.genOpts is None: | |
| 495 raise MissingGeneratorOptionsError() | |
| 496 (section, body) = self.buildEnumCDecl(self.genOpts.genEnumBeginEndRange, groupinfo, groupName) | |
| 497 self.appendSection(section, f"\n{body}") | |
| 498 | |
| 499 def genEnum(self, enuminfo, name, alias): | |
| 500 """Generate the C declaration for a constant (a single <enum> value). | |
| 501 | |
| 502 <enum> tags may specify their values in several ways, but are usually | |
| 503 just integers.""" | |
| 504 | |
| 505 OutputGenerator.genEnum(self, enuminfo, name, alias) | |
| 506 | |
| 507 body = self.deprecationComment(enuminfo.elem) | |
| 508 body += self.buildConstantCDecl(enuminfo, name, alias) | |
| 509 self.appendSection('enum', body) | |
| 510 | |
| 511 def genCmd(self, cmdinfo, name, alias): | |
| 512 "Command generation" | |
| 513 OutputGenerator.genCmd(self, cmdinfo, name, alias) | |
| 514 | |
| 515 # if alias: | |
| 516 # prefix = '// ' + name + ' is an alias of command ' + alias + '\n' | |
| 517 # else: | |
| 518 # prefix = '' | |
| 519 if self.genOpts is None: | |
| 520 raise MissingGeneratorOptionsError() | |
| 521 | |
| 522 prefix = '' | |
| 523 decls = self.makeCDecls(cmdinfo.elem) | |
| 524 | |
| 525 # If the 'export' attribute is not set for this command, or does not | |
| 526 # match the export name selected during generation, wrap the command | |
| 527 # prototype in a C conditional which can be enabled to make the | |
| 528 # prototype not appear at compile time. | |
| 529 | |
| 530 export = cmdinfo.elem.get('export','') | |
| 531 protect_prefix = protect_suffix = '' | |
| 532 if export is None or self.genOpts.protectExportName not in export.split(','): | |
| 533 if self.genOpts.protectExportProtoStr is not None: | |
| 534 # Command is not exported, so should not be visible if | |
| 535 # suppressed by this symbol | |
| 536 protect_prefix = f'#ifndef {self.genOpts.protectExportProtoStr}\n' | |
| 537 protect_suffix = '\n#endif' | |
| 538 | |
| 539 decls[0] = protect_prefix + decls[0] + protect_suffix | |
| 540 | |
| 541 self.appendSection('command', f"{prefix + decls[0]}\n") | |
| 542 if self.genOpts.genFuncPointers: | |
| 543 self.appendSection('commandPointer', decls[1]) | |
| 544 | |
| 545 def misracstyle(self): | |
| 546 return self.genOpts.misracstyle | |
| 547 | |
| 548 def misracppstyle(self): | |
| 549 return self.genOpts.misracppstyle |
