1e8556ba3Sopenharmony_ci#!/usr/bin/python3 -i 2e8556ba3Sopenharmony_ci# 3e8556ba3Sopenharmony_ci# Copyright 2013-2024 The Khronos Group Inc. 4e8556ba3Sopenharmony_ci# 5e8556ba3Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0 6e8556ba3Sopenharmony_ci 7e8556ba3Sopenharmony_ci# Base class for working-group-specific style conventions, 8e8556ba3Sopenharmony_ci# used in generation. 9e8556ba3Sopenharmony_ci 10e8556ba3Sopenharmony_cifrom enum import Enum 11e8556ba3Sopenharmony_ciimport abc 12e8556ba3Sopenharmony_ciimport re 13e8556ba3Sopenharmony_ci 14e8556ba3Sopenharmony_ci# Type categories that respond "False" to isStructAlwaysValid 15e8556ba3Sopenharmony_ci# basetype is home to typedefs like ..Bool32 16e8556ba3Sopenharmony_ciCATEGORIES_REQUIRING_VALIDATION = set(('handle', 17e8556ba3Sopenharmony_ci 'enum', 18e8556ba3Sopenharmony_ci 'bitmask', 19e8556ba3Sopenharmony_ci 'basetype', 20e8556ba3Sopenharmony_ci None)) 21e8556ba3Sopenharmony_ci 22e8556ba3Sopenharmony_ci# These are basic C types pulled in via openxr_platform_defines.h 23e8556ba3Sopenharmony_ciTYPES_KNOWN_ALWAYS_VALID = set(('char', 24e8556ba3Sopenharmony_ci 'float', 25e8556ba3Sopenharmony_ci 'int8_t', 'uint8_t', 26e8556ba3Sopenharmony_ci 'int16_t', 'uint16_t', 27e8556ba3Sopenharmony_ci 'int32_t', 'uint32_t', 28e8556ba3Sopenharmony_ci 'int64_t', 'uint64_t', 29e8556ba3Sopenharmony_ci 'size_t', 30e8556ba3Sopenharmony_ci 'intptr_t', 'uintptr_t', 31e8556ba3Sopenharmony_ci 'int', 32e8556ba3Sopenharmony_ci )) 33e8556ba3Sopenharmony_ci 34e8556ba3Sopenharmony_ci# Split an extension name into vendor ID and name portions 35e8556ba3Sopenharmony_ciEXT_NAME_DECOMPOSE_RE = re.compile(r'(?P<prefix>[A-Za-z]+)_(?P<vendor>[A-Za-z]+)_(?P<name>[\w_]+)') 36e8556ba3Sopenharmony_ci 37e8556ba3Sopenharmony_ci# Match an API version name. 38e8556ba3Sopenharmony_ci# Match object includes API prefix, major, and minor version numbers. 39e8556ba3Sopenharmony_ci# This could be refined further for specific APIs. 40e8556ba3Sopenharmony_ciAPI_VERSION_NAME_RE = re.compile(r'(?P<apivariant>[A-Za-z]+)_VERSION_(?P<major>[0-9]+)_(?P<minor>[0-9]+)') 41e8556ba3Sopenharmony_ci 42e8556ba3Sopenharmony_ciclass ProseListFormats(Enum): 43e8556ba3Sopenharmony_ci """A connective, possibly with a quantifier.""" 44e8556ba3Sopenharmony_ci AND = 0 45e8556ba3Sopenharmony_ci EACH_AND = 1 46e8556ba3Sopenharmony_ci OR = 2 47e8556ba3Sopenharmony_ci ANY_OR = 3 48e8556ba3Sopenharmony_ci 49e8556ba3Sopenharmony_ci @classmethod 50e8556ba3Sopenharmony_ci def from_string(cls, s): 51e8556ba3Sopenharmony_ci if s == 'or': 52e8556ba3Sopenharmony_ci return cls.OR 53e8556ba3Sopenharmony_ci if s == 'and': 54e8556ba3Sopenharmony_ci return cls.AND 55e8556ba3Sopenharmony_ci raise RuntimeError("Unrecognized string connective: " + s) 56e8556ba3Sopenharmony_ci 57e8556ba3Sopenharmony_ci @property 58e8556ba3Sopenharmony_ci def connective(self): 59e8556ba3Sopenharmony_ci if self in (ProseListFormats.OR, ProseListFormats.ANY_OR): 60e8556ba3Sopenharmony_ci return 'or' 61e8556ba3Sopenharmony_ci return 'and' 62e8556ba3Sopenharmony_ci 63e8556ba3Sopenharmony_ci def quantifier(self, n): 64e8556ba3Sopenharmony_ci """Return the desired quantifier for a list of a given length.""" 65e8556ba3Sopenharmony_ci if self == ProseListFormats.ANY_OR: 66e8556ba3Sopenharmony_ci if n > 1: 67e8556ba3Sopenharmony_ci return 'any of ' 68e8556ba3Sopenharmony_ci elif self == ProseListFormats.EACH_AND: 69e8556ba3Sopenharmony_ci if n > 2: 70e8556ba3Sopenharmony_ci return 'each of ' 71e8556ba3Sopenharmony_ci if n == 2: 72e8556ba3Sopenharmony_ci return 'both of ' 73e8556ba3Sopenharmony_ci return '' 74e8556ba3Sopenharmony_ci 75e8556ba3Sopenharmony_ci 76e8556ba3Sopenharmony_ciclass ConventionsBase(abc.ABC): 77e8556ba3Sopenharmony_ci """WG-specific conventions.""" 78e8556ba3Sopenharmony_ci 79e8556ba3Sopenharmony_ci def __init__(self): 80e8556ba3Sopenharmony_ci self._command_prefix = None 81e8556ba3Sopenharmony_ci self._type_prefix = None 82e8556ba3Sopenharmony_ci 83e8556ba3Sopenharmony_ci def formatVersionOrExtension(self, name): 84e8556ba3Sopenharmony_ci """Mark up an API version or extension name as a link in the spec.""" 85e8556ba3Sopenharmony_ci 86e8556ba3Sopenharmony_ci # Is this a version name? 87e8556ba3Sopenharmony_ci match = API_VERSION_NAME_RE.match(name) 88e8556ba3Sopenharmony_ci if match is not None: 89e8556ba3Sopenharmony_ci return self.formatVersion(name, 90e8556ba3Sopenharmony_ci match.group('apivariant'), 91e8556ba3Sopenharmony_ci match.group('major'), 92e8556ba3Sopenharmony_ci match.group('minor')) 93e8556ba3Sopenharmony_ci else: 94e8556ba3Sopenharmony_ci # If not, assumed to be an extension name. Might be worth checking. 95e8556ba3Sopenharmony_ci return self.formatExtension(name) 96e8556ba3Sopenharmony_ci 97e8556ba3Sopenharmony_ci def formatVersion(self, name, apivariant, major, minor): 98e8556ba3Sopenharmony_ci """Mark up an API version name as a link in the spec.""" 99e8556ba3Sopenharmony_ci return '`<<{}>>`'.format(name) 100e8556ba3Sopenharmony_ci 101e8556ba3Sopenharmony_ci def formatExtension(self, name): 102e8556ba3Sopenharmony_ci """Mark up an extension name as a link in the spec.""" 103e8556ba3Sopenharmony_ci return '`<<{}>>`'.format(name) 104e8556ba3Sopenharmony_ci 105e8556ba3Sopenharmony_ci def formatSPIRVlink(self, name): 106e8556ba3Sopenharmony_ci """Mark up a SPIR-V extension name as an external link in the spec. 107e8556ba3Sopenharmony_ci Since these are external links, the formatting probably will be 108e8556ba3Sopenharmony_ci the same for all APIs creating such links, so long as they use 109e8556ba3Sopenharmony_ci the asciidoctor {spirv} attribute for the base path to the SPIR-V 110e8556ba3Sopenharmony_ci extensions.""" 111e8556ba3Sopenharmony_ci 112e8556ba3Sopenharmony_ci (vendor, _) = self.extension_name_split(name) 113e8556ba3Sopenharmony_ci 114e8556ba3Sopenharmony_ci return f'{{spirv}}/{vendor}/{name}.html[{name}]' 115e8556ba3Sopenharmony_ci 116e8556ba3Sopenharmony_ci @property 117e8556ba3Sopenharmony_ci @abc.abstractmethod 118e8556ba3Sopenharmony_ci def null(self): 119e8556ba3Sopenharmony_ci """Preferred spelling of NULL.""" 120e8556ba3Sopenharmony_ci raise NotImplementedError 121e8556ba3Sopenharmony_ci 122e8556ba3Sopenharmony_ci def makeProseList(self, elements, fmt=ProseListFormats.AND, with_verb=False, *args, **kwargs): 123e8556ba3Sopenharmony_ci """Make a (comma-separated) list for use in prose. 124e8556ba3Sopenharmony_ci 125e8556ba3Sopenharmony_ci Adds a connective (by default, 'and') 126e8556ba3Sopenharmony_ci before the last element if there are more than 1. 127e8556ba3Sopenharmony_ci 128e8556ba3Sopenharmony_ci Adds the right one of "is" or "are" to the end if with_verb is true. 129e8556ba3Sopenharmony_ci 130e8556ba3Sopenharmony_ci Optionally adds a quantifier (like 'any') before a list of 2 or more, 131e8556ba3Sopenharmony_ci if specified by fmt. 132e8556ba3Sopenharmony_ci 133e8556ba3Sopenharmony_ci Override with a different method or different call to 134e8556ba3Sopenharmony_ci _implMakeProseList if you want to add a comma for two elements, 135e8556ba3Sopenharmony_ci or not use a serial comma. 136e8556ba3Sopenharmony_ci """ 137e8556ba3Sopenharmony_ci return self._implMakeProseList(elements, fmt, with_verb, *args, **kwargs) 138e8556ba3Sopenharmony_ci 139e8556ba3Sopenharmony_ci @property 140e8556ba3Sopenharmony_ci def struct_macro(self): 141e8556ba3Sopenharmony_ci """Get the appropriate format macro for a structure. 142e8556ba3Sopenharmony_ci 143e8556ba3Sopenharmony_ci May override. 144e8556ba3Sopenharmony_ci """ 145e8556ba3Sopenharmony_ci return 'slink:' 146e8556ba3Sopenharmony_ci 147e8556ba3Sopenharmony_ci @property 148e8556ba3Sopenharmony_ci def external_macro(self): 149e8556ba3Sopenharmony_ci """Get the appropriate format macro for an external type like uint32_t. 150e8556ba3Sopenharmony_ci 151e8556ba3Sopenharmony_ci May override. 152e8556ba3Sopenharmony_ci """ 153e8556ba3Sopenharmony_ci return 'code:' 154e8556ba3Sopenharmony_ci 155e8556ba3Sopenharmony_ci @property 156e8556ba3Sopenharmony_ci @abc.abstractmethod 157e8556ba3Sopenharmony_ci def structtype_member_name(self): 158e8556ba3Sopenharmony_ci """Return name of the structure type member. 159e8556ba3Sopenharmony_ci 160e8556ba3Sopenharmony_ci Must implement. 161e8556ba3Sopenharmony_ci """ 162e8556ba3Sopenharmony_ci raise NotImplementedError() 163e8556ba3Sopenharmony_ci 164e8556ba3Sopenharmony_ci @property 165e8556ba3Sopenharmony_ci @abc.abstractmethod 166e8556ba3Sopenharmony_ci def nextpointer_member_name(self): 167e8556ba3Sopenharmony_ci """Return name of the structure pointer chain member. 168e8556ba3Sopenharmony_ci 169e8556ba3Sopenharmony_ci Must implement. 170e8556ba3Sopenharmony_ci """ 171e8556ba3Sopenharmony_ci raise NotImplementedError() 172e8556ba3Sopenharmony_ci 173e8556ba3Sopenharmony_ci @property 174e8556ba3Sopenharmony_ci @abc.abstractmethod 175e8556ba3Sopenharmony_ci def xml_api_name(self): 176e8556ba3Sopenharmony_ci """Return the name used in the default API XML registry for the default API""" 177e8556ba3Sopenharmony_ci raise NotImplementedError() 178e8556ba3Sopenharmony_ci 179e8556ba3Sopenharmony_ci @abc.abstractmethod 180e8556ba3Sopenharmony_ci def generate_structure_type_from_name(self, structname): 181e8556ba3Sopenharmony_ci """Generate a structure type name, like XR_TYPE_CREATE_INSTANCE_INFO. 182e8556ba3Sopenharmony_ci 183e8556ba3Sopenharmony_ci Must implement. 184e8556ba3Sopenharmony_ci """ 185e8556ba3Sopenharmony_ci raise NotImplementedError() 186e8556ba3Sopenharmony_ci 187e8556ba3Sopenharmony_ci def makeStructName(self, name): 188e8556ba3Sopenharmony_ci """Prepend the appropriate format macro for a structure to a structure type name. 189e8556ba3Sopenharmony_ci 190e8556ba3Sopenharmony_ci Uses struct_macro, so just override that if you want to change behavior. 191e8556ba3Sopenharmony_ci """ 192e8556ba3Sopenharmony_ci return self.struct_macro + name 193e8556ba3Sopenharmony_ci 194e8556ba3Sopenharmony_ci def makeExternalTypeName(self, name): 195e8556ba3Sopenharmony_ci """Prepend the appropriate format macro for an external type like uint32_t to a type name. 196e8556ba3Sopenharmony_ci 197e8556ba3Sopenharmony_ci Uses external_macro, so just override that if you want to change behavior. 198e8556ba3Sopenharmony_ci """ 199e8556ba3Sopenharmony_ci return self.external_macro + name 200e8556ba3Sopenharmony_ci 201e8556ba3Sopenharmony_ci def _implMakeProseList(self, elements, fmt, with_verb, comma_for_two_elts=False, serial_comma=True): 202e8556ba3Sopenharmony_ci """Internal-use implementation to make a (comma-separated) list for use in prose. 203e8556ba3Sopenharmony_ci 204e8556ba3Sopenharmony_ci Adds a connective (by default, 'and') 205e8556ba3Sopenharmony_ci before the last element if there are more than 1, 206e8556ba3Sopenharmony_ci and only includes commas if there are more than 2 207e8556ba3Sopenharmony_ci (if comma_for_two_elts is False). 208e8556ba3Sopenharmony_ci 209e8556ba3Sopenharmony_ci Adds the right one of "is" or "are" to the end if with_verb is true. 210e8556ba3Sopenharmony_ci 211e8556ba3Sopenharmony_ci Optionally adds a quantifier (like 'any') before a list of 2 or more, 212e8556ba3Sopenharmony_ci if specified by fmt. 213e8556ba3Sopenharmony_ci 214e8556ba3Sopenharmony_ci Do not edit these defaults, override self.makeProseList(). 215e8556ba3Sopenharmony_ci """ 216e8556ba3Sopenharmony_ci assert(serial_comma) # did not implement what we did not need 217e8556ba3Sopenharmony_ci if isinstance(fmt, str): 218e8556ba3Sopenharmony_ci fmt = ProseListFormats.from_string(fmt) 219e8556ba3Sopenharmony_ci 220e8556ba3Sopenharmony_ci my_elts = list(elements) 221e8556ba3Sopenharmony_ci if len(my_elts) > 1: 222e8556ba3Sopenharmony_ci my_elts[-1] = '{} {}'.format(fmt.connective, my_elts[-1]) 223e8556ba3Sopenharmony_ci 224e8556ba3Sopenharmony_ci if not comma_for_two_elts and len(my_elts) <= 2: 225e8556ba3Sopenharmony_ci prose = ' '.join(my_elts) 226e8556ba3Sopenharmony_ci else: 227e8556ba3Sopenharmony_ci prose = ', '.join(my_elts) 228e8556ba3Sopenharmony_ci 229e8556ba3Sopenharmony_ci quantifier = fmt.quantifier(len(my_elts)) 230e8556ba3Sopenharmony_ci 231e8556ba3Sopenharmony_ci parts = [quantifier, prose] 232e8556ba3Sopenharmony_ci 233e8556ba3Sopenharmony_ci if with_verb: 234e8556ba3Sopenharmony_ci if len(my_elts) > 1: 235e8556ba3Sopenharmony_ci parts.append(' are') 236e8556ba3Sopenharmony_ci else: 237e8556ba3Sopenharmony_ci parts.append(' is') 238e8556ba3Sopenharmony_ci return ''.join(parts) 239e8556ba3Sopenharmony_ci 240e8556ba3Sopenharmony_ci @property 241e8556ba3Sopenharmony_ci @abc.abstractmethod 242e8556ba3Sopenharmony_ci def file_suffix(self): 243e8556ba3Sopenharmony_ci """Return suffix of generated Asciidoctor files""" 244e8556ba3Sopenharmony_ci raise NotImplementedError 245e8556ba3Sopenharmony_ci 246e8556ba3Sopenharmony_ci @abc.abstractmethod 247e8556ba3Sopenharmony_ci def api_name(self, spectype=None): 248e8556ba3Sopenharmony_ci """Return API or specification name for citations in ref pages. 249e8556ba3Sopenharmony_ci 250e8556ba3Sopenharmony_ci spectype is the spec this refpage is for. 251e8556ba3Sopenharmony_ci 'api' (the default value) is the main API Specification. 252e8556ba3Sopenharmony_ci If an unrecognized spectype is given, returns None. 253e8556ba3Sopenharmony_ci 254e8556ba3Sopenharmony_ci Must implement.""" 255e8556ba3Sopenharmony_ci raise NotImplementedError 256e8556ba3Sopenharmony_ci 257e8556ba3Sopenharmony_ci def should_insert_may_alias_macro(self, genOpts): 258e8556ba3Sopenharmony_ci """Return true if we should insert a "may alias" macro in this file. 259e8556ba3Sopenharmony_ci 260e8556ba3Sopenharmony_ci Only used by OpenXR right now.""" 261e8556ba3Sopenharmony_ci return False 262e8556ba3Sopenharmony_ci 263e8556ba3Sopenharmony_ci @property 264e8556ba3Sopenharmony_ci def command_prefix(self): 265e8556ba3Sopenharmony_ci """Return the expected prefix of commands/functions. 266e8556ba3Sopenharmony_ci 267e8556ba3Sopenharmony_ci Implemented in terms of api_prefix.""" 268e8556ba3Sopenharmony_ci if not self._command_prefix: 269e8556ba3Sopenharmony_ci self._command_prefix = self.api_prefix[:].replace('_', '').lower() 270e8556ba3Sopenharmony_ci return self._command_prefix 271e8556ba3Sopenharmony_ci 272e8556ba3Sopenharmony_ci @property 273e8556ba3Sopenharmony_ci def type_prefix(self): 274e8556ba3Sopenharmony_ci """Return the expected prefix of type names. 275e8556ba3Sopenharmony_ci 276e8556ba3Sopenharmony_ci Implemented in terms of command_prefix (and in turn, api_prefix).""" 277e8556ba3Sopenharmony_ci if not self._type_prefix: 278e8556ba3Sopenharmony_ci self._type_prefix = ''.join( 279e8556ba3Sopenharmony_ci (self.command_prefix[0:1].upper(), self.command_prefix[1:])) 280e8556ba3Sopenharmony_ci return self._type_prefix 281e8556ba3Sopenharmony_ci 282e8556ba3Sopenharmony_ci @property 283e8556ba3Sopenharmony_ci @abc.abstractmethod 284e8556ba3Sopenharmony_ci def api_prefix(self): 285e8556ba3Sopenharmony_ci """Return API token prefix. 286e8556ba3Sopenharmony_ci 287e8556ba3Sopenharmony_ci Typically two uppercase letters followed by an underscore. 288e8556ba3Sopenharmony_ci 289e8556ba3Sopenharmony_ci Must implement.""" 290e8556ba3Sopenharmony_ci raise NotImplementedError 291e8556ba3Sopenharmony_ci 292e8556ba3Sopenharmony_ci @property 293e8556ba3Sopenharmony_ci def extension_name_prefix(self): 294e8556ba3Sopenharmony_ci """Return extension name prefix. 295e8556ba3Sopenharmony_ci 296e8556ba3Sopenharmony_ci Typically two uppercase letters followed by an underscore. 297e8556ba3Sopenharmony_ci 298e8556ba3Sopenharmony_ci Assumed to be the same as api_prefix, but some APIs use different 299e8556ba3Sopenharmony_ci case conventions.""" 300e8556ba3Sopenharmony_ci 301e8556ba3Sopenharmony_ci return self.api_prefix 302e8556ba3Sopenharmony_ci 303e8556ba3Sopenharmony_ci @property 304e8556ba3Sopenharmony_ci def write_contacts(self): 305e8556ba3Sopenharmony_ci """Return whether contact list should be written to extension appendices""" 306e8556ba3Sopenharmony_ci return False 307e8556ba3Sopenharmony_ci 308e8556ba3Sopenharmony_ci @property 309e8556ba3Sopenharmony_ci def write_extension_type(self): 310e8556ba3Sopenharmony_ci """Return whether extension type should be written to extension appendices""" 311e8556ba3Sopenharmony_ci return True 312e8556ba3Sopenharmony_ci 313e8556ba3Sopenharmony_ci @property 314e8556ba3Sopenharmony_ci def write_extension_number(self): 315e8556ba3Sopenharmony_ci """Return whether extension number should be written to extension appendices""" 316e8556ba3Sopenharmony_ci return True 317e8556ba3Sopenharmony_ci 318e8556ba3Sopenharmony_ci @property 319e8556ba3Sopenharmony_ci def write_extension_revision(self): 320e8556ba3Sopenharmony_ci """Return whether extension revision number should be written to extension appendices""" 321e8556ba3Sopenharmony_ci return True 322e8556ba3Sopenharmony_ci 323e8556ba3Sopenharmony_ci @property 324e8556ba3Sopenharmony_ci def write_refpage_include(self): 325e8556ba3Sopenharmony_ci """Return whether refpage include should be written to extension appendices""" 326e8556ba3Sopenharmony_ci return True 327e8556ba3Sopenharmony_ci 328e8556ba3Sopenharmony_ci @property 329e8556ba3Sopenharmony_ci def api_version_prefix(self): 330e8556ba3Sopenharmony_ci """Return API core version token prefix. 331e8556ba3Sopenharmony_ci 332e8556ba3Sopenharmony_ci Implemented in terms of api_prefix. 333e8556ba3Sopenharmony_ci 334e8556ba3Sopenharmony_ci May override.""" 335e8556ba3Sopenharmony_ci return self.api_prefix + 'VERSION_' 336e8556ba3Sopenharmony_ci 337e8556ba3Sopenharmony_ci @property 338e8556ba3Sopenharmony_ci def KHR_prefix(self): 339e8556ba3Sopenharmony_ci """Return extension name prefix for KHR extensions. 340e8556ba3Sopenharmony_ci 341e8556ba3Sopenharmony_ci Implemented in terms of api_prefix. 342e8556ba3Sopenharmony_ci 343e8556ba3Sopenharmony_ci May override.""" 344e8556ba3Sopenharmony_ci return self.api_prefix + 'KHR_' 345e8556ba3Sopenharmony_ci 346e8556ba3Sopenharmony_ci @property 347e8556ba3Sopenharmony_ci def EXT_prefix(self): 348e8556ba3Sopenharmony_ci """Return extension name prefix for EXT extensions. 349e8556ba3Sopenharmony_ci 350e8556ba3Sopenharmony_ci Implemented in terms of api_prefix. 351e8556ba3Sopenharmony_ci 352e8556ba3Sopenharmony_ci May override.""" 353e8556ba3Sopenharmony_ci return self.api_prefix + 'EXT_' 354e8556ba3Sopenharmony_ci 355e8556ba3Sopenharmony_ci def writeFeature(self, featureExtraProtect, filename): 356e8556ba3Sopenharmony_ci """Return True if OutputGenerator.endFeature should write this feature. 357e8556ba3Sopenharmony_ci 358e8556ba3Sopenharmony_ci Defaults to always True. 359e8556ba3Sopenharmony_ci Used in COutputGenerator. 360e8556ba3Sopenharmony_ci 361e8556ba3Sopenharmony_ci May override.""" 362e8556ba3Sopenharmony_ci return True 363e8556ba3Sopenharmony_ci 364e8556ba3Sopenharmony_ci def requires_error_validation(self, return_type): 365e8556ba3Sopenharmony_ci """Return True if the return_type element is an API result code 366e8556ba3Sopenharmony_ci requiring error validation. 367e8556ba3Sopenharmony_ci 368e8556ba3Sopenharmony_ci Defaults to always False. 369e8556ba3Sopenharmony_ci 370e8556ba3Sopenharmony_ci May override.""" 371e8556ba3Sopenharmony_ci return False 372e8556ba3Sopenharmony_ci 373e8556ba3Sopenharmony_ci @property 374e8556ba3Sopenharmony_ci def required_errors(self): 375e8556ba3Sopenharmony_ci """Return a list of required error codes for validation. 376e8556ba3Sopenharmony_ci 377e8556ba3Sopenharmony_ci Defaults to an empty list. 378e8556ba3Sopenharmony_ci 379e8556ba3Sopenharmony_ci May override.""" 380e8556ba3Sopenharmony_ci return [] 381e8556ba3Sopenharmony_ci 382e8556ba3Sopenharmony_ci def is_voidpointer_alias(self, tag, text, tail): 383e8556ba3Sopenharmony_ci """Return True if the declaration components (tag,text,tail) of an 384e8556ba3Sopenharmony_ci element represents a void * type. 385e8556ba3Sopenharmony_ci 386e8556ba3Sopenharmony_ci Defaults to a reasonable implementation. 387e8556ba3Sopenharmony_ci 388e8556ba3Sopenharmony_ci May override.""" 389e8556ba3Sopenharmony_ci return tag == 'type' and text == 'void' and tail.startswith('*') 390e8556ba3Sopenharmony_ci 391e8556ba3Sopenharmony_ci def make_voidpointer_alias(self, tail): 392e8556ba3Sopenharmony_ci """Reformat a void * declaration to include the API alias macro. 393e8556ba3Sopenharmony_ci 394e8556ba3Sopenharmony_ci Defaults to a no-op. 395e8556ba3Sopenharmony_ci 396e8556ba3Sopenharmony_ci Must override if you actually want to use this feature in your project.""" 397e8556ba3Sopenharmony_ci return tail 398e8556ba3Sopenharmony_ci 399e8556ba3Sopenharmony_ci def category_requires_validation(self, category): 400e8556ba3Sopenharmony_ci """Return True if the given type 'category' always requires validation. 401e8556ba3Sopenharmony_ci 402e8556ba3Sopenharmony_ci Defaults to a reasonable implementation. 403e8556ba3Sopenharmony_ci 404e8556ba3Sopenharmony_ci May override.""" 405e8556ba3Sopenharmony_ci return category in CATEGORIES_REQUIRING_VALIDATION 406e8556ba3Sopenharmony_ci 407e8556ba3Sopenharmony_ci def type_always_valid(self, typename): 408e8556ba3Sopenharmony_ci """Return True if the given type name is always valid (never requires validation). 409e8556ba3Sopenharmony_ci 410e8556ba3Sopenharmony_ci This is for things like integers. 411e8556ba3Sopenharmony_ci 412e8556ba3Sopenharmony_ci Defaults to a reasonable implementation. 413e8556ba3Sopenharmony_ci 414e8556ba3Sopenharmony_ci May override.""" 415e8556ba3Sopenharmony_ci return typename in TYPES_KNOWN_ALWAYS_VALID 416e8556ba3Sopenharmony_ci 417e8556ba3Sopenharmony_ci @property 418e8556ba3Sopenharmony_ci def should_skip_checking_codes(self): 419e8556ba3Sopenharmony_ci """Return True if more than the basic validation of return codes should 420e8556ba3Sopenharmony_ci be skipped for a command.""" 421e8556ba3Sopenharmony_ci 422e8556ba3Sopenharmony_ci return False 423e8556ba3Sopenharmony_ci 424e8556ba3Sopenharmony_ci @property 425e8556ba3Sopenharmony_ci def generate_index_terms(self): 426e8556ba3Sopenharmony_ci """Return True if asiidoctor index terms should be generated as part 427e8556ba3Sopenharmony_ci of an API interface from the docgenerator.""" 428e8556ba3Sopenharmony_ci 429e8556ba3Sopenharmony_ci return False 430e8556ba3Sopenharmony_ci 431e8556ba3Sopenharmony_ci @property 432e8556ba3Sopenharmony_ci def generate_enum_table(self): 433e8556ba3Sopenharmony_ci """Return True if asciidoctor tables describing enumerants in a 434e8556ba3Sopenharmony_ci group should be generated as part of group generation.""" 435e8556ba3Sopenharmony_ci return False 436e8556ba3Sopenharmony_ci 437e8556ba3Sopenharmony_ci @property 438e8556ba3Sopenharmony_ci def generate_max_enum_in_docs(self): 439e8556ba3Sopenharmony_ci """Return True if MAX_ENUM tokens should be generated in 440e8556ba3Sopenharmony_ci documentation includes.""" 441e8556ba3Sopenharmony_ci return False 442e8556ba3Sopenharmony_ci 443e8556ba3Sopenharmony_ci def extension_name_split(self, name): 444e8556ba3Sopenharmony_ci """Split an extension name, returning (vendor, rest of name). 445e8556ba3Sopenharmony_ci The API prefix of the name is ignored.""" 446e8556ba3Sopenharmony_ci 447e8556ba3Sopenharmony_ci match = EXT_NAME_DECOMPOSE_RE.match(name) 448e8556ba3Sopenharmony_ci vendor = match.group('vendor') 449e8556ba3Sopenharmony_ci bare_name = match.group('name') 450e8556ba3Sopenharmony_ci 451e8556ba3Sopenharmony_ci return (vendor, bare_name) 452e8556ba3Sopenharmony_ci 453e8556ba3Sopenharmony_ci @abc.abstractmethod 454e8556ba3Sopenharmony_ci def extension_file_path(self, name): 455e8556ba3Sopenharmony_ci """Return file path to an extension appendix relative to a directory 456e8556ba3Sopenharmony_ci containing all such appendices. 457e8556ba3Sopenharmony_ci - name - extension name 458e8556ba3Sopenharmony_ci 459e8556ba3Sopenharmony_ci Must implement.""" 460e8556ba3Sopenharmony_ci raise NotImplementedError 461e8556ba3Sopenharmony_ci 462e8556ba3Sopenharmony_ci def extension_include_string(self, name): 463e8556ba3Sopenharmony_ci """Return format string for include:: line for an extension appendix 464e8556ba3Sopenharmony_ci file. 465e8556ba3Sopenharmony_ci - name - extension name""" 466e8556ba3Sopenharmony_ci 467e8556ba3Sopenharmony_ci return 'include::{{appendices}}/{}[]'.format( 468e8556ba3Sopenharmony_ci self.extension_file_path(name)) 469e8556ba3Sopenharmony_ci 470e8556ba3Sopenharmony_ci @property 471e8556ba3Sopenharmony_ci def provisional_extension_warning(self): 472e8556ba3Sopenharmony_ci """Return True if a warning should be included in extension 473e8556ba3Sopenharmony_ci appendices for provisional extensions.""" 474e8556ba3Sopenharmony_ci return True 475e8556ba3Sopenharmony_ci 476e8556ba3Sopenharmony_ci @property 477e8556ba3Sopenharmony_ci def generated_include_path(self): 478e8556ba3Sopenharmony_ci """Return path relative to the generated reference pages, to the 479e8556ba3Sopenharmony_ci generated API include files.""" 480e8556ba3Sopenharmony_ci 481e8556ba3Sopenharmony_ci return '{generated}' 482e8556ba3Sopenharmony_ci 483e8556ba3Sopenharmony_ci @property 484e8556ba3Sopenharmony_ci def include_extension_appendix_in_refpage(self): 485e8556ba3Sopenharmony_ci """Return True if generating extension refpages by embedding 486e8556ba3Sopenharmony_ci extension appendix content (default), False otherwise 487e8556ba3Sopenharmony_ci (OpenXR).""" 488e8556ba3Sopenharmony_ci 489e8556ba3Sopenharmony_ci return True 490e8556ba3Sopenharmony_ci 491e8556ba3Sopenharmony_ci def valid_flag_bit(self, bitpos): 492e8556ba3Sopenharmony_ci """Return True if bitpos is an allowed numeric bit position for 493e8556ba3Sopenharmony_ci an API flag. 494e8556ba3Sopenharmony_ci 495e8556ba3Sopenharmony_ci Behavior depends on the data type used for flags (which may be 32 496e8556ba3Sopenharmony_ci or 64 bits), and may depend on assumptions about compiler 497e8556ba3Sopenharmony_ci handling of sign bits in enumerated types, as well.""" 498e8556ba3Sopenharmony_ci return True 499e8556ba3Sopenharmony_ci 500e8556ba3Sopenharmony_ci @property 501e8556ba3Sopenharmony_ci def duplicate_aliased_structs(self): 502e8556ba3Sopenharmony_ci """ 503e8556ba3Sopenharmony_ci Should aliased structs have the original struct definition listed in the 504e8556ba3Sopenharmony_ci generated docs snippet? 505e8556ba3Sopenharmony_ci """ 506e8556ba3Sopenharmony_ci return False 507e8556ba3Sopenharmony_ci 508e8556ba3Sopenharmony_ci @property 509e8556ba3Sopenharmony_ci def protectProtoComment(self): 510e8556ba3Sopenharmony_ci """Return True if generated #endif should have a comment matching 511e8556ba3Sopenharmony_ci the protection symbol used in the opening #ifdef/#ifndef.""" 512e8556ba3Sopenharmony_ci return False 513e8556ba3Sopenharmony_ci 514e8556ba3Sopenharmony_ci @property 515e8556ba3Sopenharmony_ci def extra_refpage_headers(self): 516e8556ba3Sopenharmony_ci """Return any extra headers (preceding the title) for generated 517e8556ba3Sopenharmony_ci reference pages.""" 518e8556ba3Sopenharmony_ci return '' 519e8556ba3Sopenharmony_ci 520e8556ba3Sopenharmony_ci @property 521e8556ba3Sopenharmony_ci def extra_refpage_body(self): 522e8556ba3Sopenharmony_ci """Return any extra text (following the title) for generated 523e8556ba3Sopenharmony_ci reference pages.""" 524e8556ba3Sopenharmony_ci return '' 525e8556ba3Sopenharmony_ci 526e8556ba3Sopenharmony_ci def is_api_version_name(self, name): 527e8556ba3Sopenharmony_ci """Return True if name is an API version name.""" 528e8556ba3Sopenharmony_ci 529e8556ba3Sopenharmony_ci return API_VERSION_NAME_RE.match(name) is not None 530e8556ba3Sopenharmony_ci 531e8556ba3Sopenharmony_ci @property 532e8556ba3Sopenharmony_ci def docgen_language(self): 533e8556ba3Sopenharmony_ci """Return the language to be used in docgenerator [source] 534e8556ba3Sopenharmony_ci blocks.""" 535e8556ba3Sopenharmony_ci 536e8556ba3Sopenharmony_ci return 'c++' 537