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