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.

394 lines
9.4 KiB
Python

# general text parser
import os
import sys
from time import sleep
import glob
import json
import re
#import jsonpickle
# config
# file (inc. glob)
# list of searches: type (re, etc), singe/multiline, text, template
class Spec:
def __init__(self):
self.val = None
self.multiline = False
self.re = False
self.post = None # postprocessor function
self.ci = False # case-insensitive
self.flags = 0 # re flags
self.matchOnly = False # return re match, or whole result (if not multiline)
self.before = 0
self.after = 0
# start from prev?
# callback for every match?
self.search = False # use re.search instead of re.match
class Config:
def __init__(self):
self.specs = None
self.title = None
def toJson(self):
return json.dumps(self, default=lambda o: o.__dict__)
class Log:
def __init__(self, config=None):
self.config = config
# process all matching files, or newest only
def processGlob(self, g, spec, newest=False):
files = glob.glob(g)
if newest:
files = [max(files, key=os.path.getctime)]
for f in files:
self.processFile(f, spec)
# read file
def processFile(self, fn, spec):
contents = None
lines = None
# process spec list in order
results = []
for s in spec:
if s.multiline and contents is None:
with open(fn, 'r') as f:
contents = f.read()
elif lines is None:
lines = []
with open(fn, 'r') as f:
for l in f:
lines.append(l.rstrip('\n'))
v = []
if s.re:
if s.multiline:
r = re.findall(s.val, contents, s.flags)
for i in range(len(r)):
v.append(r[i])
else:
for i in range(len(lines)):
l = lines[i]
matchFn = re.match if not s.search else re.search
res = matchFn(s.val, l, s.flags)
if res is not None:
if s.matchOnly:
v.append(res.groups())
else:
if s.before == -1:
for j in range(0, i):
v.append(lines[j])
elif s.before > 0:
for j in range(max(0, i-s.before), i):
v.append(lines[j])
v.append(l)
if s.after == -1:
for j in range(i+1, len(lines)):
v.append(lines[j])
elif s.after > 0:
for j in range(i+1, i+1+s.after):
v.append(lines[j])
else:
if s.multiline:
p = 0
while p < len(contents):
p1 = contents.find(s.val, p)
if p1 == -1:
break
v.append(p1)
p += len(p1)
else:
for i in range(len(lines)):
l = lines[i]
if l.find(s.val) != -1:
if s.before == -1:
for j in range(0, i):
v.append(lines[j])
elif s.before > 0:
for j in range(max(0, i-s.before), i):
v.append(lines[j])
v.append(l)
if s.after == -1:
for j in range(i+1, len(lines)):
v.append(lines[j])
elif s.after > 0:
for j in range(i+1, i+1+s.after):
v.append(lines[j])
results.append(v)
return results
if __name__ == '__main__':
import os.path, time
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('logFile')
parser.add_argument('-l', '--loops', type=int, dest='loops', default=200, help='loops to run; default=200')
parser.add_argument('-m', '--move', type=int, dest='move', default=10, help='rate of movement (1/n iterations); default=10')
parser.add_argument('--test', dest='testVal', default=None, help='test value')
args = parser.parse_args()
logDir = args.logFile
# openroad testing
log = Log()
# --------------------
logFile = logDir + '/1_1_yosys.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'^Yosys .* \(git sha1'
s0.re = True
s1 = Spec()
s1.val = r'\n(30\. .*)'
s1.re = True
s1.multiline = True
s1.flags = re.DOTALL
specs = [s0, s1]
config = Config()
config.specs = specs
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
print()
print('*** Warnings ***')
print()
s0 = Spec()
s0.val = r'(Warning:.*)'
s0.re = True
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
s0 = Spec()
s0.val = r'(Error:.*)'
s0.re = True
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
found = False
for i in range(len(res)):
for l in res[i]:
if not found:
print()
print('*** Errors ***')
print()
found = True
print(l)
print('')
# --------------------
logFile = logDir + '/2_1_floorplan.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n(Design area .*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# --------------------
logFile = logDir + '/2_2_floorplan_io.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n\[INFO ODB-0134\].*?\n(.*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# --------------------
logFile = logDir + '/2_3_tdms_place.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n\[INFO ODB-0134\].*?\n(.*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# --------------------
logFile = logDir + '/2_4_mplace.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n\[INFO ODB-0134\].*?\n(.*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# --------------------
logFile = logDir + '/2_5_tapcell.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n\[INFO TAP-0005\].*?\n(.*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# --------------------
logFile = logDir + '/2_6_pdn.log'
print('Report: ' + logFile)
print('')
s0 = Spec()
s0.val = r'\n\[INFO PDN-0015\].*?\n(.*)'
s0.re = True
s0.multiline = True
s0.flags = re.DOTALL
config = Config()
config.specs = [s0]
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
quit()
# python makes this hard for even trivial objects
print('Writing config.json...')
configJson = json.dumps(config, default=lambda x: x.__dict__)
#configJson = jsonpickle.encode(config)
print(configJson)
#quit()
#
#configJson = json.dumps(config.toJson(), indent=2)
with open('config.json', 'w') as configFile:
configFile.write(configJson)
configFile.close()
print('Reading config.json...')
print('')
print('string')
with open('config.json', 'r') as configFile:
print(configFile.read())
configFile.close()
print('loads')
with open('config.json', 'r') as configFile:
config = json.loads(configFile.read())
print(config)
configFile.close()
res = log.processFile(logFile, config.specs)
for i in range(len(res)):
for l in res[i]:
print(l)
print('')
# fpga
s0 = Spec()
s0.val = r'.*Command.*-hierarchical (.*)\*.*'
s0.re = True
s0.matchOnly = True
specs = [s0]
log = Log()
res = log.processFile(logFile, specs)
comps = []
for r in res:
for i in r:
comps.append({
'name': i[0],
'luts': -1
})
s0.val = r'.*Slice LUTs.*?\|(.*?)\|'
res = log.processFile(logFile, specs)
for r in res:
for i in range(len(r)):
comps[i]['luts'] = r[i][0]
mod = time.ctime(os.path.getmtime(logFile))
print(f"report: {logFile} [{mod}]")
for i in range(len(comps)):
print(f"{comps[i]['name']:16}: {comps[i]['luts']:>7}")
quit()