123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #
- # Copyright (c) Contributors to the Open 3D Engine Project.
- # For complete copyright and license terms please see the LICENSE at the root of this distribution.
- #
- # 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()
|