blob: 3c02dfe6bc9d93877f35f671c12ae7e23662816b [file] [log] [blame]
Tobin Ehlis3198ba32017-04-19 17:30:52 -06001#!/usr/bin/python -i
Tobin Ehlis5ade0692016-10-05 17:18:15 -06002
3import sys
Mark Lobodzinski8c9633d2017-06-05 13:50:10 -06004try:
5 import urllib.request as urllib2
6except ImportError:
7 import urllib2
Tobin Ehlis3198ba32017-04-19 17:30:52 -06008from bs4 import BeautifulSoup
Tobin Ehlis98d109a2017-05-11 14:42:38 -06009import json
10import vuid_mapping
Tobin Ehlis5ade0692016-10-05 17:18:15 -060011
12#############################
13# spec.py script
14#
Tobin Ehlisda3916c2017-05-24 14:13:46 -060015# Overview - this script is intended to generate validation error codes and message strings from the json spec file
16# that contains all of the valid usage statements. In addition to generating the header file, it provides a number of
17# corrollary services to aid in generating/updating the header.
Tobin Ehlis5ade0692016-10-05 17:18:15 -060018#
Tobin Ehlisda3916c2017-05-24 14:13:46 -060019# Ideal flow - Pull the valid usage text and IDs from the spec json, pull the IDs from the validation error database,
20# then update the database with any new IDs from the json file and generate new database and header file.
Tobin Ehlis5ade0692016-10-05 17:18:15 -060021#
22# TODO:
Tobin Ehlisda3916c2017-05-24 14:13:46 -060023# 1. When VUs go away (in error DB, but not in json) need to report them and remove from DB as deleted
Tobin Ehlis5ade0692016-10-05 17:18:15 -060024#
25#############################
26
27
Mark Lobodzinskie3787b42017-06-21 13:41:00 -060028out_filename = "../layers/vk_validation_error_messages.h" # can override w/ '-out <filename>' option
29db_filename = "../layers/vk_validation_error_database.txt" # can override w/ '-gendb <filename>' option
Tobin Ehlis2c932132017-05-19 16:32:15 -060030json_filename = None # con pass in w/ '-json <filename> option
Tobin Ehlis5ade0692016-10-05 17:18:15 -060031gen_db = False # set to True when '-gendb <filename>' option provided
Tobin Ehlis2c932132017-05-19 16:32:15 -060032json_compare = False # compare existing DB to json file input
Tobin Ehlis828781a2017-05-23 15:23:40 -060033json_url = "https://www.khronos.org/registry/vulkan/specs/1.0-extensions/validation/validusage.json"
34read_json = False
Tobin Ehlis5ade0692016-10-05 17:18:15 -060035# This is the root spec link that is used in error messages to point users to spec sections
Tobin Ehlisbd0a9c62016-10-14 18:06:16 -060036#old_spec_url = "https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html"
Tobin Ehlisa55b1d42017-04-04 12:23:48 -060037spec_url = "https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html"
Tobin Ehlis828781a2017-05-23 15:23:40 -060038core_url = "https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html"
39ext_url = "https://www.khronos.org/registry/vulkan/specs/1.0-extensions/html/vkspec.html"
Tobin Ehlis5ade0692016-10-05 17:18:15 -060040# After the custom validation error message, this is the prefix for the standard message that includes the
41# spec valid usage language as well as the link to nearest section of spec to that language
Tobin Ehlisda3916c2017-05-24 14:13:46 -060042error_msg_prefix = "The spec valid usage text states "
Mark Lobodzinski629d47b2016-10-18 13:34:58 -060043validation_error_enum_name = "VALIDATION_ERROR_"
Tobin Ehlis5ade0692016-10-05 17:18:15 -060044
45def printHelp():
Tobin Ehlisda3916c2017-05-24 14:13:46 -060046 print ("Usage: python spec.py [-out <headerfile.h>] [-gendb <databasefile.txt>] [-update] [-json <json_file>] [-help]")
Tobin Ehlis3198ba32017-04-19 17:30:52 -060047 print ("\n Default script behavior is to parse the specfile and generate a header of unique error enums and corresponding error messages based on the specfile.\n")
48 print (" Default specfile is from online at %s" % (spec_url))
49 print (" Default headerfile is %s" % (out_filename))
50 print (" Default databasefile is %s" % (db_filename))
51 print ("\nIf '-gendb' option is specified then a database file is generated to default file or <databasefile.txt> if supplied. The database file stores")
52 print (" the list of enums and their error messages.")
Tobin Ehlis3198ba32017-04-19 17:30:52 -060053 print ("\nIf '-update' option is specified this triggers the master flow to automate updating header and database files using default db file as baseline")
54 print (" and online spec file as the latest. The default header and database files will be updated in-place for review and commit to the git repo.")
Tobin Ehlis828781a2017-05-23 15:23:40 -060055 print ("\nIf '-json' option is used trigger the script to load in data from a json file.")
56 print ("\nIf '-json-file' option is it will point to a local json file, else '%s' is used from the web." % (json_url))
Tobin Ehlis5ade0692016-10-05 17:18:15 -060057
Tobin Ehlis3c37fb32017-05-24 09:31:13 -060058def get8digithex(dec_num):
59 """Convert a decimal # into an 8-digit hex"""
60 if dec_num > 4294967295:
61 print ("ERROR: Decimal # %d can't be represented in 8 hex digits" % (dec_num))
62 sys.exit()
63 hex_num = hex(dec_num)
64 return hex_num[2:].zfill(8)
65
Tobin Ehlis5ade0692016-10-05 17:18:15 -060066class Specification:
67 def __init__(self):
68 self.tree = None
Tobin Ehlis5ade0692016-10-05 17:18:15 -060069 self.error_db_dict = {} # dict of previous error values read in from database file
70 self.delimiter = '~^~' # delimiter for db file
Tobin Ehlisa55b1d42017-04-04 12:23:48 -060071 # Global dicts used for tracking spec updates from old to new VUs
Tobin Ehlisa55b1d42017-04-04 12:23:48 -060072 self.orig_no_link_msg_dict = {} # Pair of API,Original msg w/o spec link to ID list mapping
73 self.orig_core_msg_dict = {} # Pair of API,Original core msg (no link or section) to ID list mapping
74 self.last_mapped_id = -10 # start as negative so we don't hit an accidental sequence
75 self.orig_test_imp_enums = set() # Track old enums w/ tests and/or implementation to flag any that aren't carried fwd
Tobin Ehlis2c932132017-05-19 16:32:15 -060076 # Dict of data from json DB
77 # Key is API,<short_msg> which leads to dict w/ following values
78 # 'ext' -> <core|<ext_name>>
79 # 'string_vuid' -> <string_vuid>
80 # 'number_vuid' -> <numerical_vuid>
81 self.json_db = {}
82 self.json_missing = 0
83 self.struct_to_func_map = {} # Map structs to the API func that they fall under in the spec
84 self.duplicate_json_key_count = 0
Tobin Ehlis5ade0692016-10-05 17:18:15 -060085 self.copyright = """/* THIS FILE IS GENERATED. DO NOT EDIT. */
86
87/*
88 * Vulkan
89 *
90 * Copyright (c) 2016 Google Inc.
Mark Lobodzinski629d47b2016-10-18 13:34:58 -060091 * Copyright (c) 2016 LunarG, Inc.
Tobin Ehlis5ade0692016-10-05 17:18:15 -060092 *
93 * Licensed under the Apache License, Version 2.0 (the "License");
94 * you may not use this file except in compliance with the License.
95 * You may obtain a copy of the License at
96 *
97 * http://www.apache.org/licenses/LICENSE-2.0
98 *
99 * Unless required by applicable law or agreed to in writing, software
100 * distributed under the License is distributed on an "AS IS" BASIS,
101 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
102 * See the License for the specific language governing permissions and
103 * limitations under the License.
104 *
105 * Author: Tobin Ehlis <tobine@google.com>
106 */"""
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600107
Tobin Ehlis828781a2017-05-23 15:23:40 -0600108 def readJSON(self):
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600109 """Read in JSON file"""
Tobin Ehlis828781a2017-05-23 15:23:40 -0600110 if json_filename is not None:
111 with open(json_filename) as jsf:
Mark Lobodzinski8c9633d2017-06-05 13:50:10 -0600112 self.json_data = json.load(jsf, encoding='utf-8')
Tobin Ehlis828781a2017-05-23 15:23:40 -0600113 else:
Mark Lobodzinski8c9633d2017-06-05 13:50:10 -0600114 response = urllib2.urlopen(json_url).read().decode('utf-8')
115 self.json_data = json.loads(response)
Tobin Ehlis828781a2017-05-23 15:23:40 -0600116
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600117 def parseJSON(self):
118 """Parse JSON VUIDs into data struct"""
119 # Format of JSON file is:
120 # "API": { "core|EXT": [ {"vuid": "<id>", "text": "<VU txt>"}]},
121 # "VK_KHX_external_memory" & "VK_KHX_device_group" - extension case (vs. "core")
Tobin Ehlis798c1392017-06-05 13:23:44 -0600122 for top_level in sorted(self.json_data):
123 if "validation" == top_level:
124 for api in sorted(self.json_data[top_level]):
125 for ext in sorted(self.json_data[top_level][api]):
126 for vu_txt_dict in self.json_data[top_level][api][ext]:
127 print ("Looking at dict for api:ext entry %s:%s" % (api, ext))
128 vuid = vu_txt_dict['vuid']
129 vutxt = vu_txt_dict['text']
130 #print ("%s:%s:%s:%s" % (api, ext, vuid, vutxt))
131 #print ("VUTXT orig:%s" % (vutxt))
132 just_txt = BeautifulSoup(vutxt, 'html.parser')
133 #print ("VUTXT only:%s" % (just_txt.get_text()))
134 num_vuid = vuid_mapping.convertVUID(vuid)
135 self.json_db[vuid] = {}
136 self.json_db[vuid]['ext'] = ext
137 self.json_db[vuid]['number_vuid'] = num_vuid
138 self.json_db[vuid]['struct_func'] = api
139 just_txt = just_txt.get_text().strip()
140 unicode_map = {
141 u"\u2019" : "'",
Mark Lobodzinski85946ae2017-10-09 09:10:21 -0600142 u"\u201c" : "\"",
143 u"\u201d" : "\"",
Tobin Ehlis798c1392017-06-05 13:23:44 -0600144 u"\u2192" : "->",
145 }
146 for um in unicode_map:
147 just_txt = just_txt.replace(um, unicode_map[um])
148 self.json_db[vuid]['vu_txt'] = just_txt.replace("\\", "")
149 print ("Spec vu txt:%s" % (self.json_db[vuid]['vu_txt']))
Tobin Ehlis828781a2017-05-23 15:23:40 -0600150 #sys.exit()
Tobin Ehlis2c932132017-05-19 16:32:15 -0600151
152 def compareJSON(self):
153 """Compare parsed json file with existing data read in from DB file"""
Tobin Ehlis828781a2017-05-23 15:23:40 -0600154 json_db_set = set()
155 for vuid in self.json_db: # pull entries out and see which fields we're missing from error_db
156 json_db_set.add(vuid)
Tobin Ehlis2c932132017-05-19 16:32:15 -0600157 for enum in self.error_db_dict:
Tobin Ehlis828781a2017-05-23 15:23:40 -0600158 vuid_string = self.error_db_dict[enum]['vuid_string']
159 if vuid_string not in self.json_db:
160 #print ("Full string for %s is:%s" % (enum, full_error_string))
161 print ("WARN: Couldn't find vuid_string in json db:%s" % (vuid_string))
Tobin Ehlis2c932132017-05-19 16:32:15 -0600162 self.json_missing = self.json_missing + 1
Tobin Ehlis828781a2017-05-23 15:23:40 -0600163 self.error_db_dict[enum]['ext'] = 'core'
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600164 # TODO: Currently GL843 tracks 2 VUs that are missing from json incorrectly
165 # Fix will land in 1.0.51 spec. After that we should take some alternative
166 # action here to indicate that VUs have gone away.
167 # Can have a removed_enums set that we add to and report to user
Tobin Ehlis828781a2017-05-23 15:23:40 -0600168 #sys.exit()
169 else:
170 json_db_set.remove(vuid_string)
Tobin Ehlis828781a2017-05-23 15:23:40 -0600171 self.error_db_dict[enum]['ext'] = self.json_db[vuid_string]['ext']
172 if 'core' == self.json_db[vuid_string]['ext'] or '!' in self.json_db[vuid_string]['ext']:
173 spec_link = "%s#%s" % (core_url, vuid_string)
174 else:
175 spec_link = "%s#%s" % (ext_url, vuid_string)
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600176 self.error_db_dict[enum]['error_msg'] = "%s'%s' (%s)" % (error_msg_prefix, self.json_db[vuid_string]['vu_txt'], spec_link)
Tobin Ehlis828781a2017-05-23 15:23:40 -0600177 print ("Updated error_db error_msg:%s" % (self.error_db_dict[enum]['error_msg']))
178 #sys.exit()
179 print ("These json DB entries are not in error DB:")
180 for extra_vuid in json_db_set:
181 print ("\t%s" % (extra_vuid))
182 # Add these missing entries into the error_db
183 # Create link into core or ext spec as needed
184 if 'core' == self.json_db[extra_vuid]['ext'] or '!' in self.json_db[extra_vuid]['ext']:
185 spec_link = "%s#%s" % (core_url, extra_vuid)
186 else:
187 spec_link = "%s#%s" % (ext_url, extra_vuid)
Tobin Ehlis798c1392017-06-05 13:23:44 -0600188 error_enum = "%s%s" % (validation_error_enum_name, get8digithex(self.json_db[extra_vuid]['number_vuid']))
Tobin Ehlis828781a2017-05-23 15:23:40 -0600189 self.error_db_dict[error_enum] = {}
190 self.error_db_dict[error_enum]['check_implemented'] = 'N'
191 self.error_db_dict[error_enum]['testname'] = 'None'
192 self.error_db_dict[error_enum]['api'] = self.json_db[extra_vuid]['struct_func']
193 self.error_db_dict[error_enum]['vuid_string'] = extra_vuid
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600194 self.error_db_dict[error_enum]['error_msg'] = "%s'%s' (%s)" % (error_msg_prefix, self.json_db[extra_vuid]['vu_txt'], spec_link)
Tobin Ehlis828781a2017-05-23 15:23:40 -0600195 self.error_db_dict[error_enum]['note'] = ''
196 self.error_db_dict[error_enum]['ext'] = self.json_db[extra_vuid]['ext']
Tobin Ehlis798c1392017-06-05 13:23:44 -0600197 implicit = False
198 last_segment = extra_vuid.split("-")[-1]
199 if last_segment in vuid_mapping.implicit_type_map:
200 implicit = True
201 elif not last_segment.isdigit(): # Explicit ids should only have digits in last segment
202 print ("ERROR: Found last segment of val error ID that isn't in implicit map and doesn't have numbers in last segment: %s" % (last_segment))
203 sys.exit()
204 self.error_db_dict[error_enum]['implicit'] = implicit
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600205
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600206 def genHeader(self, header_file):
207 """Generate a header file based on the contents of a parsed spec"""
Tobin Ehlis3198ba32017-04-19 17:30:52 -0600208 print ("Generating header %s..." % (header_file))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600209 file_contents = []
210 file_contents.append(self.copyright)
211 file_contents.append('\n#pragma once')
Mark Lobodzinski267a7cf2017-01-25 09:33:25 -0700212 file_contents.append('\n// Disable auto-formatting for generated file')
213 file_contents.append('// clang-format off')
214 file_contents.append('\n#include <unordered_map>')
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600215 file_contents.append('\n// enum values for unique validation error codes')
216 file_contents.append('// Corresponding validation error message for each enum is given in the mapping table below')
217 file_contents.append('// When a given error occurs, these enum values should be passed to the as the messageCode')
218 file_contents.append('// parameter to the PFN_vkDebugReportCallbackEXT function')
Tobin Ehlis387fd632016-12-08 13:32:05 -0700219 enum_decl = ['enum UNIQUE_VALIDATION_ERROR_CODE {\n VALIDATION_ERROR_UNDEFINED = -1,']
Tobin Ehlisbf98b692016-10-06 12:58:06 -0600220 error_string_map = ['static std::unordered_map<int, char const *const> validation_error_map{']
Tobin Ehlisce1e56f2017-01-25 12:42:55 -0800221 enum_value = 0
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600222 max_enum_val = 0
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600223 for enum in sorted(self.error_db_dict):
Tobin Ehlis3198ba32017-04-19 17:30:52 -0600224 #print ("Header enum is %s" % (enum))
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600225 # TMP: Use updated value
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600226 vuid_str = self.error_db_dict[enum]['vuid_string']
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600227 if vuid_str in self.json_db:
228 enum_value = self.json_db[vuid_str]['number_vuid']
229 else:
230 enum_value = vuid_mapping.convertVUID(vuid_str)
231 new_enum = "%s%s" % (validation_error_enum_name, get8digithex(enum_value))
232 enum_decl.append(' %s = 0x%s,' % (new_enum, get8digithex(enum_value)))
Mark Lobodzinski85946ae2017-10-09 09:10:21 -0600233 error_string_map.append(' {%s, "%s"},' % (new_enum, self.error_db_dict[enum]['error_msg'].replace('"', '\\"')))
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600234 max_enum_val = max(max_enum_val, enum_value)
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600235 enum_decl.append(' %sMAX_ENUM = %d,' % (validation_error_enum_name, max_enum_val + 1))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600236 enum_decl.append('};')
Tobin Ehlise7560e72016-10-19 15:59:38 -0600237 error_string_map.append('};\n')
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600238 file_contents.extend(enum_decl)
239 file_contents.append('\n// Mapping from unique validation error enum to the corresponding error message')
240 file_contents.append('// The error message should be appended to the end of a custom error message that is passed')
241 file_contents.append('// as the pMessage parameter to the PFN_vkDebugReportCallbackEXT function')
242 file_contents.extend(error_string_map)
Tobin Ehlis3198ba32017-04-19 17:30:52 -0600243 #print ("File contents: %s" % (file_contents))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600244 with open(header_file, "w") as outfile:
245 outfile.write("\n".join(file_contents))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600246 def genDB(self, db_file):
Tobin Ehlis828781a2017-05-23 15:23:40 -0600247 """Generate a database of check_enum, check_coded?, testname, API, VUID_string, core|ext, error_string, notes"""
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600248 db_lines = []
249 # Write header for database file
250 db_lines.append("# This is a database file with validation error check information")
251 db_lines.append("# Comments are denoted with '#' char")
252 db_lines.append("# The format of the lines is:")
Tobin Ehlis828781a2017-05-23 15:23:40 -0600253 db_lines.append("# <error_enum>%s<check_implemented>%s<testname>%s<api>%s<vuid_string>%s<core|ext>%s<errormsg>%s<note>" % (self.delimiter, self.delimiter, self.delimiter, self.delimiter, self.delimiter, self.delimiter, self.delimiter))
Mark Lobodzinski629d47b2016-10-18 13:34:58 -0600254 db_lines.append("# error_enum: Unique error enum for this check of format %s<uniqueid>" % validation_error_enum_name)
Mike Weiblenfe186122017-02-03 12:44:53 -0700255 db_lines.append("# check_implemented: 'Y' if check has been implemented in layers, or 'N' for not implemented")
Dave Houlton14f7e662017-05-17 13:25:53 -0600256 db_lines.append("# testname: Name of validation test for this check, 'Unknown' for unknown, 'None' if not implemented, or 'NotTestable' if cannot be implemented")
Tobin Ehlise7560e72016-10-19 15:59:38 -0600257 db_lines.append("# api: Vulkan API function that this check is related to")
Tobin Ehlis2c932132017-05-19 16:32:15 -0600258 db_lines.append("# vuid_string: Unique string to identify this check")
Tobin Ehlis828781a2017-05-23 15:23:40 -0600259 db_lines.append("# core|ext: Either 'core' for core spec or some extension string that indicates the extension required for this VU to be relevant")
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600260 db_lines.append("# errormsg: The unique error message for this check that includes spec language and link")
Tobin Ehlise7560e72016-10-19 15:59:38 -0600261 db_lines.append("# note: Free txt field with any custom notes related to the check in question")
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600262 for enum in sorted(self.error_db_dict):
Tobin Ehlis798c1392017-06-05 13:23:44 -0600263 print ("Gen DB for enum %s" % (enum))
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600264 implicit = self.error_db_dict[enum]['implicit']
265 implemented = self.error_db_dict[enum]['check_implemented']
266 testname = self.error_db_dict[enum]['testname']
267 note = self.error_db_dict[enum]['note']
268 core_ext = self.error_db_dict[enum]['ext']
269 self.error_db_dict[enum]['vuid_string'] = self.error_db_dict[enum]['vuid_string']
Tobin Ehlis2a176b12017-01-11 16:18:20 -0700270 if implicit and 'implicit' not in note: # add implicit note
271 if '' != note:
272 note = "implicit, %s" % (note)
273 else:
274 note = "implicit"
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600275 db_lines.append("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (enum, self.delimiter, implemented, self.delimiter, testname, self.delimiter, self.error_db_dict[enum]['api'], self.delimiter, self.error_db_dict[enum]['vuid_string'], self.delimiter, core_ext, self.delimiter, self.error_db_dict[enum]['error_msg'], self.delimiter, note))
Tobin Ehlisaf75f7c2016-10-31 11:10:38 -0600276 db_lines.append("\n") # newline at end of file
Tobin Ehlis3198ba32017-04-19 17:30:52 -0600277 print ("Generating database file %s" % (db_file))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600278 with open(db_file, "w") as outfile:
279 outfile.write("\n".join(db_lines))
280 def readDB(self, db_file):
Tobin Ehlis2c932132017-05-19 16:32:15 -0600281 """Read a db file into a dict, refer to genDB function above for format of each line"""
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600282 with open(db_file, "r") as infile:
283 for line in infile:
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600284 line = line.strip()
Tobin Ehlisf4245cb2016-10-31 07:55:19 -0600285 if line.startswith('#') or '' == line:
286 continue
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600287 db_line = line.split(self.delimiter)
Tobin Ehlis828781a2017-05-23 15:23:40 -0600288 if len(db_line) != 8:
289 print ("ERROR: Bad database line doesn't have 8 elements: %s" % (line))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600290 error_enum = db_line[0]
291 implemented = db_line[1]
292 testname = db_line[2]
Tobin Ehlis70980c02016-10-25 14:00:20 -0600293 api = db_line[3]
Tobin Ehlis828781a2017-05-23 15:23:40 -0600294 vuid_str = db_line[4]
295 core_ext = db_line[5]
296 error_str = db_line[6]
297 note = db_line[7]
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600298 # Also read complete database contents into our class var for later use
299 self.error_db_dict[error_enum] = {}
300 self.error_db_dict[error_enum]['check_implemented'] = implemented
301 self.error_db_dict[error_enum]['testname'] = testname
Tobin Ehlis70980c02016-10-25 14:00:20 -0600302 self.error_db_dict[error_enum]['api'] = api
Tobin Ehlis828781a2017-05-23 15:23:40 -0600303 self.error_db_dict[error_enum]['vuid_string'] = vuid_str
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600304 self.error_db_dict[error_enum]['ext'] = core_ext
Tobin Ehlis828781a2017-05-23 15:23:40 -0600305 self.error_db_dict[error_enum]['error_msg'] = error_str
Tobin Ehlis70980c02016-10-25 14:00:20 -0600306 self.error_db_dict[error_enum]['note'] = note
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600307 implicit = False
308 last_segment = vuid_str.split("-")[-1]
309 if last_segment in vuid_mapping.implicit_type_map:
310 implicit = True
311 elif not last_segment.isdigit(): # Explicit ids should only have digits in last segment
Tobin Ehlis798c1392017-06-05 13:23:44 -0600312 print ("ERROR: Found last segment of val error ID that isn't in implicit map and doesn't have numbers in last segment: %s" % (last_segment))
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600313 sys.exit()
314 self.error_db_dict[error_enum]['implicit'] = implicit
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600315if __name__ == "__main__":
316 i = 1
317 use_online = True # Attempt to grab spec from online by default
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600318 while (i < len(sys.argv)):
319 arg = sys.argv[i]
320 i = i + 1
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600321 if (arg == '-json-file'):
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600322 json_filename = sys.argv[i]
323 i = i + 1
Tobin Ehlis828781a2017-05-23 15:23:40 -0600324 elif (arg == '-json'):
325 read_json = True
Tobin Ehlis2c932132017-05-19 16:32:15 -0600326 elif (arg == '-json-compare'):
327 json_compare = True
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600328 elif (arg == '-out'):
329 out_filename = sys.argv[i]
330 i = i + 1
331 elif (arg == '-gendb'):
332 gen_db = True
333 # Set filename if supplied, else use default
334 if i < len(sys.argv) and not sys.argv[i].startswith('-'):
335 db_filename = sys.argv[i]
336 i = i + 1
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600337 elif (arg == '-update'):
Tobin Ehlis3c37fb32017-05-24 09:31:13 -0600338 read_json = True
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600339 json_compare = True
340 gen_db = True
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600341 elif (arg in ['-help', '-h']):
342 printHelp()
343 sys.exit()
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600344 spec = Specification()
Tobin Ehlis828781a2017-05-23 15:23:40 -0600345 if read_json:
346 spec.readJSON()
Tobin Ehlis98d109a2017-05-11 14:42:38 -0600347 spec.parseJSON()
Tobin Ehlis2c932132017-05-19 16:32:15 -0600348 #sys.exit()
349 if (json_compare):
350 # Read in current spec info from db file
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600351 (orig_err_msg_dict) = spec.readDB(db_filename)
Tobin Ehlis2c932132017-05-19 16:32:15 -0600352 spec.compareJSON()
353 print ("Found %d missing db entries in json db" % (spec.json_missing))
354 print ("Found %d duplicate json entries" % (spec.duplicate_json_key_count))
Tobin Ehlisda3916c2017-05-24 14:13:46 -0600355 spec.genDB(db_filename)
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600356 if (gen_db):
357 spec.genDB(db_filename)
Tobin Ehlis3198ba32017-04-19 17:30:52 -0600358 print ("Writing out file (-out) to '%s'" % (out_filename))
Tobin Ehlis5ade0692016-10-05 17:18:15 -0600359 spec.genHeader(out_filename)