replace defunct calcprogress.py

This commit is contained in:
ProjectRevoTPP
2024-08-11 23:34:02 -04:00
parent bb2d5e85ee
commit 2f032a165f
2 changed files with 98 additions and 118 deletions
-118
View File
@@ -1,118 +0,0 @@
#!/usr/bin/env python3
import argparse
import json
import csv
import git
import os
import re
parser = argparse.ArgumentParser(description="Computes current progress throughout the whole project.")
parser.add_argument("format", nargs="?", default="text", choices=["text", "csv", "shield-json"])
parser.add_argument("-m", "--matching", dest='matching', action='store_true',
help="Output matching progress instead of decompilation progress")
args = parser.parse_args()
NON_MATCHING_PATTERN = r"#ifdef\s+NON_MATCHING.*?#pragma\s+GLOBAL_ASM\s*\(\s*\"(.*?)\"\s*\).*?#endif"
def GetNonMatchingFunctions(files):
functions = []
for file in files:
with open(file) as f:
functions += re.findall(NON_MATCHING_PATTERN, f.read(), re.DOTALL)
return functions
def ReadAllLines(fileName):
lineList = list()
with open(fileName) as f:
lineList = f.readlines()
return lineList
def GetFiles(path, ext):
files = []
for r, d, f in os.walk(path):
for file in f:
if file.endswith(ext):
files.append(os.path.join(r, file))
return files
nonMatchingFunctions = GetNonMatchingFunctions(GetFiles("src", ".c")) if not args.matching else []
def GetNonMatchingSize(path):
size = 0
asmFiles = GetFiles(path, ".s")
for asmFilePath in asmFiles:
if asmFilePath not in nonMatchingFunctions:
asmLines = ReadAllLines(asmFilePath)
for asmLine in asmLines:
if (asmLine.startswith("/*")):
size += 4
return size
def IsCFile(objfile):
srcfile = objfile.strip().replace("build/", "").replace(".c.o", ".c")
return os.path.isfile(srcfile)
mapFile = ReadAllLines("build/pokestadium.map")
src = 0
asm = 0
for line in mapFile:
lineSplit = list(filter(None, line.split(" ")))
if (len(lineSplit) == 4 and lineSplit[0].startswith(".")):
section = lineSplit[0]
size = int(lineSplit[2], 16)
objFile = lineSplit[3]
if (section == ".text"):
if (IsCFile(objFile) and objFile.startswith("build/src")):
src += size
elif (objFile.startswith("build/asm")):
asm += size
nonMatchingASM = GetNonMatchingSize("asm/non_matchings")
src -= nonMatchingASM
total = src + nonMatchingASM + asm
srcPct = 100 * src / total
bytesPerPokemon = total // 151
if args.format == 'csv':
csv_version = 2
git_object = git.Repo().head.object
timestamp = str(git_object.committed_date)
git_hash = git_object.hexsha
csv_list = [str(csv_version), timestamp, git_hash, str(src), str(total), str(code), str(codeSize), str(boot), str(bootSize), str(ovl), str(ovlSize), str(nonMatchingASM), str(len(nonMatchingFunctions))]
print(",".join(csv_list))
elif args.format == 'shield-json':
# https://shields.io/endpoint
print(json.dumps({
"schemaVersion": 1,
"label": "progress",
"message": f"{srcPct:.3g}%",
"color": 'yellow' if srcPct < 100 else 'brightgreen',
}))
elif args.format == 'text':
adjective = "decompiled" if not args.matching else "matched"
print(str(total) + " total bytes of decompilable code")
print(str(src) + " bytes " + adjective + " in src " + str(srcPct) + "%\n")
print("------------------------------------\n")
pokemonCount = int(src / bytesPerPokemon)
print("You have " + str(pokemonCount) + "/151 Pokedex entries.\n")
else:
print("Unknown format argument: " + args.format)
Executable
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: © 2023 ZeldaRET
# SPDX-License-Identifier: MIT
from __future__ import annotations
import argparse
import mapfile_parser
from pathlib import Path
ASMPATH = Path("asm")
NONMATCHINGS = "nonmatchings"
def getProgressFromMapFile(mapFile: mapfile_parser.MapFile, asmPath: Path, nonmatchings: Path, aliases: dict[str, str]=dict(), pathIndex: int=2) -> tuple[mapfile_parser.ProgressStats, dict[str, mapfile_parser.ProgressStats]]:
totalStats = mapfile_parser.ProgressStats()
progressPerFolder: dict[str, mapfile_parser.ProgressStats] = dict()
for segment in mapFile:
for file in segment:
if len(file) == 0:
continue
folder = file.filepath.parts[pathIndex]
if ".a" in folder:
folder = folder.split('.a')[0]
if folder in aliases:
folder = aliases[folder]
if folder not in progressPerFolder:
progressPerFolder[folder] = mapfile_parser.ProgressStats()
originalFilePath = Path(*file.filepath.parts[pathIndex:])
extensionlessFilePath = originalFilePath
while extensionlessFilePath.suffix:
extensionlessFilePath = extensionlessFilePath.with_suffix("")
fullAsmFile = asmPath / extensionlessFilePath.with_suffix(".s")
wholeFileIsUndecomped = fullAsmFile.exists()
for func in file:
funcAsmPath = nonmatchings / extensionlessFilePath / f"{func.name}.s"
symSize = 0
if func.size is not None:
symSize = func.size
if wholeFileIsUndecomped:
totalStats.undecompedSize += symSize
progressPerFolder[folder].undecompedSize += symSize
elif funcAsmPath.exists():
totalStats.undecompedSize += symSize
progressPerFolder[folder].undecompedSize += symSize
else:
totalStats.decompedSize += symSize
progressPerFolder[folder].decompedSize += symSize
return totalStats, progressPerFolder
def getProgress(mapPath: Path, version: str) -> tuple[mapfile_parser.ProgressStats, dict[str, mapfile_parser.ProgressStats]]:
mapFile = mapfile_parser.MapFile()
mapFile.readMapFile(mapPath)
for segment in mapFile:
for file in segment:
if len(file) == 0:
continue
filepathParts = list(file.filepath.parts)
if version in filepathParts:
filepathParts.remove(version)
file.filepath = Path(*filepathParts)
nonMatchingsPath = ASMPATH / version / NONMATCHINGS
return getProgressFromMapFile(mapFile.filterBySectionType(".text"), ASMPATH / version, nonMatchingsPath, aliases={"ultralib": "libultra"})
def progressMain():
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--version", help="version to process", default="us")
args = parser.parse_args()
mapPath = Path("build") / f"pokestadium-{args.version}.map"
totalStats, progressPerFolder = getProgress(mapPath, args.version)
mapfile_parser.progress_stats.printStats(totalStats, progressPerFolder)
if __name__ == "__main__":
progressMain()