bthci/bthci2/CommandsEvents/generator/teststep.py
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 #
       
    15 
       
    16 
       
    17 import ConfigParser
       
    18 import string
       
    19 import re
       
    20 
       
    21 from datainput import getFolded, getEntries, getTypes
       
    22 from time import strftime
       
    23 from utils import doTimeStampCompareAndWrite
       
    24 
       
    25 #
       
    26 # Class wraps up external information needed for test steps
       
    27 # such as script file data, ini file data etc.
       
    28 #
       
    29 
       
    30 class TestStep:
       
    31     def __init__(self, aName, aType):
       
    32         self.iName = aName
       
    33         self.iType = aType
       
    34 
       
    35     def headerFile(self):
       
    36         if self.iType == 'command':
       
    37             return self.iName.lower() + 'commandstep.h'
       
    38         elif self.iType == 'event':
       
    39             return self.iName.lower() + 'eventstep.h'
       
    40         elif self.iType == 'completeevent':
       
    41             return self.iName.lower() + 'completeeventstep.h'
       
    42 
       
    43     def teststepName(self):
       
    44         if self.iType == 'command':
       
    45             return self.iName + 'CommandStep'
       
    46         elif self.iType == 'event':                                  
       
    47             return self.iName + 'EventStep'
       
    48         elif self.iType == 'completeevent':
       
    49             return self.iName + 'CompleteEventStep'
       
    50 
       
    51     def isPanic(self):
       
    52         if self.iType == 'command':
       
    53             return False
       
    54         elif self.iType == 'event' or self.iType == 'completeevent':
       
    55             return True
       
    56 
       
    57     def panicCode(self):
       
    58         return '0'
       
    59 
       
    60     def panicMessage(self):
       
    61         return 'Event cast error'
       
    62 
       
    63 
       
    64 #returns a maximum possible value of the parameter to be used as an initialiser
       
    65 #this function is needed because parameters representing array dimension cannot be 0xff
       
    66 
       
    67 def getParamValueMaxMaker( aParam, aParams):
       
    68    for p in aParams:
       
    69       if aParam == p.iArray:
       
    70            return '0x01'
       
    71            break
       
    72    for p in aParams:
       
    73       if aParam == p.iName:
       
    74            return p.iType.toMaxMaker()   
       
    75            break                 
       
    76 
       
    77            
       
    78 #returns a string containing maximum possible value of the parameter
       
    79 #this function is needed because parameters representing array dimension cannot be 0xff
       
    80 
       
    81 def getParamValueMaxStr( aParam, aParams):
       
    82    for p in aParams:
       
    83       if aParam == p.iArray:
       
    84            return '\\x01'                                                                        
       
    85    for p in aParams:
       
    86       if aParam == p.iName:
       
    87            return p.iType.maxValueStr()   
       
    88            
       
    89            
       
    90 #
       
    91 # Returns a string with the maximum values of parameters that can be used
       
    92 # when creating commands. Maximum is largest possible value of the data and not the delimiter noted in
       
    93 # in the bluetooth spec. The maximum value is retrieved from the type file.
       
    94 #
       
    95 
       
    96 def makeMaxParameters(aParams):
       
    97     max_str = ''
       
    98 
       
    99     for p in aParams:
       
   100         if p.iArray != '':
       
   101             max_str += p.iName + '_max, '
       
   102         else:
       
   103             max_str += getParamValueMaxMaker( p.iName, aParams) + ', '
       
   104 
       
   105     return max_str[:-2]
       
   106 
       
   107 
       
   108 #
       
   109 # Returns a string with the minimum values of parameters that can be used
       
   110 # when creating commands. Minimum value is retrieved from the type file.
       
   111 #
       
   112 
       
   113 def makeMinParameters(aParams):
       
   114     min_str = ''
       
   115 
       
   116     for p in aParams:                
       
   117         if p.iArray != '':
       
   118             min_str += p.iName + '_min, '
       
   119         else:
       
   120             min_str += p.iType.toMinMaker() + ', '        
       
   121 
       
   122     return min_str[:-2]
       
   123 
       
   124 
       
   125 #
       
   126 # Returns a string testing command 'getter' values against the maximum value.
       
   127 # For arrays this will test each and every value in the array.
       
   128 #
       
   129 
       
   130 def makeCommandMaxAccessors(aParams, aPtr):
       
   131     acc_str = ''
       
   132 
       
   133     for p in aParams:
       
   134         if p.iArray != '':                        
       
   135             acc_str += '\tfor(TInt i = 0; i < cmd->' + p.iArray + '(); ++i)\n\t\t{\n'
       
   136             acc_str += '\t\tif(' + aPtr + '->' + p.iName + '(i) != ' + p.iType.toMaxMaker() + ')\n\t\t\t{\n\t\t\treturn TestStepResult();\n\t\t\t}\n'
       
   137             acc_str += '\t\t}\n\n'
       
   138         else:
       
   139             acc_str += '\tif(' + aPtr + '->' + p.iName + '() != ' + getParamValueMaxMaker( p.iName, aParams) + ')\n\t\t{\n\t\treturn TestStepResult();\n\t\t}\n\n'
       
   140 
       
   141     return acc_str
       
   142 
       
   143 
       
   144 #
       
   145 # Returns a string testing event 'getter' values against the maximum value for events.
       
   146 # For arrays this will test each and every value in the array.
       
   147 # Event are specific because "Status"  value is checked by ErrorCode method, so we need to skip getter for Status
       
   148 #
       
   149 
       
   150 def makeEventMaxAccessors(aParams, aPtr):
       
   151     acc_str = ''
       
   152 
       
   153     for p in aParams:
       
   154         if p.iName != 'Status':
       
   155             if p.iArray != '':
       
   156                 acc_str += '\tfor(TInt i = 0; i < event->' + p.iArray + '(); ++i)\n\t\t{\n'
       
   157                 acc_str += '\t\tif(' + aPtr + '->' + p.iName + '(i) != ' + p.iType.toMaxMaker() + ')\n\t\t\t{\n\t\t\treturn TestStepResult();\n\t\t\t}\n'
       
   158                 acc_str += '\t\t}\n\n'
       
   159             else:
       
   160                 acc_str += '\tif(' + aPtr + '->' + p.iName + '() != ' + getParamValueMaxMaker( p.iName, aParams) + ')\n\t\t{\n\t\treturn TestStepResult();\n\t\t}\n\n'
       
   161 
       
   162     return acc_str
       
   163 
       
   164 
       
   165 #
       
   166 # Returns a string testing command 'getter' values against the minimum value.
       
   167 # For arrays this will test each and every value in the array.
       
   168 #
       
   169 
       
   170 def makeCommandMinAccessors(aParams, aPtr):
       
   171     acc_str = ''
       
   172 
       
   173     for p in aParams:
       
   174         if p.iArray != '':
       
   175             acc_str += '\tfor(TInt i = 0; i < cmd->' + p.iArray + '(); ++i)\n\t\t{\n'
       
   176             acc_str += '\t\tif(' + aPtr + '->' + p.iName + '(i) != ' + p.iType.toMinMaker() + ')\n\t\t\t{\n\t\t\treturn TestStepResult();\n\t\t\t}\n'
       
   177             acc_str += '\t\t}\n\n'
       
   178         else:
       
   179             acc_str += '\tif(' + aPtr + '->' + p.iName + '() != ' + p.iType.toMinMaker() + ')\n\t\t{\n\t\treturn TestStepResult();\n\t\t}\n\n'
       
   180 
       
   181     return acc_str
       
   182 
       
   183     
       
   184 #
       
   185 # Returns a string testing event 'getter' values against the minimum value for events.
       
   186 # For arrays this will test each and every value in the array.
       
   187 # Event are specific because "Status"  value is checked by ErrorCode method, so we need to skip getter for Status
       
   188 #
       
   189 
       
   190 def makeEventMinAccessors(aParams, aPtr):
       
   191     acc_str = ''
       
   192 
       
   193     for p in aParams:
       
   194         if p.iName != 'Status':
       
   195             if p.iArray != '':
       
   196                 acc_str += '\tfor(TInt i = 0; i < event->' + p.iArray + '(); ++i)\n\t\t{\n'
       
   197                 acc_str += '\t\tif(' + aPtr + '->' + p.iName + '(i) != ' + p.iType.toMinMaker() + ')\n\t\t\t{\n\t\t\treturn TestStepResult();\n\t\t\t}'
       
   198                 acc_str += '\t\t}\n\n'
       
   199             else:
       
   200                 acc_str += '\tif(' + aPtr + '->' + p.iName + '() != ' + p.iType.toMinMaker() + ')\n\t\t{\n\t\treturn TestStepResult();\n\t\t}\n\n'
       
   201 
       
   202     return acc_str    
       
   203 
       
   204 
       
   205 #
       
   206 # Returns a C-string, "...", useful for creating event data with maximum values of every parameter.
       
   207 #
       
   208 
       
   209 def makeMaxData(aParams):
       
   210     frame_str = ''
       
   211 
       
   212     for p in aParams:
       
   213         if not p.iNotInFrame:
       
   214             if p.iArray != '':
       
   215                 num = int(getParamValueMaxMaker( p.iArray,aParams), 16)
       
   216                 while num > 0:
       
   217                     num -= 1
       
   218                     frame_str += p.iType.maxValueStr()
       
   219             else:
       
   220                 frame_str += getParamValueMaxStr(p.iName, aParams)
       
   221 
       
   222     return frame_str
       
   223 
       
   224 
       
   225 #
       
   226 # Returns a C-string, "...", useful for creating event data with minimum values of every parameter.
       
   227 #
       
   228 
       
   229 def makeMinData(aParams):
       
   230     frame_str = ''
       
   231 
       
   232     for p in aParams:
       
   233         if not p.iNotInFrame:
       
   234             if p.iArray != '':
       
   235                 num = int(filter(lambda (e): e.iName == p.iArray, aParams)[0].iType.minValue(), 16)
       
   236                 while num < 0:
       
   237                     num -= num
       
   238                     frame_str +=  p.iType.minValueStr()
       
   239             else:
       
   240                 frame_str +=  p.iType.minValueStr()
       
   241 
       
   242     return frame_str
       
   243 
       
   244 
       
   245 #
       
   246 # Returns a string for creating a single argument string to be used in a constructr for commands.
       
   247 #                                               
       
   248 
       
   249 def makeCommandInitMinParams( aParams):
       
   250     min_str = ''
       
   251 
       
   252     for p in aParams:                
       
   253         if p.iType.CStringAvoider() != '':
       
   254             min_str += '\t_LIT8(' + p.iType.CStringAvoider() + ',"' + p.iType.minValueStr() + '");\n'
       
   255         if p.iType.PckgBufType() != '':
       
   256             min_str += '\t' + p.iType.PckgBufType() + ' ' + p.iType.PckgBufType() + '_instance_min = ' + p.iType.minValue() + ';\n'
       
   257         if p.iArray != '':
       
   258             min_str += '\tRArray<' + p.iType.iTypename + '> ' + p.iName + '_min;\n';
       
   259     return min_str
       
   260 
       
   261 
       
   262 #
       
   263 # Returns a string for creating a single argument string to be used in a constructr for commands.
       
   264 #                                               
       
   265 
       
   266 def makeCommandInitMaxParams(aParams):
       
   267     max_str = ''
       
   268     for p in aParams:
       
   269            if p.iType.PckgBufType() != '':
       
   270                max_str += '\t' + p.iType.PckgBufType() + ' ' + p.iType.PckgBufType() + '_instance_max = ' + p.iType.maxValue() + ';\n'
       
   271            if p.iArray != '':
       
   272                max_str += '\tRArray<' + p.iType.iTypename + '> ' + p.iName + '_max;\n';
       
   273                max_str += '\tfor(TInt i = 0; i < ' + getParamValueMaxMaker( p.iArray, aParams) + '; ++i)\n\t\t{\n'
       
   274                max_str += '\t\t' + p.iName + '_max.Append(' + p.iType.toMaxMaker() + ');\n'
       
   275                max_str += '\t\t}\n\n'    
       
   276     return max_str
       
   277                   
       
   278 
       
   279 #                                                                                    
       
   280 # Returns a string for creating a single argument string to be used in a constructr for events .
       
   281 #
       
   282 
       
   283 def makeEventInitMinParams(aEventCode, aParams):
       
   284 
       
   285     par_str = '\t_LIT8(formatter,"'
       
   286     #1- event code,1- length of the event data;   
       
   287     par_str +=  '%c\\x0'
       
   288     par_str +=  makeMinData(aParams) + '");\n'          
       
   289     par_str +=  '\tTBuf8<255> init_value;'
       
   290     par_str +=  '\n\tinit_value.Format(formatter,' 
       
   291     par_str +=  aEventCode + ' & 0xff);\n '
       
   292     for p in aParams:
       
   293         if p.iType.CStringAvoider() != '':
       
   294             par_str += '\t_LIT8(' + p.iType.CStringAvoider() + ',"' + p.iType.minValueStr() + '");\n'
       
   295         if p.iType.PckgBufType() != '':
       
   296             par_str += p.iType.PckgBufType() + ' ' + p.iType.PckgBufType() + '_instance_min = ' + p.iType.minValue() + ';'
       
   297     return par_str
       
   298 
       
   299 
       
   300 #                                                                                    
       
   301 # Returns a string for creating a single argument string to be used in a constructr for completeevents.
       
   302 #
       
   303 
       
   304 def makeCompleteEventInitMinParams(aEventCode, aOpcode, aParams):
       
   305 
       
   306     par_str = '\t_LIT8(formatter,"'
       
   307     #1- length of the event data, 1- command credits, 2- opcode;   
       
   308     par_str +=  '%c\\x0\\x0%c%c'
       
   309     par_str +=  makeMinData(aParams) + '");\n'
       
   310     par_str +=  '\tTBuf8<255> init_value;\n'
       
   311     par_str +=  '\tinit_value.Format(formatter,' 
       
   312     par_str +=  aEventCode + ' & 0xff, ' 
       
   313     par_str +=  aOpcode + ' & 0xff, ' 
       
   314     par_str +=  aOpcode + '>>8 & 0xff);\n '
       
   315     for p in aParams:               
       
   316         if p.iType.CStringAvoider() != '':
       
   317             par_str += '\t_LIT8(' + p.iType.CStringAvoider() + ',"' + p.iType.minValueStr() + '");\n'
       
   318         if p.iType.PckgBufType() != '':
       
   319            par_str += p.iType.PckgBufType() + ' ' + p.iType.PckgBufType() + '_instance_max = ' + p.iType.maxValue() + ';\n'
       
   320     return par_str
       
   321 
       
   322 def makeMatchCompleteEevnt(aOpcode):
       
   323     match_str = '\t_LIT8(complete_formatter,"'
       
   324     #1- event code, #1- length of the event data, 1- command credits, 2- opcode;   
       
   325     match_str +=  '%c\\x0\\x0%c%c");\n'
       
   326     match_str +=  '\tTBuf8<255> event_data;\n'
       
   327     match_str +=  '\tevent_data.Format(complete_formatter,' 
       
   328     match_str +=  'ECommandCompleteEvent & 0xff, ' 
       
   329     match_str +=  aOpcode + ' & 0xff, ' 
       
   330     match_str +=  aOpcode + '>>8 & 0xff);\n'
       
   331     match_str += '\tTVendorDebugCompleteEvent* complete_event = new(ELeave) TVendorDebugCompleteEvent(event_data);\n'
       
   332     match_str += '\tTBool event_matches=EFalse; TBool event_concludes=EFalse; TBool event_continue_matching=EFalse;\n'
       
   333     match_str += '\tcmd->Match (*complete_event, event_matches, event_concludes, event_continue_matching);\n'
       
   334     match_str += '\tif ((!event_matches)||(!event_concludes))\n' # We don't consider continuations as "in general" a complete event
       
   335                                                                  # may or may not continue (e.g. Inquiry_Cancel_Complete_Event continues)
       
   336     match_str += '\t\t{\n\t\treturn TestStepResult();\n\t\t}\n'
       
   337     return match_str
       
   338     
       
   339 def makeMatchStatusEevnt(aOpcode):
       
   340     match_str = '\t_LIT8(status_formatter,"'
       
   341     #1- event code, #1- length of the event data, 1- command credits, 2- opcode;   
       
   342     match_str +=  '%c\\x0\\x0\\x0%c%c");\n'
       
   343     match_str +=  '\tevent_data.Format(status_formatter,' 
       
   344     match_str +=  'ECommandStatusEvent & 0xff, '
       
   345     match_str +=  aOpcode + ' & 0xff, ' 
       
   346     match_str +=  aOpcode + '>>8 & 0xff);\n'
       
   347     match_str += '\tTVendorDebugEvent* status_event = new(ELeave) TVendorDebugEvent(event_data);\n'
       
   348     match_str += '\tevent_matches=EFalse; event_concludes=EFalse; event_continue_matching=EFalse;\n'
       
   349     match_str += '\tcmd->Match (*status_event, event_matches, event_concludes, event_continue_matching);\n' 
       
   350     match_str += '\tif ((!event_matches)||(event_concludes)||(event_continue_matching))\n'
       
   351     match_str += '\t\t{\n\t\treturn TestStepResult();\n\t\t}\n'   
       
   352     return match_str
       
   353 
       
   354 def makeMatchProprietaryEevnt(aOpcode, aEvent, ind):    
       
   355     match_str = '\t_LIT8(proprietary_formatter'+ ind + ',"'
       
   356     if aEvent == 'EModeChangeEvent':
       
   357         match_str +=  '%c\\x0\\x0\\x0\\x0\\x0\\x0\\x0");\n'
       
   358         match_str +=  '\tevent_data.Format(proprietary_formatter'+ ind + ',' 
       
   359         match_str +=  aEvent + ' & 0xff);\n'
       
   360     else:
       
   361         if aEvent == 'EConnectionCompleteEvent' or aEvent == 'ESynchronousConnectionCompleteEvent':
       
   362             #for ConnectionCompleteEvent we imitate BT Device Address as it will be needed to match the event
       
   363             match_str +=  '%c\\x0\\x0%c%c\\x0\\x0\\x0\\x0\\x0\\x0\\x0\\x0");\n'
       
   364         else:
       
   365         #1- event code, 1- length of the event data, 1- command credits, 2- opcode;   	
       
   366             match_str +=  '%c\\x0\\x0%c%c");\n'
       
   367         match_str +=  '\tevent_data.Format(proprietary_formatter'+ ind + ',' 
       
   368         match_str +=  aEvent + ' & 0xff, '
       
   369         match_str +=  aOpcode + ' & 0xff, '
       
   370         match_str +=  aOpcode + '>>8 & 0xff);\n'    	
       
   371     match_str += '\tTVendorDebugEvent* proprietary_event'+ ind + '= new(ELeave) TVendorDebugEvent(event_data);\n'
       
   372     match_str += '\tevent_matches=EFalse; event_concludes=EFalse; event_continue_matching=EFalse;\n'
       
   373     match_str += '\tcmd->Match (*proprietary_event'+ ind + ', event_matches, event_concludes, event_continue_matching);\n'
       
   374     match_str += '\tif (!event_matches)\n'
       
   375     match_str += '\t\t{\n\t\treturn TestStepResult();\n\t\t}\n'   
       
   376  
       
   377     return match_str
       
   378              
       
   379 def makeMatchProprietaryEevnts(aOpcode, aParams):
       
   380     m =0 
       
   381     ind = 1
       
   382     match_str = ''
       
   383     while ('Match' in aParams[m:]):
       
   384         m = m + aParams[m:].index('Match') + 1
       
   385         match_str += makeMatchProprietaryEevnt(aOpcode, 'E' + aParams[m], str(ind)) + '\n'       
       
   386         ind += 1 
       
   387     return match_str         
       
   388     
       
   389 def makeMatchEmptyEevnt(aOpcode): 
       
   390     match_str = '\t_LIT8(empty_formatter,"'
       
   391     #1- event code, #1- length of the event data, 1- command credits, 2- opcode;   
       
   392     match_str +=  '\\x0\\x0\\x0\\x0\\x0");\n'
       
   393     match_str += '\tTVendorDebugEvent* empty_event = new(ELeave) TVendorDebugEvent(empty_formatter);\n'
       
   394     match_str += '\tevent_matches=EFalse; event_concludes=EFalse; event_continue_matching=EFalse;\n'
       
   395     match_str += '\tcmd->Match (*empty_event, event_matches, event_concludes, event_continue_matching);\n' 
       
   396     match_str += '\tif ((event_matches)||(event_concludes)||(event_continue_matching))\n'
       
   397     match_str += '\t\t{\n\t\treturn TestStepResult();\n\t\t}\n'
       
   398 
       
   399     return match_str   
       
   400     
       
   401     
       
   402 #                                                                                    
       
   403 # Returns a string to be passed as a single argument to the constructr for events.
       
   404 #
       
   405 
       
   406 def makeEventParams(aParams):
       
   407      return 'init_value'      
       
   408 
       
   409 
       
   410 #
       
   411 # Writes command test step. Template substitutions are:
       
   412 #
       
   413 # $FILENAME: name of file, of the form nameofcommandcommandstep
       
   414 # $CLASSNAME: name of test step class, of the form CNameOfCommandCommandStep
       
   415 # $HEADERGUARD: for header guard defines, of the form NAMEOFCOMMANDCOMMANDSTEP 
       
   416 # $CMDNAME: name of command to test, of the form CNameOfCommandCommand
       
   417 # $CMDFILENAME: name of files containing command to test, of the for nameofcommandcommand
       
   418 # $MAXPARAMETERS: command maximum construction parameters
       
   419 # $CMDOPCODE: opcode of the command to test, of the form KNameOfCommandOpcode
       
   420 # $CHECK_MAX_ACCESSORS: code checking that the command parameters have been set to their maximum values
       
   421 # $FRAMEDATA: a descriptor containing max parameters values, used to very that CHctlCommandFrame is written correctly
       
   422 # $MINPARAMETERS: command minimum construction parameters
       
   423 # $CHECK_MAX_ACCESSORS: code checking that the command parameters have been set to their minimum values
       
   424 # $TESTSTEPNAME: name for this test step                      
       
   425 # $CMDINITMAXPARAMS: initialistation of params for the constructor of command with max values of all fields
       
   426 # $CMDINITMIXPARAMS: initialistation of params for the constructor of command with min values of all fields
       
   427 # $GENERATE_TIME_STAMP: timestamp showing when the generator produced the file
       
   428 #
       
   429             
       
   430 def writeCommandTestStep(aCmd, aMatchData, aParams, aHeaderTemplate, aSourceTemplate, aPath):
       
   431    matchParams = re.split(r'[^a-zA-Z_0-9\*]+', aMatchData);
       
   432    
       
   433    cmd = {'FILENAME': aCmd.lower() + 'commandstep',
       
   434            'CLASSNAME': 'C' + aCmd + 'CommandStep',
       
   435            'HEADERGUARD': aCmd.upper() + 'COMMANDSTEP',
       
   436            'CMDNAME': 'C' + aCmd + 'Command',         
       
   437            'CMDFILENAME': aCmd.lower() + 'command',
       
   438            'MAXPARAMETERS': makeMaxParameters(aParams),
       
   439            'CMDOPCODE': 'K' + aCmd + 'Opcode',
       
   440            'CHECK_MAX_ACCESSORS': makeCommandMaxAccessors(aParams, 'cmd'),
       
   441            'FRAMEDATA': makeMaxData(aParams),
       
   442            'MINPARAMETERS': makeMinParameters(aParams),
       
   443            'CHECK_MIN_ACCESSORS': makeCommandMinAccessors(aParams, 'cmd'),
       
   444            'TESTSTEPNAME': aCmd + 'CommandStep',
       
   445            'CMDINITMAXPARAMS': makeCommandInitMaxParams(aParams),   
       
   446            'CMDINITMINPARAMS': makeCommandInitMinParams(aParams),
       
   447            'MATCH_COMPLETE_EVENT': makeMatchCompleteEevnt('K' + aCmd + 'Opcode'),
       
   448            'MATCH_STATUS_EVENT': makeMatchStatusEevnt('K' + aCmd + 'Opcode'),
       
   449            'MATCH_PROPRIETARY_EVENT': makeMatchProprietaryEevnts('K' + aCmd + 'Opcode',matchParams),
       
   450            'MATCH_EMPTY_EVENT': makeMatchEmptyEevnt('K' + aCmd + 'Opcode'),
       
   451            'GENERATE_TIME_STAMP': strftime("%a, %d %b %Y %H:%M:%S") + ' (time stamp)'}
       
   452             
       
   453    #file(aPath + '\\' + cmd['FILENAME'] + '.h', 'w+').write(aHeaderTemplate.substitute(cmd))
       
   454    #file(aPath + '\\' + cmd['FILENAME'] + '.cpp', 'w+').write(aSourceTemplate.substitute(cmd))
       
   455    doTimeStampCompareAndWrite(aPath + '\\' + cmd['FILENAME'] + '.h', aHeaderTemplate.substitute(cmd))
       
   456    doTimeStampCompareAndWrite(aPath + '\\' + cmd['FILENAME'] + '.cpp', aSourceTemplate.substitute(cmd))
       
   457 
       
   458 
       
   459 #
       
   460 # Write event test step. Template substitutions are:
       
   461 #
       
   462 # $FILENAME: name of file, of the form nameofeventeventstep
       
   463 # $CLASSNAME: name of test step class, of the the form CNameOfEventEventStep
       
   464 # $HEADERGUARD: for header guard defines, of the form NAMEOFEVENTEVENTSTEP
       
   465 # $EVENTNAME: name of event to test, of the form TNameOfEventEvent
       
   466 # $EVENTFILENAME: name of files containing command to test, of the form nameofeventevent
       
   467 # $EVENTCODE: event code of event to test, of the form ENameOfEventEvent
       
   468 # $EVENTPARAMS: parameters used to construct the event, is a descriptor
       
   469 # $CHECK_EVENT_ACCESSORS: code checking that the event parameters have been set properly
       
   470 # $TESTSTEPNAME: name for this test step                      
       
   471 # $EVENTINITPARAMS: initialistation of params for the constructor of event with min values of all fields
       
   472 # $GENERATE_TIME_STAMP: timestamp showing when the generator produced the file
       
   473 #
       
   474 
       
   475 def writeEventTestStep(aEvent, aParams, aHeaderTemplate, aSourceTemplate, aPath):
       
   476     eve = {'FILENAME': aEvent.lower() + 'eventstep',
       
   477            'CLASSNAME': 'C' + aEvent + 'EventStep',
       
   478            'HEADERGUARD': aEvent.upper() + 'EVENTSTEP',
       
   479            'EVENTNAME': 'T' + aEvent + 'Event',
       
   480            'EVENTFILENAME': aEvent.lower() + 'event',
       
   481            'EVENTCODE': 'E' + aEvent + 'Event',      
       
   482            'EVENTPARAMS': makeEventParams(aParams),
       
   483            'CHECK_EVENT_ACCESSORS': makeEventMinAccessors(aParams, 'event'),
       
   484            'TESTSTEPNAME': aEvent + 'EventStep',
       
   485            'EVENTINITPARAMS': makeEventInitMinParams('E' + aEvent + 'Event', aParams),
       
   486            'GENERATE_TIME_STAMP': strftime("%a, %d %b %Y %H:%M:%S") + ' (time stamp)'}
       
   487 
       
   488     #file(aPath + '\\' + eve['FILENAME'] + '.h', 'w+').write(aHeaderTemplate.substitute(eve))
       
   489     #file(aPath + '\\' + eve['FILENAME'] + '.cpp', 'w+').write(aSourceTemplate.substitute(eve))
       
   490     doTimeStampCompareAndWrite(aPath + '\\' + eve['FILENAME'] + '.h', aHeaderTemplate.substitute(eve))
       
   491     doTimeStampCompareAndWrite(aPath + '\\' + eve['FILENAME'] + '.cpp', aSourceTemplate.substitute(eve))
       
   492 
       
   493 
       
   494 #
       
   495 # Write complete event test step. Template substitutions are:
       
   496 #
       
   497 # $FILENAME: name of file, of the form nameofcompleteeventcompleteeventstep
       
   498 # $CLASSNAME: name of test step class, of the the form CNameOfCompleteEventCompleteEventStep
       
   499 # $HEADERGUARD: for header guard defines, of the form NAMEOFCOMPLETEEVENTCOMPLETEEVENTSTEP
       
   500 # $EVENTNAME: name of event to test, of the form TNameOfCompleteEventCompleteEvent
       
   501 # $EVENTFILENAME: name of files containing command to test, of the form nameofcompleteeventcompleteevent
       
   502 # $EVENTCODE: event code of event to test, always ECommandCompleteEvent
       
   503 # $EVENTPARAMS: parameters used to construct the event, is a descriptor
       
   504 # $CHECK_EVENT_ACCESSORS: code checking that the event parameters have been set properly
       
   505 # $TESTSTEPNAME: name for this test step                      
       
   506 # $EVENTINITPARAMS: initialistation of params for the constructor of completeevent with min values of all fields
       
   507 # $GENERATE_TIME_STAMP: timestamp showing when the generator produced the file
       
   508 #
       
   509 
       
   510 def writeCompleteEventTestStep(aEvent, aParams, aHeaderTemplate, aSourceTemplate, aPath):
       
   511     eve = {'FILENAME': aEvent.lower() + 'completeeventstep',
       
   512            'CLASSNAME': 'C' + aEvent + 'CompleteEventStep',
       
   513            'HEADERGUARD': aEvent.upper() + 'COMPLETEEVENTSTEP',
       
   514            'EVENTNAME': 'T' + aEvent + 'CompleteEvent',
       
   515            'EVENTFILENAME': aEvent.lower() + 'completeevent',
       
   516            'EVENTCODE': 'ECommandCompleteEvent',
       
   517            'EVENTPARAMS': makeEventParams(aParams),
       
   518            'CHECK_EVENT_ACCESSORS': makeEventMinAccessors(aParams, 'event'),
       
   519            'TESTSTEPNAME': aEvent + 'CompleteEventStep',
       
   520            'EVENTINITPARAMS': makeCompleteEventInitMinParams('ECommandCompleteEvent', 'K' + aEvent + 'Opcode', aParams),
       
   521            'GENERATE_TIME_STAMP': strftime("%a, %d %b %Y %H:%M:%S") + ' (time stamp)'}
       
   522 
       
   523     #file(aPath + '\\' + eve['FILENAME'] + '.h', 'w+').write(aHeaderTemplate.substitute(eve))
       
   524     #file(aPath + '\\' + eve['FILENAME'] + '.cpp', 'w+').write(aSourceTemplate.substitute(eve))
       
   525     doTimeStampCompareAndWrite(aPath + '\\' + eve['FILENAME'] + '.h', aHeaderTemplate.substitute(eve))
       
   526     doTimeStampCompareAndWrite(aPath + '\\' + eve['FILENAME'] + '.cpp', aSourceTemplate.substitute(eve))
       
   527 
       
   528 #
       
   529 # Writes aEntries as CommandTestSteps
       
   530 #
       
   531 
       
   532 def writeCommandTestSteps(aEntries, aHeaderTemplate, aSourceTemplate, aPath):
       
   533     for e in aEntries:
       
   534         writeCommandTestStep(e, aEntries[e][0], aEntries[e][1], aHeaderTemplate, aSourceTemplate, aPath)
       
   535 
       
   536 
       
   537 #
       
   538 # Writes aEntries as EventTestSteps
       
   539 #
       
   540 
       
   541 def writeEventTestSteps(aEntries, aHeaderTemplate, aSourceTemplate, aPath):
       
   542     for e in aEntries:
       
   543         writeEventTestStep(e, aEntries[e][1], aHeaderTemplate, aSourceTemplate, aPath)
       
   544 
       
   545 #
       
   546 # Writes aEntries as CompleteEventTestSteps
       
   547 #
       
   548 
       
   549 def writeCompleteEventTestSteps(aEntries, aHeaderTemplate, aSourceTemplate, aPath):
       
   550     for e in aEntries:
       
   551         writeCompleteEventTestStep(e, aEntries[e][1], aHeaderTemplate, aSourceTemplate, aPath)
       
   552 
       
   553 #
       
   554 # Writes test steps to files. Uses .ini file aIni to get types, datafile and templates.
       
   555 #
       
   556         
       
   557 def writeTestSteps(aIni, aPath):
       
   558     cfg = ConfigParser.ConfigParser()
       
   559     cfg.readfp(file(aIni))
       
   560 
       
   561     for s in cfg.sections():
       
   562         typ = cfg.get(s, 'Type').lower()
       
   563 
       
   564         if typ == 'command':
       
   565             folded = getFolded(getEntries(cfg.get(s, 'Datafile')), getTypes(cfg.get(s, 'Typefile')), 3)
       
   566             writeCommandTestSteps(folded,
       
   567                                   string.Template(file(cfg.get(s, 'TestStepHeaderTemplate')).read()),
       
   568                                   string.Template(file(cfg.get(s, 'TestStepSourceTemplate')).read()),
       
   569                                   aPath)
       
   570         elif typ == 'event':
       
   571             writeEventTestSteps(getFolded(getEntries(cfg.get(s, 'Datafile')), getTypes(cfg.get(s, 'Typefile')), 0),
       
   572                                 string.Template(file(cfg.get(s, 'TestStepHeaderTemplate')).read()),
       
   573                                 string.Template(file(cfg.get(s, 'TestStepSourceTemplate')).read()),
       
   574                                 aPath)
       
   575         elif typ == 'completeevent':
       
   576             writeCompleteEventTestSteps(getFolded(getEntries(cfg.get(s, 'Datafile')), getTypes(cfg.get(s, 'Typefile')), 0),
       
   577                                         string.Template(file(cfg.get(s, 'TestStepHeaderTemplate')).read()),
       
   578                                         string.Template(file(cfg.get(s, 'TestStepSourceTemplate')).read()),
       
   579                                         aPath)
       
   580