Page MenuHomeWildfire Games
Paste P279

Find missing macro/symbol headers
ActivePublic

Authored by Stan on Wed, Jun 22, 3:08 PM.
#!/usr/bin/env python3
# -*- mode: python-mode; python-indent-offset: 4; -*-
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: © 2022 Stanislas Daniel Claude Dolcini
import argparse
from os import listdir, path
from logging import getLogger, StreamHandler, INFO, WARNING, Formatter, Filter
from pathlib import Path
from sys import stdout, stderr
class SingleLevelFilter(Filter):
def __init__(self, passlevel, reject):
self.passlevel = passlevel
self.reject = reject
def filter(self, record):
if self.reject:
return (record.levelno != self.passlevel)
else:
return (record.levelno == self.passlevel)
class MissingMacroHeaderFinder():
def __init__(self, root, macro = None, include = None, verbose=False):
self.root = Path(root)
self.verbose = verbose
self.include = include
self.macro = macro
self.__init_logger
self.bad_files = set()
@property
def __init_logger(self):
logger = getLogger(__name__)
logformat = '%(levelname)s - %(message)s'
logger.setLevel(INFO)
# create a console handler, seems nicer to Windows and for future uses
ch = StreamHandler(stdout)
ch.setLevel(INFO)
ch.setFormatter(Formatter(logformat))
f1 = SingleLevelFilter(INFO, False)
ch.addFilter(f1)
logger.addHandler(ch)
errorch = StreamHandler(stderr)
errorch.setLevel(WARNING)
errorch.setFormatter(Formatter(logformat))
logger.addHandler(errorch)
self.logger = logger
def find_files_recursively(self, folder_path, extension):
files = []
for file_name in listdir(folder_path):
file_path = path.join(folder_path, file_name)
if path.isdir(file_path):
for file in self.find_files_recursively(file_path, extension):
files.append(file)
elif extension in file_name:
files.append(file_path)
return files;
def get_bad_source_files(self):
source_files = self.find_files_recursively(self.root, '.cpp');
if(self.verbose):
self.logger.info(f"Found {len(source_files)} source file{'s' if len(source_files) > 0 else ''} to parse.")
for source_file in source_files:
with open(source_file, encoding = "utf-8") as source_file_io_wrapper:
file_data = source_file_io_wrapper.read()
if self.macro in file_data and not self.include in file_data:
name, _ = path.splitext(source_file)
header_file = f"{name}.h"
if not path.exists(header_file):
if(self.verbose):
self.logger.warning(f"Could not find {header_file}")
self.bad_files.add(source_file)
continue
with open(header_file) as header_file_io_wrapper:
header_file_data = header_file_io_wrapper.read()
if self.include not in header_file_data:
self.bad_files.add(source_file)
def get_bad_headers(self):
header_files = self.find_files_recursively(self.root, '.h');
if(self.verbose):
self.logger.info(f"Found {len(header_files)} header file{'s' if len(header_files) > 0 else ''} to parse.")
for header_file in header_files:
with open(header_file, encoding = "utf-8") as header_file_io_wrapper:
file_data = header_file_io_wrapper.read()
if self.macro in file_data and not self.include in file_data:
self.bad_files.add(header_file)
def run(self):
if(self.verbose):
self.logger.info(f"Parsing {self.root}")
self.get_bad_source_files()
self.get_bad_headers()
if(self.verbose):
self.logger.info(f"Found {len(self.bad_files)} file{'s' if len(self.bad_files) > 0 else ''} with missing headers for {self.macro}.")
for file_path in self.bad_files:
self.logger.error(file_path)
if __name__ == '__main__':
default_root = path.dirname(path.realpath(__file__))
parser = argparse.ArgumentParser(description='Missing Macro Header Finder.')
parser.add_argument('-m', '--macro', action='store', dest='macro', default='CONFIG2_GLES')
parser.add_argument('-i', '--include', action='store', dest='include', default='#include "lib/config2.h"')
parser.add_argument('-r', '--root', action='store', dest='root', default=default_root)
parser.add_argument('-v', '--verbose', action='store_true', default=False,
help="Log validation errors.")
args = parser.parse_args()
finder = MissingMacroHeaderFinder(args.root, args.macro, args.include, args.verbose)
finder.run()

Event Timeline

Stan created this paste.Wed, Jun 22, 3:08 PM
Stan created this object with visibility "Public (No Login Required)".
$ python ./find-missing-config2-includes.py -m "CONFIG2_"  -v
INFO - Parsing C:\Dev\Perso\0ad-svn\source
INFO - Found 709 source files to parse.
INFO - Found 795 header files to parse.
INFO - Found 14 files with missing headers for CONFIG2_.
ERROR - C:\Dev\Perso\0ad-svn\source\graphics\TextureConverter.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\lobby\scripting\JSInterface_Lobby.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\renderer\backend\gl\ShaderProgram.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\renderer\backend\gl\DeviceCommandContext.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\ps\Profiler2GPU.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\graphics\TextureConverter.h
ERROR - C:\Dev\Perso\0ad-svn\source\renderer\ShadowMap.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\ps\Profiler2GPU.h
ERROR - C:\Dev\Perso\0ad-svn\source\ps\GameSetup\HWDetect.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\renderer\backend\gl\Device.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\renderer\SceneRenderer.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\lib\posix\posix_aio.h
ERROR - C:\Dev\Perso\0ad-svn\source\ps\Util.cpp
ERROR - C:\Dev\Perso\0ad-svn\source\ps\scripting\JSInterface_Game.cpp