Skip to content

Commit

Permalink
feat: added black/whitelisting, labeling of error boxes, SC box @ same
Browse files Browse the repository at this point in the history
height, file @ correct line, line highlighting, grey shading

feat: added black-/whitelisting functionality (issue #4)
feat: added object and function names in error boxes (issue #2)
feat: added source boxes are now at the same vertical position (issue #3)
feat: file is displayed at the correct source line (issue #1)
feat: affected source line is highlighted
feat: object without source file are grey shaded
refactor: minor design changes
  • Loading branch information
philip-harr committed Jul 3, 2019
1 parent 6366563 commit 983ad0d
Showing 1 changed file with 146 additions and 47 deletions.
193 changes: 146 additions & 47 deletions drace-gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
import os
import shutil

copy_file = True
if not copy_file:
copy_text = True
else:
copy_text = False
SOURCEFILE_BL = list()
SOURCEFILE_WL = list()
BLACKLISTING = True
WHITELISTING = False

class ReportCreator:
__errorTag = 'error'
__htmlTemplatesPath = "templates/entries.xml"
__htmlTemplates = (ET.parse(__htmlTemplatesPath)).getroot()
sourcefileList = list()
__callStackNumber = 0
__errorNumber = 0
snippets = str()



def __init__(self, pathOfReport):
Expand Down Expand Up @@ -43,77 +46,170 @@ def __getHeader(self):

return header

def __returnCode(self, filename, directory):
def __handleSourceCode(self, filename, directory):
fullPath = directory +'/'+ filename
fullPath = fullPath.replace('\\', '/')

if os.path.isfile(fullPath):
if copy_file:
sourceCode = (self.__htmlTemplates.find('code_entry_reference').text).replace('*SOURCEFILE*', filename)
self.sourcefileList.append(fullPath)
return sourceCode
src = self.__returnCode(fullPath, justExistance=1)
if src == -1:
return -1, self.__htmlTemplates.find('no_code_entry').text

else:
try:
index = self.sourcefileList.index(fullPath)
except ValueError:
self.sourcefileList.append(fullPath)
index = self.sourcefileList.index(fullPath)

if copy_text:
sourceFile = open(fullPath, mode='r')
sourceCode = sourceFile.read()
sourceFile.close()
sourceCode = (self.__htmlTemplates.find('code_entry').text).replace('*CODE*', self.adjText(sourceCode))
return sourceCode
return index, (self.__htmlTemplates.find('code_entry').text)

def __createCodeVars(self):
codeString = str()

for sourcefile in self.sourcefileList:
src = self.__returnCode(sourcefile, justExistance=0)
tmpCode = "code_" + str(self.sourcefileList.index(sourcefile)) + ' = `' + src + '`;\n'
codeString += tmpCode

self.htmlReport = self.htmlReport.replace("*CODE_VARIABLES*", codeString)
self.htmlReport = self.htmlReport.replace("*SNIPPET_VARIABLES*", self.snippets)

def __returnCode(self, fullPath, justExistance):

if os.path.isfile(fullPath):
if BLACKLISTING:
for element in SOURCEFILE_BL:
if element in fullPath:
return -1
if justExistance:
return 0
else:
sourceFile = open(fullPath, mode='r')
sourceCode = sourceFile.read()
sourceFile.close()
sourceCode = self.adjText(sourceCode)
return sourceCode

if WHITELISTING:
for element in SOURCEFILE_WL:
if element in fullPath:
if justExistance:
return 0
else:
sourceFile = open(fullPath, mode='r')
sourceCode = sourceFile.read()
sourceFile.close()
sourceCode = self.adjText(sourceCode)
return sourceCode
return -1
else:
return self.__htmlTemplates.find('no_code_entry').text
return -1

def __createCallStack(self, errorEntry, position):
def __createCallStack(self, errorEntry, position, outputID):

callStack = str()
stackTemplate = self.__htmlTemplates.find('stack_entry').text
snippetTemplate = self.__htmlTemplates.find('snippet_entry').text
stackArray = errorEntry.findall('stack')
stack = stackArray[position]

elementNumber = 0
for frame in stack.findall('frame'):
newStackElement = stackTemplate.replace('*STACK_NUMBER*', self.adjText(hex(elementNumber)))
newStackElement = newStackElement.replace('*OBJ*', self.adjText(frame.find('obj').text))
newStackElement = newStackElement.replace('*FUNCTION*', self.adjText(frame.find('fn').text))
newStackElement = newStackElement.replace('*INSTRUCTION_POINTER*', self.adjText(frame.find('ip').text))

###make heading in read box###
if elementNumber == 0:
if len(self.__errorHeading) == 0:
self.__errorHeading += "<br> Obj. 1: " + (self.adjText(frame.find('obj').text) + ': "' + self.adjText(frame.find('fn').text)) + '" <br> '
else:
self.__errorHeading += "Obj. 2: " + (self.adjText(frame.find('obj').text) + ': "' + self.adjText(frame.find('fn').text)) + '"'


newStackElement = stackTemplate.replace('*STACK_NUMBER*', self.adjText(hex(elementNumber))+":")
newStackElement = newStackElement.replace('*SNIPPET_VAR*', ("snippet_" + str(self.__callStackNumber)))
newStackElement = newStackElement.replace('*OUTPUT_ID*', outputID+str(position))

newSnippet = snippetTemplate.replace('*SNIPPET_VAR*', ("snippet_" + str(self.__callStackNumber)))
newSnippet = newSnippet.replace('*STACK_NUMBER*', self.adjText(hex(elementNumber)))
newSnippet = newSnippet.replace('*OBJ*', self.adjText(frame.find('obj').text))
newSnippet = newSnippet.replace('*FUNCTION*', self.adjText(frame.find('fn').text))
newSnippet = newSnippet.replace('*INSTRUCTION_POINTER*', self.adjText(frame.find('ip').text))




if (frame.find('file')!= None):
code_index, tag = self.__handleSourceCode(frame.find('file').text, frame.find('dir').text)

newStackElement = newStackElement.replace('*FILE*', self.adjText(frame.find('file').text))
newStackElement = newStackElement.replace('*DIRECTORY*', self.adjText(frame.find('dir').text))
newStackElement = newStackElement.replace('*CODE_TAG*', self.__returnCode(frame.find('file').text, frame.find('dir').text))
newStackElement = newStackElement.replace('*LINE_OF_CODE*', self.adjText(frame.find('line').text))
else:
newSnippet = newSnippet.replace('*FILE*', self.adjText(frame.find('file').text))
newSnippet = newSnippet.replace('*DIRECTORY*', self.adjText(frame.find('dir').text))
newSnippet = newSnippet.replace('*CODE_TAG*', tag)
newSnippet = newSnippet.replace('*LINE_OF_CODE*', self.adjText(frame.find('line').text))

if(code_index != -1):
newStackElement = newStackElement.replace('*CODE_VAR*', "code_"+str(code_index))
newStackElement = newStackElement.replace('*CODE_ID_VAR*', "'snippet_"+str(self.__callStackNumber)+"_code'")
newStackElement = newStackElement.replace('*LINE_OF_CODE*', self.adjText(frame.find('line').text))
newSnippet = newSnippet.replace('*CODE_ID_VAR*', "snippet_"+str(self.__callStackNumber)+"_code")

else: #file is not available on device
newStackElement = newStackElement.replace('*CODE_VAR*', "'None'")
newStackElement = newStackElement.replace('*CODE_ID_VAR*', "'None'")
newStackElement = newStackElement.replace('*LINE_OF_CODE*', "'None'")
newSnippet = newSnippet.replace('*CODE_ID_VAR*', "'None'")

insertPosition = newStackElement.find('btn"')
newStackElement = newStackElement[:insertPosition] + "grey " + newStackElement[insertPosition:]

else: #no filepath for file is given
code_index, tag = self.__handleSourceCode("","")

newStackElement = newStackElement.replace('*FILE*', 'no filename available')
newStackElement = newStackElement.replace('*DIRECTORY*', 'no directory available')
newStackElement = newStackElement.replace('*CODE_TAG*', self.__returnCode('',''))
newStackElement = newStackElement.replace('*LINE_OF_CODE*', 'no line of code available')
newStackElement = newStackElement.replace('*LINE_OF_CODE*', "'None'")

newSnippet = newSnippet.replace('*FILE*', 'no filename available')
newSnippet = newSnippet.replace('*DIRECTORY*', 'no directory available')
newSnippet = newSnippet.replace('*CODE_TAG*', tag)

newStackElement = newStackElement.replace('*CODE_VAR*', "'None'")
newStackElement = newStackElement.replace('*CODE_ID_VAR*', "'None'")
newSnippet = newSnippet.replace('*LINE_OF_CODE*', 'no line of code available')

insertPosition = newStackElement.find('btn"')
newStackElement = newStackElement[:insertPosition] + "grey " + newStackElement[insertPosition:]



callStack += newStackElement
callStack += newStackElement #append stack element
self.snippets += newSnippet #append referenced code snippet
elementNumber += 1

self.__callStackNumber += 1 #increase global call stack number (used for reference variables)
return callStack



def __createErrorList(self):
self.__strErrors = str()

errorTemplate = self.__htmlTemplates.find('error_entry').text
errorList = self.__reportRoot.findall(self.__errorTag)
self.__numberOfErrors = len(errorList)

for error in errorList:
self.__errorNumber += 1
outputID = "output_"+str(self.__errorNumber)+"_"
newError = errorTemplate.replace('*ERROR_ID*', self.adjText(error.find('unique').text))
newError = newError.replace('*ERROR_TYPE*', self.adjText(error.find('kind').text))

xwhat = error.findall('xwhat')
newError = newError.replace('*XWHAT_TEXT_1*', self.adjText(xwhat[0].find('text').text))
newError = newError.replace('*XWHAT_TEXT_2*', self.adjText(xwhat[1].find('text').text))

newError = newError.replace('*CALL_STACK_ENTRIES_1*', self.__createCallStack(error, 0))
newError = newError.replace('*CALL_STACK_ENTRIES_2*', self.__createCallStack(error, 1))

self.__errorHeading = str() #filled by __createCallStack
newError = newError.replace('*CALL_STACK_ENTRIES_1*', self.__createCallStack(error, 0, outputID))
newError = newError.replace('*CALL_STACK_ENTRIES_2*', self.__createCallStack(error, 1, outputID))
newError = newError.replace('*OUTPUT_ID_1*', outputID+'0')
newError = newError.replace('*OUTPUT_ID_2*', outputID+'1')
newError = newError.replace('*ERROR_HEADING*', self.__errorHeading)

self.__strErrors += newError

def __createHeader(self):
Expand All @@ -132,32 +228,35 @@ def __createHeader(self):
def __createReport(self):
self.__createErrorList()
self.__createHeader()
self.__createCodeVars()


def adjText(self, text):
#text = text.replace('<', '&lt;')
#text = text.replace('>', '&gr;')
#text = text.replace('&', '&amp;')
def adjText(self, text): #change html symbols
text = text.replace('&', '&amp;')
text = text.replace('<', '&lt;')
text = text.replace('>', '&gt;')
text = text.replace('"', '&quot;')
text = text.replace('\\', '/')
return text


def main():
targetDirectory = 'test_files/output'

report = ReportCreator('test_files/test.xml')
report = ReportCreator('test_files/test.1.xml')

shutil.rmtree(targetDirectory)

if not os.path.isdir(targetDirectory):
os.mkdir(targetDirectory)


output = open(targetDirectory+'/output.html', mode='w')
output.write(report.htmlReport)
output.close()

for path in report.sourcefileList:
shutil.copy(path, targetDirectory)

#shutil.copy("templates/css", targetDirectory)
#shutil.copy("templates/js", targetDirectory)
shutil.copytree("templates/css", targetDirectory+"/css")
shutil.copytree("templates/js", targetDirectory+"/js")

return 0

Expand Down

0 comments on commit 983ad0d

Please sign in to comment.