1#!/usr/bin/python3 -i 2# 3# Copyright (c) 2013-2019 The Khronos Group Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17# Working-group-specific style conventions, 18# used in generation. 19 20import re 21 22from conventions import ConventionsBase 23 24 25# Modified from default implementation - see category_requires_validation() below 26CATEGORIES_REQUIRING_VALIDATION = set(('handle', 'enum', 'bitmask')) 27 28 29class VulkanConventions(ConventionsBase): 30 def formatExtension(self, name): 31 """Mark up a name as an extension for the spec.""" 32 return '`<<{}>>`'.format(name) 33 34 @property 35 def null(self): 36 """Preferred spelling of NULL.""" 37 return '`NULL`' 38 39 @property 40 def constFlagBits(self): 41 """Returns True if static const flag bits should be generated, False if an enumerated type should be generated.""" 42 return False 43 44 @property 45 def structtype_member_name(self): 46 """Return name of the structure type member""" 47 return 'sType' 48 49 @property 50 def nextpointer_member_name(self): 51 """Return name of the structure pointer chain member""" 52 return 'pNext' 53 54 @property 55 def valid_pointer_prefix(self): 56 """Return prefix to pointers which must themselves be valid""" 57 return 'valid' 58 59 def is_structure_type_member(self, paramtype, paramname): 60 """Determine if member type and name match the structure type member.""" 61 return paramtype == 'VkStructureType' and paramname == self.structtype_member_name 62 63 def is_nextpointer_member(self, paramtype, paramname): 64 """Determine if member type and name match the next pointer chain member.""" 65 return paramtype == 'void' and paramname == self.nextpointer_member_name 66 67 def generate_structure_type_from_name(self, structname): 68 """Generate a structure type name, like VK_STRUCTURE_TYPE_CREATE_INSTANCE_INFO""" 69 structure_type_parts = [] 70 # Tokenize into "words" 71 for elem in re.findall(r'(([A-Z][a-z]+)|([A-Z][A-Z]+))', structname): 72 if elem[0] == 'Vk': 73 structure_type_parts.append('VK_STRUCTURE_TYPE') 74 else: 75 structure_type_parts.append(elem[0].upper()) 76 return '_'.join(structure_type_parts) 77 78 @property 79 def warning_comment(self): 80 """Return warning comment to be placed in header of generated Asciidoctor files""" 81 return '// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry' 82 83 @property 84 def file_suffix(self): 85 """Return suffix of generated Asciidoctor files""" 86 return '.txt' 87 88 def api_name(self, spectype='api'): 89 """Return API or specification name for citations in ref pages.ref 90 pages should link to for 91 92 spectype is the spec this refpage is for: 'api' is the Vulkan API 93 Specification. Defaults to 'api'. If an unrecognized spectype is 94 given, returns None. 95 """ 96 if spectype == 'api' or spectype is None: 97 return 'Vulkan' 98 else: 99 return None 100 101 @property 102 def xml_supported_name_of_api(self): 103 """Return the supported= attribute used in API XML""" 104 return 'vulkan' 105 106 @property 107 def api_prefix(self): 108 """Return API token prefix""" 109 return 'VK_' 110 111 @property 112 def write_contacts(self): 113 """Return whether contact list should be written to extension appendices""" 114 return True 115 116 @property 117 def write_refpage_include(self): 118 """Return whether refpage include should be written to extension appendices""" 119 return True 120 121 @property 122 def member_used_for_unique_vuid(self): 123 """Return the member name used in the VUID-...-...-unique ID.""" 124 return self.structtype_member_name 125 126 def is_externsync_command(self, protoname): 127 """Returns True if the protoname element is an API command requiring 128 external synchronization 129 """ 130 return protoname is not None and 'vkCmd' in protoname 131 132 def is_api_name(self, name): 133 """Returns True if name is in the reserved API namespace. 134 For Vulkan, these are names with a case-insensitive 'vk' prefix, or 135 a 'PFN_vk' function pointer type prefix. 136 """ 137 return name[0:2].lower() == 'vk' or name[0:6] == 'PFN_vk' 138 139 def specURL(self, spectype='api'): 140 """Return public registry URL which ref pages should link to for the 141 current all-extensions HTML specification, so xrefs in the 142 asciidoc source that aren't to ref pages can link into it 143 instead. N.b. this may need to change on a per-refpage basis if 144 there are multiple documents involved. 145 """ 146 return 'https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html' 147 148 @property 149 def xml_api_name(self): 150 """Return the name used in the default API XML registry for the default API""" 151 return 'vulkan' 152 153 @property 154 def registry_path(self): 155 """Return relpath to the default API XML registry in this project.""" 156 return 'xml/vk.xml' 157 158 @property 159 def specification_path(self): 160 """Return relpath to the Asciidoctor specification sources in this project.""" 161 return '../appendices/meta' 162 163 @property 164 def extra_refpage_headers(self): 165 """Return any extra text to add to refpage headers.""" 166 return 'include::../config/attribs.txt[]' 167 168 @property 169 def extension_index_prefixes(self): 170 """Return a list of extension prefixes used to group extension refpages.""" 171 return ['VK_KHR', 'VK_EXT', 'VK'] 172 173 @property 174 def unified_flag_refpages(self): 175 """Returns True if Flags/FlagBits refpages are unified, False if 176 they're separate. 177 """ 178 return False 179 180 @property 181 def spec_reflow_path(self): 182 """Return the relative path to the spec source folder to reflow""" 183 return '.' 184 185 @property 186 def spec_no_reflow_dirs(self): 187 """Return a set of directories not to automatically descend into 188 when reflowing spec text 189 """ 190 return ('scripts', 'style') 191 192 @property 193 def zero(self): 194 return '`0`' 195 196 def category_requires_validation(self, category): 197 """Return True if the given type 'category' always requires validation. 198 199 Overridden because Vulkan doesn't require "valid" text for basetype in the spec right now.""" 200 return category in CATEGORIES_REQUIRING_VALIDATION 201