Files
2025-09-29 00:52:08 +02:00

287 lines
8.1 KiB
Python
Executable File

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' TODO
' Eric J Anderson
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
import os
import os.path
import sys
import re
# Classes
class CResource:
def __init__(self):
self.name = ""
self.size = 0
self.callstack = []
def __str__(self):
value = self.name + "," + str(self.size)
#for item in self.callstack:
# value += item + '\n'
return value
def GetName(self):
return self.name
def SetName(self, name):
self.name = name
def GetSize(self):
return self.size
def SetSize(self, size):
self.size = int(size)
def GetCallstack(self):
return self.callstack
def AddFunction(self, function):
return self.callstack.append(function)
# Utility
def GetInput(pos):
if len(sys.argv) < 3:
print 'USAGE: python comapre_callstacks.py <source> <target>'
exit(-1)
return sys.argv[pos]
def GetSource():
return GetInput(1)
def GetTarget():
return GetInput(2)
def GetTag(path):
pos = path.find('/')
if pos == -1:
pos = path.find('\\')
if pos == -1:
pos = len(path)
return path[0:pos].upper()
def GetName(line):
name = ""
end = line.rfind(" | ")
if end > -1:
name = line[:end]
if not ("." in name or "platform:" in name):
name = None
else:
name = name.lower()
return name
def GetSize(line):
size = -1
start = line.rfind(" | ")
if start > -1:
start += 3
end = line.find(" ", start)
if end > -1:
size = int(line[start:end])
return size
def GetFunction(line):
name = None
end = line.rfind(" | ")
if end > -1:
name = line[:end]
return name
def ParseMeta(path):
file = open(path, 'r')
metadata = {}
for line in file.readlines():
if line[0] != '#':
break
m = re.match(r"\s*(?P<key>[^\:]+):\s*(?P<value>.+)", line[1:])
if m.lastindex < 1:
print 'Warning - unable to parse metadata ' + line[1:]
else:
key = m.group('key').strip().lower()
value = m.group('value').strip()
metadata[key] = value
file.close()
return metadata
def Parse(path):
file = open(path, 'r')
data = {}
external = []
res = CResource()
pos = 0
ignore = False
for line in file.readlines():
if line[0] == '#':
continue
line = line.strip()
if len(line) == 0:
res = CResource()
pos = 0
ignore = False
continue
if ignore == True:
continue
# Get size
if pos == 0:
size = GetSize(line)
function = GetFunction(line)
res.AddFunction(function)
res.SetSize(size)
elif pos == 1:
name = GetName(line)
if name != None:
res.SetName(name)
data[name] = res
elif pos == 3 and len(res.GetName()) == 0:
name = GetName(line)
if name == None:
external.append(line)
ignore = True
continue
res.SetName(name)
data[name] = res
else:
function = GetFunction(line)
if not (function == "Resource Virtual") or (function == "Resource Physical"):
res.AddFunction(function)
pos += 1
file.close()
# External Allocations
#for item in external:
# print item
return data
# Main
def Main():
source = GetSource()
sourceTag = GetTag(source)
sourceMeta = ParseMeta(source)
sourceData = Parse(source)
#print "Source Tag:", sourceTag
#print "Source Data =", len(sourceData)
#print "Source = ", source
target = GetTarget()
targetTag = GetTag(target)
targetMeta = ParseMeta(target)
targetData = Parse(target)
#print "Target Tag:", targetTag
#print "Target Data =", len(targetData)
#print "Target = ", target
# In source, not target
'''vSource = "SOURCE_KB"
if sourceMeta.get("buildversion") != None:
vSource = sourceMeta["buildversion"]'''
print "\n{0:{width}}".format("UNIQUE " + sourceTag, width=64), "{:>{}}".format("BYTES", 8), "{:>{}}".format("KB", 12)
print("------------------------------------------------------------------------------------------------------")
totalSource = 0
sourceList = sorted(list(set(sourceData)))
for item in sourceList:
if not item in targetData:
res = sourceData[item]
print "{0:{width}}".format(res.GetName(), width=64), "{:>{}}".format(res.GetSize(), 8), "{:>{}}".format(res.GetSize() / 1024, 12)
totalSource += res.GetSize()
print("------------------------------------------------------------------------------------------------------")
print "{0:{width}}".format("Total", width=64), "{:>{}}".format(totalSource, 8), "{:>{}} KB".format(totalSource / 1024, 12),
print "\n\n"
# In target, not source
'''vTarget = "TARGET_KB"
if targetMeta.get("buildversion") != None:
vTarget = targetMeta["buildversion"]'''
print "{0:{width}}".format("UNIQUE " + targetTag, width=64), "{:>{}}".format("BYTES", 8), "{:>{}}".format("KB", 12)
print("------------------------------------------------------------------------------------------------------")
print
totalTarget = 0
targetList = sorted(list(set(targetData)))
for item in targetList:
if not item in sourceData:
res = targetData[item]
print "{0:{width}}".format(res.GetName(), width=64), "{:>{}}".format(res.GetSize(), 8), "{:>{}}".format(res.GetSize() / 1024, 12)
totalTarget += res.GetSize()
print("------------------------------------------------------------------------------------------------------")
print "{0:{width}}".format("Total", width=64), "{:>{}}".format(totalTarget, 8), "{:>{}} KB".format(totalTarget / 1024, 12),
print "\n\n"
# Delta
print
print "{0:{width}}".format("DIFFERENT", width=64), "{:>{}}".format(sourceTag, 8), "{:>{}}".format(targetTag, 12), "{:>{}}".format("DELTA", 12)
print("------------------------------------------------------------------------------------------------------")
delta = totalTarget - totalSource
totalSource = 0
totalTarget = 0
totalDelta = 0
for item in sourceList:
if item in targetData:
resSource = sourceData[item]
resTarget = targetData[item]
if resSource.GetSize() != resTarget.GetSize():
sizeDelta = resTarget.GetSize() - resSource.GetSize()
totalDelta += sizeDelta
totalSource += max(0, resSource.GetSize() - resTarget.GetSize())
totalTarget += max(0, resTarget.GetSize() - resSource.GetSize())
print "{0:{width}}".format(resSource.GetName(), width=64), "{:>{}}".format(resSource.GetSize(), 8), "{:>{}}".format(resTarget.GetSize(), 12), "{:>{}}".format(sizeDelta, 12)
print("------------------------------------------------------------------------------------------------------")
print "{0:{width}}".format("Total", width=64), "{:>{}}".format(totalSource, 8), "{:>{}}".format(totalTarget, 12), "{:>{}} KB".format(totalDelta / 1024, 12)
print "\n\n"
# Same
print "{0:{width}}".format("COMMON", width=64), "{:>{}}".format("BYTES", 8), "{:>{}}".format("KB", 12)
print("------------------------------------------------------------------------------------------------------")
common = 0
for item in sourceList:
if item in targetData:
resSource = sourceData[item]
resTarget = targetData[item]
if resSource.GetSize() == resTarget.GetSize():
common += resSource.GetSize()
print "{0:{width}}".format(resSource.GetName(), width=64), "{:>{}}".format(resSource.GetSize(), 8), "{:>{}}".format(resSource.GetSize() / 1024, 12)
print("------------------------------------------------------------------------------------------------------")
print "{0:{width}}".format("Total", width=64), "{:>{}}".format(common, 8), "{:>{}} KB".format(common / 1024, 12),
print "\n\n"
delta += (totalTarget - totalSource)
print("------------------------------------------------------------------------------------------------------")
print "UNIQUE TOTAL =", (totalTarget - totalSource), "(", (totalTarget - totalSource) / 1024, "KB", "{0:.2f}".format(float((totalTarget - totalSource) / 1024.0 / 1024.0)), "MB )"
print "DELTA TOTAL =", delta, "(", delta / 1024, "KB,", "{0:.2f}".format(float(delta / 1024.0 / 1024.0)), "MB )"
print "COMMON TOTAL =", common, "(", common / 1024, "KB,", "{0:.2f}".format(float(common / 1024.0 / 1024.0)), "MB )"
# Run
if __name__ == "__main__":
Main()