blob: faacdf3d8e67e6ce91c46a3b45a7cb24718e6439 [file] [log] [blame]
Tobin Ehlis35308dd2016-10-31 13:27:36 -06001#!/usr/bin/env python3
Dave Houltoncacef472018-05-29 13:00:42 -06002# Copyright (c) 2015-2018 The Khronos Group Inc.
3# Copyright (c) 2015-2018 Valve Corporation
4# Copyright (c) 2015-2018 LunarG, Inc.
5# Copyright (c) 2015-2018 Google Inc.
Tobin Ehlis35308dd2016-10-31 13:27:36 -06006#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19# Author: Tobin Ehlis <tobine@google.com>
Dave Houltoncacef472018-05-29 13:00:42 -060020# Author: Dave Houlton <daveh@lunarg.com>
Tobin Ehlis35308dd2016-10-31 13:27:36 -060021
22import argparse
23import os
24import sys
Dave Houltoncacef472018-05-29 13:00:42 -060025import operator
Tobin Ehlis35308dd2016-10-31 13:27:36 -060026import platform
Dave Houltoncacef472018-05-29 13:00:42 -060027import json
28import re
29import csv
30import html
31from collections import defaultdict
Tobin Ehlis35308dd2016-10-31 13:27:36 -060032
Dave Houltoncacef472018-05-29 13:00:42 -060033verbose_mode = False
34txt_db = False
35csv_db = False
36html_db = False
37txt_filename = "validation_error_database.txt"
38csv_filename = "validation_error_database.csv"
39html_filename = "validation_error_database.html"
Dave Houlton407df732018-08-06 17:58:24 -060040header_filename = "../layers/vk_validation_error_messages.h"
Dave Houltoncacef472018-05-29 13:00:42 -060041test_file = '../tests/layer_validation_tests.cpp'
42vuid_prefixes = ['VUID-', 'UNASSIGNED-']
Tobin Ehlis35308dd2016-10-31 13:27:36 -060043
Dave Houltoncacef472018-05-29 13:00:42 -060044# Hard-coded flags that could be command line args, if we decide that's useful
45# replace KHR vuids with non-KHR during consistency checking
46dealias_khr = True
47ignore_unassigned = True # These are not found in layer code unless they appear explicitly (most don't), so produce false positives
48
Mark Lobodzinski05849f02017-06-21 14:44:14 -060049generated_layer_source_directories = [
50'build',
51'dbuild',
52'release',
53]
54generated_layer_source_files = [
Mark Lobodzinskid4950072017-08-01 13:02:20 -060055'parameter_validation.cpp',
Mark Lobodzinski09fa2d42017-07-21 10:16:53 -060056'object_tracker.cpp',
Mark Lobodzinski05849f02017-06-21 14:44:14 -060057]
Tobin Ehlis35308dd2016-10-31 13:27:36 -060058layer_source_files = [
Mark Lobodzinskie3787b42017-06-21 13:41:00 -060059'../layers/core_validation.cpp',
60'../layers/descriptor_sets.cpp',
Mark Lobodzinskid4950072017-08-01 13:02:20 -060061'../layers/parameter_validation_utils.cpp',
Mark Lobodzinskib2de97f2017-07-06 15:28:11 -060062'../layers/object_tracker_utils.cpp',
Mark Lobodzinskie3787b42017-06-21 13:41:00 -060063'../layers/shader_validation.cpp',
64'../layers/buffer_validation.cpp',
Tobin Ehlis35308dd2016-10-31 13:27:36 -060065]
Tobin Ehlis35308dd2016-10-31 13:27:36 -060066
Dave Houlton407df732018-08-06 17:58:24 -060067# This needs to be updated as new extensions roll in
Dave Houltoncacef472018-05-29 13:00:42 -060068khr_aliases = {
69 'VUID-vkBindBufferMemory2KHR-device-parameter' : 'VUID-vkBindBufferMemory2-device-parameter',
70 'VUID-vkBindBufferMemory2KHR-pBindInfos-parameter' : 'VUID-vkBindBufferMemory2-pBindInfos-parameter',
71 'VUID-vkBindImageMemory2KHR-device-parameter' : 'VUID-vkBindImageMemory2-device-parameter',
72 'VUID-vkBindImageMemory2KHR-pBindInfos-parameter' : 'VUID-vkBindImageMemory2-pBindInfos-parameter',
73 'VUID-vkCmdDispatchBaseKHR-commandBuffer-parameter' : 'VUID-vkCmdDispatchBase-commandBuffer-parameter',
74 'VUID-vkCmdSetDeviceMaskKHR-commandBuffer-parameter' : 'VUID-vkCmdSetDeviceMask-commandBuffer-parameter',
75 'VUID-vkCreateDescriptorUpdateTemplateKHR-device-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-device-parameter',
76 'VUID-vkCreateDescriptorUpdateTemplateKHR-pDescriptorUpdateTemplate-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-pDescriptorUpdateTemplate-parameter',
77 'VUID-vkCreateSamplerYcbcrConversionKHR-device-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-device-parameter',
78 'VUID-vkCreateSamplerYcbcrConversionKHR-pYcbcrConversion-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-pYcbcrConversion-parameter',
79 'VUID-vkDestroyDescriptorUpdateTemplateKHR-descriptorUpdateTemplate-parameter' : 'VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parameter',
80 'VUID-vkDestroyDescriptorUpdateTemplateKHR-descriptorUpdateTemplate-parent' : 'VUID-vkDestroyDescriptorUpdateTemplate-descriptorUpdateTemplate-parent',
81 'VUID-vkDestroyDescriptorUpdateTemplateKHR-device-parameter' : 'VUID-vkDestroyDescriptorUpdateTemplate-device-parameter',
82 'VUID-vkDestroySamplerYcbcrConversionKHR-device-parameter' : 'VUID-vkDestroySamplerYcbcrConversion-device-parameter',
83 'VUID-vkDestroySamplerYcbcrConversionKHR-ycbcrConversion-parameter' : 'VUID-vkDestroySamplerYcbcrConversion-ycbcrConversion-parameter',
84 'VUID-vkDestroySamplerYcbcrConversionKHR-ycbcrConversion-parent' : 'VUID-vkDestroySamplerYcbcrConversion-ycbcrConversion-parent',
85 'VUID-vkEnumeratePhysicalDeviceGroupsKHR-instance-parameter' : 'VUID-vkEnumeratePhysicalDeviceGroups-instance-parameter',
86 'VUID-vkEnumeratePhysicalDeviceGroupsKHR-pPhysicalDeviceGroupProperties-parameter' : 'VUID-vkEnumeratePhysicalDeviceGroups-pPhysicalDeviceGroupProperties-parameter',
87 'VUID-vkGetBufferMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetBufferMemoryRequirements2-device-parameter',
88 'VUID-vkGetDescriptorSetLayoutSupportKHR-device-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-device-parameter',
89 'VUID-vkGetDeviceGroupPeerMemoryFeaturesKHR-device-parameter' : 'VUID-vkGetDeviceGroupPeerMemoryFeatures-device-parameter',
90 'VUID-vkGetDeviceGroupPeerMemoryFeaturesKHR-pPeerMemoryFeatures-parameter' : 'VUID-vkGetDeviceGroupPeerMemoryFeatures-pPeerMemoryFeatures-parameter',
91 'VUID-vkGetImageMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetImageMemoryRequirements2-device-parameter',
92 'VUID-vkGetImageSparseMemoryRequirements2KHR-device-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-device-parameter',
93 'VUID-vkGetImageSparseMemoryRequirements2KHR-pSparseMemoryRequirements-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-pSparseMemoryRequirements-parameter',
94 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-physicalDevice-parameter',
95 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-physicalDevice-parameter',
96 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-physicalDevice-parameter',
97 'VUID-vkGetPhysicalDeviceFeatures2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceFeatures2-physicalDevice-parameter',
98 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-format-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-format-parameter',
99 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-physicalDevice-parameter',
100 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-physicalDevice-parameter',
101 'VUID-vkGetPhysicalDeviceMemoryProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceMemoryProperties2-physicalDevice-parameter',
102 'VUID-vkGetPhysicalDeviceProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceProperties2-physicalDevice-parameter',
103 'VUID-vkGetPhysicalDeviceQueueFamilyProperties2KHR-pQueueFamilyProperties-parameter' : 'VUID-vkGetPhysicalDeviceQueueFamilyProperties2-pQueueFamilyProperties-parameter',
104 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-pProperties-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pProperties-parameter',
105 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-physicalDevice-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-physicalDevice-parameter',
106 'VUID-vkTrimCommandPoolKHR-commandPool-parameter' : 'VUID-vkTrimCommandPool-commandPool-parameter',
107 'VUID-vkTrimCommandPoolKHR-commandPool-parent' : 'VUID-vkTrimCommandPool-commandPool-parent',
108 'VUID-vkTrimCommandPoolKHR-device-parameter' : 'VUID-vkTrimCommandPool-device-parameter',
109 'VUID-vkTrimCommandPoolKHR-flags-zerobitmask' : 'VUID-vkTrimCommandPool-flags-zerobitmask',
110 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorSet-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorSet-parameter',
111 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parameter',
112 'VUID-vkUpdateDescriptorSetWithTemplateKHR-descriptorUpdateTemplate-parent' : 'VUID-vkUpdateDescriptorSetWithTemplate-descriptorUpdateTemplate-parent',
113 'VUID-vkUpdateDescriptorSetWithTemplateKHR-device-parameter' : 'VUID-vkUpdateDescriptorSetWithTemplate-device-parameter',
114 'VUID-vkCreateDescriptorUpdateTemplateKHR-pCreateInfo-parameter' : 'VUID-vkCreateDescriptorUpdateTemplate-pCreateInfo-parameter',
115 'VUID-vkCreateSamplerYcbcrConversionKHR-pCreateInfo-parameter' : 'VUID-vkCreateSamplerYcbcrConversion-pCreateInfo-parameter',
116 'VUID-vkGetBufferMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetBufferMemoryRequirements2-pInfo-parameter',
117 'VUID-vkGetBufferMemoryRequirements2KHR-pMemoryRequirements-parameter' : 'VUID-vkGetBufferMemoryRequirements2-pMemoryRequirements-parameter',
118 'VUID-vkGetDescriptorSetLayoutSupportKHR-pCreateInfo-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-pCreateInfo-parameter',
119 'VUID-vkGetDescriptorSetLayoutSupportKHR-pSupport-parameter' : 'VUID-vkGetDescriptorSetLayoutSupport-pSupport-parameter',
120 'VUID-vkGetImageMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetImageMemoryRequirements2-pInfo-parameter',
121 'VUID-vkGetImageMemoryRequirements2KHR-pMemoryRequirements-parameter' : 'VUID-vkGetImageMemoryRequirements2-pMemoryRequirements-parameter',
122 'VUID-vkGetImageSparseMemoryRequirements2KHR-pInfo-parameter' : 'VUID-vkGetImageSparseMemoryRequirements2-pInfo-parameter',
123 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-pExternalBufferInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-pExternalBufferInfo-parameter',
124 'VUID-vkGetPhysicalDeviceExternalBufferPropertiesKHR-pExternalBufferProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalBufferProperties-pExternalBufferProperties-parameter',
125 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-pExternalFenceInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-pExternalFenceInfo-parameter',
126 'VUID-vkGetPhysicalDeviceExternalFencePropertiesKHR-pExternalFenceProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalFenceProperties-pExternalFenceProperties-parameter',
127 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-pExternalSemaphoreInfo-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-pExternalSemaphoreInfo-parameter',
128 'VUID-vkGetPhysicalDeviceExternalSemaphorePropertiesKHR-pExternalSemaphoreProperties-parameter' : 'VUID-vkGetPhysicalDeviceExternalSemaphoreProperties-pExternalSemaphoreProperties-parameter',
129 'VUID-vkGetPhysicalDeviceFeatures2KHR-pFeatures-parameter' : 'VUID-vkGetPhysicalDeviceFeatures2-pFeatures-parameter',
130 'VUID-vkGetPhysicalDeviceFormatProperties2KHR-pFormatProperties-parameter' : 'VUID-vkGetPhysicalDeviceFormatProperties2-pFormatProperties-parameter',
131 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-pImageFormatInfo-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-pImageFormatInfo-parameter',
132 'VUID-vkGetPhysicalDeviceImageFormatProperties2KHR-pImageFormatProperties-parameter' : 'VUID-vkGetPhysicalDeviceImageFormatProperties2-pImageFormatProperties-parameter',
133 'VUID-vkGetPhysicalDeviceMemoryProperties2KHR-pMemoryProperties-parameter' : 'VUID-vkGetPhysicalDeviceMemoryProperties2-pMemoryProperties-parameter',
134 'VUID-vkGetPhysicalDeviceProperties2KHR-pProperties-parameter' : 'VUID-vkGetPhysicalDeviceProperties2-pProperties-parameter',
135 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2KHR-pFormatInfo-parameter' : 'VUID-vkGetPhysicalDeviceSparseImageFormatProperties2-pFormatInfo-parameter' }
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600136
Dave Houltoncacef472018-05-29 13:00:42 -0600137def printHelp():
138 print ("Usage:")
139 print (" python vk_validation_stats.py <json_file>")
140 print (" [ -c ]")
141 print (" [ -todo ]")
142 print (" [ -vuid <vuid_name> ]")
143 print (" [ -text [ <text_out_filename>] ]")
144 print (" [ -csv [ <csv_out_filename>] ]")
145 print (" [ -html [ <html_out_filename>] ]")
Dave Houlton407df732018-08-06 17:58:24 -0600146 print (" [ -export_header ]")
Dave Houltoncacef472018-05-29 13:00:42 -0600147 print (" [ -verbose ]")
148 print (" [ -help ]")
149 print ("\n The vk_validation_stats script parses validation layer source files to")
150 print (" determine the set of valid usage checks and tests currently implemented,")
151 print (" and generates coverage values by comparing against the full set of valid")
152 print (" usage identifiers in the Vulkan-Headers registry file 'validusage.json'")
153 print ("\nArguments: ")
154 print (" <json-file> (required) registry file 'validusage.json'")
155 print (" -c report consistency warnings")
156 print (" -todo report unimplemented VUIDs")
157 print (" -vuid <vuid_name> report status of individual VUID <vuid_name>")
158 print (" -text [filename] output the error database text to <text_database_filename>,")
159 print (" defaults to 'validation_error_database.txt'")
160 print (" -csv [filename] output the error database in csv to <csv_database_filename>,")
161 print (" defaults to 'validation_error_database.csv'")
162 print (" -html [filename] output the error database in html to <html_database_filename>,")
163 print (" defaults to 'validation_error_database.html'")
Dave Houlton407df732018-08-06 17:58:24 -0600164 print (" -export_header export a new VUID error text header file to <%s>" % header_filename)
Dave Houltoncacef472018-05-29 13:00:42 -0600165 print (" -verbose show your work (to stdout)")
166
167class ValidationJSON:
168 def __init__(self, filename):
169 self.filename = filename
170 self.explicit_vuids = set()
171 self.implicit_vuids = set()
172 self.all_vuids = set()
173 self.vuid_db = defaultdict(list) # Maps VUID string to list of json-data dicts
174 self.apiversion = ""
Dave Houltoncacef472018-05-29 13:00:42 -0600175 self.duplicate_vuids = set()
Dave Houlton407df732018-08-06 17:58:24 -0600176
177 # A set of specific regular expression substitutions needed to clean up VUID text
178 self.regex_dict = {}
179 self.regex_dict[re.compile('<.*?>|&(amp;)+lt;|&(amp;)+gt;')] = ""
180 self.regex_dict[re.compile(r'\\\(codeSize \\over 4\\\)')] = "(codeSize/4)"
181 self.regex_dict[re.compile(r'\\\(\\lceil\{\\mathit\{rasterizationSamples} \\over 32}\\rceil\\\)')] = "(rasterizationSamples/32)"
182 # Some fancy punctuation chars that break the Android build...
183 self.regex_dict[re.compile('&#8594;')] = "->" # Arrow char
184 self.regex_dict[re.compile('&#8217;')] = "'" # Left-slanting apostrophe to apostrophe
185 self.regex_dict[re.compile('&#822(0|1);')] = "'" # L/R-slanting quotes to apostrophe
Dave Houltoncacef472018-05-29 13:00:42 -0600186
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600187 def read(self):
Dave Houltoncacef472018-05-29 13:00:42 -0600188 self.json_dict = {}
189 if os.path.isfile(self.filename):
Dave Houlton407df732018-08-06 17:58:24 -0600190 json_file = open(self.filename, 'r', encoding='utf-8')
Dave Houltoncacef472018-05-29 13:00:42 -0600191 self.json_dict = json.load(json_file)
192 json_file.close()
193 if len(self.json_dict) == 0:
194 print("Error: Error loading validusage.json file <%s>" % self.filename)
195 sys.exit(-1)
196 try:
197 version = self.json_dict['version info']
198 validation = self.json_dict['validation']
199 self.apiversion = version['api version']
200 except:
201 print("Error: Failure parsing validusage.json object")
202 sys.exit(-1)
203
204 # Parse vuid from json into local databases
205 for apiname in validation.keys():
206 # print("entrypoint:%s"%apiname)
207 apidict = validation[apiname]
208 for ext in apidict.keys():
209 vlist = apidict[ext]
210 for ventry in vlist:
211 vuid_string = ventry['vuid']
212 if (vuid_string[-5:-1].isdecimal()):
213 self.explicit_vuids.add(vuid_string) # explicit end in 5 numeric chars
214 vtype = 'explicit'
215 else:
216 self.implicit_vuids.add(vuid_string) # otherwise, implicit
217 vtype = 'implicit'
218 vuid_text = ventry['text']
Dave Houlton407df732018-08-06 17:58:24 -0600219 for regex, replacement in self.regex_dict.items():
220 vuid_text = re.sub(regex, replacement, vuid_text) # do regex substitution
221 vuid_text = html.unescape(vuid_text) # anything missed by the regex
222 self.vuid_db[vuid_string].append({'api':apiname, 'ext':ext, 'type':vtype, 'text':vuid_text})
Dave Houltoncacef472018-05-29 13:00:42 -0600223 self.all_vuids = self.explicit_vuids | self.implicit_vuids
224 self.duplicate_vuids = set({v for v in self.vuid_db if len(self.vuid_db[v]) > 1})
Dave Houlton407df732018-08-06 17:58:24 -0600225 if len(self.duplicate_vuids) > 0:
226 print("Warning: duplicate VUIDs found in validusage.json")
227
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600228
229class ValidationSource:
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600230 def __init__(self, source_file_list, generated_source_file_list, generated_source_directories):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600231 self.source_files = source_file_list
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600232 self.generated_source_files = generated_source_file_list
233 self.generated_source_dirs = generated_source_directories
Dave Houltoncacef472018-05-29 13:00:42 -0600234 self.vuid_count_dict = {} # dict of vuid values to the count of how much they're used, and location of where they're used
235 self.duplicated_checks = 0
236 self.explicit_vuids = set()
237 self.implicit_vuids = set()
238 self.unassigned_vuids = set()
239 self.all_vuids = set()
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600240
241 if len(self.generated_source_files) > 0:
242 qualified_paths = []
243 for source in self.generated_source_files:
244 for build_dir in self.generated_source_dirs:
245 filepath = '../%s/layers/%s' % (build_dir, source)
246 if os.path.isfile(filepath):
247 qualified_paths.append(filepath)
John Zulaufdde04c42018-01-16 15:32:45 -0700248 break
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600249 if len(self.generated_source_files) != len(qualified_paths):
Mark Lobodzinski2d193ac2017-06-27 09:38:15 -0600250 print("Error: Unable to locate one or more of the following source files in the %s directories" % (", ".join(generated_source_directories)))
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600251 print(self.generated_source_files)
Dave Houltoncacef472018-05-29 13:00:42 -0600252 print("Failed to locate one or more codegen files in layer source code - cannot proceed.")
John Zulaufdde04c42018-01-16 15:32:45 -0700253 exit(1)
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600254 else:
255 self.source_files.extend(qualified_paths)
256
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600257 def parse(self):
Dave Houltoncacef472018-05-29 13:00:42 -0600258 prepend = None
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600259 for sf in self.source_files:
Tobin Ehlis3d1f2bd2016-12-22 11:19:15 -0700260 line_num = 0
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600261 with open(sf) as f:
262 for line in f:
Tobin Ehlis3d1f2bd2016-12-22 11:19:15 -0700263 line_num = line_num + 1
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600264 if True in [line.strip().startswith(comment) for comment in ['//', '/*']]:
265 continue
Dave Houltoncacef472018-05-29 13:00:42 -0600266 # Find vuid strings
267 if prepend != None:
268 line = prepend[:-2] + line.lstrip().lstrip('"') # join lines skipping CR, whitespace and trailing/leading quote char
269 prepend = None
270 if any(prefix in line for prefix in vuid_prefixes):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600271 line_list = line.split()
Dave Houltoncacef472018-05-29 13:00:42 -0600272
273 # A VUID string that has been broken by clang will start with a vuid prefix and end with -, and will be last in the list
274 broken_vuid = line_list[-1].strip('"')
275 if any(broken_vuid.startswith(prefix) for prefix in vuid_prefixes) and broken_vuid.endswith('-'):
276 prepend = line
277 continue
278
279 vuid_list = []
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600280 for str in line_list:
Dave Houltoncacef472018-05-29 13:00:42 -0600281 if any(prefix in str for prefix in vuid_prefixes):
282 vuid_list.append(str.strip(',);{}"'))
283 for vuid in vuid_list:
284 if vuid not in self.vuid_count_dict:
285 self.vuid_count_dict[vuid] = {}
286 self.vuid_count_dict[vuid]['count'] = 1
287 self.vuid_count_dict[vuid]['file_line'] = []
288 else:
289 if self.vuid_count_dict[vuid]['count'] == 1: # only count first time duplicated
290 self.duplicated_checks = self.duplicated_checks + 1
291 self.vuid_count_dict[vuid]['count'] = self.vuid_count_dict[vuid]['count'] + 1
292 self.vuid_count_dict[vuid]['file_line'].append('%s,%d' % (sf, line_num))
293 # Sort vuids by type
294 for vuid in self.vuid_count_dict.keys():
295 if (vuid.startswith('VUID-')):
296 if (vuid[-5:-1].isdecimal()):
297 self.explicit_vuids.add(vuid) # explicit end in 5 numeric chars
298 else:
299 self.implicit_vuids.add(vuid)
300 elif (vuid.startswith('UNASSIGNED-')):
301 self.unassigned_vuids.add(vuid)
302 else:
303 print("Unable to categorize VUID: %s" % vuid)
304 print("Confused while parsing VUIDs in layer source code - cannot proceed. (FIXME)")
305 exit(-1)
306 self.all_vuids = self.explicit_vuids | self.implicit_vuids | self.unassigned_vuids
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600307
308# Class to parse the validation layer test source and store testnames
Dave Houltoncacef472018-05-29 13:00:42 -0600309class ValidationTests:
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600310 def __init__(self, test_file_list, test_group_name=['VkLayerTest', 'VkPositiveLayerTest', 'VkWsiEnabledLayerTest']):
311 self.test_files = test_file_list
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600312 self.test_trigger_txt_list = []
313 for tg in test_group_name:
314 self.test_trigger_txt_list.append('TEST_F(%s' % tg)
Dave Houltoncacef472018-05-29 13:00:42 -0600315 self.explicit_vuids = set()
316 self.implicit_vuids = set()
317 self.unassigned_vuids = set()
318 self.all_vuids = set()
319 #self.test_to_vuids = {} # Map test name to VUIDs tested
320 self.vuid_to_tests = defaultdict(set) # Map VUIDs to set of test names where implemented
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600321
322 # Parse test files into internal data struct
323 def parse(self):
324 # For each test file, parse test names into set
325 grab_next_line = False # handle testname on separate line than wildcard
Tobin Ehlis9a68c982016-12-29 14:51:17 -0700326 testname = ''
Dave Houltoncacef472018-05-29 13:00:42 -0600327 prepend = None
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600328 for test_file in self.test_files:
329 with open(test_file) as tf:
330 for line in tf:
331 if True in [line.strip().startswith(comment) for comment in ['//', '/*']]:
332 continue
333
Dave Houltoncacef472018-05-29 13:00:42 -0600334 # if line ends in a broken VUID string, fix that before proceeding
335 if prepend != None:
336 line = prepend[:-2] + line.lstrip().lstrip('"') # join lines skipping CR, whitespace and trailing/leading quote char
337 prepend = None
338 if any(prefix in line for prefix in vuid_prefixes):
339 line_list = line.split()
340
341 # A VUID string that has been broken by clang will start with a vuid prefix and end with -, and will be last in the list
342 broken_vuid = line_list[-1].strip('"')
343 if any(broken_vuid.startswith(prefix) for prefix in vuid_prefixes) and broken_vuid.endswith('-'):
344 prepend = line
345 continue
346
347 if any(ttt in line for ttt in self.test_trigger_txt_list):
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600348 testname = line.split(',')[-1]
349 testname = testname.strip().strip(' {)')
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600350 if ('' == testname):
351 grab_next_line = True
352 continue
Dave Houltoncacef472018-05-29 13:00:42 -0600353 #self.test_to_vuids[testname] = []
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600354 if grab_next_line: # test name on its own line
355 grab_next_line = False
356 testname = testname.strip().strip(' {)')
Dave Houltoncacef472018-05-29 13:00:42 -0600357 #self.test_to_vuids[testname] = []
358 if any(prefix in line for prefix in vuid_prefixes):
359 line_list = re.split('[\s{}[\]()"]+',line)
Tobin Ehlis71f38c12017-01-12 14:26:56 -0700360 for sub_str in line_list:
Dave Houltoncacef472018-05-29 13:00:42 -0600361 if any(prefix in sub_str for prefix in vuid_prefixes):
362 vuid_str = sub_str.strip(',);:"')
363 self.vuid_to_tests[vuid_str].add(testname)
364 #self.test_to_vuids[testname].append(vuid_str)
365 if (vuid_str.startswith('VUID-')):
366 if (vuid_str[-5:-1].isdecimal()):
367 self.explicit_vuids.add(vuid_str) # explicit end in 5 numeric chars
368 else:
369 self.implicit_vuids.add(vuid_str)
370 elif (vuid_str.startswith('UNASSIGNED-')):
371 self.unassigned_vuids.add(vuid_str)
372 else:
373 print("Unable to categorize VUID: %s" % vuid_str)
374 print("Confused while parsing VUIDs in test code - cannot proceed. (FIXME)")
375 exit(-1)
376 self.all_vuids = self.explicit_vuids | self.implicit_vuids | self.unassigned_vuids
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600377
Dave Houltoncacef472018-05-29 13:00:42 -0600378# Class to do consistency checking
379#
380class Consistency:
381 def __init__(self, all_json, all_checks, all_tests):
382 self.valid = all_json
383 self.checks = all_checks
384 self.tests = all_tests
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600385
Dave Houltoncacef472018-05-29 13:00:42 -0600386 if (dealias_khr):
387 dk = set()
388 for vuid in self.checks:
389 if vuid in khr_aliases:
390 dk.add(khr_aliases[vuid])
391 else:
392 dk.add(vuid)
393 self.checks = dk
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600394
Dave Houltoncacef472018-05-29 13:00:42 -0600395 dk = set()
396 for vuid in self.tests:
397 if vuid in khr_aliases:
398 dk.add(khr_aliases[vuid])
399 else:
400 dk.add(vuid)
401 self.tests = dk
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600402
Dave Houltoncacef472018-05-29 13:00:42 -0600403 # Report undefined VUIDs in source code
404 def undef_vuids_in_layer_code(self):
405 undef_set = self.checks - self.valid
406 undef_set.discard('VUID-Undefined') # don't report Undefined
407 if ignore_unassigned:
408 unassigned = set({uv for uv in undef_set if uv.startswith('UNASSIGNED-')})
409 undef_set = undef_set - unassigned
410 if (len(undef_set) > 0):
411 print("\nFollowing VUIDs found in layer code are not defined in validusage.json (%d):" % len(undef_set))
412 undef = list(undef_set)
413 undef.sort()
414 for vuid in undef:
415 print(" %s" % vuid)
416 return False
417 return True
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600418
Dave Houltoncacef472018-05-29 13:00:42 -0600419 # Report undefined VUIDs in tests
420 def undef_vuids_in_tests(self):
421 undef_set = self.tests - self.valid
422 undef_set.discard('VUID-Undefined') # don't report Undefined
423 if ignore_unassigned:
424 unassigned = set({uv for uv in undef_set if uv.startswith('UNASSIGNED-')})
425 undef_set = undef_set - unassigned
426 if (len(undef_set) > 0):
427 ok = False
428 print("\nFollowing VUIDs found in layer tests are not defined in validusage.json (%d):" % len(undef_set))
429 undef = list(undef_set)
430 undef.sort()
431 for vuid in undef:
432 print(" %s" % vuid)
433 return False
434 return True
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600435
Dave Houltoncacef472018-05-29 13:00:42 -0600436 # Report vuids in tests that are not in source
437 def vuids_tested_not_checked(self):
438 undef_set = self.tests - self.checks
439 undef_set.discard('VUID-Undefined') # don't report Undefined
440 if ignore_unassigned:
441 unassigned = set()
442 for vuid in undef_set:
443 if vuid.startswith('UNASSIGNED-'):
444 unassigned.add(vuid)
445 undef_set = undef_set - unassigned
446 if (len(undef_set) > 0):
447 ok = False
448 print("\nFollowing VUIDs found in tests but are not checked in layer code (%d):" % len(undef_set))
449 undef = list(undef_set)
450 undef.sort()
451 for vuid in undef:
452 print(" %s" % vuid)
453 return False
454 return True
455
456 # TODO: Explicit checked VUIDs which have no test
457 # def explicit_vuids_checked_not_tested(self):
458
459
460# Class to output database in various flavors
461#
462class OutputDatabase:
463 def __init__(self, val_json, val_source, val_tests):
464 self.vj = val_json
465 self.vs = val_source
466 self.vt = val_tests
Dave Houlton407df732018-08-06 17:58:24 -0600467 self.header_preamble = """/* THIS FILE IS GENERATED. DO NOT EDIT. */
468/* (scripts/vk_validation_stats.py) */
469/*
470 * Vulkan
471 *
472 * Copyright (c) 2016-2018 Google Inc.
473 * Copyright (c) 2016-2018 LunarG, Inc.
474 *
475 * Licensed under the Apache License, Version 2.0 (the "License");
476 * you may not use this file except in compliance with the License.
477 * You may obtain a copy of the License at
478 *
479 * http://www.apache.org/licenses/LICENSE-2.0
480 *
481 * Unless required by applicable law or agreed to in writing, software
482 * distributed under the License is distributed on an "AS IS" BASIS,
483 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
484 * See the License for the specific language governing permissions and
485 * limitations under the License.
486 *
487 * Author: Tobin Ehlis <tobine@google.com>
488 * Author: Dave Houlton <daveh@lunarg.com>
489 */
490
491#pragma once
492
493// Disable auto-formatting for generated file
494// clang-format off
495
496#include <string>
497#include <unordered_map>
498
499// Mapping from VUID string to the corresponding spec text
500#ifdef VALIDATION_ERROR_MAP_IMPL
501std::unordered_map<std::string, std::string> vuid_to_error_text_map {
502"""
503 self.header_postamble = """};
504#else
505extern std::unordered_map<std::string, std::string> vuid_to_error_text_map;
506#endif"""
507 self.spec_url = "https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html"
Dave Houltoncacef472018-05-29 13:00:42 -0600508
509 def dump_txt(self):
510 print("\n Dumping database to text file: %s" % txt_filename)
511 with open (txt_filename, 'w') as txt:
512 txt.write("## VUID Database\n")
513 txt.write("## Format: VUID_NAME | CHECKED | TEST | TYPE | API/STRUCT | EXTENSION | VUID_TEXT\n##\n")
514 vuid_list = list(self.vj.all_vuids)
515 vuid_list.sort()
516 for vuid in vuid_list:
517 db_list = self.vj.vuid_db[vuid]
518 db_list.sort(key=operator.itemgetter('ext')) # sort list to ease diffs of output file
519 for db_entry in db_list:
520 checked = 'N'
521 if vuid in self.vs.all_vuids:
522 checked = 'Y'
523 test = 'None'
524 if vuid in self.vt.vuid_to_tests:
525 test_list = list(self.vt.vuid_to_tests[vuid])
526 test_list.sort() # sort tests, for diff-ability
527 sep = ', '
528 test = sep.join(test_list)
529
530 txt.write("%s | %s | %s | %s | %s | %s | %s\n" % (vuid, checked, test, db_entry['type'], db_entry['api'], db_entry['ext'], db_entry['text']))
531
532 def dump_csv(self):
533 print("\n Dumping database to csv file: %s" % csv_filename)
534 with open (csv_filename, 'w', newline='') as csvfile:
535 cw = csv.writer(csvfile)
536 cw.writerow(['VUID_NAME','CHECKED','TEST','TYPE','API/STRUCT','EXTENSION','VUID_TEXT'])
537 vuid_list = list(self.vj.all_vuids)
538 vuid_list.sort()
539 for vuid in vuid_list:
540 for db_entry in self.vj.vuid_db[vuid]:
541 row = [vuid]
542 if vuid in self.vs.all_vuids:
543 row.append('Y')
544 else:
545 row.append('N')
546 test = 'None'
547 if vuid in self.vt.vuid_to_tests:
548 sep = ', '
549 test = sep.join(self.vt.vuid_to_tests[vuid])
550 row.append(test)
551 row.append(db_entry['type'])
552 row.append(db_entry['api'])
553 row.append(db_entry['ext'])
554 row.append(db_entry['text'])
555 cw.writerow(row)
556
557 def dump_html(self):
558 print("\n Dumping database to html file: %s" % html_filename)
559 preamble = '<!DOCTYPE html>\n<html>\n<head>\n<style>\ntable, th, td {\n border: 1px solid black;\n border-collapse: collapse; \n}\n</style>\n<body>\n<h2>Valid Usage Database</h2>\n<font size="2" face="Arial">\n<table style="width:100%">\n'
560 headers = '<tr><th>VUID NAME</th><th>CHECKED</th><th>TEST</th><th>TYPE</th><th>API/STRUCT</th><th>EXTENSION</th><th>VUID TEXT</th></tr>\n'
561 with open (html_filename, 'w') as hfile:
562 hfile.write(preamble)
563 hfile.write(headers)
564 vuid_list = list(self.vj.all_vuids)
565 vuid_list.sort()
566 for vuid in vuid_list:
567 for db_entry in self.vj.vuid_db[vuid]:
568 hfile.write('<tr><th>%s</th>' % vuid)
569 checked = '<span style="color:red;">N</span>'
570 if vuid in self.vs.all_vuids:
571 checked = '<span style="color:limegreen;">Y</span>'
572 hfile.write('<th>%s</th>' % checked)
573 test = 'None'
574 if vuid in self.vt.vuid_to_tests:
575 sep = ', '
576 test = sep.join(self.vt.vuid_to_tests[vuid])
577 hfile.write('<th>%s</th>' % test)
578 hfile.write('<th>%s</th>' % db_entry['type'])
579 hfile.write('<th>%s</th>' % db_entry['api'])
580 hfile.write('<th>%s</th>' % db_entry['ext'])
581 hfile.write('<th>%s</th></tr>\n' % db_entry['text'])
582 hfile.write('</table>\n</body>\n</html>\n')
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600583
Dave Houlton407df732018-08-06 17:58:24 -0600584 def export_header(self):
585 print("\n Exporting header file to: %s" % header_filename)
586 with open (header_filename, 'w') as hfile:
587 hfile.write(self.header_preamble)
588 vuid_list = list(self.vj.all_vuids)
589 vuid_list.sort()
590 for vuid in vuid_list:
591 db_entry = self.vj.vuid_db[vuid][0]
592 hfile.write(' {"%s", "%s (%s#%s)"},\n' % (vuid, db_entry['text'].strip(' '), self.spec_url, vuid))
593 # For multiply-defined VUIDs, include versions with extension appended
594 if len(self.vj.vuid_db[vuid]) > 1:
595 for db_entry in self.vj.vuid_db[vuid]:
596 hfile.write(' {"%s[%s]", "%s (%s#%s)"},\n' % (vuid, db_entry['ext'].strip(' '), db_entry['text'].strip(' '), self.spec_url, vuid))
597 hfile.write(self.header_postamble)
598
Mark Lobodzinskib44c54a2017-06-12 12:02:38 -0600599def main(argv):
Dave Houltoncacef472018-05-29 13:00:42 -0600600 global verbose_mode
601 global txt_filename
602 global csv_filename
603 global html_filename
604
605 run_consistency = False
606 report_unimplemented = False
607 get_vuid_status = ''
608 txt_out = False
609 csv_out = False
610 html_out = False
Dave Houlton407df732018-08-06 17:58:24 -0600611 header_out = False
Dave Houltoncacef472018-05-29 13:00:42 -0600612
613 if (1 > len(argv)):
614 printHelp()
615 sys.exit()
616
617 # Parse script args
618 json_filename = argv[0]
619 i = 1
620 while (i < len(argv)):
621 arg = argv[i]
622 i = i + 1
623 if (arg == '-c'):
624 run_consistency = True
625 elif (arg == '-vuid'):
626 get_vuid_status = argv[i]
627 i = i + 1
628 elif (arg == '-todo'):
629 report_unimplemented = True
Karl Schultz49d66bb2018-07-09 16:24:46 -0600630 elif (arg == '-text'):
Dave Houltoncacef472018-05-29 13:00:42 -0600631 txt_out = True
632 # Set filename if supplied, else use default
633 if i < len(argv) and not argv[i].startswith('-'):
634 txt_filename = argv[i]
635 i = i + 1
636 elif (arg == '-csv'):
637 csv_out = True
638 # Set filename if supplied, else use default
639 if i < len(argv) and not argv[i].startswith('-'):
640 csv_filename = argv[i]
641 i = i + 1
642 elif (arg == '-html'):
643 html_out = True
644 # Set filename if supplied, else use default
645 if i < len(argv) and not argv[i].startswith('-'):
646 html_filename = argv[i]
647 i = i + 1
Dave Houlton407df732018-08-06 17:58:24 -0600648 elif (arg == '-export_header'):
649 header_out = True
Dave Houltoncacef472018-05-29 13:00:42 -0600650 elif (arg in ['-verbose']):
651 verbose_mode = True
652 elif (arg in ['-help', '-h']):
653 printHelp()
654 sys.exit()
655 else:
656 print("Unrecognized argument: %s\n" % arg)
657 printHelp()
658 sys.exit()
659
Tobin Ehlis20e32582016-12-05 14:50:03 -0700660 result = 0 # Non-zero result indicates an error case
Dave Houltoncacef472018-05-29 13:00:42 -0600661
662 # Parse validusage json
663 val_json = ValidationJSON(json_filename)
664 val_json.read()
665 exp_json = len(val_json.explicit_vuids)
666 imp_json = len(val_json.implicit_vuids)
667 all_json = len(val_json.all_vuids)
668 if verbose_mode:
669 print("Found %d unique error vuids in validusage.json file." % all_json)
670 print(" %d explicit" % exp_json)
671 print(" %d implicit" % imp_json)
672 if len(val_json.duplicate_vuids) > 0:
673 print("%d VUIDs appear in validusage.json more than once." % len(val_json.duplicate_vuids))
674 for vuid in val_json.duplicate_vuids:
675 print(" %s" % vuid)
676 for ext in val_json.vuid_db[vuid]:
677 print(" with extension: %s" % ext['ext'])
678
679 # Parse layer source files
Mark Lobodzinski05849f02017-06-21 14:44:14 -0600680 val_source = ValidationSource(layer_source_files, generated_layer_source_files, generated_layer_source_directories)
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600681 val_source.parse()
Dave Houltoncacef472018-05-29 13:00:42 -0600682 exp_checks = len(val_source.explicit_vuids)
683 imp_checks = len(val_source.implicit_vuids)
684 all_checks = len(val_source.vuid_count_dict.keys())
685 if verbose_mode:
686 print("Found %d unique vuid checks in layer source code." % all_checks)
687 print(" %d explicit" % exp_checks)
688 print(" %d implicit" % imp_checks)
689 print(" %d unassigned" % len(val_source.unassigned_vuids))
690 print(" %d checks are implemented more that once" % val_source.duplicated_checks)
691
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600692 # Parse test files
Dave Houltoncacef472018-05-29 13:00:42 -0600693 val_tests = ValidationTests([test_file, ])
694 val_tests.parse()
695 exp_tests = len(val_tests.explicit_vuids)
696 imp_tests = len(val_tests.implicit_vuids)
697 all_tests = len(val_tests.all_vuids)
Mark Lobodzinski060a8e32018-01-08 09:08:06 -0700698 if verbose_mode:
Dave Houltoncacef472018-05-29 13:00:42 -0600699 print("Found %d unique error vuids in test file %s." % (all_tests, test_file))
700 print(" %d explicit" % exp_tests)
701 print(" %d implicit" % imp_tests)
702 print(" %d unassigned" % len(val_tests.unassigned_vuids))
Mike Weiblenfe186122017-02-03 12:44:53 -0700703
Dave Houltoncacef472018-05-29 13:00:42 -0600704 # Process stats
705 print("\nValidation Statistics (using validusage.json version %s)" % val_json.apiversion)
706 print(" VUIDs defined in JSON file: %04d explicit, %04d implicit, %04d total." % (exp_json, imp_json, all_json))
707 print(" VUIDs checked in layer code: %04d explicit, %04d implicit, %04d total." % (exp_checks, imp_checks, all_checks))
708 print(" VUIDs tested in layer tests: %04d explicit, %04d implicit, %04d total." % (exp_tests, imp_tests, all_tests))
709
710 print("\nVUID check coverage")
711 print(" Explicit VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * exp_checks / exp_json), exp_checks, exp_json))
712 print(" Implicit VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * imp_checks / imp_json), imp_checks, imp_json))
713 print(" Overall VUIDs checked: %.1f%% (%d checked vs %d defined)" % ((100.0 * all_checks / all_json), all_checks, all_json))
Mike Weiblenfe186122017-02-03 12:44:53 -0700714
Dave Houltoncacef472018-05-29 13:00:42 -0600715 print("\nVUID test coverage")
716 print(" Explicit VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * exp_tests / exp_checks), exp_tests, exp_checks))
717 print(" Implicit VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * imp_tests / imp_checks), imp_tests, imp_checks))
718 print(" Overall VUIDs tested: %.1f%% (%d tested vs %d checks)" % ((100.0 * all_tests / all_checks), all_tests, all_checks))
Mike Weiblenfe186122017-02-03 12:44:53 -0700719
Dave Houltoncacef472018-05-29 13:00:42 -0600720 # Report status of a single VUID
721 if len(get_vuid_status) > 1:
722 print("\n\nChecking status of <%s>" % get_vuid_status);
723 if get_vuid_status not in val_json.all_vuids:
724 print(' Not a valid VUID string.')
725 else:
726 if get_vuid_status in val_source.explicit_vuids:
727 print(' Implemented!')
728 line_list = val_source.vuid_count_dict[get_vuid_status]['file_line']
729 for line in line_list:
730 print(' => %s' % line)
Dave Houltonf93bbab2018-06-26 17:21:12 -0600731 elif get_vuid_status in val_source.implicit_vuids:
732 print(' Implemented! (Implicit)')
733 line_list = val_source.vuid_count_dict[get_vuid_status]['file_line']
734 for line in line_list:
735 print(' => %s' % line)
Tobin Ehlis9a68c982016-12-29 14:51:17 -0700736 else:
Dave Houltoncacef472018-05-29 13:00:42 -0600737 print(' Not implemented.')
Dave Houltonf93bbab2018-06-26 17:21:12 -0600738 if get_vuid_status in val_tests.all_vuids:
Dave Houltoncacef472018-05-29 13:00:42 -0600739 print(' Has a test!')
740 test_list = val_tests.vuid_to_tests[get_vuid_status]
741 for test in test_list:
742 print(' => %s' % test)
743 else:
744 print(' Not tested.')
Mike Weiblenfe186122017-02-03 12:44:53 -0700745
Dave Houltoncacef472018-05-29 13:00:42 -0600746 # Report unimplemented explicit VUIDs
747 if report_unimplemented:
748 unim_explicit = val_json.explicit_vuids - val_source.explicit_vuids
749 print("\n\n%d explicit VUID checks remain unimplemented:" % len(unim_explicit))
750 ulist = list(unim_explicit)
751 ulist.sort()
752 for vuid in ulist:
753 print(" => %s" % vuid)
754
755 # Consistency tests
756 if run_consistency:
757 print("\n\nRunning consistency tests...")
758 con = Consistency(val_json.all_vuids, val_source.all_vuids, val_tests.all_vuids)
759 ok = con.undef_vuids_in_layer_code()
760 ok &= con.undef_vuids_in_tests()
761 ok &= con.vuids_tested_not_checked()
762
763 if ok:
764 print(" OK! No inconsistencies found.")
765
766 # Output database in requested format(s)
767 db_out = OutputDatabase(val_json, val_source, val_tests)
768 if txt_out:
769 db_out.dump_txt()
770 if csv_out:
771 db_out.dump_csv()
772 if html_out:
773 db_out.dump_html()
Dave Houlton407df732018-08-06 17:58:24 -0600774 if header_out:
775 db_out.export_header()
Tobin Ehlis20e32582016-12-05 14:50:03 -0700776 return result
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600777
778if __name__ == "__main__":
Mark Lobodzinskib44c54a2017-06-12 12:02:38 -0600779 sys.exit(main(sys.argv[1:]))
Tobin Ehlis35308dd2016-10-31 13:27:36 -0600780