You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
5.3 KiB
Python
140 lines
5.3 KiB
Python
#
|
|
# Copyright (c) Contributors to the Open 3D Engine Project
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
#
|
|
#
|
|
|
|
import sys
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import argparse
|
|
|
|
warnre = re.compile(r'(.*)\((\d*),(\d*)\): warning C(\d+): (.*)')
|
|
w4100_message_lambda = re.compile(r'.*\'(.*)\'.*')
|
|
|
|
# will contain a dictionary<filename, dictionary<linenumber, dictionary<column, warningcode>>>
|
|
all_warnings = dict()
|
|
|
|
def fix_debug_wrap(fix_function, warningNumber, fileLines, lineNumber, columnNumber, message):
|
|
print('Input: ')
|
|
print(fileLines[lineNumber].rstrip())
|
|
print(' ' * (columnNumber-1) + f'^ w{warningNumber}')
|
|
|
|
ret = fix_function(fileLines, lineNumber, columnNumber, message)
|
|
|
|
if ret:
|
|
print('Output: ')
|
|
print(fileLines[lineNumber].rstrip())
|
|
else:
|
|
print('Unmodified')
|
|
return ret
|
|
|
|
def fix_4100(fileLines, lineNumber, columnNumber, message):
|
|
line = fileLines[lineNumber]
|
|
startColumn = columnNumber-1
|
|
lastNonSpacePosition = startColumn
|
|
for colIndex in range(startColumn, 0, -1):
|
|
if line[colIndex] in (',', '('):
|
|
fileLines[lineNumber] = line[:colIndex+1] + ('',' ')[line[colIndex] == ','] + '[[maybe_unused]]' + ('',' ')[line[colIndex] == '('] + line[colIndex+1:]
|
|
return True
|
|
if line[colIndex] not in (' ', '\t'):
|
|
lastNonSpacePosition = colIndex
|
|
if lastNonSpacePosition < (startColumn-1): # cases where the parameter is in a new line
|
|
fileLines[lineNumber] = line[:lastNonSpacePosition] + '[[maybe_unused]] ' + line[lastNonSpacePosition:]
|
|
return True
|
|
# This warning is also issued for lambdas, but in the lambda case, the warning points to the end of the lambda
|
|
if line[columnNumber-1] == '}': # lambda case
|
|
reResult = w4100_message_lambda.search(message)
|
|
if reResult:
|
|
variable = ' ' + reResult.group(1)
|
|
# Now search lines above. Since the variable is not used in the lambda, we can iterate until we find it
|
|
for lineIndex in range(lineNumber-1, 0, -1):
|
|
col = fileLines[lineIndex].find(variable)
|
|
if col != -1:
|
|
return fix_4100(fileLines, lineIndex, col, message)
|
|
|
|
return False
|
|
|
|
def fix_4189(fileLines, lineNumber, columnNumber, message):
|
|
del fileLines[lineNumber]
|
|
return True
|
|
|
|
warning_fixers = dict()
|
|
warning_fixers[4100] = fix_4100
|
|
warning_fixers[4189] = fix_4189
|
|
|
|
def loadBuildLog(build_log):
|
|
try:
|
|
with open(build_log, 'r') as log_file:
|
|
try:
|
|
logLines = log_file.readlines()
|
|
except UnicodeDecodeError as err:
|
|
print('Error reading file {}, err: {}'.format(input_file, err))
|
|
return
|
|
except IOError as err:
|
|
print('Error opening {}: {}'.format(input_file, err))
|
|
return
|
|
|
|
for logLine in logLines:
|
|
reResult = warnre.search(logLine)
|
|
if reResult:
|
|
filename = os.path.abspath(reResult.group(1))
|
|
lineNumber = int(reResult.group(2))
|
|
columnNumber = int(reResult.group(3))
|
|
warningNumber = int(reResult.group(4))
|
|
message = reResult.group(5)
|
|
|
|
(all_warnings.setdefault(filename, dict())
|
|
.setdefault(lineNumber, dict())
|
|
.setdefault(columnNumber, dict())
|
|
.setdefault(warningNumber, message))
|
|
|
|
def processWarnings():
|
|
|
|
for filename, filename_warnings in all_warnings.items(): # file sorting irrelevant
|
|
with open(filename, 'r') as read_file:
|
|
try:
|
|
fileLines = read_file.readlines()
|
|
except UnicodeDecodeError as err:
|
|
print('Error reading file {}, err: {}'.format(input_file, err))
|
|
continue
|
|
|
|
hasEdit = False
|
|
for lineNumber, line_warnings in sorted(filename_warnings.items(), reverse=True): # Invert line number ordering to start from the bottom
|
|
for columnNumber, column_warnings in sorted(line_warnings.items(), reverse=True): # Invert column number odering to start from the right
|
|
for warningNumber, message in column_warnings.items(): # warning sorting irrelevant
|
|
if warningNumber in warning_fixers.keys():
|
|
#edited = fix_debug_wrap(warning_fixers[warningNumber], warningNumber, fileLines, lineNumber-1, columnNumber, message)
|
|
edited = warning_fixers[warningNumber](fileLines, lineNumber-1, columnNumber, message)
|
|
if not edited:
|
|
print(f'unfixed w{warningNumber}: {filename}({lineNumber},{columnNumber})')
|
|
hasEdit |= edited
|
|
|
|
if hasEdit:
|
|
# p4 edit the file
|
|
# subprocess.check_call(['p4', 'edit', filename])
|
|
with open(filename, 'w') as destination_file:
|
|
destination_file.writelines(fileLines)
|
|
|
|
# Stop during debugging
|
|
#break
|
|
|
|
def main():
|
|
"""script main function"""
|
|
parser = argparse.ArgumentParser(description='This script fixes warnings in msvc builds',
|
|
formatter_class=argparse.RawTextHelpFormatter)
|
|
parser.add_argument('build_log', type=str,
|
|
help='file with the build output')
|
|
|
|
args = parser.parse_args()
|
|
|
|
loadBuildLog(args.build_log)
|
|
processWarnings()
|
|
|
|
#entrypoint
|
|
if __name__ == '__main__':
|
|
main()
|