| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896 |
- import TestScripts.Parser
- import sys
- import os.path
- import math
- groupCode="""class %s : public Client::Group
- {
- public:
- %s(Testing::testID_t id):Client::Group(id)
- %s
- {
- %s
- }
- private:
- %s
- };
- """
- suiteCode="""
- #include \"%s.h\"
- %s::%s(Testing::testID_t id):Client::Suite(id)
- {
- %s
- }
- """
- def decodeHex(hexstr,bits,mask):
- value = int(hexstr,16) & mask
- if value & (1 << (bits-1)):
- value -= 1 << bits
- return value
- def createMissingDir(destPath):
- theDir=os.path.normpath(os.path.dirname(destPath))
- if not os.path.exists(theDir):
- os.makedirs(theDir)
-
- class CodeGen:
- """ Code generation from the parsed description file
-
- Generate include files, cpp files, and .txt files for test control
- Generation depends on the mode (fpga or semihosting)
- """
- def __init__(self,patternDir,paramDir,fpga):
- """ Create a CodeGen object
-
- Args:
- patternDir (str) : where pattern must be read
- Used to generate include file in fpag mode
- fpga (bool) : false in semihosting mode
- Raises:
- Nothing
- Returns:
- CodeGen : CodeGen object
- """
- self._fpga = fpga
- self._patternDir = patternDir
- self._paramDir = paramDir
- self._currentPaths = [self._patternDir]
- self._currentParamPaths = [self._paramDir]
- self._alignment=8
-
- def _genGroup(self,root,fi):
- """ Generate header definition for a group of tests
-
- Args:
- root (TreeElem) : group object to use
- fi (file) : Header file (TestDesc.h)
- Where to write include definitions for the classes
- Raises:
- Nothing
- Returns:
- Nothing
- """
- # Get the CPP class name
- theClass = root.data["class"]
- # Get the group ID
- theId = root.id
-
- varInit = ""
- testInit = ""
- testDecl = ""
-
- # Generate initializer for the constructors
- # All the member variables corresponding to the
- # suites and groups contained in this group.
- i = 1
- for c in root:
- theData = c.data
- theMemberId = c.id
- if not theData["deprecated"]:
- theMemberClass = theData["class"]
- theMemberVar = theMemberClass + "Var"
- varInit += (",%s(%d)\n" % (theMemberVar,theMemberId))
- i = i + 1
- # Generate initialization code for the constructor
- i = 1
- for c in root:
- theData = c.data
- if theData["deprecated"]:
- testInit += "this->addContainer(NULL);"
- else:
- theMemberClass = theData["class"]
- theMemberVar = theMemberClass+"Var"
- testInit += "this->addContainer(&%s);\n" % (theMemberVar)
- i = i + 1
- # Generate member variables for the groups and the suites
- # contained in this group.
- i = 1
- for c in root:
- theData = c.data
- if not theData["deprecated"]:
- theMemberClass = theData["class"]
- theMemberVar = theMemberClass+"Var"
- theMemberId = c.id
- testDecl += "%s %s;\n" % (theMemberClass,theMemberVar)
- i = i + 1
- fi.write(groupCode % (theClass,theClass,varInit,testInit,testDecl) )
- def _genSuite(self,root,thedir,sourceFile):
- """ Generate source definition for suite
-
- Args:
- root (TreeElem) : suite object to use
- fi (file) : Source file (TestDesc.cpp)
- Where to write source definitions for the classes
- Raises:
- Nothing
- Returns:
- Nothing
- """
- # Get the CPP class
- theClass = root.data["class"]
- testInit = ""
- testDecl=""
- declared={}
- # Generate constructor for the class
- # Test functions are added in the constructor.
- # Keep track of the list of test functions
- # (since a test function can be reused by several tests)
- for c in root:
- theData = c.data
- theId = c.id
- theTestName = theData["class"]
- if not theData["deprecated"]:
- testInit += "this->addTest(%d,(Client::test)&%s::%s);\n" % (theId,theClass,theTestName)
- # To be able to deprecated tests without having to change the code
- # we dump const declaration even for deprecated functions
- if theTestName not in declared:
- testDecl += "void %s();\n" % (theTestName)
- declared[theTestName] = 1
- # Generate the suite constructor.
- sourceFile.write(suiteCode % (theClass,theClass,theClass,testInit) )
- # Generate specific header file for this suite
- with open(os.path.join(thedir,"%s_decl.h" % theClass),"w") as decl:
- # Use list of test functions to
- # declare them in the header.
- # Since we don't want to declare the functino several times,
- # that's why we needed to keep track of functions in the code above:
- # to remove redundancies since the function
- # can appear several time in the root object.
- decl.write(testDecl)
- # Generate the pattern ID for patterns
- # defined in this suite
- decl.write("\n// Pattern IDs\n")
- i = 0
- for p in root.patterns:
- newId = "static const int %s=%d;\n" % (p[0],i)
- decl.write(newId)
- i = i + 1
- # Generate output ID for the output categories
- # defined in this suite
- decl.write("\n// Output IDs\n")
- i = 0
- for p in root.outputs:
- newId = "static const int %s=%d;\n" % (p[0],i)
- decl.write(newId)
- i = i + 1
- # Generate test ID for the test define din this suite
- i = 0
- decl.write("\n// Test IDs\n")
- for c in root:
- theData = c.data
- theId = c.id
-
- # To be able to deprecated tests without having to change the code
- # we dump const declaration even for deprecated functions
- #if not theData["deprecated"]:
- theTestName = theData["class"]
- defTestID = "static const int %s_%d=%d;\n" % (theTestName.upper(),theId,theId)
- decl.write(defTestID)
- i = i + 1
-
- def _genCode(self,root,dir,sourceFile,headerFile):
- """ Generate code for the tree of tests
-
- Args:
- root (TreeElem) : root object containing the tree
- sourceFile (file) : Source file (TestDesc.cpp)
- Where to write source definitions for the classes
- headerFile (file) : Heade5 file (TestDesc.h)
- Where to write header definitions for the classes
- Raises:
- Nothing
- Returns:
- Nothing
- """
- deprecated = root.data["deprecated"]
- if not deprecated:
- if root.kind == TestScripts.Parser.TreeElem.GROUP:
- # For a group, first iterate on the children then on the
- # parent because the parent definitino in the header is
- # dependent on the children definition (member varaiables)
- # So children must gbe defined before.
- for c in root:
- self._genCode(c,dir,sourceFile,headerFile)
- self._genGroup(root,headerFile)
-
- # For a suite, we do not need to recurse since it is a leaf
- # of the tree of tests and is containing a list of tests to
- # generate
- if root.kind == TestScripts.Parser.TreeElem.SUITE:
- self._genSuite(root,dir,sourceFile)
- def getSuites(self,root,listOfSuites):
- """ Extract the list of all suites defined in the tree
-
- Args:
- root (TreeElem) : root object containing the tree
- listOfSuites (list) : list of suites
- Raises:
- Nothing
- Returns:
- list : list of suites
- """
- deprecated = root.data["deprecated"]
- if not deprecated:
- theClass = root.data["class"]
- if root.kind == TestScripts.Parser.TreeElem.SUITE:
- # Append current suite to the list and return the result
- listOfSuites.append(theClass)
- return(listOfSuites)
- elif root.kind == TestScripts.Parser.TreeElem.GROUP:
- # Recurse on the children to get the listOfSuite.
- # getSuites is appending to the list argument.
- # So the line listOfSuites = self.getSuites(c,listOfSuites)
- # is a fold.
- for c in root:
- listOfSuites = self.getSuites(c,listOfSuites)
- return(listOfSuites)
- else:
- return(listOfSuites)
- else:
- return(listOfSuites)
- def _genText(self,root,textFile):
- """ Generate the text file which is driving the tests in semihosting
- Format of file is:
- node kind (group, suite or test)
- node id (group id, suite id, test id)
- y or n to indicate if this node has some parameters
- if y there is the parameter ID
- y or n to indicate if entering this node is adding a new
- folder to the path used to get input files
- if y, the path for the node is added.
- Then, if node is a suite, description of the suite is generated.
- Number of parameters or 0
- It is the number of arguments used by function setUp (arity).
- It is not the number of samples in a paramater file
- The number of samples is always a multiple
- For instance if width and height are the parameters then number
- of parameters (arity) is 2.
- But each parameter file may contain several combination of (width,height)
- So the lenght of those files will be a multiple of 2.
- The number of patterns path is generated
- The patterns names are generated
- The number of output names is generated
- The output names are generated
- The number of parameter path is generated
- The parameter description are generated
- p
- path if a path
- g
- gen data if a generator
- If a generator:
- Generator kind (only 1 = cartesian product generator)
- Number of input samples (number of values to encode all parameters)
- Number of output samples (number of generated values)
- Number of dimensions
- For each dimension
- Length
- Samples
- For instance, with A=[1,2] and B=[1,2,3].
- Input dimension is 1+2 + 1 + 3 = 7 (number of values needed to encode the two lists
- with their length).
- Number of output dimensions is 2 * 3 = 6
- So, for a test (which is also a TreeElement in the structure),
- only node kind and node id are generated followed by
- param description and n for folder (since ther is never any folder)
-
- In the test description file, there is never any way to change the pattern
- folder for a test.
-
-
- Args:
- root (TreeElem) : root object containing the tree
- textFile (file) : where to write the driving description
- Raises:
- Nothing
- Returns:
- Nothing
- """
- deprecated = root.data["deprecated"]
- if not deprecated:
- textFile.write(str(root.kind))
- textFile.write(" ")
- textFile.write(str(root.id))
- textFile.write("\n")
- if "PARAMID" in root.data:
- if root.parameterToID:
- textFile.write("y\n")
- paramId = root.parameterToID[root.data["PARAMID"]]
- textFile.write(str(paramId))
- textFile.write("\n")
- elif root.parent.parameterToID:
- textFile.write("y\n")
- paramId = root.parent.parameterToID[root.data["PARAMID"]]
- textFile.write(str(paramId))
- textFile.write("\n")
- else:
- textFile.write("n\n")
- else:
- textFile.write("n\n")
- # Always dump even if there is no path for a test
- # so for a test it will always be n
- # It is done to simplify parsing on C side
- if root.path:
- textFile.write("y\n")
- textFile.write(root.path)
- textFile.write('\n')
- else:
- textFile.write("n\n")
-
- if root.kind == TestScripts.Parser.TreeElem.SUITE:
- # Here we dump the number of parameters used
- # for the tests / benchmarks
- if root.params:
- textFile.write("%d\n" % len(root.params.full))
- else:
- textFile.write("0\n")
- # Generate patterns path
- textFile.write("%d\n" % len(root.patterns))
- for (patid,patpath) in root.patterns:
- #textFile.write(patid)
- #textFile.write("\n")
- textFile.write(patpath.strip())
- textFile.write("\n")
- # Generate output names
- textFile.write("%d\n" % len(root.outputs))
- for (outid,outname) in root.outputs:
- #textFile.write(patid)
- #textFile.write("\n")
- textFile.write(outname.strip())
- textFile.write("\n")
- # Generate parameters path or generator
- textFile.write("%d\n" % len(root.parameters))
- for (paramKind,parid,parpath) in root.parameters:
- if paramKind == TestScripts.Parser.TreeElem.PARAMFILE:
- textFile.write("p\n")
- textFile.write(parpath.strip())
- textFile.write("\n")
- # Generator kind (only 1 = cartesian product generator)
- # Number of input samples (dimensions + vectors)
- # Number of samples generated when run
- # Number of dimensions
- # For each dimension
- # Length
- # Samples
- if paramKind == TestScripts.Parser.TreeElem.PARAMGEN:
- textFile.write("g\n")
- dimensions = len(parpath)
- nbOutputSamples = 1
- nbInputSamples = 0
- for c in parpath:
- nbOutputSamples = nbOutputSamples * len(c["INTS"])
- nbInputSamples = nbInputSamples + len(c["INTS"]) + 1
- textFile.write("1")
- textFile.write("\n")
- textFile.write(str(nbInputSamples))
- textFile.write("\n")
- textFile.write(str(nbOutputSamples))
- textFile.write("\n")
- textFile.write(str(dimensions))
- textFile.write("\n")
- for c in parpath:
- textFile.write(str(len(c["INTS"])))
- textFile.write("\n")
- for d in c["INTS"]:
- textFile.write(str(d))
- textFile.write("\n")
- # Iterate on the children
- for c in root:
- self._genText(c,textFile)
- def _write64(self,v,f):
- """ Write four integers into a C char array to represent word32
-
- It is used to dump input patterns in include files
- or test drive in include file
-
- Args:
- v (int) : The int64 to write
- f (file) : the opended file
- Raises:
- Nothing
- Returns:
- Nothing
- """
- a=[0,0,0,0,0,0,0,0]
- a[0]= v & 0x0FF
- v = v >> 8
- a[1]= v & 0x0FF
- v = v >> 8
- a[2]= v & 0x0FF
- v = v >> 8
- a[3]= v & 0x0FF
- v = v >> 8
- a[4]= v & 0x0FF
- v = v >> 8
- a[5]= v & 0x0FF
- v = v >> 8
- a[6]= v & 0x0FF
- v = v >> 8
- a[7]= v & 0x0FF
- v = v >> 8
- f.write("%d,%d,%d,%d,%d,%d,%d,%d,\n" % (a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]))
- def _write32(self,v,f):
- """ Write four integers into a C char array to represent word32
-
- It is used to dump input patterns in include files
- or test drive in include file
-
- Args:
- v (int) : The int32 to write
- f (file) : the opended file
- Raises:
- Nothing
- Returns:
- Nothing
- """
- a=[0,0,0,0]
- a[0]= v & 0x0FF
- v = v >> 8
- a[1]= v & 0x0FF
- v = v >> 8
- a[2]= v & 0x0FF
- v = v >> 8
- a[3]= v & 0x0FF
- v = v >> 8
- f.write("%d,%d,%d,%d,\n" % (a[0],a[1],a[2],a[3]))
- def _write16(self,v,f):
- """ Write 2 integers into a C char array to represent word32
-
- It is used to dump input patterns in include files
- or test drive in include file
-
- Args:
- v (int) : The int3 to write
- f (file) : the opended file
- Raises:
- Nothing
- Returns:
- Nothing
- """
- a=[0,0]
- a[0]= v & 0x0FF
- v = v >> 8
- a[1]= v & 0x0FF
- f.write("%d,%d,\n" % (a[0],a[1]))
- def _write8(self,v,f):
- """ Write 4 integers into a C char array to represent word8
-
- It is used to dump input patterns in include files
- or test drive in include file
-
- Args:
- v (int) : The int to write
- f (file) : the opended file
- Raises:
- Nothing
- Returns:
- Nothing
- """
- a=[0]
- a[0]= v & 0x0FF
- f.write("%d,\n" % (a[0]))
- def _writeString(self,v,f):
- """ Write a C string into a C char array to represent as a list of int
-
- It is used to dump input patterns in include files
- or test drive in include file
-
- Args:
- v (str) : The string to write
- f (file) : the opended file
- Raises:
- Nothing
- Returns:
- Nothing
- """
- for c in v:
- f.write("'%c'," % c)
- f.write("'\\0',\n")
- def convertToInt(self,k,s):
- v = 0
- if k == "D":
- v = decodeHex(s,64,0x0FFFFFFFFFFFFFFFF)
- if k == "W":
- v = decodeHex(s,32,0x0FFFFFFFF)
- if k == "H":
- v = decodeHex(s,16,0x0FFFF)
- if k == "B":
- v = decodeHex(s,8,0x0FF)
- return(v)
- def addPattern(self,includeFile,path):
- """ Add a pattern to the include file
-
- It is writing sequence of int into a C char array
- to represent the pattern.
- Assuming the C chr array is aligned, pattern offset are
- aligned too.
- So, some padding with 0 may also be generated after the patterm
-
- Args:
- includeFile (file) : Opened include file
- path (str) : Path to file containing the data
- Raises:
- Nothing
- Returns:
- (int,int) : The pattern offset in the array and the number of samples
- """
- # Current offset in the array which is the offset for the
- # pattern being added to this array
- returnOffset = self._offset
- # Read the pattern for the pattern file
- with open(path,"r") as pat:
- # Read pattern word size (B,H or W for 8, 16 or 32 bits)
- # Patterns are containing data in hex format (big endian for ARM)
- # So there is no conversion to do.
- # Hex data is read and copied as it is in the C array
-
- k =pat.readline().strip()
- sampleSize=1
- if k == 'D':
- sampleSize = 8
- if k == 'W':
- sampleSize = 4
- if k == 'H':
- sampleSize = 2
- # Read number of samples
- nbSamples = int(pat.readline().strip())
- # Compute new offset based on pattern length only
- newOffset = self._offset + sampleSize * nbSamples
- # Compute padding due to alignment constraint
- pad = self._alignment*math.ceil(newOffset / self._alignment) - newOffset
- # New offset in the array
- self._offset=newOffset + pad
- # Generate all samples into the C array
- for i in range(nbSamples):
- # In pattern file we have a comment giving the
- # true value (for instance float)
- # and then a line giving the hex data
- # We Ignore comment
- pat.readline()
- # Then we read the Value
- v = self.convertToInt(k,pat.readline())
- # Depending on the word size, this hex must be writen to
- # the C array as 4,2 or 1 number.
- if k == 'D':
- self._write64(v,includeFile)
- if k == 'W':
- self._write32(v,includeFile)
- if k == 'H':
- self._write16(v,includeFile)
- if k == 'B':
- self._write8(v,includeFile)
- #includeFile.write("%d,\n" % v)
- # Add the padding to the pattern
- for i in range(pad):
- includeFile.write("0,\n")
-
- return(returnOffset,nbSamples)
- def addParameter(self,includeFile,path):
- """ Add a parameter array to the include file
-
- It is writing sequence of int into a C char array
- to represent the pattern.
- Assuming the C chr array is aligned, pattern offset are
- aligned too.
- So, some padding with 0 may also be generated after the patterm
-
- Args:
- includeFile (file) : Opened include file
- path (str) : Path to file containing the data
- Raises:
- Nothing
- Returns:
- (int,int) : The pattern offset in the array and the number of samples
- """
- # Current offset in the array which is the offset for the
- # pattern being added to this array
- returnOffset = self._offset
- # Read the pattern for the pattern file
- with open(path,"r") as pat:
- # Read pattern word size (B,H or W for 8, 16 or 32 bits)
- # Patterns are containing data in hex format (big endian for ARM)
- # So there is no conversion to do.
- # Hex data is read and copied as it is in the C array
-
- sampleSize = 4
- # Read number of samples
- nbSamples = int(pat.readline().strip())
- # Compute new offset based on pattern length only
- newOffset = self._offset + sampleSize * nbSamples
- # Compute padding due to alignment constraint
- pad = self._alignment*math.ceil(newOffset / self._alignment) - newOffset
- # New offset in the array
- self._offset=newOffset + pad
- # Generate all samples into the C array
- for i in range(nbSamples):
- # In pattern file we have a comment giving the
- # true value (for instance float)
- # and then a line giving the hex data
- # Then we read the Value
- v = int(pat.readline().strip(),0)
- # Depending on the word size, this hex must be writen to
- # the C array as 4,2 or 1 number.
- self._write32(v,includeFile)
- # Add the padding to the pattern
- for i in range(pad):
- includeFile.write("0,\n")
-
- return(returnOffset,nbSamples)
- def _genDriver(self,root,driverFile,includeFile):
- """ Generate the driver file and the pattern file
- Args:
- root (TreeElement) : Tree of test descriptions
- driverFile (file) : where to generate C array for test descriptions
- includeFile (file) : where to generate C array for patterns
- Raises:
- Nothing
- Returns:
- Nothing
- """
- #if root.parent:
- # print(root.parent.data["message"])
- #print(" ",root.data["message"])
- #print(self._currentPaths)
-
- deprecated = root.data["deprecated"]
- # We follow a format quite similar to what is generated in _genText
- # for the text description
- # But here we are using an offset into the pattern array
- # rather than a path to a pattern file.
- # It is the only difference
- # But for outputs we still need the path so the logic is the same
- # Path for output is required to be able to extract data from the stdout file
- # and know where the data must be written to.
- # Please refer to comments of _genText for description of the format
- oldPath = self._currentPaths.copy()
- oldParamPath = self._currentParamPaths.copy()
- if not deprecated:
- # We write node kind and node id
- self._write32(root.kind,driverFile)
- self._write32(root.id,driverFile)
-
- if "PARAMID" in root.data:
- if root.parameterToID:
- driverFile.write("'y',")
- paramId = root.parameterToID[root.data["PARAMID"]]
- self._write32(int(paramId),driverFile)
- elif root.parent.parameterToID:
- driverFile.write("'y',")
- paramId = root.parent.parameterToID[root.data["PARAMID"]]
- self._write32(int(paramId),driverFile)
- else:
- driverFile.write("'n',")
- else:
- driverFile.write("'n',")
- # We write a folder path
- # if folder changed in test description file
- # Always dumped for a test even if no path for
- # a test. So a test will always have n
- # It is done to simplify parsing on C side
- if root.path:
- self._currentPaths.append(root.path)
- self._currentParamPaths.append(root.path)
- driverFile.write("'y',")
- self._writeString(root.path,driverFile)
- else:
- driverFile.write("'n',\n")
- if root.kind == TestScripts.Parser.TreeElem.SUITE:
- # Number of parameters
- if root.params:
- self._write32(len(root.params.full),driverFile)
- else:
- self._write32(0,driverFile)
- # Patterns offsets are written
- # and pattern length since the length is not available in a file
- # like for semihosting version
- self._write32(len(root.patterns),driverFile)
- for (patid,patpath) in root.patterns:
- temp = self._currentPaths.copy()
- temp.append(patpath)
-
- includeFile.write("// " + os.path.join(*temp) + "\n")
- offset,nbSamples=self.addPattern(includeFile,os.path.join(*temp))
- #driverFile.write(patpath)
- #driverFile.write("\n")
- self._write32(offset,driverFile)
- self._write32(nbSamples,driverFile)
- # Generate output names
- self._write32(len(root.outputs),driverFile)
- for (outid,outname) in root.outputs:
- #textFile.write(patid)
- #textFile.write("\n")
- self._writeString(outname.strip(),driverFile)
- # Parameters offsets are written
- # and parameter length since the length is not available in a file
- # like for semihosting version
- self._write32(len(root.parameters),driverFile)
- for (paramKind,parid,parpath) in root.parameters:
- if paramKind == TestScripts.Parser.TreeElem.PARAMFILE:
- temp = self._currentParamPaths.copy()
- temp.append(parpath)
- includeFile.write("// " + os.path.join(*temp) + "\n")
- offset,nbSamples=self.addParameter(includeFile,os.path.join(*temp))
-
- #driverFile.write(patpath)
- #driverFile.write("\n")
- driverFile.write("'p',")
- self._write32(offset,driverFile)
- self._write32(nbSamples,driverFile)
- # TO DO
- if paramKind == TestScripts.Parser.TreeElem.PARAMGEN:
- temp = self._currentParamPaths.copy()
-
- includeFile.write("// " + os.path.join(*temp) + "\n")
-
- driverFile.write("'g',")
- dimensions = len(parpath)
- nbOutputSamples = 1
- nbInputSamples = 0
- for c in parpath:
- nbOutputSamples = nbOutputSamples * len(c["INTS"])
- nbInputSamples = nbInputSamples + len(c["INTS"]) + 1
- self._write32(1,driverFile)
- self._write32(nbInputSamples,driverFile)
- self._write32(nbOutputSamples,driverFile)
- self._write32(dimensions,driverFile)
- for c in parpath:
- self._write32(len(c["INTS"]),driverFile)
- for d in c["INTS"]:
- self._write32(d,driverFile)
- # Recurse on the children
- for c in root:
- self._genDriver(c,driverFile,includeFile)
- self._currentPaths = oldPath.copy()
- self._currentParamPaths = oldParamPath.copy()
- def genCodeForTree(self,root,benchMode):
- """ Generate all files from the trees of tests
-
- Args:
- root (TreeElement) : Tree of test descriptions
- Raises:
- Nothing
- Returns:
- Nothing
- """
- # Get a list of all suites contained in the tree
- suites = self.getSuites(root,[])
- src = "GeneratedSource"
- header = "GeneratedInclude"
- if benchMode:
- src += "Bench"
- header += "Bench"
- # Generate .cpp and .h files neded to run the tests
- with open("%s/TestDesc.cpp" % src,"w") as sourceFile:
- with open("%s/TestDesc.h" % header,"w") as headerFile:
- headerFile.write("#include \"Test.h\"\n")
- headerFile.write("#include \"Pattern.h\"\n")
- sourceFile.write("#include \"Test.h\"\n")
- for s in suites:
- headerFile.write("#include \"%s.h\"\n" % s)
- self._genCode(root,"%s" % header,sourceFile,headerFile)
-
- # Generate a driver file for semihosting
- # (always generated for debug purpose since it is the reference format)
- with open("TestDesc.txt","w") as textFile:
- self._genText(root,textFile)
- # If fpga mode we need to generate
- # a include file version of the driver file and of
- # the pattern files.
- # Driver file is similar in this case but different from semihosting
- # one.
- if not self._fpga:
- with open("%s/TestDrive.h" % header,"w") as driverFile:
- driverFile.write("// Empty driver include in semihosting mode")
- with open("%s/Patterns.h" % header,"w") as includeFile:
- includeFile.write("// Empty pattern include in semihosting mode")
- else:
- with open("%s/TestDrive.h" % header,"w") as driverFile:
- driverFile.write("#ifndef _DRIVER_H_\n")
- driverFile.write("#define _DRIVER_H_\n")
- driverFile.write("__ALIGNED(8) const char testDesc[]={\n")
- self._offset=0
- with open("%s/Patterns.h" % header,"w") as includeFile:
- includeFile.write("#ifndef _PATTERNS_H_\n")
- includeFile.write("#define _PATTERNS_H_\n")
- includeFile.write("__ALIGNED(8) const char patterns[]={\n")
- self._genDriver(root,driverFile,includeFile)
- includeFile.write("};\n")
- includeFile.write("#endif\n")
- driverFile.write("};\n")
- driverFile.write("#endif\n")
-
-
|