How to use verify_extensions method in tempest

Best Python code snippet using tempest_python

validation_layer_generator.py

Source:validation_layer_generator.py Github

copy

Full Screen

1#!/usr/bin/python3 -i2#3# Copyright (c) 2017 The Khronos Group Inc.4# Copyright (c) 2017 Valve Corporation5# Copyright (c) 2017 LunarG, Inc.6#7# SPDX-License-Identifier: Apache-2.08#9# Licensed under the Apache License, Version 2.0 (the "License");10# you may not use this file except in compliance with the License.11# You may obtain a copy of the License at12#13# http://www.apache.org/licenses/LICENSE-2.014#15# Unless required by applicable law or agreed to in writing, software16# distributed under the License is distributed on an "AS IS" BASIS,17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.18# See the License for the specific language governing permissions and19# limitations under the License.20#21# Author: Mark Young <marky@lunarg.com>22import re23from automatic_source_generator import (AutomaticSourceOutputGenerator,24 undecorate)25from generator import write26# The following commands have a manually defined component to them.27VALID_USAGE_MANUALLY_DEFINED = set((28 'xrCreateInstance',29 'xrDestroyInstance',30 'xrCreateSession',31 # We manually implement some of the XR_EXT_debug_utils entry-points so that we32 # can return validation messages to known debug utils messengers33 'xrSetDebugUtilsObjectNameEXT',34 'xrCreateDebugUtilsMessengerEXT',35 'xrDestroyDebugUtilsMessengerEXT',36 'xrSessionBeginDebugUtilsLabelRegionEXT',37 'xrSessionEndDebugUtilsLabelRegionEXT',38 'xrSessionInsertDebugUtilsLabelEXT',39))40# ValidationSourceOutputGenerator - subclass of AutomaticSourceOutputGenerator.41class ValidationSourceOutputGenerator(AutomaticSourceOutputGenerator):42 """Generate core validation layer source using XML element attributes from registry"""43 # Override the base class header warning so the comment indicates this file.44 # self the ValidationSourceOutputGenerator object45 def outputGeneratedHeaderWarning(self):46 generated_warning = '// *********** THIS FILE IS GENERATED - DO NOT EDIT ***********\n'47 generated_warning += '// See validation_layer_generator.py for modifications\n'48 generated_warning += '// ************************************************************\n'49 write(generated_warning, file=self.outFile)50 # Call the base class to properly begin the file, and then add51 # the file-specific header information.52 # self the ValidationSourceOutputGenerator object53 # gen_opts the ValidationSourceGeneratorOptions object54 def beginFile(self, genOpts):55 AutomaticSourceOutputGenerator.beginFile(self, genOpts)56 preamble = ''57 if self.genOpts.filename == 'xr_generated_core_validation.hpp':58 preamble += '#pragma once\n'59 preamble += '#include "xr_generated_dispatch_table.h"\n'60 preamble += '#include "validation_utils.h"\n'61 preamble += '#include "api_layer_platform_defines.h"\n'62 preamble += '#include "xr_dependencies.h"\n'63 preamble += '#include <openxr/openxr.h>\n'64 preamble += '#include <openxr/openxr_platform.h>\n\n'65 preamble += '#include <vector>\n'66 preamble += '#include <string>\n'67 preamble += '#include <unordered_map>\n'68 preamble += '#include <thread>\n'69 preamble += '#include <mutex>\n\n'70 elif self.genOpts.filename == 'xr_generated_core_validation.cpp':71 preamble += '#include "xr_generated_core_validation.hpp"\n'72 preamble += '\n'73 preamble += '#include "api_layer_platform_defines.h"\n'74 preamble += '#include "hex_and_handles.h"\n'75 preamble += '#include "validation_utils.h"\n'76 preamble += '#include "xr_dependencies.h"\n'77 preamble += '#include "xr_generated_dispatch_table.h"\n'78 preamble += '\n'79 preamble += '#include "api_layer_platform_defines.h"\n'80 preamble += '#include "xr_dependencies.h"\n'81 preamble += '#include <openxr/openxr.h>\n'82 preamble += '#include <openxr/openxr_platform.h>\n\n'83 preamble += '#include <algorithm>\n'84 preamble += '#include <cstring>\n'85 preamble += '#include <memory>\n'86 preamble += '#include <sstream>\n'87 preamble += '#include <string>\n'88 preamble += '#include <unordered_map>\n'89 preamble += '#include <utility>\n'90 preamble += '#include <vector>\n'91 preamble += '\n'92 write(preamble, file=self.outFile)93 # Write out all the information for the appropriate file,94 # and then call down to the base class to wrap everything up.95 # self the ValidationSourceOutputGenerator object96 def endFile(self):97 file_data = ''98 if self.genOpts.filename == 'xr_generated_core_validation.hpp':99 file_data += self.outputValidationHeaderInfo()100 elif self.genOpts.filename == 'xr_generated_core_validation.cpp':101 file_data += self.outputCommonTypesForValidation()102 file_data += self.outputValidationSourceFuncs()103 write(file_data, file=self.outFile)104 # Finish processing in superclass105 AutomaticSourceOutputGenerator.endFile(self)106 def makeInfoName(self, handle_type=None, handle_type_name=None):107 if not handle_type_name:108 handle_type_name = handle_type.name109 base_handle_name = undecorate(handle_type_name)110 return 'g_%s_info' % base_handle_name111 def outputInfoMapDeclarations(self, extern):112 lines = []113 extern_keyword = 'extern ' if extern else ''114 for handle in self.api_handles:115 handle_name = handle.name116 if handle.protect_value:117 lines.append('#if %s' % handle.protect_string)118 if handle.name == 'XrInstance':119 info_type = "InstanceHandleInfo"120 else:121 info_type = 'HandleInfo<%s>' % handle_name122 lines.append('%s%s %s;' % (extern_keyword,123 info_type, self.makeInfoName(handle)))124 if handle.protect_value:125 lines.append('#endif // %s' % handle.protect_string)126 return '\n'.join(lines)127 # Write out common internal types for validation128 # self the ValidationSourceOutputGenerator object129 def outputCommonTypesForValidation(self):130 common_validation_types = ''131 common_validation_types += '// Structure used for indicating status of \'flags\' test.\n'132 common_validation_types += 'enum ValidateXrFlagsResult {\n'133 common_validation_types += ' VALIDATE_XR_FLAGS_ZERO,\n'134 common_validation_types += ' VALIDATE_XR_FLAGS_INVALID,\n'135 common_validation_types += ' VALIDATE_XR_FLAGS_SUCCESS,\n'136 common_validation_types += '};\n\n'137 return common_validation_types138 # Generate C++ structures and maps used for validating the states identified139 # in the specification.140 # self the ValidationSourceOutputGenerator object141 def outputValidationStateCheckStructs(self):142 validation_state_checks = '// Structure used for state validation.\n'143 active_structures = dict()144 for cur_state in self.api_states:145 type_name = '%s' % cur_state.type146 cur_list = []147 if active_structures.get(type_name) is not None:148 cur_list = active_structures.get(type_name)149 cur_list.append(cur_state.variable)150 active_structures[type_name] = cur_list151 for type_name, variable_list in active_structures.items():152 validation_state_checks += 'struct %sValidationStates {\n' % type_name153 for variable in variable_list:154 validation_state_checks += ' bool %s;\n' % variable155 validation_state_checks += '};\n'156 validation_state_checks += 'std::unordered_map<%s, %sValidationStates*> g_%s_valid_states;\n' % (157 type_name, type_name, undecorate(type_name))158 validation_state_checks += '\n'159 return validation_state_checks160 # Generate C++ structure and utility function prototypes for validating161 # the 'next' chains in structures.162 # self the ValidationSourceOutputGenerator object163 def outputValidationSourceNextChainProtos(self):164 next_chain_info = ''165 next_chain_info += '// Result return value for next chain validation\n'166 next_chain_info += 'enum NextChainResult {\n'167 next_chain_info += ' NEXT_CHAIN_RESULT_VALID = 0,\n'168 next_chain_info += ' NEXT_CHAIN_RESULT_ERROR = -1,\n'169 next_chain_info += ' NEXT_CHAIN_RESULT_DUPLICATE_STRUCT = -2,\n'170 next_chain_info += '};\n\n'171 next_chain_info += '// Prototype for validateNextChain command (it uses the validate structure commands so add it after\n'172 next_chain_info += 'NextChainResult ValidateNextChain(GenValidUsageXrInstanceInfo *instance_info,\n'173 next_chain_info += ' const std::string &command_name,\n'174 next_chain_info += ' std::vector<GenValidUsageXrObjectInfo>& objects_info,\n'175 next_chain_info += ' const void* next,\n'176 next_chain_info += ' std::vector<XrStructureType>& valid_ext_structs,\n'177 next_chain_info += ' std::vector<XrStructureType>& encountered_structs,\n'178 next_chain_info += ' std::vector<XrStructureType>& duplicate_structs);\n\n'179 return next_chain_info180 # Generate C++ enum and utility function prototypes for validating181 # the flags in structures.182 # self the ValidationSourceOutputGenerator object183 def outputValidationSourceFlagBitValues(self):184 flag_value_validate = ''185 for flag_tuple in self.api_flags:186 if flag_tuple.protect_value:187 flag_value_validate += '#if %s\n' % flag_tuple.protect_string188 flag_value_validate += '// Function to validate %s flags\n' % flag_tuple.name189 flag_value_validate += 'ValidateXrFlagsResult ValidateXr%s(const %s value) {\n' % (190 flag_tuple.name[2:], flag_tuple.type)191 # We need to return a value indicating that the value is zero because in some192 # circumstances, 0 is ok. However, in other cases, 0 is disallowed. So, leave193 # it up to the calling function to decide what is correct.194 flag_value_validate += ' if (0 == value) {\n'195 flag_value_validate += ' return VALIDATE_XR_FLAGS_ZERO;\n'196 flag_value_validate += ' }\n'197 # If the flag has no values defined for this flag, then anything other than198 # zero generates an error.199 if flag_tuple.valid_flags is None:200 flag_value_validate += ' return VALIDATE_XR_FLAGS_INVALID;\n'201 else:202 # This flag has values set. So, check (and remove) each valid value. Once that's done203 # anything left over would be invalid.204 flag_value_validate += ' %s int_value = value;\n' % flag_tuple.type205 for mask_tuple in self.api_bitmasks:206 if mask_tuple.name == flag_tuple.valid_flags:207 for cur_value in mask_tuple.values:208 if cur_value.protect_value and flag_tuple.protect_value != cur_value.protect_value:209 flag_value_validate += '#if %s\n' % cur_value.protect_string210 flag_value_validate += ' if ((int_value & %s) != 0) {\n' % cur_value.name211 flag_value_validate += ' // Clear the value %s since it is valid\n' % cur_value.name212 flag_value_validate += ' int_value &= ~%s;\n' % cur_value.name213 flag_value_validate += ' }\n'214 if cur_value.protect_value and flag_tuple.protect_value != cur_value.protect_value:215 flag_value_validate += '#endif // %s\n' % cur_value.protect_string216 break217 flag_value_validate += ' if (int_value != 0) {\n'218 flag_value_validate += ' // Something is left, it must be invalid\n'219 flag_value_validate += ' return VALIDATE_XR_FLAGS_INVALID;\n'220 flag_value_validate += ' }\n'221 flag_value_validate += ' return VALIDATE_XR_FLAGS_SUCCESS;\n'222 flag_value_validate += '}\n\n'223 if flag_tuple.protect_value:224 flag_value_validate += '#endif // %s\n' % flag_tuple.protect_string225 return flag_value_validate226 # Generate C++ functions for validating enums.227 # self the ValidationSourceOutputGenerator object228 def outputValidationSourceEnumValues(self):229 enum_value_validate = ''230 for enum_tuple in self.api_enums:231 if enum_tuple.protect_value:232 enum_value_validate += '#if %s\n' % enum_tuple.protect_string233 enum_value_validate += '// Function to validate %s enum\n' % enum_tuple.name234 enum_value_validate += 'bool ValidateXrEnum(GenValidUsageXrInstanceInfo *instance_info,\n'235 enum_value_validate += ' const std::string &command_name,\n'236 enum_value_validate += ' const std::string &validation_name,\n'237 enum_value_validate += ' const std::string &item_name,\n'238 enum_value_validate += ' std::vector<GenValidUsageXrObjectInfo>& objects_info,\n'239 enum_value_validate += ' const %s value) {\n' % enum_tuple.name240 indent = 1241 enum_value_validate += self.writeIndent(indent)242 enum_value_validate += '(void)instance_info; // quiet warnings\n'243 enum_value_validate += self.writeIndent(indent)244 enum_value_validate += '(void)command_name; // quiet warnings\n'245 enum_value_validate += self.writeIndent(indent)246 enum_value_validate += '(void)validation_name; // quiet warnings\n'247 enum_value_validate += self.writeIndent(indent)248 enum_value_validate += '(void)item_name; // quiet warnings\n'249 enum_value_validate += self.writeIndent(indent)250 enum_value_validate += '(void)objects_info; // quiet warnings\n'251 checked_extension = ''252 if enum_tuple.ext_name and not self.isCoreExtensionName(enum_tuple.ext_name):253 checked_extension = enum_tuple.ext_name254 enum_value_validate += self.writeIndent(indent)255 enum_value_validate += '// Enum requires extension %s, so check that it is enabled\n' % enum_tuple.ext_name256 enum_value_validate += self.writeIndent(indent)257 enum_value_validate += 'if (nullptr != instance_info && !ExtensionEnabled(instance_info->enabled_extensions, "%s")) {\n' % enum_tuple.ext_name258 indent += 1259 enum_value_validate += self.writeIndent(indent)260 enum_value_validate += 'std::string vuid = "VUID-";\n'261 enum_value_validate += self.writeIndent(indent)262 enum_value_validate += 'vuid += validation_name;\n'263 enum_value_validate += self.writeIndent(indent)264 enum_value_validate += 'vuid += "-";\n'265 enum_value_validate += self.writeIndent(indent)266 enum_value_validate += 'vuid += item_name;\n'267 enum_value_validate += self.writeIndent(indent)268 enum_value_validate += 'vuid += "-parameter";\n'269 enum_value_validate += self.writeIndent(indent)270 enum_value_validate += 'std::string error_str = "%s requires extension ";\n' % enum_tuple.name271 enum_value_validate += self.writeIndent(indent)272 enum_value_validate += 'error_str += " \\"%s\\" to be enabled, but it is not enabled";\n' % enum_tuple.ext_name273 enum_value_validate += self.writeIndent(indent)274 enum_value_validate += 'CoreValidLogMessage(instance_info, vuid,\n'275 enum_value_validate += self.writeIndent(indent)276 enum_value_validate += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, command_name,\n'277 enum_value_validate += self.writeIndent(indent)278 enum_value_validate += ' objects_info, error_str);\n'279 enum_value_validate += self.writeIndent(indent)280 enum_value_validate += 'return false;\n'281 indent -= 1282 enum_value_validate += self.writeIndent(indent)283 enum_value_validate += '}\n'284 enum_value_validate += self.writeIndent(indent)285 enum_value_validate += 'switch (value) {\n'286 indent += 1287 for cur_value in enum_tuple.values:288 avoid_dupe = None289 if cur_value.alias:290 aliased = [x for x in enum_tuple.values if x.name == cur_value.alias]291 aliased_value = aliased[0]292 if aliased_value.protect_value and aliased_value.protect_value != cur_value.protect_value and aliased_value.protect_value != enum_tuple.protect_value:293 avoid_dupe = aliased_value.protect_string294 enum_value_validate += '#if !(%s)\n' % avoid_dupe295 else:296 # This would unconditionally cause a duplicate case297 continue298 value_protect = None299 if cur_value.protect_value and enum_tuple.protect_value != cur_value.protect_value:300 value_protect = cur_value.protect_string301 enum_value_validate += '#if %s\n' % value_protect302 enum_value_validate += self.writeIndent(indent)303 enum_value_validate += 'case %s:\n' % cur_value.name304 if cur_value.ext_name and cur_value.ext_name != checked_extension and not self.isCoreExtensionName(cur_value.ext_name):305 indent += 1306 enum_value_validate += self.writeIndent(indent)307 enum_value_validate += '// Enum value %s requires extension %s, so check that it is enabled\n' % (308 cur_value.name, cur_value.ext_name)309 enum_value_validate += self.writeIndent(indent)310 enum_value_validate += 'if (nullptr != instance_info && !ExtensionEnabled(instance_info->enabled_extensions, "%s")) {\n' % cur_value.ext_name311 indent += 1312 enum_value_validate += self.writeIndent(indent)313 enum_value_validate += 'std::string vuid = "VUID-";\n'314 enum_value_validate += self.writeIndent(indent)315 enum_value_validate += 'vuid += validation_name;\n'316 enum_value_validate += self.writeIndent(indent)317 enum_value_validate += 'vuid += "-";\n'318 enum_value_validate += self.writeIndent(indent)319 enum_value_validate += 'vuid += item_name;\n'320 enum_value_validate += self.writeIndent(indent)321 enum_value_validate += 'vuid += "-parameter";\n'322 enum_value_validate += self.writeIndent(indent)323 enum_value_validate += 'std::string error_str = "%s value \\"%s\\"";\n' % (324 enum_tuple.name, cur_value.name)325 enum_value_validate += self.writeIndent(indent)326 enum_value_validate += 'error_str += " being used, which requires extension ";\n'327 enum_value_validate += self.writeIndent(indent)328 enum_value_validate += 'error_str += " \\"%s\\" to be enabled, but it is not enabled";\n' % cur_value.ext_name329 enum_value_validate += self.writeIndent(indent)330 enum_value_validate += 'CoreValidLogMessage(instance_info, vuid,\n'331 enum_value_validate += self.writeIndent(indent)332 enum_value_validate += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, command_name,\n'333 enum_value_validate += self.writeIndent(indent)334 enum_value_validate += ' objects_info, error_str);\n'335 enum_value_validate += self.writeIndent(indent)336 enum_value_validate += 'return false;\n'337 indent -= 1338 enum_value_validate += self.writeIndent(indent)339 enum_value_validate += '}\n'340 enum_value_validate += self.writeIndent(indent)341 enum_value_validate += 'return true;\n'342 indent -= 1343 elif cur_value.name == 'XR_TYPE_UNKNOWN':344 enum_value_validate += self.writeIndent(indent + 1)345 enum_value_validate += 'return false; // Invalid XrStructureType \n'346 else:347 enum_value_validate += self.writeIndent(indent + 1)348 enum_value_validate += 'return true;\n'349 if value_protect:350 enum_value_validate += '#endif // %s\n' % value_protect351 if avoid_dupe:352 enum_value_validate += '#endif // !(%s)\n' % avoid_dupe353 indent -= 1354 enum_value_validate += self.writeIndent(indent)355 enum_value_validate += 'default:\n'356 enum_value_validate += self.writeIndent(indent + 1)357 enum_value_validate += 'return false;\n'358 indent -= 1359 enum_value_validate += '}\n'360 enum_value_validate += '}\n\n'361 if enum_tuple.protect_value:362 enum_value_validate += '#endif // %s\n' % enum_tuple.protect_string363 return enum_value_validate364 # Generate prototypes for functions used internal to the source file so other functions can use them365 # self the ValidationSourceOutputGenerator object366 def outputValidationInternalProtos(self):367 validation_internal_protos = ''368 for handle in self.api_handles:369 if handle.protect_value:370 validation_internal_protos += '#if %s\n' % handle.protect_string371 validation_internal_protos += 'ValidateXrHandleResult Verify%sHandle(const %s* handle_to_check);\n' % (372 handle.name, handle.name)373 if handle.protect_value:374 validation_internal_protos += '#endif // %s\n' % handle.protect_string375 validation_internal_protos += '\n// Write out prototypes for handle parent verification functions\n'376 validation_internal_protos += 'bool VerifyXrParent(XrObjectType handle1_type, const uint64_t handle1,\n'377 validation_internal_protos += ' XrObjectType handle2_type, const uint64_t handle2,\n'378 validation_internal_protos += ' bool check_this);\n'379 validation_internal_protos += '\n// Function to check if an extension has been enabled\n'380 validation_internal_protos += 'bool ExtensionEnabled(const std::vector<std::string> &extensions, const char* const check_extension_name);\n'381 validation_internal_protos += '\n// Functions to validate structures\n'382 for xr_struct in self.api_structures:383 if xr_struct.protect_value:384 validation_internal_protos += '#if %s\n' % xr_struct.protect_string385 validation_internal_protos += 'XrResult ValidateXrStruct(GenValidUsageXrInstanceInfo *instance_info, const std::string &command_name,\n'386 validation_internal_protos += ' std::vector<GenValidUsageXrObjectInfo>& objects_info, bool check_members,\n'387 validation_internal_protos += ' const %s* value);\n' % xr_struct.name388 if xr_struct.protect_value:389 validation_internal_protos += '#endif // %s\n' % xr_struct.protect_string390 return validation_internal_protos391 # Generate C++ functions for validating 'next' chains in a structure.392 # self the ValidationSourceOutputGenerator object393 def outputValidationSourceNextChainFunc(self):394 next_chain_info = ''395 next_chain_info += 'NextChainResult ValidateNextChain(GenValidUsageXrInstanceInfo *instance_info,\n'396 next_chain_info += ' const std::string &command_name,\n'397 next_chain_info += ' std::vector<GenValidUsageXrObjectInfo>& objects_info,\n'398 next_chain_info += ' const void* next,\n'399 next_chain_info += ' std::vector<XrStructureType>& valid_ext_structs,\n'400 next_chain_info += ' std::vector<XrStructureType>& encountered_structs,\n'401 next_chain_info += ' std::vector<XrStructureType>& duplicate_structs) {\n'402 next_chain_info += self.writeIndent(1)403 next_chain_info += 'NextChainResult return_result = NEXT_CHAIN_RESULT_VALID;\n'404 next_chain_info += self.writeIndent(1)405 next_chain_info += '// NULL is valid\n'406 next_chain_info += self.writeIndent(1)407 next_chain_info += 'if (nullptr == next) {\n'408 next_chain_info += self.writeIndent(2)409 next_chain_info += 'return return_result;\n'410 next_chain_info += self.writeIndent(1)411 next_chain_info += '}\n'412 next_chain_info += self.writeIndent(1)413 next_chain_info += '// Non-NULL is not valid if there is no valid extension structs\n'414 next_chain_info += self.writeIndent(1)415 next_chain_info += 'if (nullptr != next && 0 == valid_ext_structs.size()) {\n'416 next_chain_info += self.writeIndent(2)417 next_chain_info += 'return NEXT_CHAIN_RESULT_ERROR;\n'418 next_chain_info += self.writeIndent(1)419 next_chain_info += '}\n'420 next_chain_info += self.writeIndent(1)421 next_chain_info += 'const XrBaseInStructure* next_header = reinterpret_cast<const XrBaseInStructure*>(next);\n'422 next_chain_info += self.writeIndent(1)423 next_chain_info += 'auto valid_ext = std::find(valid_ext_structs.begin(), valid_ext_structs.end(), next_header->type);\n'424 next_chain_info += self.writeIndent(1)425 next_chain_info += 'if (valid_ext == valid_ext_structs.end()) {\n'426 next_chain_info += self.writeIndent(2)427 next_chain_info += '// Not a valid extension structure type for this next chain.\n'428 next_chain_info += self.writeIndent(2)429 next_chain_info += 'return NEXT_CHAIN_RESULT_ERROR;\n'430 next_chain_info += self.writeIndent(1)431 next_chain_info += '} else {\n'432 next_chain_info += self.writeIndent(2)433 next_chain_info += '// Check to see if we\'ve already encountered this structure.\n'434 next_chain_info += self.writeIndent(2)435 next_chain_info += 'auto already_encountered_ext = std::find(encountered_structs.begin(), encountered_structs.end(), next_header->type);\n'436 next_chain_info += self.writeIndent(2)437 next_chain_info += 'if (already_encountered_ext != encountered_structs.end()) {\n'438 next_chain_info += self.writeIndent(3)439 next_chain_info += '// Make sure we only put in unique types into our duplicate list.\n'440 next_chain_info += self.writeIndent(3)441 next_chain_info += 'auto already_duplicate = std::find(duplicate_structs.begin(), duplicate_structs.end(), next_header->type);\n'442 next_chain_info += self.writeIndent(3)443 next_chain_info += 'if (already_duplicate == duplicate_structs.end()) {\n'444 next_chain_info += self.writeIndent(4)445 next_chain_info += 'duplicate_structs.push_back(next_header->type);\n'446 next_chain_info += self.writeIndent(3)447 next_chain_info += '}\n'448 next_chain_info += self.writeIndent(3)449 next_chain_info += 'return_result = NEXT_CHAIN_RESULT_DUPLICATE_STRUCT;\n'450 next_chain_info += self.writeIndent(2)451 next_chain_info += '}\n'452 next_chain_info += self.writeIndent(1)453 next_chain_info += '}\n'454 # Validate the rest of this struct455 next_chain_info += self.writeIndent(1)456 next_chain_info += 'switch (next_header->type) {\n'457 enum_tuple = [x for x in self.api_enums if x.name == 'XrStructureType'][0]458 for cur_value in enum_tuple.values:459 struct_define_name = self.genXrStructureName(460 cur_value.name)461 if not struct_define_name:462 continue463 struct_tuple = self.getStruct(struct_define_name)464 avoid_dupe = None465 if cur_value.alias:466 aliased_value = [x for x in enum_tuple.values if x.name == cur_value.alias][0]467 if aliased_value.protect_value and aliased_value.protect_value != cur_value.protect_value and aliased_value.protect_value != struct_tuple.protect_value:468 avoid_dupe = aliased_value.protect_string469 next_chain_info += '#if !(%s)\n' % avoid_dupe470 else:471 # This would unconditionally cause a duplicate case472 continue473 if struct_tuple.protect_value:474 next_chain_info += '#if %s\n' % struct_tuple.protect_string475 476 next_chain_info += self.writeIndent(2)477 next_chain_info += 'case %s:\n' % cur_value.name478 next_chain_info += self.writeIndent(3)479 next_chain_info += 'if (XR_SUCCESS != ValidateXrStruct(instance_info, command_name, objects_info, false,\n'480 next_chain_info += self.writeIndent(3)481 next_chain_info += ' reinterpret_cast<const %s*>(next))) {\n' % struct_define_name482 next_chain_info += self.writeIndent(4)483 next_chain_info += 'return NEXT_CHAIN_RESULT_ERROR;\n'484 next_chain_info += self.writeIndent(3)485 next_chain_info += '}\n'486 next_chain_info += self.writeIndent(3)487 next_chain_info += 'break;\n'488 if struct_tuple.protect_value:489 next_chain_info += '#endif // %s\n' % struct_tuple.protect_string490 if avoid_dupe:491 next_chain_info += '#endif // !(%s)\n' % avoid_dupe492 next_chain_info += self.writeIndent(2)493 next_chain_info += 'default:\n'494 next_chain_info += self.writeIndent(3)495 next_chain_info += 'return NEXT_CHAIN_RESULT_ERROR;\n'496 next_chain_info += self.writeIndent(1)497 next_chain_info += '}\n'498 # Validate any chained structs499 next_chain_info += self.writeIndent(1)500 next_chain_info += 'NextChainResult next_result = ValidateNextChain(instance_info, command_name,\n'501 next_chain_info += self.writeIndent(1)502 next_chain_info += ' objects_info, next_header->next,\n'503 next_chain_info += self.writeIndent(1)504 next_chain_info += ' valid_ext_structs,\n'505 next_chain_info += self.writeIndent(1)506 next_chain_info += ' encountered_structs,\n'507 next_chain_info += self.writeIndent(1)508 next_chain_info += ' duplicate_structs);\n'509 next_chain_info += self.writeIndent(1)510 next_chain_info += 'if (NEXT_CHAIN_RESULT_VALID == next_result && NEXT_CHAIN_RESULT_VALID != return_result) {\n'511 next_chain_info += self.writeIndent(2)512 next_chain_info += 'return return_result;\n'513 next_chain_info += self.writeIndent(1)514 next_chain_info += '} else {\n'515 next_chain_info += self.writeIndent(2)516 next_chain_info += 'return next_result;\n'517 next_chain_info += self.writeIndent(1)518 next_chain_info += '}\n'519 next_chain_info += '}\n\n'520 return next_chain_info521 # Generate C++ header information containing functionality used in both522 # the generated and manual code.523 # - Structures used to store validation information on a per-handle basis.524 # - Unordered_map and mutexes used for storing the structure information on a per handle basis.525 # self the ValidationSourceOutputGenerator object526 def outputValidationHeaderInfo(self):527 commands = []528 validation_header_info = ''529 cur_extension_name = ''530 validation_header_info += '// Unordered Map associating pointer to a vector of session label information to a session\'s handle\n'531 validation_header_info += 'extern std::unordered_map<XrSession, std::vector<GenValidUsageXrInternalSessionLabel*>*> g_xr_session_labels;\n\n'532 for x in range(0, 2):533 if x == 0:534 commands = self.core_commands535 else:536 commands = self.ext_commands537 for cur_cmd in commands:538 if cur_cmd.ext_name != cur_extension_name:539 if 'XR_VERSION_' in cur_cmd.ext_name:540 validation_header_info += '\n// ---- Core %s commands\n' % cur_cmd.ext_name[11:].replace(541 "_", ".")542 else:543 validation_header_info += '\n// ---- %s extension commands\n' % cur_cmd.ext_name544 cur_extension_name = cur_cmd.ext_name545 prototype = cur_cmd.cdecl546 # We need to always export xrGetInstanceProcAddr, even though we automatically generate it.547 # Also, we really only need the core function, not the others.548 if 'xrGetInstanceProcAddr' in cur_cmd.name:549 validation_header_info += '%s\n' % prototype.replace(550 " xr", " GenValidUsageXr")551 continue552 elif cur_cmd.name in self.no_trampoline_or_terminator or not cur_cmd.name in VALID_USAGE_MANUALLY_DEFINED:553 continue554 if cur_cmd.protect_value:555 validation_header_info += '#if %s\n' % cur_cmd.protect_string556 # Core call, for us to make from here into the manually implemented code557 validation_header_info += '%s\n' % prototype.replace(558 " xr", " CoreValidationXr")559 # Validate Inputs and Next calls for the validation to make560 validation_header_info += 'XrResult %s(' % cur_cmd.name.replace(561 "xr", "GenValidUsageInputsXr")562 count = 0563 for param in cur_cmd.params:564 if count > 0:565 validation_header_info += ', '566 count = count + 1567 validation_header_info += param.cdecl.strip()568 validation_header_info += ');\n'569 validation_header_info += '%s\n' % prototype.replace(570 " xr", " GenValidUsageNextXr")571 if cur_cmd.protect_value:572 validation_header_info += '#endif // %s\n' % cur_cmd.protect_string573 validation_header_info += '\n// Current API version of the Core Validation API Layer\n#define XR_CORE_VALIDATION_API_VERSION '574 validation_header_info += self.api_version_define575 validation_header_info += '\n'576 validation_header_info += '#if defined(__GNUC__)\n'577 validation_header_info += '#pragma GCC diagnostic push\n'578 validation_header_info += '#pragma GCC diagnostic ignored "-Wunused-parameter"\n'579 validation_header_info += '#pragma GCC diagnostic ignored "-Wunused-variable"\n'580 validation_header_info += '#endif\n'581 validation_header_info += '\n// Externs for Core Validation\n'582 validation_header_info += self.outputInfoMapDeclarations(extern=True)583 validation_header_info += 'void GenValidUsageCleanUpMaps(GenValidUsageXrInstanceInfo *instance_info);\n\n'584 validation_header_info += '\n// Function to convert XrObjectType to string\n'585 validation_header_info += 'std::string GenValidUsageXrObjectTypeToString(const XrObjectType& type);\n\n'586 validation_header_info += '// Function to record all the core validation information\n'587 validation_header_info += 'extern void CoreValidLogMessage(GenValidUsageXrInstanceInfo *instance_info, const std::string &message_id,\n'588 validation_header_info += ' GenValidUsageDebugSeverity message_severity, const std::string &command_name,\n'589 validation_header_info += ' std::vector<GenValidUsageXrObjectInfo> objects_info, const std::string &message);\n'590 return validation_header_info591 # Generate C++ utility functions to verify that all the required extensions have been enabled.592 # self the ValidationSourceOutputGenerator object593 def writeVerifyExtensions(self):594 verify_extensions = 'bool ExtensionEnabled(const std::vector<std::string> &extensions, const char* const check_extension_name) {\n'595 verify_extensions += self.writeIndent(1)596 verify_extensions += 'for (const auto& enabled_extension: extensions) {\n'597 verify_extensions += self.writeIndent(2)598 verify_extensions += 'if (enabled_extension == check_extension_name) {\n'599 verify_extensions += self.writeIndent(3)600 verify_extensions += 'return true;\n'601 verify_extensions += self.writeIndent(2)602 verify_extensions += '}\n'603 verify_extensions += self.writeIndent(1)604 verify_extensions += '}\n'605 verify_extensions += self.writeIndent(1)606 verify_extensions += 'return false;\n'607 verify_extensions += '}\n\n'608 number_of_instance_extensions = 0609 number_of_system_extensions = 0610 for extension in self.extensions:611 if extension.type == 'instance':612 number_of_instance_extensions += 1613 elif extension.type == 'system':614 number_of_system_extensions += 1615 verify_extensions += 'bool ValidateInstanceExtensionDependencies(GenValidUsageXrInstanceInfo *gen_instance_info,\n'616 verify_extensions += ' const std::string &command,\n'617 verify_extensions += ' const std::string &struct_name,\n'618 verify_extensions += ' std::vector<GenValidUsageXrObjectInfo>& objects_info,\n'619 verify_extensions += ' std::vector<std::string> &extensions) {\n'620 indent = 1621 if number_of_instance_extensions > 0:622 verify_extensions += self.writeIndent(indent)623 verify_extensions += 'for (uint32_t cur_index = 0; cur_index < extensions.size(); ++cur_index) {\n'624 indent += 1625 for extension in self.extensions:626 number_of_required = len(extension.required_exts) - 1627 if extension.type == 'instance' and number_of_required > 0:628 verify_extensions += self.writeIndent(indent)629 verify_extensions += 'if (extensions[cur_index] == "%s") {\n' % extension.name630 current_count = 0631 indent += 1632 verify_extensions += self.writeIndent(indent)633 verify_extensions += 'for (uint32_t check_index = 0; check_index < extensions.size(); ++check_index) {\n'634 indent += 1635 verify_extensions += self.writeIndent(indent)636 verify_extensions += 'if (cur_index == check_index) {\n'637 verify_extensions += self.writeIndent(indent + 1)638 verify_extensions += 'continue;\n'639 verify_extensions += self.writeIndent(indent)640 verify_extensions += '}\n'641 current_count = 0642 for required_ext in extension.required_exts:643 if current_count > 0:644 found = False645 for extension_look in self.extensions:646 if extension_look.name == required_ext:647 found = True648 if extension_look.type != 'instance':649 verify_extensions += self.printCodeGenErrorMessage('Instance extension "%s" requires non-instance extension "%s" which is not allowed' % (650 self.currentExtension, required_ext))651 if not found:652 verify_extensions += self.printCodeGenErrorMessage('Instance extension "%s" lists extension "%s" as a requirement, but'653 ' it is not defined in the registry.' % (654 self.currentExtension, required_ext))655 verify_extensions += self.writeIndent(indent)656 verify_extensions += 'if (!ExtensionEnabled(extensions, "%s")) {\n' % required_ext657 indent += 1658 verify_extensions += self.writeIndent(indent)659 verify_extensions += 'if (nullptr != gen_instance_info) {\n'660 indent += 1661 verify_extensions += self.writeIndent(indent)662 verify_extensions += 'std::string vuid = "VUID-";\n'663 verify_extensions += self.writeIndent(indent)664 verify_extensions += 'vuid += command;\n'665 verify_extensions += self.writeIndent(indent)666 verify_extensions += 'vuid += "-";\n'667 verify_extensions += self.writeIndent(indent)668 verify_extensions += 'vuid += struct_name;\n'669 verify_extensions += self.writeIndent(indent)670 verify_extensions += 'vuid += "-parameter";\n'671 verify_extensions += self.writeIndent(indent)672 verify_extensions += 'CoreValidLogMessage(gen_instance_info, vuid, VALID_USAGE_DEBUG_SEVERITY_ERROR,\n'673 verify_extensions += self.writeIndent(indent)674 verify_extensions += ' command, objects_info,\n'675 verify_extensions += self.writeIndent(indent)676 verify_extensions += ' "Missing extension dependency \\"%s\\" (required by extension" \\\n' % required_ext677 verify_extensions += self.writeIndent(indent)678 verify_extensions += ' "\\"%s\\") from enabled extension list");\n' % extension.name679 indent -= 1680 verify_extensions += self.writeIndent(indent)681 verify_extensions += '}\n'682 verify_extensions += self.writeIndent(indent)683 verify_extensions += 'return false;\n'684 indent -= 1685 verify_extensions += self.writeIndent(indent)686 verify_extensions += '}\n'687 current_count += 1688 indent -= 1689 verify_extensions += self.writeIndent(indent)690 verify_extensions += '}\n'691 indent -= 1692 verify_extensions += self.writeIndent(indent)693 verify_extensions += '}\n'694 indent -= 1695 verify_extensions += self.writeIndent(indent)696 verify_extensions += '}\n'697 else:698 verify_extensions += self.writeIndent(indent)699 verify_extensions += '// No instance extensions to check dependencies for\n'700 verify_extensions += self.writeIndent(indent)701 verify_extensions += 'return true;\n'702 verify_extensions += '}\n\n'703 verify_extensions += 'bool ValidateSystemExtensionDependencies(GenValidUsageXrInstanceInfo *gen_instance_info,\n'704 verify_extensions += ' const std::string &command,\n'705 verify_extensions += ' const std::string &struct_name,\n'706 verify_extensions += ' std::vector<GenValidUsageXrObjectInfo>& objects_info,\n'707 verify_extensions += ' std::vector<std::string> &extensions) {\n'708 indent = 1709 if number_of_system_extensions > 0:710 verify_extensions += self.writeIndent(indent)711 verify_extensions += 'for (uint32_t cur_index = 0; cur_index < extensions.size(); ++cur_index) {\n'712 indent += 1713 for extension in self.extensions:714 number_of_required = len(self.required_exts) - 1715 if extension.type == 'system' and number_of_required > 0:716 verify_extensions += self.writeIndent(indent)717 verify_extensions += 'if (extensions[cur_index] == "%s") {\n' % extension.name718 current_count = 0719 indent += 1720 verify_extensions += self.writeIndent(indent)721 verify_extensions += 'for (uint32_t check_index = 0; check_index < extensions.size(); ++check_index) {\n'722 indent += 1723 verify_extensions += self.writeIndent(indent)724 verify_extensions += 'if (cur_index == check_index) {\n'725 verify_extensions += self.writeIndent(indent + 1)726 verify_extensions += 'continue;\n'727 verify_extensions += self.writeIndent(indent)728 verify_extensions += '}\n'729 current_count = 0730 for required_ext in extension.required_exts:731 if current_count > 0:732 found = False733 is_instance = False734 for extension_look in self.extensions:735 if extension_look.name == required_ext:736 found = True737 if extension_look.type == 'instance':738 is_instance = True739 if not is_instance and extension_look.type != 'system':740 verify_extensions += self.printCodeGenErrorMessage('System extension "%s" has an extension dependency on extension "%s" '741 'which is of an invalid type.' % (742 self.currentExtension, required_ext))743 if not found:744 verify_extensions += self.printCodeGenErrorMessage('System extension "%s" lists extension "%s" as a requirement, but'745 ' it is not defined in the registry.' % (746 self.currentExtension, required_ext))747 if is_instance:748 verify_extensions += self.writeIndent(indent)749 verify_extensions += '// This is an instance extension dependency, so make sure it is enabled in the instance\n'750 verify_extensions += self.writeIndent(indent)751 verify_extensions += 'if (!ExtensionEnabled(gen_instance_info->enabled_extensions, "%s") {\n' % required_ext752 else:753 verify_extensions += self.writeIndent(indent)754 verify_extensions += 'if (!ExtensionEnabled(extensions, "%s")) {\n' % required_ext755 indent += 1756 verify_extensions += self.writeIndent(indent)757 verify_extensions += 'std::string vuid = "VUID-";\n'758 verify_extensions += self.writeIndent(indent)759 verify_extensions += 'vuid += command;\n'760 verify_extensions += self.writeIndent(indent)761 verify_extensions += 'vuid += "-";\n'762 verify_extensions += self.writeIndent(indent)763 verify_extensions += 'vuid += struct_name;\n'764 verify_extensions += self.writeIndent(indent)765 verify_extensions += 'vuid += "-parameter";\n'766 verify_extensions += self.writeIndent(indent)767 verify_extensions += 'CoreValidLogMessage(gen_instance_info, vuid, VALID_USAGE_DEBUG_SEVERITY_ERROR,\n'768 verify_extensions += self.writeIndent(indent)769 verify_extensions += ' command, objects_info,\n'770 verify_extensions += self.writeIndent(indent)771 verify_extensions += ' "Missing extension dependency \\"%s\\" (required by extension" \\' % required_ext772 verify_extensions += self.writeIndent(indent)773 verify_extensions += ' "\\"%s\\") from enabled extension list");\n' % extension.name774 verify_extensions += self.writeIndent(indent)775 verify_extensions += 'return false;\n'776 indent -= 1777 verify_extensions += self.writeIndent(indent)778 verify_extensions += '}\n'779 current_count += 1780 indent -= 1781 verify_extensions += self.writeIndent(indent)782 verify_extensions += '}\n'783 indent -= 1784 verify_extensions += self.writeIndent(indent)785 verify_extensions += '}\n'786 indent -= 1787 verify_extensions += self.writeIndent(indent)788 verify_extensions += '}\n'789 else:790 verify_extensions += self.writeIndent(indent)791 verify_extensions += '// No system extensions to check dependencies for\n'792 verify_extensions += self.writeIndent(indent)793 verify_extensions += 'return true;\n'794 verify_extensions += '}\n\n'795 return verify_extensions796 # Generate C++ enum and utility functions for verify that handles are valid.797 # self the ValidationSourceOutputGenerator object798 def writeValidateHandleChecks(self):799 verify_handle = ''800 for handle in self.api_handles:801 if handle.protect_value:802 verify_handle += '#if %s\n' % handle.protect_string803 indent = 1804 verify_handle += 'ValidateXrHandleResult Verify%sHandle(const %s* handle_to_check) {\n' % (805 handle.name, handle.name)806 verify_handle += self.writeIndent(indent)807 verify_handle += 'return %s.verifyHandle(handle_to_check);\n' % self.makeInfoName(handle)808 verify_handle += '}\n\n'809 if handle.protect_value:810 verify_handle += '#endif // %s\n' % handle.protect_string811 return verify_handle812 # Generate C++ utility functions for verify that handles share a parent.813 # self the ValidationSourceOutputGenerator object814 def writeValidateHandleParent(self):815 verify_parent = '// Implementation function to get parent handle information\n'816 verify_parent += 'bool GetXrParent(const XrObjectType inhandle_type, const uint64_t inhandle,\n'817 verify_parent += ' XrObjectType& outhandle_type, uint64_t& outhandle) {\n'818 indent = 1819 for handle in self.api_handles:820 if handle.name == 'XrInstance':821 verify_parent += self.writeIndent(indent)822 verify_parent += 'if (inhandle_type == XR_OBJECT_TYPE_INSTANCE) {\n'823 verify_parent += self.writeIndent(indent + 1)824 verify_parent += 'return false;\n'825 verify_parent += self.writeIndent(indent)826 verify_parent += '}\n'827 else:828 handle_info = '%s.get(TreatIntegerAsHandle<%s>(inhandle))' % (self.makeInfoName(handle), handle.name)829 verify_parent += self.writeIndent(indent)830 verify_parent += 'if (inhandle_type == %s) {\n' % self.genXrObjectType(831 handle.name)832 indent += 1833 verify_parent += self.writeIndent(indent)834 verify_parent += '// Get the object and parent of the handle\n'835 verify_parent += self.writeIndent(indent)836 verify_parent += 'GenValidUsageXrHandleInfo *handle_info = %s;\n' % handle_info837 verify_parent += self.writeIndent(indent)838 verify_parent += 'outhandle_type = handle_info->direct_parent_type;\n'839 verify_parent += self.writeIndent(indent)840 verify_parent += 'outhandle = handle_info->direct_parent_handle;\n'841 verify_parent += self.writeIndent(indent)842 verify_parent += 'return true;\n'843 indent -= 1844 verify_parent += self.writeIndent(indent)845 verify_parent += '}\n'846 verify_parent += ' return false;\n'847 verify_parent += '}\n\n'848 verify_parent += '// Implementation of VerifyXrParent function\n'849 verify_parent += 'bool VerifyXrParent(XrObjectType handle1_type, const uint64_t handle1,\n'850 verify_parent += ' XrObjectType handle2_type, const uint64_t handle2,\n'851 verify_parent += ' bool check_this) {\n'852 indent = 1853 verify_parent += self.writeIndent(indent)854 verify_parent += 'if (IsIntegerNullHandle(handle1) || IsIntegerNullHandle(handle2)) {\n'855 verify_parent += self.writeIndent(indent + 1)856 verify_parent += 'return false;\n'857 verify_parent += self.writeIndent(indent)858 verify_parent += '} else if (check_this && handle1_type == handle2_type) {\n'859 verify_parent += self.writeIndent(indent + 1)860 verify_parent += 'return (handle1 == handle2);\n'861 verify_parent += self.writeIndent(indent)862 verify_parent += '}\n'863 verify_parent += self.writeIndent(indent)864 verify_parent += 'if (handle1_type == XR_OBJECT_TYPE_INSTANCE && handle2_type != XR_OBJECT_TYPE_INSTANCE) {\n'865 indent += 1866 verify_parent += self.writeIndent(indent)867 verify_parent += 'XrObjectType parent_type;\n'868 verify_parent += self.writeIndent(indent)869 verify_parent += 'uint64_t parent_handle;\n'870 verify_parent += self.writeIndent(indent)871 verify_parent += 'if (!GetXrParent(handle2_type, handle2, parent_type, parent_handle)) {\n'872 verify_parent += self.writeIndent(indent + 1)873 verify_parent += 'return false;\n'874 verify_parent += self.writeIndent(indent)875 verify_parent += '}\n'876 verify_parent += self.writeIndent(indent)877 verify_parent += 'return VerifyXrParent(handle1_type, handle1, parent_type, parent_handle, true);\n'878 indent -= 1879 verify_parent += self.writeIndent(indent)880 verify_parent += '} else if (handle2_type == XR_OBJECT_TYPE_INSTANCE && handle1_type != XR_OBJECT_TYPE_INSTANCE) {\n'881 indent += 1882 verify_parent += self.writeIndent(indent)883 verify_parent += 'XrObjectType parent_type;\n'884 verify_parent += self.writeIndent(indent)885 verify_parent += 'uint64_t parent_handle;\n'886 verify_parent += self.writeIndent(indent)887 verify_parent += 'if (!GetXrParent(handle1_type, handle1, parent_type, parent_handle)) {\n'888 verify_parent += self.writeIndent(indent + 1)889 verify_parent += 'return false;\n'890 verify_parent += self.writeIndent(indent)891 verify_parent += '}\n'892 verify_parent += self.writeIndent(indent)893 verify_parent += 'return VerifyXrParent(parent_type, parent_handle, handle2_type, handle2, true);\n'894 indent -= 1895 verify_parent += self.writeIndent(indent)896 verify_parent += '} else {\n'897 indent += 1898 verify_parent += self.writeIndent(indent)899 verify_parent += 'XrObjectType parent1_type;\n'900 verify_parent += self.writeIndent(indent)901 verify_parent += 'uint64_t parent1_handle;\n'902 verify_parent += self.writeIndent(indent)903 verify_parent += self.writeIndent(indent)904 verify_parent += 'XrObjectType parent2_type;\n'905 verify_parent += self.writeIndent(indent)906 verify_parent += 'uint64_t parent2_handle;\n'907 verify_parent += self.writeIndent(indent)908 verify_parent += 'if (!GetXrParent(handle1_type, handle1, parent1_type, parent1_handle)) {\n'909 verify_parent += self.writeIndent(indent + 1)910 verify_parent += 'return false;\n'911 verify_parent += self.writeIndent(indent)912 verify_parent += '}\n'913 verify_parent += self.writeIndent(indent)914 verify_parent += 'if (!GetXrParent(handle2_type, handle2, parent2_type, parent2_handle)) {\n'915 verify_parent += self.writeIndent(indent + 1)916 verify_parent += 'return false;\n'917 verify_parent += self.writeIndent(indent)918 verify_parent += '}\n'919 verify_parent += self.writeIndent(indent)920 verify_parent += 'if (parent1_type == handle2_type) {\n'921 verify_parent += self.writeIndent(indent + 1)922 verify_parent += 'return (parent1_handle == handle2);\n'923 verify_parent += self.writeIndent(indent)924 verify_parent += '} else if (handle1_type == parent2_type) {\n'925 verify_parent += self.writeIndent(indent + 1)926 verify_parent += 'return (handle1 == parent2_handle);\n'927 verify_parent += self.writeIndent(indent)928 verify_parent += '} else {\n'929 verify_parent += self.writeIndent(indent + 1)930 verify_parent += 'return VerifyXrParent(parent1_type, parent1_handle, parent2_type, parent2_handle, true);\n'931 verify_parent += self.writeIndent(indent)932 verify_parent += '}\n'933 indent -= 1934 verify_parent += self.writeIndent(indent)935 verify_parent += '}\n'936 verify_parent += self.writeIndent(indent)937 verify_parent += 'return false;\n'938 indent -= 1939 verify_parent += '}\n\n'940 return verify_parent941 # Generate inline C++ code to check if a 'next' chain is valid for the current structure.942 # self the ValidationSourceOutputGenerator object943 # struct_type the name of the type of structure performing the validation check944 # member the member generated in automatic_source_generator.py to validate945 # indent the number of "tabs" to space in for the resulting C+ code.946 def writeValidateStructNextCheck(self, struct_type, struct_name, member, indent):947 validate_struct_next = self.writeIndent(indent)948 validate_struct_next += 'std::vector<XrStructureType> valid_ext_structs;\n'949 validate_struct_next += self.writeIndent(indent)950 validate_struct_next += 'std::vector<XrStructureType> duplicate_ext_structs;\n'951 validate_struct_next += self.writeIndent(indent)952 validate_struct_next += 'std::vector<XrStructureType> encountered_structs;\n'953 if member.valid_extension_structs:954 for valid_struct in member.valid_extension_structs:955 validate_struct_next += self.writeIndent(indent)956 validate_struct_next += 'valid_ext_structs.push_back(%s);\n' % self.genXrStructureType(957 valid_struct)958 validate_struct_next += self.writeIndent(indent)959 validate_struct_next += 'NextChainResult next_result = ValidateNextChain(instance_info, command_name, objects_info,\n'960 validate_struct_next += self.writeIndent(indent)961 validate_struct_next += ' %s->%s, valid_ext_structs,\n' % (962 struct_name, member.name)963 validate_struct_next += self.writeIndent(indent)964 validate_struct_next += ' encountered_structs,\n'965 validate_struct_next += self.writeIndent(indent)966 validate_struct_next += ' duplicate_ext_structs);\n'967 validate_struct_next += self.writeIndent(indent)968 validate_struct_next += '// No valid extension structs for this \'next\'. Therefore, must be NULL\n'969 validate_struct_next += self.writeIndent(indent)970 validate_struct_next += '// or only contain a list of valid extension structures.\n'971 validate_struct_next += self.writeIndent(indent)972 validate_struct_next += 'if (NEXT_CHAIN_RESULT_ERROR == next_result) {\n'973 validate_struct_next += self.writeIndent(indent + 1)974 validate_struct_next += 'CoreValidLogMessage(instance_info, "VUID-%s-%s-next",\n' % (struct_type,975 member.name)976 validate_struct_next += self.writeIndent(indent + 1)977 validate_struct_next += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, command_name,\n'978 validate_struct_next += self.writeIndent(indent + 1)979 validate_struct_next += ' objects_info, "Invalid structure(s) in \\"next\\" chain for %s struct \\"%s\\"");\n' % (struct_type,980 member.name)981 validate_struct_next += self.writeIndent(indent + 1)982 validate_struct_next += 'xr_result = XR_ERROR_VALIDATION_FAILURE;\n'983 validate_struct_next += self.writeIndent(indent)984 validate_struct_next += '} else if (NEXT_CHAIN_RESULT_DUPLICATE_STRUCT == next_result) {\n'985 validate_struct_next += self.writeIndent(indent + 1)986 validate_struct_next += 'std::string error_message = "Multiple structures of the same type(s) in \\"next\\" chain for ";\n'987 validate_struct_next += self.writeIndent(indent + 1)988 validate_struct_next += 'error_message += "%s : ";\n' % struct_type989 validate_struct_next += self.writeIndent(indent + 1)990 validate_struct_next += 'error_message += StructTypesToString(instance_info, duplicate_ext_structs);\n'991 validate_struct_next += self.writeIndent(indent + 1)992 validate_struct_next += 'CoreValidLogMessage(instance_info, "VUID-%s-next-unique",\n' % struct_type993 validate_struct_next += self.writeIndent(indent + 1)994 validate_struct_next += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, command_name,\n'995 validate_struct_next += self.writeIndent(indent + 1)996 validate_struct_next += ' objects_info,\n'997 validate_struct_next += self.writeIndent(indent + 1)998 validate_struct_next += '"Multiple structures of the same type(s) in \\"next\\" chain for %s struct");\n' % struct_type999 validate_struct_next += self.writeIndent(indent + 1)1000 validate_struct_next += 'xr_result = XR_ERROR_VALIDATION_FAILURE;\n'1001 validate_struct_next += self.writeIndent(indent)1002 validate_struct_next += '}\n'1003 return validate_struct_next1004 # Generate inline C++ code to check if a pointer to a variable or array is valid.1005 # self the ValidationSourceOutputGenerator object1006 # cmd_struct_name the name of the structure or command generating this validation check.1007 # member_param_name the name of the member or parameter getting validated1008 # member_param_type the type of the member or parameter getting validated1009 # pointer_to_check the full name of the pointer to check (usually cmd_struct_name +1010 # member_param_name in some fashion)1011 # full_count_var the full name of the array count variable (if this is an array), or None1012 # short_count_var the short name of the array count variable (if this is an array), or None1013 # is_in_cmd Boolean indicating that this is being called directly from inside a command1014 # indent the number of "tabs" to space in for the resulting C+ code.1015 def writeValidatePointerArrayNonNull(self, cmd_struct_name, member_param_name, member_param_type,1016 pointer_to_check, full_count_var, short_count_var, is_in_cmd,1017 indent):1018 array_check = self.writeIndent(indent)1019 instance_info_string = 'instance_info'1020 command_string = 'command_name'1021 error_prefix = ''1022 if is_in_cmd:1023 if cmd_struct_name == 'xrCreateInstance':1024 instance_info_string = 'nullptr'1025 else:1026 instance_info_string = 'gen_instance_info'1027 command_string = '"%s"' % cmd_struct_name1028 error_prefix = 'Invalid NULL for'1029 else:1030 error_prefix = '%s contains invalid NULL for' % cmd_struct_name1031 if not full_count_var:1032 array_check += '// Non-optional pointer/array variable that needs to not be NULL\n'1033 array_check += self.writeIndent(indent)1034 array_check += 'if (nullptr == %s) {\n' % pointer_to_check1035 indent = indent + 11036 array_check += self.writeIndent(indent)1037 array_check += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_string,1038 cmd_struct_name,1039 member_param_name)1040 array_check += self.writeIndent(indent)1041 array_check += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s, objects_info,\n' % command_string1042 array_check += self.writeIndent(indent)1043 array_check += ' "%s %s \\"%s\\" which is not "\n' % (error_prefix,1044 member_param_type,1045 member_param_name)1046 array_check += self.writeIndent(indent)1047 array_check += ' "optional and must be non-NULL");\n'1048 else:1049 array_check += '// Pointer/array variable with a length variable. Make sure that\n'1050 array_check += self.writeIndent(indent)1051 array_check += '// if length variable is non-zero that the pointer is not NULL\n'1052 array_check += self.writeIndent(indent)1053 array_check += 'if (nullptr == %s && 0 != %s) {\n' % (1054 pointer_to_check, full_count_var)1055 indent = indent + 11056 array_check += self.writeIndent(indent)1057 array_check += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_string,1058 cmd_struct_name,1059 member_param_name)1060 array_check += self.writeIndent(indent)1061 array_check += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s, objects_info,\n' % command_string1062 array_check += self.writeIndent(indent)1063 array_check += ' "%s %s \\"%s\\" is which not "\n' % (error_prefix,1064 member_param_type,1065 member_param_name)1066 array_check += self.writeIndent(indent)1067 array_check += ' "optional since \\"%s\\" is set and must be non-NULL");\n' % short_count_var1068 array_check += self.writeIndent(indent)1069 array_check += 'return XR_ERROR_VALIDATION_FAILURE;\n'1070 indent = indent - 11071 array_check += self.writeIndent(indent)1072 array_check += '}\n'1073 return array_check1074 # Write an inline check to make sure an Enum is valid1075 # self the ValidationSourceOutputGenerator object1076 # cmd_struct_name the name of the structure or command generating this validation check.1077 # cmd_name_param the name of the parameter containing the command name1078 # param_type the type of enum to validate getting validated1079 # param_name the name of the parameter to validate1080 # full_param_name the full name of the parameter to check (usually cmd_struct_name +1081 # member_param_name in some fashion)1082 # param_is_pointer Boolean indicate that the parameter is a pointer1083 # is_in_cmd Boolean indicating that this is being called directly from inside a command1084 # indent the number of "tabs" to space in for the resulting C+ code.1085 def writeValidateInlineEnum(self, cmd_struct_name, cmd_name_param, param_type, param_name, full_param_name,1086 param_is_pointer, is_in_cmd, indent):1087 int_indent = indent1088 inline_enum_str = self.writeIndent(int_indent)1089 inline_enum_str += '// Make sure the enum type %s value is valid\n' % param_type1090 inline_enum_str += self.writeIndent(int_indent)1091 pointer_string = ''1092 if param_is_pointer:1093 pointer_string = '*'1094 instance_info_string = 'instance_info'1095 error_prefix = ''1096 if is_in_cmd:1097 if cmd_struct_name == 'xrCreateInstance':1098 instance_info_string = 'nullptr'1099 else:1100 instance_info_string = 'gen_instance_info'1101 error_prefix = 'Invalid'1102 else:1103 error_prefix = '%s contains invalid' % cmd_struct_name1104 inline_enum_str += 'if (!ValidateXrEnum(%s, %s, "%s", "%s", objects_info, %s%s)) {\n' % (1105 instance_info_string, cmd_name_param, cmd_struct_name, param_name, pointer_string, full_param_name)1106 int_indent = int_indent + 11107 inline_enum_str += self.writeIndent(int_indent)1108 inline_enum_str += 'std::ostringstream oss_enum;\n'1109 inline_enum_str += self.writeIndent(int_indent)1110 inline_enum_str += 'oss_enum << "%s %s \\"%s\\" enum value ";\n' % (error_prefix,1111 param_type,1112 param_name)1113 inline_enum_str += self.writeIndent(int_indent)1114 inline_enum_str += 'oss_enum << Uint32ToHexString(static_cast<uint32_t>(%s%s));\n' % (pointer_string,1115 full_param_name)1116 inline_enum_str += self.writeIndent(int_indent)1117 inline_enum_str += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_string,1118 cmd_struct_name,1119 param_name)1120 inline_enum_str += self.writeIndent(int_indent)1121 inline_enum_str += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name_param1122 inline_enum_str += self.writeIndent(int_indent)1123 inline_enum_str += ' objects_info, oss_enum.str());\n'1124 inline_enum_str += self.writeIndent(int_indent)1125 inline_enum_str += 'return XR_ERROR_VALIDATION_FAILURE;\n'1126 int_indent = int_indent - 11127 inline_enum_str += self.writeIndent(int_indent)1128 inline_enum_str += '}\n'1129 return inline_enum_str1130 # Write an inline check to make sure a flag is valid1131 # self the ValidationSourceOutputGenerator object1132 # cmd_struct_name the name of the structure or command generating this validation check.1133 # cmd_name_param the name of the parameter containing the command name1134 # param_type the type of flag to validate getting validated1135 # param_name the name of the parameter to validate1136 # full_param_name the full name of the parameter to check (usually cmd_struct_name +1137 # member_param_name in some fashion)1138 # param_is_pointer Boolean indicating that the parameter is a pointer1139 # is_optional Boolean indicating that the parameter is optional1140 # is_in_cmd Boolean indicating that this is being called directly from inside a command1141 # indent the number of "tabs" to space in for the resulting C+ code.1142 def writeValidateInlineFlag(self, cmd_struct_name, cmd_name_param, param_type, param_name, full_param_name,1143 param_is_pointer, is_optional, is_in_cmd, indent):1144 int_indent = indent1145 inline_flag_str = self.writeIndent(int_indent)1146 # Add underscore between lowercase then uppercase1147 result_name = re.sub('([a-z0-9])([A-Z])', r'\1_\2', param_type)1148 # Change to uppercase1149 result_name = result_name[3:].lower()1150 result_name += '_result'1151 pointer_string = ''1152 if param_is_pointer:1153 pointer_string = '*'1154 instance_info_string = 'instance_info'1155 error_prefix = ''1156 if is_in_cmd:1157 if cmd_struct_name == 'xrCreateInstance':1158 instance_info_string = 'nullptr'1159 else:1160 instance_info_string = 'gen_instance_info'1161 error_prefix = 'Invalid'1162 else:1163 error_prefix = '%s invalid member' % cmd_struct_name1164 inline_flag_str += 'ValidateXrFlagsResult %s = ValidateXr%s(%s%s);\n' % (result_name,1165 param_type[2:],1166 pointer_string,1167 full_param_name)1168 if self.flagHasValidValues(param_type):1169 if not is_optional:1170 # Must be non-zero1171 inline_flag_str += self.writeIndent(int_indent)1172 inline_flag_str += '// Flags must be non-zero in this case.\n'1173 inline_flag_str += self.writeIndent(int_indent)1174 inline_flag_str += 'if (VALIDATE_XR_FLAGS_ZERO == %s) {\n' % result_name1175 int_indent = int_indent + 11176 inline_flag_str += self.writeIndent(int_indent)1177 inline_flag_str += 'CoreValidLogMessage(%s, "VUID-%s-%s-requiredbitmask",\n' % (instance_info_string,1178 cmd_struct_name,1179 param_name)1180 inline_flag_str += self.writeIndent(int_indent)1181 inline_flag_str += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name_param1182 inline_flag_str += self.writeIndent(int_indent)1183 inline_flag_str += ' objects_info, "%s \\"%s\\" flag must be non-zero");\n' % (param_type,1184 param_name)1185 inline_flag_str += self.writeIndent(int_indent)1186 inline_flag_str += 'return XR_ERROR_VALIDATION_FAILURE;\n'1187 int_indent = int_indent - 11188 inline_flag_str += self.writeIndent(int_indent)1189 inline_flag_str += '} else if (VALIDATE_XR_FLAGS_SUCCESS != %s) {\n' % result_name1190 else:1191 inline_flag_str += self.writeIndent(int_indent)1192 inline_flag_str += '// Valid flags available, so it must be invalid to fail.\n'1193 inline_flag_str += self.writeIndent(int_indent)1194 inline_flag_str += 'if (VALIDATE_XR_FLAGS_INVALID == %s) {\n' % result_name1195 int_indent = int_indent + 11196 inline_flag_str += self.writeIndent(int_indent)1197 inline_flag_str += '// Otherwise, flags must be valid.\n'1198 inline_flag_str += self.writeIndent(int_indent)1199 inline_flag_str += 'std::ostringstream oss_enum;\n'1200 inline_flag_str += self.writeIndent(int_indent)1201 inline_flag_str += 'oss_enum << "%s %s \\"%s\\" flag value ";\n' % (error_prefix,1202 param_type,1203 param_name)1204 inline_flag_str += self.writeIndent(int_indent)1205 inline_flag_str += 'oss_enum << Uint32ToHexString(static_cast<uint32_t>(%s%s));\n' % (pointer_string,1206 full_param_name)1207 inline_flag_str += self.writeIndent(int_indent)1208 inline_flag_str += 'oss_enum <<" contains illegal bit";\n'1209 inline_flag_str += self.writeIndent(int_indent)1210 inline_flag_str += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_string,1211 cmd_struct_name,1212 param_name)1213 inline_flag_str += self.writeIndent(int_indent)1214 inline_flag_str += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name_param1215 inline_flag_str += self.writeIndent(int_indent)1216 inline_flag_str += ' objects_info, oss_enum.str());\n'1217 inline_flag_str += self.writeIndent(int_indent)1218 inline_flag_str += 'return XR_ERROR_VALIDATION_FAILURE;\n'1219 int_indent = int_indent - 11220 inline_flag_str += self.writeIndent(int_indent)1221 inline_flag_str += '}\n'1222 else:1223 # Must be zero1224 inline_flag_str += self.writeIndent(int_indent)1225 inline_flag_str += '// Flags must be zero in this case.\n'1226 inline_flag_str += self.writeIndent(int_indent)1227 inline_flag_str += 'if (VALIDATE_XR_FLAGS_ZERO != %s) {\n' % result_name1228 int_indent = int_indent + 11229 inline_flag_str += self.writeIndent(int_indent)1230 inline_flag_str += 'CoreValidLogMessage(%s, "VUID-%s-%s-zerobitmask",\n' % (instance_info_string,1231 cmd_struct_name,1232 param_name)1233 inline_flag_str += self.writeIndent(int_indent)1234 inline_flag_str += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name_param1235 inline_flag_str += self.writeIndent(int_indent)1236 inline_flag_str += ' objects_info, "%s \\"%s\\" flag must be zero");\n' % (param_type,1237 param_name)1238 inline_flag_str += self.writeIndent(int_indent)1239 inline_flag_str += 'return XR_ERROR_VALIDATION_FAILURE;\n'1240 int_indent = int_indent - 11241 inline_flag_str += self.writeIndent(int_indent)1242 inline_flag_str += '}\n'1243 return inline_flag_str1244 # Write an inline check to make sure a handle is valid1245 # self the ValidationSourceOutputGenerator object1246 # cmd_name the name of the command generating this validation check.1247 # vuid_name the name of the structure or command to put in the VUID1248 # member_param the member or parameter generated in automatic_source_generator.py to validate1249 # mem_par_desc_name Descriptive name of parameter1250 # return_on_null Boolean indicating we need to return immediately if we encounter a NULL1251 # instance_info_name Name of the parameter storing the instance information1252 # element_in_array This is a single element in an array1253 # indent the number of "tabs" to space in for the resulting C+ code.1254 def writeValidateInlineHandleValidation(self, cmd_name, vuid_name, member_param, mem_par_desc_name,1255 return_on_null, instance_info_name,1256 element_in_array, indent):1257 inline_validate_handle = ''1258 adjust_to_pointer = ''1259 if (not element_in_array and member_param.pointer_count == 0) or (element_in_array and member_param.pointer_count == 1):1260 adjust_to_pointer = '&'1261 inline_validate_handle += self.writeIndent(indent)1262 inline_validate_handle += '{\n'1263 indent += 11264 inline_validate_handle += self.writeIndent(indent) + "// writeValidateInlineHandleValidation\n"1265 inline_validate_handle += self.writeIndent(indent)1266 inline_validate_handle += 'ValidateXrHandleResult handle_result = Verify%sHandle(%s%s);\n' % (member_param.type, adjust_to_pointer,1267 mem_par_desc_name)1268 wrote_first_if = False1269 if member_param.is_optional:1270 # If we have to return on a Handle that has a value of XR_NULL_HANDLE, do so.1271 if return_on_null:1272 wrote_first_if = True1273 inline_validate_handle += self.writeIndent(indent)1274 inline_validate_handle += 'if (handle_result == VALIDATE_XR_HANDLE_NULL) {\n'1275 inline_validate_handle += self.writeIndent(indent + 1)1276 inline_validate_handle += '// Handle is optional so NULL is valid. But we can\'t do anything else, either.\n'1277 inline_validate_handle += self.writeIndent(indent + 1)1278 inline_validate_handle += 'return XR_SUCCESS;\n'1279 inline_validate_handle += self.writeIndent(indent)1280 inline_validate_handle += '}'1281 # Otherwise, catch the non-success case. If we catch the NULL handle above, we add an "else" to1282 # the if below.1283 if not member_param.no_auto_validity:1284 if wrote_first_if:1285 inline_validate_handle += ' else '1286 else:1287 inline_validate_handle += self.writeIndent(indent)1288 indent = indent + 11289 if member_param.is_optional:1290 inline_validate_handle += 'if (handle_result == VALIDATE_XR_HANDLE_INVALID) {\n'1291 inline_validate_handle += self.writeIndent(indent)1292 inline_validate_handle += '// Not a valid handle\n'1293 else:1294 inline_validate_handle += 'if (handle_result != VALIDATE_XR_HANDLE_SUCCESS) {\n'1295 inline_validate_handle += self.writeIndent(indent)1296 inline_validate_handle += '// Not a valid handle or NULL (which is not valid in this case)\n'1297 inline_validate_handle += self.writeIndent(indent)1298 inline_validate_handle += 'std::ostringstream oss;\n'1299 inline_validate_handle += self.writeIndent(indent)1300 inline_validate_handle += 'oss << "Invalid %s handle \\"%s\\" ";\n' % (member_param.type,1301 member_param.name)1302 inline_validate_handle += self.writeIndent(indent)1303 inline_validate_handle += 'oss << HandleToHexString(%s);\n' % mem_par_desc_name1304 inline_validate_handle += self.writeIndent(indent)1305 inline_validate_handle += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_name,1306 vuid_name,1307 member_param.name)1308 inline_validate_handle += self.writeIndent(indent)1309 inline_validate_handle += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name1310 inline_validate_handle += self.writeIndent(indent)1311 inline_validate_handle += ' objects_info, oss.str());\n'1312 inline_validate_handle += self.writeIndent(indent)1313 inline_validate_handle += 'return XR_ERROR_HANDLE_INVALID;\n'1314 indent = indent - 11315 inline_validate_handle += self.writeIndent(indent)1316 inline_validate_handle += '}\n'1317 else:1318 inline_validate_handle += '\n'1319 indent -= 11320 inline_validate_handle += self.writeIndent(indent)1321 inline_validate_handle += '}\n'1322 return inline_validate_handle1323 def outputParamMemberContents(self, is_command, struct_command_name, param_member, param_member_prefix, instance_info_variable,1324 command_name_variable, is_first_param, primary_handle, primary_handle_desc_name, primary_handle_tuple,1325 wrote_handle_proto, indent):1326 param_member_contents = ''1327 is_loop = False1328 is_pointer = False1329 is_array = param_member.is_array1330 check_pointer_array_null = False1331 loop_string = ''1332 wrote_loop = False1333 prefixed_param_member_name = param_member_prefix1334 prefixed_param_member_name += param_member.name1335 pre_loop_prefixed_param_member_name = prefixed_param_member_name1336 loop_param_name = 'value_'1337 loop_param_name += param_member.name.lower()1338 loop_param_name += '_inc'1339 if param_member.array_count_var:1340 is_array = True1341 if param_member.pointer_count > 0:1342 is_pointer = True1343 elif param_member.pointer_count_var:1344 is_array = True1345 if param_member.pointer_count > 1:1346 is_pointer = True1347 elif param_member.pointer_count > 0:1348 is_pointer = True1349 if is_array or is_pointer:1350 check_pointer_array_null = not param_member.is_optional and not param_member.is_static_array1351 short_count_var = None1352 full_count_var = None1353 if is_array:1354 long_count_name = param_member_prefix1355 if param_member.is_static_array:1356 short_count_var = param_member.static_array_sizes[0]1357 long_count_name = param_member.static_array_sizes[0]1358 elif param_member.array_count_var:1359 short_count_var = param_member.array_count_var1360 if self.isAllUpperCase(param_member.array_count_var):1361 long_count_name = param_member.array_count_var1362 else:1363 long_count_name += param_member.array_count_var1364 else:1365 short_count_var = param_member.pointer_count_var1366 if self.isAllUpperCase(param_member.pointer_count_var):1367 long_count_name = param_member.pointer_count_var1368 else:1369 long_count_name += param_member.pointer_count_var1370 if check_pointer_array_null:1371 full_count_var = long_count_name1372 param_member_contents += self.writeValidatePointerArrayNonNull(struct_command_name,1373 param_member.name,1374 param_member.type,1375 prefixed_param_member_name,1376 full_count_var,1377 short_count_var,1378 is_command,1379 indent)1380 if (param_member.is_handle or self.isEnumType(param_member.type) or1381 (self.isStruct(param_member.type) and not self.isStructAlwaysValid(param_member.type))):1382 loop_string += self.writeIndent(indent)1383 loop_string += 'if (%s) {\n' % (prefixed_param_member_name)1384 indent = indent + 11385 loop_string += self.writeIndent(indent)1386 loop_string += 'for (uint32_t %s = 0; %s < %s; ++%s) {\n' % (loop_param_name,1387 loop_param_name,1388 long_count_name,1389 loop_param_name)1390 indent = indent + 11391 prefixed_param_member_name = '%s[%s]' % (1392 prefixed_param_member_name, loop_param_name)1393 is_loop = True1394 elif check_pointer_array_null:1395 param_member_contents += self.writeValidatePointerArrayNonNull(struct_command_name,1396 param_member.name,1397 param_member.type,1398 prefixed_param_member_name,1399 None,1400 None,1401 is_command,1402 indent)1403 if not param_member.is_static_array and param_member.array_length_for:1404 if param_member.is_optional:1405 param_member_contents += self.writeIndent(indent)1406 param_member_contents += '// Optional array must be non-NULL when %s is non-zero\n' % prefixed_param_member_name1407 param_member_contents += self.writeIndent(indent)1408 param_member_contents += 'if (0 != %s && nullptr == %s%s) {\n' % (1409 prefixed_param_member_name, param_member_prefix, param_member.array_length_for)1410 param_member_contents += self.writeIndent(indent + 1)1411 param_member_contents += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (instance_info_variable,1412 struct_command_name,1413 param_member.array_length_for)1414 param_member_contents += self.writeIndent(indent + 1)1415 param_member_contents += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % command_name_variable1416 param_member_contents += self.writeIndent(indent + 1)1417 param_member_contents += ' objects_info,\n'1418 param_member_contents += self.writeIndent(indent + 1)1419 param_member_contents += ' '1420 if is_command:1421 param_member_contents += '"Command %s param %s' % (1422 struct_command_name, param_member.array_length_for)1423 else:1424 param_member_contents += '"Structure %s member %s' % (1425 struct_command_name, param_member.name)1426 param_member_contents += ' is NULL, but %s is greater than 0");\n' % prefixed_param_member_name1427 param_member_contents += self.writeIndent(indent + 1)1428 param_member_contents += 'return XR_ERROR_VALIDATION_FAILURE;\n'1429 param_member_contents += self.writeIndent(indent)1430 param_member_contents += '}\n'1431 else:1432 param_member_contents += self.writeIndent(indent)1433 param_member_contents += '// Non-optional array length must be non-zero\n'1434 param_member_contents += self.writeIndent(indent)1435 param_member_contents += 'if (0 >= %s && nullptr != %s%s) {\n' % (1436 prefixed_param_member_name, param_member_prefix, param_member.array_length_for)1437 param_member_contents += self.writeIndent(indent + 1)1438 param_member_contents += 'CoreValidLogMessage(%s, "VUID-%s-%s-arraylength",\n' % (instance_info_variable,1439 struct_command_name,1440 param_member.name)1441 param_member_contents += self.writeIndent(indent + 1)1442 param_member_contents += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % command_name_variable1443 param_member_contents += self.writeIndent(indent + 1)1444 param_member_contents += ' objects_info,\n'1445 param_member_contents += self.writeIndent(indent + 1)1446 param_member_contents += ' '1447 if is_command:1448 param_member_contents += '"Command %s param %s' % (1449 struct_command_name, param_member.name)1450 else:1451 param_member_contents += '"Structure %s member %s' % (1452 struct_command_name, param_member.name)1453 param_member_contents += ' is non-optional and must be greater than 0");\n'1454 param_member_contents += self.writeIndent(indent + 1)1455 param_member_contents += 'xr_result = XR_ERROR_VALIDATION_FAILURE;\n'1456 param_member_contents += self.writeIndent(indent)1457 param_member_contents += '}\n'1458 first_time_handle_check = not wrote_handle_proto1459 if param_member.is_handle:1460 if param_member.pointer_count == 0:1461 param_member_contents += self.writeValidateInlineHandleValidation(command_name_variable,1462 struct_command_name,1463 param_member,1464 prefixed_param_member_name,1465 is_command,1466 instance_info_variable,1467 False,1468 indent)1469 # If the first item is a handle, and this is a different handle, we need to verify that1470 # one is either the parent of the other, or that they share a common ancestor.1471 if primary_handle_tuple is not None and not first_time_handle_check:1472 current_handle_tuple = self.getHandle(param_member.type)1473 param_member_contents += self.writeInlineParentCheckCall(instance_info_variable,1474 primary_handle_tuple,1475 primary_handle,1476 primary_handle_desc_name,1477 current_handle_tuple,1478 param_member,1479 prefixed_param_member_name,1480 struct_command_name,1481 command_name_variable,1482 indent)1483 elif not is_command:1484 primary_handle_tuple = self.getHandle(param_member.type)1485 primary_handle = param_member1486 primary_handle_desc_name = prefixed_param_member_name1487 elif is_array:1488 param_member_contents += loop_string1489 wrote_loop = True1490 param_member_contents += self.writeValidateInlineHandleValidation(command_name_variable,1491 struct_command_name,1492 param_member,1493 prefixed_param_member_name,1494 is_command,1495 instance_info_variable,1496 True,1497 indent)1498 elif self.isStruct(param_member.type) and not self.isStructAlwaysValid(param_member.type):1499 param_member_contents += loop_string1500 wrote_loop = True1501 # Check to see if this struct is the base of a relation group1502 relation_group = self.getRelationGroupForBaseStruct(param_member.type)1503 is_relation_group = (relation_group is not None)1504 # If this struct is the base of a relation group, check to see if this call really should go to any one of1505 # it's children instead of itself.1506 if is_relation_group:1507 for child in relation_group.child_struct_names:1508 child_struct = self.getStruct(child)1509 if child_struct.protect_value:1510 param_member_contents += '#if %s\n' % child_struct.protect_string1511 param_member_contents += self.writeIndent(indent)1512 param_member_contents += '// Validate if %s is a child structure of type %s and it is valid\n' % (1513 param_member.type, child)1514 param_member_contents += self.writeIndent(indent)1515 param_member_contents += '{\n'1516 indent = indent + 11517 param_member_contents += self.writeIndent(indent)1518 base_child_struct_name = undecorate(child)1519 if is_pointer or is_array:1520 new_type_info = param_member.cdecl.replace(1521 param_member.type, child)1522 new_type_info = new_type_info.replace(1523 param_member.name, "")1524 new_type_info = new_type_info.strip().rstrip()1525 param_member_contents += '%s new_%s_value = reinterpret_cast<%s>(%s);\n' % (1526 new_type_info, base_child_struct_name, new_type_info, pre_loop_prefixed_param_member_name)1527 param_member_contents += self.writeIndent(indent)1528 deref_string = '->' if is_pointer else '.'1529 if is_array:1530 param_member_contents += 'if (new_%s_value[%s]%stype == %s) {\n' % (1531 base_child_struct_name, loop_param_name, deref_string, self.genXrStructureType(child))1532 else:1533 param_member_contents += 'if (new_%s_value%stype == %s) {\n' % (1534 base_child_struct_name, deref_string, self.genXrStructureType(child))1535 else:1536 param_member_contents += 'const %s* new_%s_value = reinterpret_cast<const %s*>(&%s);\n' % (1537 child, base_child_struct_name, child, pre_loop_prefixed_param_member_name)1538 param_member_contents += self.writeIndent(indent)1539 param_member_contents += 'if (new_%s_value->type == %s) {\n' % (1540 base_child_struct_name, self.genXrStructureType(child))1541 indent = indent + 11542 if param_member.is_optional:1543 param_member_contents += self.writeIndent(indent)1544 param_member_contents += 'if (nullptr != new_%s_value) {\n' % base_child_struct_name1545 indent = indent + 11546 param_member_contents += self.writeIndent(indent)1547 param_member_contents += 'xr_result = ValidateXrStruct(%s, %s,\n' % (1548 instance_info_variable, command_name_variable)1549 param_member_contents += self.writeIndent(indent)1550 param_member_contents += ' objects_info,'1551 if is_command:1552 param_member_contents += ' false,'1553 else:1554 param_member_contents += ' check_members,'1555 if is_array:1556 if is_pointer:1557 param_member_contents += ' new_%s_value[%s]);\n' % (1558 base_child_struct_name, loop_param_name)1559 else:1560 param_member_contents += ' &new_%s_value[%s]);\n' % (1561 base_child_struct_name, loop_param_name)1562 else:1563 param_member_contents += ' new_%s_value);\n' % base_child_struct_name1564 else:1565 param_member_contents += self.writeIndent(indent)1566 param_member_contents += 'xr_result = ValidateXrStruct(%s, %s,\n' % (1567 instance_info_variable, command_name_variable)1568 param_member_contents += self.writeIndent(indent)1569 param_member_contents += ' objects_info,'1570 if is_command:1571 param_member_contents += 'false,'1572 else:1573 param_member_contents += ' check_members,'1574 if is_array:1575 param_member_contents += ' new_%s_value[%s]);\n' % (1576 base_child_struct_name, loop_param_name)1577 else:1578 param_member_contents += ' new_%s_value);\n' % base_child_struct_name1579 param_member_contents += self.writeIndent(indent)1580 param_member_contents += 'if (XR_SUCCESS != xr_result) {\n'1581 indent = indent + 11582 param_member_contents += self.writeIndent(indent)1583 param_member_contents += 'std::string error_message = "'1584 if is_command:1585 param_member_contents += 'Command %s param %s";\n' % (1586 struct_command_name, param_member.name)1587 else:1588 param_member_contents += 'Structure %s member %s";\n' % (1589 struct_command_name, param_member.name)1590 if is_array:1591 param_member_contents += self.writeIndent(indent)1592 param_member_contents += 'error_message += "[";\n'1593 param_member_contents += self.writeIndent(indent)1594 param_member_contents += 'error_message += std::to_string(%s);\n' % loop_param_name1595 param_member_contents += self.writeIndent(indent)1596 param_member_contents += 'error_message += "]";\n'1597 param_member_contents += self.writeIndent(indent)1598 param_member_contents += 'error_message += " is invalid";\n'1599 param_member_contents += self.writeIndent(indent)1600 param_member_contents += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (1601 instance_info_variable, struct_command_name, param_member.name)1602 param_member_contents += self.writeIndent(indent)1603 param_member_contents += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % command_name_variable1604 param_member_contents += self.writeIndent(indent)1605 param_member_contents += ' objects_info,\n'1606 param_member_contents += self.writeIndent(indent)1607 param_member_contents += ' error_message);\n'1608 param_member_contents += self.writeIndent(indent)1609 param_member_contents += 'return XR_ERROR_VALIDATION_FAILURE;\n'1610 if is_array:1611 param_member_contents += self.writeIndent(indent)1612 param_member_contents += 'break;\n'1613 param_member_contents += self.writeIndent(indent - 1)1614 param_member_contents += '} else {\n'1615 param_member_contents += self.writeIndent(indent)1616 param_member_contents += 'continue;\n'1617 if param_member.is_optional:1618 param_member_contents += self.writeIndent(indent)1619 param_member_contents += '}\n'1620 indent = indent - 11621 indent = indent - 11622 param_member_contents += self.writeIndent(indent)1623 param_member_contents += '}\n'1624 indent = indent - 11625 param_member_contents += self.writeIndent(indent)1626 param_member_contents += '}\n'1627 indent = indent - 11628 param_member_contents += self.writeIndent(indent)1629 param_member_contents += '}\n'1630 if child_struct.protect_value:1631 param_member_contents += '#endif // %s\n' % child_struct.protect_string1632 param_member_contents += self.writeIndent(indent)1633 if is_relation_group:1634 param_member_contents += '// Validate that the base-structure %s is valid\n' % (1635 param_member.type)1636 else:1637 param_member_contents += '// Validate that the structure %s is valid\n' % (1638 param_member.type)1639 param_member_contents += self.writeIndent(indent)1640 if is_pointer:1641 if param_member.is_optional:1642 param_member_contents += 'if (nullptr != %s) {\n' % prefixed_param_member_name1643 indent = indent + 11644 param_member_contents += self.writeIndent(indent)1645 param_member_contents += 'xr_result = ValidateXrStruct(%s, %s,\n' % (1646 instance_info_variable, command_name_variable)1647 param_member_contents += self.writeIndent(indent)1648 param_member_contents += ' objects_info,'1649 if is_command:1650 param_member_contents += ' false,'1651 else:1652 param_member_contents += ' check_members,'1653 param_member_contents += ' %s);\n' % prefixed_param_member_name1654 else:1655 param_member_contents += 'xr_result = ValidateXrStruct(%s, %s, objects_info,\n' % (1656 instance_info_variable, command_name_variable)1657 param_member_contents += self.writeIndent(indent)1658 param_member_contents += ' '1659 if is_command:1660 if param_member.is_const:1661 param_member_contents += 'true,'1662 else:1663 param_member_contents += 'false,'1664 else:1665 param_member_contents += 'check_members,'1666 param_member_contents += ' %s);\n' % prefixed_param_member_name1667 else:1668 param_member_contents += 'xr_result = ValidateXrStruct(%s, %s, objects_info,\n' % (1669 instance_info_variable, command_name_variable)1670 param_member_contents += self.writeIndent(indent)1671 param_member_contents += ' '1672 if is_command:1673 param_member_contents += 'true,'1674 else:1675 param_member_contents += 'check_members,'1676 param_member_contents += ' &%s);\n' % prefixed_param_member_name1677 param_member_contents += self.writeIndent(indent)1678 param_member_contents += 'if (XR_SUCCESS != xr_result) {\n'1679 indent = indent + 11680 param_member_contents += self.writeIndent(indent)1681 param_member_contents += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (1682 instance_info_variable, struct_command_name, param_member.name)1683 param_member_contents += self.writeIndent(indent)1684 param_member_contents += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % command_name_variable1685 param_member_contents += self.writeIndent(indent)1686 param_member_contents += ' objects_info,\n'1687 param_member_contents += self.writeIndent(indent)1688 param_member_contents += ' '1689 if is_command:1690 param_member_contents += '"Command %s param %s' % (1691 struct_command_name, param_member.name)1692 else:1693 param_member_contents += '"Structure %s member %s' % (1694 struct_command_name, param_member.name)1695 param_member_contents += ' is invalid");\n'1696 param_member_contents += self.writeIndent(indent)1697 param_member_contents += 'return xr_result;\n'1698 indent = indent - 11699 if is_pointer and param_member.is_optional:1700 param_member_contents += self.writeIndent(indent)1701 param_member_contents += '}\n'1702 indent = indent - 11703 param_member_contents += self.writeIndent(indent)1704 param_member_contents += '}\n'1705 elif self.isEnumType(param_member.type):1706 if is_array and not param_member.is_const:1707 param_member_contents += self.writeIndent(indent)1708 param_member_contents += '// NOTE: Can\'t validate "VUID-%s-%s-parameter" output enum buffer\n' % (struct_command_name, param_member.name)1709 else:1710 if is_array:1711 param_member_contents += loop_string1712 wrote_loop = True1713 param_member_contents += self.writeValidateInlineEnum(struct_command_name,1714 command_name_variable,1715 param_member.type,1716 param_member.name,1717 prefixed_param_member_name,1718 is_pointer,1719 is_command,1720 indent)1721 elif self.isFlagType(param_member.type):1722 param_member_contents += self.writeValidateInlineFlag(struct_command_name,1723 command_name_variable,1724 param_member.type,1725 param_member.name,1726 prefixed_param_member_name,1727 is_pointer,1728 param_member.is_optional,1729 is_command,1730 indent)1731 elif "void" not in param_member.type:1732 if param_member.is_null_terminated:1733 param_member_contents += self.writeIndent(indent)1734 param_member_contents += '// NOTE: Can\'t validate "VUID-%s-%s-parameter" null-termination\n' % (struct_command_name,1735 param_member.name)1736 elif param_member.pointer_count > 0:1737 param_member_contents += self.writeIndent(indent)1738 param_member_contents += '// NOTE: Can\'t validate "VUID-%s-%s-parameter" type\n' % (struct_command_name,1739 param_member.name)1740 elif param_member.is_static_array and "char" in param_member.type:1741 param_member_contents += self.writeIndent(indent)1742 param_member_contents += 'if (%s < std::strlen(%s)) {\n' % (1743 param_member.static_array_sizes[0], prefixed_param_member_name)1744 indent = indent + 11745 param_member_contents += self.writeIndent(indent)1746 param_member_contents += 'CoreValidLogMessage(%s, "VUID-%s-%s-parameter",\n' % (1747 instance_info_variable, struct_command_name, param_member.name)1748 param_member_contents += self.writeIndent(indent)1749 param_member_contents += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % command_name_variable1750 param_member_contents += self.writeIndent(indent)1751 param_member_contents += ' objects_info,\n'1752 param_member_contents += self.writeIndent(indent)1753 param_member_contents += ' '1754 if is_command:1755 param_member_contents += '"Command %s param %s' % (1756 struct_command_name, param_member.name)1757 else:1758 param_member_contents += '"Structure %s member %s' % (1759 struct_command_name, param_member.name)1760 param_member_contents += ' length is too long.");\n'1761 param_member_contents += self.writeIndent(indent)1762 param_member_contents += 'return XR_ERROR_VALIDATION_FAILURE;\n'1763 indent = indent - 11764 param_member_contents += self.writeIndent(indent)1765 param_member_contents += '}\n'1766 if is_loop:1767 indent = indent - 21768 if wrote_loop:1769 param_member_contents += self.writeIndent(indent + 1)1770 param_member_contents += '}\n'1771 param_member_contents += self.writeIndent(indent)1772 param_member_contents += '}\n'1773 return param_member_contents1774 # Write the validation function for every struct we know about.1775 # self the ValidationSourceOutputGenerator object1776 def writeValidateStructFuncs(self):1777 struct_check = ''1778 # Now write out the actual functions1779 for xr_struct in self.api_structures:1780 if xr_struct.name in self.structs_with_no_type:1781 continue1782 indent = 11783 is_base_type = False1784 relation_group = None1785 if xr_struct.protect_value:1786 struct_check += '#if %s\n' % xr_struct.protect_string1787 struct_check += 'XrResult ValidateXrStruct(GenValidUsageXrInstanceInfo *instance_info, const std::string &command_name,\n'1788 struct_check += ' std::vector<GenValidUsageXrObjectInfo>& objects_info, bool check_members,\n'1789 struct_check += ' const %s* value) {\n' % xr_struct.name1790 setup_bail = False1791 struct_check += ' XrResult xr_result = XR_SUCCESS;\n'1792 # Check to see if this struct is the base of a relation group1793 relation_group = self.getRelationGroupForBaseStruct(xr_struct.name)1794 if relation_group is not None:1795 is_base_type = True1796 # If this struct is the base of a relation group, check to see if this call really should go to any one of1797 # it's children instead of itself.1798 if is_base_type:1799 for member in xr_struct.members:1800 if member.name == 'next':1801 struct_check += self.writeIndent(indent)1802 struct_check += '// NOTE: Can\'t validate "VUID-%s-next-next" because it is a base structure\n' % xr_struct.name1803 else:1804 struct_check += self.writeIndent(indent)1805 struct_check += '// NOTE: Can\'t validate "VUID-%s-%s-parameter" because it is a base structure\n' % (1806 xr_struct.name, member.name)1807 for child in relation_group.child_struct_names:1808 child_struct = self.getStruct(child)1809 if child_struct.protect_value:1810 struct_check += '#if %s\n' % child_struct.protect_string1811 struct_check += self.writeIndent(indent)1812 struct_check += 'if (value->type == %s) {\n' % self.genXrStructureType(1813 child)1814 indent += 11815 struct_check += self.writeIndent(indent)1816 struct_check += 'const %s* new_value = reinterpret_cast<const %s*>(value);\n' % (1817 child, child)1818 if child_struct.ext_name and not self.isCoreExtensionName(child_struct.ext_name):1819 struct_check += self.writeIndent(indent)1820 struct_check += 'if (nullptr != instance_info && !ExtensionEnabled(instance_info->enabled_extensions, "%s")) {\n' % child_struct.ext_name1821 indent += 11822 struct_check += self.writeIndent(indent)1823 struct_check += 'std::string error_str = "%s being used with child struct type ";\n' % xr_struct.name1824 struct_check += self.writeIndent(indent)1825 struct_check += 'error_str += "\\"%s\\"";\n' % self.genXrStructureType(1826 child)1827 struct_check += self.writeIndent(indent)1828 struct_check += 'error_str += " which requires extension \\"%s\\" to be enabled, but it is not enabled";\n' % child_struct.ext_name1829 struct_check += self.writeIndent(indent)1830 struct_check += 'CoreValidLogMessage(instance_info, "VUID-%s-type-type",\n' % (1831 xr_struct.name)1832 struct_check += self.writeIndent(indent)1833 struct_check += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, command_name,\n'1834 struct_check += self.writeIndent(indent)1835 struct_check += ' objects_info, error_str);\n'1836 struct_check += self.writeIndent(indent)1837 struct_check += 'return XR_ERROR_VALIDATION_FAILURE;\n'1838 indent -= 11839 struct_check += self.writeIndent(indent)1840 struct_check += '}\n'1841 struct_check += self.writeIndent(indent)1842 struct_check += 'return ValidateXrStruct(instance_info, command_name, objects_info, check_members, new_value);\n'1843 indent -= 11844 struct_check += self.writeIndent(indent)1845 struct_check += '}\n'1846 if child_struct.protect_value:1847 struct_check += '#endif // %s\n' % child_struct.protect_string1848 struct_check += self.writeIndent(indent)1849 struct_check += 'InvalidStructureType(instance_info, command_name, objects_info, "%s",\n' % xr_struct.name1850 struct_check += self.writeIndent(indent)1851 struct_check += ' value->type, "VUID-%s-type-type");\n' % xr_struct.name1852 struct_check += self.writeIndent(indent)1853 struct_check += 'return XR_ERROR_VALIDATION_FAILURE;\n'1854 struct_check += '}\n\n'1855 continue1856 first_member_handle_tuple = None1857 first_member_handle = None1858 count = 01859 wrote_handle_check_proto = False1860 has_enable_extension_count = False1861 has_enable_extension_names = False1862 for member in xr_struct.members:1863 # If we're not supposed to check this, then skip it1864 if member.no_auto_validity:1865 continue1866 if member.name == 'type':1867 struct_check += self.writeIndent(indent)1868 struct_check += '// Make sure the structure type is correct\n'1869 struct_check += self.writeIndent(indent)1870 struct_check += 'if (value->type != %s) {\n' % self.genXrStructureType(1871 xr_struct.name)1872 indent = indent + 11873 expected = self.genXrStructureType(xr_struct.name)1874 struct_check += self.writeIndent(indent)1875 struct_check += 'InvalidStructureType(instance_info, command_name, objects_info, "%s",\n' % xr_struct.name1876 struct_check += self.writeIndent(indent)1877 struct_check += ' value->type, "VUID-%s-type-type", %s, "%s");\n' % (1878 xr_struct.name, expected, expected)1879 struct_check += self.writeIndent(indent)1880 struct_check += 'xr_result = XR_ERROR_VALIDATION_FAILURE;\n'1881 indent = indent - 11882 struct_check += self.writeIndent(indent)1883 struct_check += '}\n'1884 continue1885 elif member.name == 'next':1886 struct_check += self.writeValidateStructNextCheck(1887 xr_struct.name, 'value', member, indent)1888 elif member.name == 'enabledExtensionCount':1889 has_enable_extension_count = True1890 elif member.name == 'enabledExtensionNames':1891 has_enable_extension_names = True1892 elif not setup_bail:1893 struct_check += self.writeIndent(indent)1894 struct_check += '// If we are not to check the rest of the members, just return here.\n'1895 struct_check += self.writeIndent(indent)1896 struct_check += 'if (!check_members || XR_SUCCESS != xr_result) {\n'1897 struct_check += self.writeIndent(indent + 1)1898 struct_check += 'return xr_result;\n'1899 struct_check += self.writeIndent(indent)1900 struct_check += '}\n'1901 setup_bail = True1902 struct_check += self.outputParamMemberContents(False, xr_struct.name, member, 'value->',1903 "instance_info", "command_name",1904 count == 0,1905 first_member_handle,1906 first_member_handle,1907 first_member_handle_tuple,1908 wrote_handle_check_proto,1909 indent)1910 if member.is_handle:1911 wrote_handle_check_proto = True1912 count = count + 11913 # We only have extensions to check if both the count and enable fields are there1914 if has_enable_extension_count and has_enable_extension_names:1915 # This is create instance, so check all instance extensions1916 struct_check += self.writeIndent(indent)1917 struct_check += 'std::vector<std::string> enabled_extension_vec;\n'1918 struct_check += self.writeIndent(indent)1919 struct_check += 'for (uint32_t extension = 0; extension < value->enabledExtensionCount; ++extension) {\n'1920 struct_check += self.writeIndent(indent + 1)1921 struct_check += 'enabled_extension_vec.push_back(value->enabledExtensionNames[extension]);\n'1922 struct_check += self.writeIndent(indent)1923 struct_check += '}\n'1924 if xr_struct.name == 'XrInstanceCreateInfo':1925 struct_check += self.writeIndent(indent)1926 struct_check += 'if (!ValidateInstanceExtensionDependencies(nullptr, command_name, "%s",\n' % xr_struct.name1927 struct_check += self.writeIndent(indent)1928 struct_check += ' objects_info, enabled_extension_vec)) {\n'1929 struct_check += self.writeIndent(indent + 1)1930 struct_check += 'return XR_ERROR_VALIDATION_FAILURE;\n'1931 struct_check += self.writeIndent(indent)1932 struct_check += '}\n'1933 else:1934 struct_check += self.writeIndent(indent)1935 struct_check += 'if (!ValidateSystemExtensionDependencies(instance_info, command_name, "%s",\n' % xr_struct.name1936 struct_check += self.writeIndent(indent)1937 struct_check += ' objects_info, enabled_extension_vec)) {\n'1938 struct_check += self.writeIndent(indent + 1)1939 struct_check += 'return XR_ERROR_VALIDATION_FAILURE;\n'1940 struct_check += self.writeIndent(indent)1941 struct_check += '}\n'1942 struct_check += self.writeIndent(indent)1943 struct_check += '// Everything checked out properly\n'1944 struct_check += self.writeIndent(indent)1945 struct_check += 'return xr_result;\n'1946 struct_check += '}\n\n'1947 if xr_struct.protect_value:1948 struct_check += '#endif // %s\n' % xr_struct.protect_string1949 struct_check += '\n'1950 return struct_check1951 # Write an inline validation check for handle parents1952 # self the ValidationSourceOutputGenerator object1953 # instance_info_string string used to identify the variable associated with the instance information struct.1954 # first_handle_tuple the handle tuple associated with the type of the first handle1955 # first_handle_mem_param the member/param of the first handle1956 # first_handle_desc_name the descriptive name of the first handle1957 # cur_handle_tuple the handle tuple associated with the type of the current handle1958 # cur_handle_mem_param the member/param of the current handle1959 # cur_handle_desc_name the descriptive name of the current handle1960 # vuid_name the VUID identifier to associate this check and member/param name with1961 # cmd_name_param the parameter containing the associated command name1962 # indent the number of tab-stops to indent the current inline strings1963 def writeInlineParentCheckCall(self, instance_info_string, first_handle_tuple, first_handle_mem_param, first_handle_desc_name,1964 cur_handle_tuple, cur_handle_mem_param, cur_handle_desc_name, vuid_name,1965 cmd_name_param, indent):1966 parent_check_string = ''1967 parent_id = 'commonparent'1968 if (first_handle_tuple.name == cur_handle_tuple.parent or1969 cur_handle_tuple.name == first_handle_tuple.parent):1970 parent_id = '%s-parent' % cur_handle_mem_param.name1971 parent_check_string += self.writeIndent(indent)1972 pointer_deref = ''1973 if cur_handle_mem_param.pointer_count > 0:1974 pointer_deref = '*'1975 compare_flag = 'true'1976 if first_handle_mem_param.type == cur_handle_mem_param.type:1977 compare_flag = 'false'1978 if cur_handle_mem_param.is_optional:1979 parent_check_string += '// If the second handle is optional, only check for a common parent if\n'1980 parent_check_string += self.writeIndent(indent)1981 parent_check_string += '// it is not XR_NULL_HANDLE\n'1982 parent_check_string += self.writeIndent(indent)1983 parent_check_string += 'if (!IsIntegerNullHandle(%s) && !VerifyXrParent(%s, MakeHandleGeneric(%s),\n' % (1984 cur_handle_desc_name,1985 self.genXrObjectType(first_handle_mem_param.type),1986 first_handle_desc_name)1987 parent_check_string += ' %s, MakeHandleGeneric(%s%s), %s)) {\n' % (1988 self.genXrObjectType(cur_handle_mem_param.type),1989 pointer_deref,1990 cur_handle_desc_name,1991 compare_flag)1992 else:1993 parent_check_string += '// Verify that the handles share a common ancestry\n'1994 parent_check_string += self.writeIndent(indent)1995 parent_check_string += 'if (!VerifyXrParent(%s, MakeHandleGeneric(%s),\n' % (1996 self.genXrObjectType(first_handle_mem_param.type), first_handle_desc_name)1997 parent_check_string += ' %s, MakeHandleGeneric(%s%s), %s)) {\n' % (1998 self.genXrObjectType(cur_handle_mem_param.type), pointer_deref, cur_handle_desc_name, compare_flag)1999 indent = indent + 12000 parent_check_string += self.writeIndent(indent)2001 parent_check_string += 'std::ostringstream oss_error;\n'2002 parent_check_string += self.writeIndent(indent)2003 parent_check_string += 'oss_error << "%s " << HandleToHexString(%s);\n' % (2004 first_handle_mem_param.type, first_handle_desc_name)2005 if first_handle_tuple.name == cur_handle_tuple.parent:2006 parent_check_string += self.writeIndent(indent)2007 parent_check_string += 'oss_error << " must be a parent to %s ";\n' % cur_handle_mem_param.type2008 parent_check_string += self.writeIndent(indent)2009 parent_check_string += 'oss_error << HandleToHexString(%s);\n' % cur_handle_desc_name2010 elif cur_handle_tuple.name == first_handle_tuple.parent:2011 parent_check_string += self.writeIndent(indent)2012 parent_check_string += 'oss_error << " must be a child of %s ";\n' % cur_handle_mem_param.type2013 parent_check_string += self.writeIndent(indent)2014 parent_check_string += 'oss_error << HandleToHexString(%s);\n' % cur_handle_desc_name2015 else:2016 parent_check_string += self.writeIndent(indent)2017 parent_check_string += 'oss_error << " and %s ";\n' % cur_handle_mem_param.type2018 parent_check_string += self.writeIndent(indent)2019 parent_check_string += 'oss_error << HandleToHexString(%s);\n' % cur_handle_desc_name2020 parent_check_string += self.writeIndent(indent)2021 parent_check_string += 'oss_error << " must share a parent";\n'2022 parent_check_string += self.writeIndent(indent)2023 parent_check_string += 'CoreValidLogMessage(%s, "VUID-%s-%s",\n' % (instance_info_string,2024 vuid_name,2025 parent_id)2026 parent_check_string += self.writeIndent(indent)2027 parent_check_string += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, %s,\n' % cmd_name_param2028 parent_check_string += self.writeIndent(indent)2029 parent_check_string += ' objects_info, oss_error.str());\n'2030 parent_check_string += self.writeIndent(indent)2031 parent_check_string += 'return XR_ERROR_VALIDATION_FAILURE;\n'2032 indent = indent - 12033 parent_check_string += self.writeIndent(indent)2034 parent_check_string += '}\n'2035 return parent_check_string2036 # Generate C++ code to validate the inputs of the current command.2037 # self the ValidationSourceOutputGenerator object2038 # cur_command the command generated in automatic_source_generator.py to validate2039 def genValidateInputsFunc(self, cur_command):2040 pre_validate_func = ''2041 pre_validate_func += 'XrResult %s(' % cur_command.name.replace("xr",2042 "GenValidUsageInputsXr")2043 pre_validate_func += '\n'2044 pre_validate_func += ',\n'.join((param.cdecl.strip() for param in cur_command.params))2045 pre_validate_func += ') {\n'2046 wrote_handle_check_proto = False2047 command_name_string = '"%s"' % cur_command.name2048 # If the first parameter is a handle and we either have to validate that handle, or check2049 # for extension information, then we will need the instance information.2050 indent = 12051 pre_validate_func += self.writeIndent(indent)2052 pre_validate_func += 'try {\n'2053 indent = indent + 12054 pre_validate_func += self.writeIndent(indent)2055 pre_validate_func += 'XrResult xr_result = XR_SUCCESS;\n'2056 pre_validate_func += self.writeIndent(indent)2057 pre_validate_func += 'std::vector<GenValidUsageXrObjectInfo> objects_info;\n'2058 first_param = cur_command.params[0]2059 first_param_tuple = self.getHandle(first_param.type)2060 if first_param_tuple is not None:2061 first_handle_name = self.getFirstHandleName(first_param)2062 obj_type = self.genXrObjectType(first_param.type)2063 pre_validate_func += self.writeIndent(indent)2064 pre_validate_func += 'objects_info.emplace_back(%s, %s);\n\n'% (first_handle_name, obj_type)2065 # Must verify this param first.2066 # Can skip validating it later.2067 pre_validate_func += self.outputParamMemberContents(True, cur_command.name, first_param, '',2068 'nullptr', # no instance_info yet!2069 command_name_string,2070 True,2071 first_param,2072 first_param.name,2073 first_param_tuple,2074 wrote_handle_check_proto,2075 indent)2076 wrote_handle_check_proto = True2077 if first_param_tuple.name == 'XrInstance':2078 pre_validate_func += self.writeIndent(indent)2079 pre_validate_func += 'GenValidUsageXrInstanceInfo *gen_instance_info = g_instance_info.get(%s);\n' % first_handle_name2080 else:2081 pre_validate_func += self.writeIndent(indent)2082 pre_validate_func += 'auto info_with_instance = %s.getWithInstanceInfo(%s);\n' % (2083 self.makeInfoName(handle_type_name=first_param.type), first_handle_name)2084 pre_validate_func += self.writeIndent(indent)2085 pre_validate_func += 'GenValidUsageXrHandleInfo *gen_%s_info = info_with_instance.first;\n' % undecorate(first_param_tuple.name)2086 pre_validate_func += self.writeIndent(indent)2087 pre_validate_func += '(void)gen_%s_info; // quiet warnings\n' % undecorate(first_param_tuple.name)2088 pre_validate_func += self.writeIndent(indent)2089 pre_validate_func += 'GenValidUsageXrInstanceInfo *gen_instance_info = info_with_instance.second;\n'2090 pre_validate_func += self.writeIndent(indent)2091 pre_validate_func += '(void)gen_instance_info; // quiet warnings\n'2092 # If any of the associated handles has validation state tracking, get the2093 # appropriate struct setup for validation later in the function2094 valid_type_list = []2095 if cur_command.checks_state:2096 for cur_state in self.api_states:2097 if cur_command.name in cur_state.check_commands:2098 command_param_of_type = ''2099 for param in cur_command.params:2100 if param.type == cur_state.type:2101 command_param_of_type = param.name2102 break2103 if command_param_of_type and cur_state.type not in valid_type_list:2104 valid_type_list.append(cur_state.type)2105 pre_validate_func += self.writeIndent(2)2106 pre_validate_func += 'auto %s_valid = g_%s_valid_states[%s];\n' % (2107 undecorate(cur_state.type), undecorate(cur_state.type), command_param_of_type)2108 for additional_ext in cur_command.required_exts:2109 pre_validate_func += self.writeIndent(indent)2110 pre_validate_func += '// Check to make sure that the extension this command is in has been enabled\n'2111 pre_validate_func += self.writeIndent(indent)2112 pre_validate_func += 'if (!ExtensionEnabled(gen_instance_info->enabled_extensions, "%s")) {\n' % additional_ext2113 pre_validate_func += self.writeIndent(indent + 1)2114 pre_validate_func += 'return XR_ERROR_VALIDATION_FAILURE;\n'2115 pre_validate_func += self.writeIndent(indent)2116 pre_validate_func += '}\n'2117 instance_info_variable = 'gen_instance_info' if first_param_tuple else 'nullptr'2118 # Check for non-optional null pointers2119 for count, param in enumerate(cur_command.params):2120 is_first = (count == 0)2121 if is_first and first_param_tuple:2122 # This is the first param, which we already validated as being a handle above. Skip this here.2123 continue2124 if not is_first and param.is_handle and not param.pointer_count > 0:2125 pre_validate_func += self.writeIndent(indent)2126 pre_validate_func += 'objects_info.emplace_back(%s, %s);\n' % (param.name, self.genXrObjectType(2127 param.type))2128 if not param.no_auto_validity:2129 pre_validate_func += self.outputParamMemberContents(True, cur_command.name, param, '',2130 instance_info_variable,2131 command_name_string,2132 is_first,2133 first_param,2134 first_param.name,2135 first_param_tuple,2136 wrote_handle_check_proto,2137 indent)2138 wrote_handle_check_proto = True2139 count = count + 12140 # If this command needs to be checked to ensure that it is executing between2141 # a "begin" and an "end" command, do so.2142 if cur_command.checks_state:2143 for cur_state in self.api_states:2144 if cur_command.name in cur_state.check_commands:2145 for param in cur_command.params:2146 if param.type == cur_state.type:2147 break2148 pre_validate_func += self.writeIndent(2)2149 pre_validate_func += '// Validate that this command is called at the proper time between the\n'2150 pre_validate_func += self.writeIndent(2)2151 pre_validate_func += '// appropriate commands\n'2152 pre_validate_func += self.writeIndent(2)2153 pre_validate_func += 'if (!%s_valid->%s) {\n' % (2154 undecorate(cur_state.type), cur_state.variable)2155 pre_validate_func += self.writeIndent(3)2156 pre_validate_func += 'std::string error_msg = "%s is required to be called between successful calls to ";\n' % cur_command.name2157 pre_validate_func += self.writeIndent(3)2158 pre_validate_func += 'error_msg += "'2159 cur_count = 02160 for begin_command in cur_state.begin_commands:2161 if cur_count > 0:2162 pre_validate_func += '/'2163 cur_count += 12164 pre_validate_func += '%s' % begin_command2165 pre_validate_func += ' and '2166 cur_count = 02167 for end_command in cur_state.end_commands:2168 if cur_count > 0:2169 pre_validate_func += '/'2170 cur_count += 12171 pre_validate_func += '%s' % end_command2172 pre_validate_func += ' commands";\n'2173 pre_validate_func += self.writeIndent(3)2174 pre_validate_func += 'CoreValidLogMessage(%s, "VUID-%s-%s-checkstate",\n' % (2175 instance_info_variable, cur_command.name, cur_state.state)2176 pre_validate_func += self.writeIndent(3)2177 pre_validate_func += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, "%s", objects_info,\n' % cur_command.name2178 pre_validate_func += self.writeIndent(3)2179 pre_validate_func += ' error_msg);\n'2180 pre_validate_func += self.writeIndent(3)2181 pre_validate_func += 'return XR_ERROR_VALIDATION_FAILURE;\n'2182 pre_validate_func += self.writeIndent(2)2183 pre_validate_func += '}\n'2184 # If this command needs to indicate that a validation state has begun, do so.2185 if cur_command.begins_state:2186 for cur_state in self.api_states:2187 if cur_command.name in cur_state.check_commands:2188 for param in cur_command.params:2189 if param.type == cur_state.type:2190 break2191 # First, make sure we're not calling two (or more) "begins" in a row2192 pre_validate_func += self.writeIndent(2)2193 pre_validate_func += '// Validate that this command is called first or only after the corresponding\n'2194 pre_validate_func += self.writeIndent(2)2195 pre_validate_func += '// "completion" commands\n'2196 pre_validate_func += self.writeIndent(2)2197 pre_validate_func += 'if (%s_valid->%s) {\n' % (2198 undecorate(cur_state.type), cur_state.variable)2199 pre_validate_func += self.writeIndent(3)2200 pre_validate_func += 'std::string error_msg = "%s is called again without first successfully calling ";\n' % cur_command.name2201 pre_validate_func += self.writeIndent(3)2202 pre_validate_func += 'error_msg += "'2203 cur_count = 02204 for end_command in cur_state.end_commands:2205 if cur_count > 0:2206 pre_validate_func += '/'2207 cur_count += 12208 pre_validate_func += '%s' % end_command2209 pre_validate_func += '";\n'2210 pre_validate_func += self.writeIndent(3)2211 pre_validate_func += 'CoreValidLogMessage(%s, "VUID-%s-%s-beginstate",\n' % (2212 instance_info_variable, cur_command.name, cur_state.state)2213 pre_validate_func += self.writeIndent(3)2214 pre_validate_func += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, "%s", objects_info,\n' % cur_command.name2215 pre_validate_func += self.writeIndent(3)2216 pre_validate_func += ' error_msg);\n'2217 pre_validate_func += self.writeIndent(3)2218 pre_validate_func += 'return XR_ERROR_VALIDATION_FAILURE;\n'2219 pre_validate_func += self.writeIndent(2)2220 pre_validate_func += '}\n'2221 # Begin the appropriate state2222 pre_validate_func += self.writeIndent(2)2223 pre_validate_func += '// Begin the %s state\n' % cur_state.state2224 pre_validate_func += self.writeIndent(2)2225 pre_validate_func += '%s_valid->%s = true;\n' % (2226 undecorate(cur_state.type), cur_state.variable)2227 # If this command needs to indicate an end of a validation state, do so.2228 if cur_command.ends_state:2229 for cur_state in self.api_states:2230 if cur_command.name in cur_state.check_commands:2231 for param in cur_command.params:2232 if param.type == cur_state.type:2233 break2234 # First, make sure we're not calling two (or more) "ends" in a row (or before a "begin")2235 pre_validate_func += self.writeIndent(2)2236 pre_validate_func += '// Validate that this command is called after the corresponding\n'2237 pre_validate_func += self.writeIndent(2)2238 pre_validate_func += '// "begin" commands\n'2239 pre_validate_func += self.writeIndent(2)2240 pre_validate_func += 'if (!%s_valid->%s) {\n' % (2241 undecorate(cur_state.type), cur_state.variable)2242 pre_validate_func += self.writeIndent(3)2243 pre_validate_func += 'std::string error_msg = "%s is called again without first successfully calling ";\n' % cur_command.name2244 pre_validate_func += self.writeIndent(3)2245 pre_validate_func += 'error_msg += "'2246 cur_count = 02247 for begin_command in cur_state.begin_commands:2248 if cur_count > 0:2249 pre_validate_func += '/'2250 cur_count += 12251 pre_validate_func += '%s' % begin_command2252 pre_validate_func += '";\n'2253 pre_validate_func += self.writeIndent(3)2254 pre_validate_func += 'CoreValidLogMessage(%s, "VUID-%s-%s-endstate",\n' % (2255 instance_info_variable, cur_command.name, cur_state.state)2256 pre_validate_func += self.writeIndent(3)2257 pre_validate_func += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, "%s", objects_info,\n' % cur_command.name2258 pre_validate_func += self.writeIndent(3)2259 pre_validate_func += ' error_msg);\n'2260 pre_validate_func += self.writeIndent(3)2261 pre_validate_func += 'return XR_ERROR_VALIDATION_FAILURE;\n'2262 pre_validate_func += self.writeIndent(2)2263 pre_validate_func += '}\n'2264 # End the appropriate state2265 pre_validate_func += self.writeIndent(2)2266 pre_validate_func += '// End the %s state\n' % cur_state.state2267 pre_validate_func += self.writeIndent(2)2268 pre_validate_func += '%s_valid->%s = false;\n' % (2269 undecorate(cur_state.type), cur_state.variable)2270 pre_validate_func += self.writeIndent(indent)2271 pre_validate_func += 'return xr_result;\n'2272 indent = indent - 12273 pre_validate_func += self.writeIndent(indent)2274 pre_validate_func += '} catch (...) {\n'2275 pre_validate_func += self.writeIndent(indent + 1)2276 pre_validate_func += 'return XR_ERROR_VALIDATION_FAILURE;\n'2277 pre_validate_func += self.writeIndent(indent)2278 pre_validate_func += '}\n'2279 pre_validate_func += '}\n\n'2280 return pre_validate_func2281 # Generate C++ code to call down to the next layer/loader terminator/runtime2282 # self the ValidationSourceOutputGenerator object2283 # cur_command the command generated in automatic_source_generator.py to validate2284 # has_return Boolean indicating that the command must return a value (usually XrResult)2285 # is_create Boolean indicating that the command is a create command2286 # is_destroy Boolean indicating that the command is a destroy command2287 # is_sempath_query Boolean indicating that this is a semantic path query (treat similar to a create)2288 def genNextValidateFunc(self, cur_command, has_return, is_create, is_destroy, is_sempath_query):2289 next_validate_func = ''2290 # Note: We don't make a "next" call for xrCreateInstance in a layer because we2291 # actually have to call xrCreateApiLayerInstance. Also, we have to setup the first2292 # entry into the dispatch table so it's a special case all around.2293 if 'xrCreateInstance' in cur_command.name:2294 return ''2295 prototype = cur_command.cdecl.replace(" xr", " GenValidUsageNextXr")2296 prototype = prototype.replace(";", " {")2297 next_validate_func += '%s\n' % (prototype)2298 if has_return:2299 return_prefix = ' '2300 return_prefix += cur_command.return_type.text2301 return_prefix += ' result'2302 if cur_command.return_type.text == 'XrResult':2303 return_prefix += ' = XR_SUCCESS;\n'2304 else:2305 return_prefix += ';\n'2306 next_validate_func += return_prefix2307 next_validate_func += ' try {\n'2308 first_param = cur_command.params[0]2309 # Next, we have to call down to the next implementation of this command in the call chain.2310 # Before we can do that, we have to figure out what the dispatch table is2311 base_handle_name = undecorate(first_param.type)2312 if first_param.is_handle:2313 first_handle_tuple = self.getHandle(first_param.type)2314 first_handle_name = self.getFirstHandleName(first_param)2315 if first_handle_tuple.name == 'XrInstance':2316 next_validate_func += ' GenValidUsageXrInstanceInfo *gen_instance_info = g_instance_info.get(%s);\n' % first_handle_name2317 else:2318 next_validate_func += ' auto info_with_instance = %s.getWithInstanceInfo(%s);\n' % (2319 self.makeInfoName(handle_type_name=first_handle_tuple.name), first_handle_name)2320 next_validate_func += ' GenValidUsageXrHandleInfo *gen_%s_info = info_with_instance.first;\n' % base_handle_name2321 next_validate_func += ' (void)gen_%s_info; // quiet warnings\n' % base_handle_name2322 next_validate_func += ' GenValidUsageXrInstanceInfo *gen_instance_info = info_with_instance.second;\n'2323 else:2324 next_validate_func += '#error("Bug")\n'2325 # Call down, looking for the returned result if required.2326 next_validate_func += ' '2327 if has_return:2328 next_validate_func += 'result = '2329 next_validate_func += 'gen_instance_info->dispatch_table->%s(' % cur_command.name[2:]2330 count = 02331 for param in cur_command.params:2332 if count > 0:2333 next_validate_func += ', '2334 next_validate_func += param.name2335 count = count + 12336 next_validate_func += ');\n'2337 # If this is a create command, we have to create an entry in the appropriate2338 # unordered_map pointing to the correct dispatch table for the newly created2339 # object. Likewise, if it's a delete command, we have to remove the entry2340 # for the dispatch table from the unordered_map2341 last_param = cur_command.params[-1]2342 if last_param.is_handle:2343 first_param = cur_command.params[0]2344 last_handle_tuple = self.getHandle(last_param.type)2345 last_handle_name = last_param.name2346 if is_create:2347 assert(last_handle_tuple.name != 'XrInstance')2348 next_validate_func += ' if (XR_SUCCESS == result && nullptr != %s) {\n' % last_handle_name2349 next_validate_func += ' std::unique_ptr<GenValidUsageXrHandleInfo> handle_info(new GenValidUsageXrHandleInfo());\n'2350 next_validate_func += ' handle_info->instance_info = gen_instance_info;\n'2351 next_validate_func += ' handle_info->direct_parent_type = %s;\n' % self.genXrObjectType(2352 first_param.type)2353 next_validate_func += ' handle_info->direct_parent_handle = MakeHandleGeneric(%s);\n' % first_param.name2354 next_validate_func += ' %s.insert(*%s, std::move(handle_info));\n' % (self.makeInfoName(last_handle_tuple), last_handle_name)2355 # If this object contains a state that needs tracking, allocate it2356 valid_type_list = []2357 for cur_state in self.api_states:2358 if last_handle_tuple.name == cur_state.type and cur_state.type not in valid_type_list:2359 valid_type_list.append(cur_state.type)2360 next_validate_func += self.writeIndent(3)2361 next_validate_func += '// Check to see if this object that has been created has a validation\n'2362 next_validate_func += self.writeIndent(3)2363 next_validate_func += '// state structure that needs to be created as well.\n'2364 next_validate_func += self.writeIndent(3)2365 next_validate_func += '%sValidationStates *%s_valid_state = new %sValidationStates;\n' % (2366 cur_state.type, undecorate(cur_state.type), cur_state.type)2367 next_validate_func += self.writeIndent(3)2368 next_validate_func += '(*%s_valid_state) = {};\n' % undecorate(cur_state.type)2369 next_validate_func += self.writeIndent(3)2370 next_validate_func += 'g_%s_valid_states[(*%s)] = %s_valid_state;\n' % (2371 undecorate(cur_state.type), last_handle_name, undecorate(cur_state.type))2372 next_validate_func += ' }\n'2373 elif is_destroy:2374 if last_param.type == 'XrSession':2375 next_validate_func += '\n // Clean up any labels associated with this session\n'2376 next_validate_func += ' CoreValidationDeleteSessionLabels(session);\n\n'2377 # Only remove the handle from our map if the runtime returned success2378 next_validate_func += ' if (XR_SUCCEEDED(result)) {\n'2379 # If this object contains a state that needs tracking, free it2380 valid_type_list = []2381 for cur_state in self.api_states:2382 if last_handle_tuple.name == cur_state.type and cur_state.type not in valid_type_list:2383 valid_type_list.append(cur_state.type)2384 next_validate_func += self.writeIndent(3)2385 next_validate_func += '// Check to see if this object that is about to be destroyed has a\n'2386 next_validate_func += self.writeIndent(3)2387 next_validate_func += '// validation state structure that needs to be cleaned up.\n'2388 next_validate_func += self.writeIndent(3)2389 next_validate_func += '%sValidationStates *%s_valid_state = g_%s_valid_states[%s];\n' % (2390 cur_state.type, undecorate(cur_state.type), undecorate(cur_state.type), last_handle_name)2391 next_validate_func += self.writeIndent(3)2392 next_validate_func += 'if (nullptr != %s_valid_state) {\n' % cur_state.type[2:].lower(2393 )2394 next_validate_func += self.writeIndent(4)2395 next_validate_func += 'delete %s_valid_state;\n' % cur_state.type[2:].lower(2396 )2397 next_validate_func += self.writeIndent(4)2398 next_validate_func += 'g_%s_valid_states.erase(%s);\n' % (2399 undecorate(cur_state.type), last_handle_name)2400 next_validate_func += self.writeIndent(3)2401 next_validate_func += '}\n'2402 next_validate_func += ' %s.erase(%s);\n' % (self.makeInfoName(handle_type=last_handle_tuple), last_handle_name)2403 next_validate_func += ' }\n'2404 if 'xrDestroyInstance' in cur_command.name:2405 next_validate_func += ' GenValidUsageCleanUpMaps(gen_instance_info);\n'2406 # Catch any exceptions that may have occurred. If any occurred between any of the2407 # valid mutex lock/unlock statements, perform the unlock now. Notice that a create can2408 # also allocate items, so we want to special case catching the failure of the allocation.2409 if is_create or is_sempath_query:2410 next_validate_func += ' } catch (std::bad_alloc&) {\n'2411 next_validate_func += ' result = XR_ERROR_OUT_OF_MEMORY;\n'2412 next_validate_func += ' } catch (...) {\n'2413 if has_return:2414 next_validate_func += ' result = XR_ERROR_VALIDATION_FAILURE;\n'2415 next_validate_func += ' }\n'2416 if has_return:2417 next_validate_func += ' return result;\n'2418 next_validate_func += '}\n\n'2419 return next_validate_func2420 # Generate a top-level automatic C++ validation function which will be used until2421 # a manual function is defined.2422 # self the ValidationSourceOutputGenerator object2423 # cur_command the command generated in automatic_source_generator.py to validate2424 # has_return Boolean indicating that the command must return a value (usually XrResult)2425 def genAutoValidateFunc(self, cur_command, has_return):2426 auto_validate_func = ''2427 prototype = cur_command.cdecl.replace(" xr", " GenValidUsageXr")2428 prototype = prototype.replace(";", " {")2429 auto_validate_func += '%s\n' % (prototype)2430 auto_validate_func += self.writeIndent(1)2431 if has_return:2432 auto_validate_func += '%s test_result = ' % cur_command.return_type.text2433 # Define the pre-validate call2434 auto_validate_func += '%s(' % cur_command.name.replace("xr",2435 "GenValidUsageInputsXr")2436 count = 02437 for param in cur_command.params:2438 if count > 0:2439 auto_validate_func += ', '2440 count = count + 12441 auto_validate_func += param.name2442 auto_validate_func += ');\n'2443 if has_return and cur_command.return_type.text == 'XrResult':2444 auto_validate_func += self.writeIndent(1)2445 auto_validate_func += 'if (XR_SUCCESS != test_result) {\n'2446 auto_validate_func += self.writeIndent(2)2447 auto_validate_func += 'return test_result;\n'2448 auto_validate_func += self.writeIndent(1)2449 auto_validate_func += '}\n'2450 # Make the calldown to the next layer2451 auto_validate_func += self.writeIndent(1)2452 if has_return:2453 auto_validate_func += 'return '2454 auto_validate_func += '%s(' % cur_command.name.replace("xr",2455 "GenValidUsageNextXr")2456 count = 02457 for param in cur_command.params:2458 if count > 0:2459 auto_validate_func += ', '2460 count = count + 12461 auto_validate_func += param.name2462 auto_validate_func += ');\n'2463 auto_validate_func += '}\n\n'2464 return auto_validate_func2465 # Implementation for generated validation commands2466 # self the ValidationSourceOutputGenerator object2467 def outputValidationSourceFuncs(self):2468 commands = []2469 validation_source_funcs = ''2470 cur_extension_name = ''2471 # First, output the mapping and mutex items2472 validation_source_funcs += '// Unordered Map associating pointer to a vector of session label information to a session\'s handle\n'2473 validation_source_funcs += 'std::unordered_map<XrSession, std::vector<GenValidUsageXrInternalSessionLabel*>*> g_xr_session_labels;\n\n'2474 validation_source_funcs += self.outputInfoMapDeclarations(extern=False)2475 validation_source_funcs += '\n'2476 validation_source_funcs += self.outputValidationInternalProtos()2477 validation_source_funcs += '// Function used to clean up any residual map values that point to an instance prior to that\n'2478 validation_source_funcs += '// instance being deleted.\n'2479 validation_source_funcs += 'void GenValidUsageCleanUpMaps(GenValidUsageXrInstanceInfo *instance_info) {\n'2480 for handle in self.api_handles:2481 if handle.protect_value:2482 validation_source_funcs += '#if %s\n' % handle.protect_string2483 if handle.name == 'XrInstance':2484 validation_source_funcs += ' EraseAllInstanceTableMapElements(instance_info);\n'2485 else:2486 validation_source_funcs += ' %s.removeHandlesForInstance(instance_info);\n' % self.makeInfoName(handle_type=handle)2487 if handle.protect_value:2488 validation_source_funcs += '#endif // %s\n' % handle.protect_string2489 validation_source_funcs += '}\n'2490 validation_source_funcs += '\n'2491 validation_source_funcs += '// Function to convert XrObjectType to string\n'2492 validation_source_funcs += 'std::string GenValidUsageXrObjectTypeToString(const XrObjectType& type) {\n'2493 validation_source_funcs += ' std::string object_string;\n'2494 count = 02495 for object_type in self.api_object_types:2496 object_string = object_type.name.replace("XR_OBJECT_TYPE_", "").replace("_", "")2497 if object_string == "UNKNOWN":2498 if count == 0:2499 validation_source_funcs += ' if '2500 else:2501 validation_source_funcs += ' } else if '2502 validation_source_funcs += '(type == XR_OBJECT_TYPE_UNKNOWN) {\n'2503 validation_source_funcs += ' object_string = "Unknown XR Object";\n'2504 else:2505 for handle in self.api_handles:2506 handle_name = handle.name[2:].upper()2507 if handle_name != object_string:2508 continue2509 if object_type.protect_value:2510 validation_source_funcs += '#if %s\n' % object_type.protect_string2511 if count == 0:2512 validation_source_funcs += ' if '2513 else:2514 validation_source_funcs += ' } else if '2515 validation_source_funcs += '(type == %s) {\n' % object_type.name2516 validation_source_funcs += ' object_string = "%s";\n' % handle.name2517 if object_type.protect_value:2518 validation_source_funcs += '#endif // %s\n' % object_type.protect_string2519 count = count + 12520 validation_source_funcs += ' }\n'2521 validation_source_funcs += ' return object_string;\n'2522 validation_source_funcs += '}\n\n'2523 validation_source_funcs += self.outputValidationStateCheckStructs()2524 validation_source_funcs += self.outputValidationSourceNextChainProtos()2525 validation_source_funcs += self.outputValidationSourceFlagBitValues()2526 validation_source_funcs += self.outputValidationSourceEnumValues()2527 validation_source_funcs += self.writeVerifyExtensions()2528 validation_source_funcs += self.writeValidateHandleChecks()2529 validation_source_funcs += self.writeValidateHandleParent()2530 validation_source_funcs += self.writeValidateStructFuncs()2531 validation_source_funcs += self.outputValidationSourceNextChainFunc()2532 for x in range(0, 2):2533 if x == 0:2534 commands = self.core_commands2535 else:2536 commands = self.ext_commands2537 for cur_cmd in commands:2538 if cur_cmd.ext_name != cur_extension_name:2539 if 'XR_VERSION_' in cur_cmd.ext_name:2540 validation_source_funcs += '\n// ---- Core %s commands\n' % cur_cmd.ext_name[11:].replace(2541 "_", ".")2542 else:2543 validation_source_funcs += '\n// ---- %s extension commands\n' % cur_cmd.ext_name2544 cur_extension_name = cur_cmd.ext_name2545 if cur_cmd.name in self.no_trampoline_or_terminator:2546 continue2547 # We fill in the GetInstanceProcAddr manually at the end2548 if cur_cmd.name == 'xrGetInstanceProcAddr':2549 continue2550 if cur_cmd.protect_value:2551 validation_source_funcs += '#if %s\n' % cur_cmd.protect_string2552 validation_source_funcs += '\n'2553 is_create = False2554 is_destroy = False2555 has_return = False2556 is_sempath_query = False2557 last_param = cur_cmd.params[-1]2558 if ('xrCreate' in cur_cmd.name or 'xrConnect' in cur_cmd.name) and last_param.is_handle:2559 is_create = True2560 has_return = True2561 elif ('xrDestroy' in cur_cmd.name or 'xrDisconnect' in cur_cmd.name) and last_param.is_handle:2562 is_destroy = True2563 has_return = True2564 elif cur_cmd.return_type is not None:2565 has_return = True2566 validation_source_funcs += self.genValidateInputsFunc(cur_cmd)2567 validation_source_funcs += self.genNextValidateFunc(2568 cur_cmd, has_return, is_create, is_destroy, is_sempath_query)2569 if cur_cmd.name not in VALID_USAGE_MANUALLY_DEFINED:2570 validation_source_funcs += self.genAutoValidateFunc(2571 cur_cmd, has_return)2572 if cur_cmd.protect_value:2573 validation_source_funcs += '#endif // %s\n' % cur_cmd.protect_string2574 validation_source_funcs += '\n'2575 validation_source_funcs += '\n// API Layer\'s xrGetInstanceProcAddr\n'2576 validation_source_funcs += 'XRAPI_ATTR XrResult XRAPI_CALL GenValidUsageXrGetInstanceProcAddr(\n'2577 validation_source_funcs += ' XrInstance instance,\n'2578 validation_source_funcs += ' const char* name,\n'2579 validation_source_funcs += ' PFN_xrVoidFunction* function) {\n'2580 validation_source_funcs += ' try {\n'2581 validation_source_funcs += ' std::string func_name = name;\n'2582 validation_source_funcs += ' std::vector<GenValidUsageXrObjectInfo> objects;\n'2583 validation_source_funcs += ' if (g_instance_info.verifyHandle(&instance) == VALIDATE_XR_HANDLE_INVALID) {\n'2584 validation_source_funcs += ' // Make sure the instance is valid if it is not XR_NULL_HANDLE\n'2585 validation_source_funcs += ' std::vector<GenValidUsageXrObjectInfo> objects;\n'2586 validation_source_funcs += ' objects.resize(1);\n'2587 validation_source_funcs += ' objects[0].handle = MakeHandleGeneric(instance);\n'2588 validation_source_funcs += ' objects[0].type = XR_OBJECT_TYPE_INSTANCE;\n'2589 validation_source_funcs += ' CoreValidLogMessage(nullptr, "VUID-xrGetInstanceProcAddr-instance-parameter",\n'2590 validation_source_funcs += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, "xrGetInstanceProcAddr", objects,\n'2591 validation_source_funcs += ' "Invalid instance handle provided.");\n'2592 validation_source_funcs += ' }\n'2593 validation_source_funcs += ' // NOTE: Can\'t validate "VUID-xrGetInstanceProcAddr-name-parameter" null-termination\n'2594 validation_source_funcs += ' // If we setup the function, just return\n'2595 validation_source_funcs += ' if (function == nullptr) {\n'2596 validation_source_funcs += ' CoreValidLogMessage(nullptr, "VUID-xrGetInstanceProcAddr-function-parameter",\n'2597 validation_source_funcs += ' VALID_USAGE_DEBUG_SEVERITY_ERROR, "xrGetInstanceProcAddr", objects,\n'2598 validation_source_funcs += ' "function is NULL");\n'2599 validation_source_funcs += ' return XR_ERROR_VALIDATION_FAILURE;\n'2600 validation_source_funcs += ' }\n'2601 count = 02602 for x in range(0, 2):2603 if x == 0:2604 commands = self.core_commands2605 else:2606 commands = self.ext_commands2607 for cur_cmd in commands:2608 if cur_cmd.ext_name != cur_extension_name:2609 if 'XR_VERSION_' in cur_cmd.ext_name:2610 validation_source_funcs += '\n // ---- Core %s commands\n' % cur_cmd.ext_name[11:].replace(2611 "_", ".")2612 else:2613 validation_source_funcs += '\n // ---- %s extension commands\n' % cur_cmd.ext_name2614 cur_extension_name = cur_cmd.ext_name2615 if cur_cmd.name in self.no_trampoline_or_terminator:2616 continue2617 has_return = False2618 if cur_cmd.return_type is not None:2619 has_return = True2620 if cur_cmd.name in VALID_USAGE_MANUALLY_DEFINED:2621 # Remove 'xr' from proto name and use manual name2622 layer_command_name = cur_cmd.name.replace(2623 "xr", "CoreValidationXr")2624 else:2625 # Remove 'xr' from proto name and use generated name2626 layer_command_name = cur_cmd.name.replace(2627 "xr", "GenValidUsageXr")2628 if cur_cmd.protect_value:2629 validation_source_funcs += '#if %s\n' % cur_cmd.protect_string2630 if count == 0:2631 validation_source_funcs += ' if (func_name == "%s") {\n' % cur_cmd.name2632 else:2633 validation_source_funcs += ' } else if (func_name == "%s") {\n' % cur_cmd.name2634 count = count + 12635 validation_source_funcs += ' *function = reinterpret_cast<PFN_xrVoidFunction>(%s);\n' % layer_command_name2636 if cur_cmd.protect_value:2637 validation_source_funcs += '#endif // %s\n' % cur_cmd.protect_string2638 validation_source_funcs += ' }\n'2639 validation_source_funcs += ' // If we setup the function, just return\n'2640 validation_source_funcs += ' if (*function != nullptr) {\n'2641 validation_source_funcs += ' return XR_SUCCESS;\n'2642 validation_source_funcs += ' }\n'2643 validation_source_funcs += ' // We have not found it, so pass it down to the next layer/runtime\n'2644 validation_source_funcs += ' GenValidUsageXrInstanceInfo* instance_valid_usage_info = g_instance_info.get(instance);\n'2645 validation_source_funcs += ' if (nullptr == instance_valid_usage_info) {\n'2646 validation_source_funcs += ' return XR_ERROR_HANDLE_INVALID;\n'2647 validation_source_funcs += ' }\n'2648 validation_source_funcs += ' return instance_valid_usage_info->dispatch_table->GetInstanceProcAddr(instance, name, function);\n'2649 validation_source_funcs += ' } catch (...) {\n'2650 validation_source_funcs += ' return XR_ERROR_VALIDATION_FAILURE;\n'2651 validation_source_funcs += ' }\n'2652 validation_source_funcs += '}\n'...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run tempest automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful