def __time(self, indent = 0, printTotal = False, totalIndent = 0):
     secFormat = '{:8.4f}'
     now = time.perf_counter()  # @UndefinedVariable
     printLine('*** Duration: ' + secFormat.format(now - self.__lastTime) + ' Seconds ***', indent = indent)
     if printTotal:
         totalAsterisk = '******'
         if totalIndent < indent:
             totalAsterisk += (indent - totalIndent) * 2 * '*'
         printLine(totalAsterisk + ' Total: ' + secFormat.format(now - self.__startTime) + ' Seconds ***', indent = totalIndent)
     self.__lastTime = now
    def addCode(self, subroutineFullName, typeArgumentReferences,
                typeResultReferences, globalsReferences, callgraph, types):
        assertType(subroutineFullName, 'subroutineFullName',
                   SubroutineFullName)
        assertTypeAll(typeArgumentReferences, 'typeArgumentReferences',
                      VariableReference)
        assertTypeAll(typeResultReferences, 'typeResultReferences',
                      VariableReference)
        assertTypeAll(globalsReferences, 'globalsReferences',
                      VariableReference)
        assertType(callgraph, 'callgraph', CallGraph)
        assertType(types, 'types', TypeCollection)

        printLine('Add Code to Used Modules', indent=1)
        self.__backupFinder.setBackupSuffixPrefix(
            self.__backupFinder.EXPORT_SUFFIX_PREFIX)
        refModules = list(
            self.__getModulesFromCallgraph(callgraph).union(
                self.__extractModulesFromVariableReferences(
                    globalsReferences)))
        refModules.sort(reverse=True)
        for refModule in refModules:
            usedSourceFile = refModule.getSourceFile()
            usedSourceFilePath = usedSourceFile.getPath()
            if usedSourceFilePath.endswith(
                    self.__backupFinder.getBackupSuffix()):
                usedSourceFilePath = usedSourceFilePath.replace(
                    self.__backupFinder.getBackupSuffix(),
                    CodeGenerator.DEFAULT_SUFFIX)
                usedSourceFile = SourceFile(usedSourceFilePath,
                                            usedSourceFile.isPreprocessed())
                refModule = usedSourceFile.getModule(refModule.getName())
            self.__backupFinder.setBackupSuffixPrefix(
                BackupFileFinder.EXPORT_SUFFIX_PREFIX)
            backup = self.__backupFinder.create(usedSourceFilePath)
            subroutine = self._findSubroutine(subroutineFullName)
            self._setTypesToSubroutineVariables(subroutine, types)
            exportTemplateNameSpace = ExportTemplatesNameSpace(
                refModule, typeArgumentReferences, typeResultReferences,
                globalsReferences, subroutine, callgraph, self._postProcessor)
            lastLine = refModule.getContainsLineNumber()
            if lastLine < 0:
                lastLine = refModule.getLastLineNumber()
            result = self._processTemplate(usedSourceFilePath, lastLine - 1,
                                           self.BEFORE_CONTAINS_TEMPLATE_PART,
                                           exportTemplateNameSpace)
            lastUseLineNumber = refModule.getLastUseLineNumber()
            lastUseLineNumber = self._shiftLineNumberByPreprocesserorEndifs(
                refModule, lastUseLineNumber)
            result = self._processTemplate(usedSourceFilePath,
                                           lastUseLineNumber,
                                           self.AFTER_USE_TEMPLATE_PART,
                                           exportTemplateNameSpace) or result
            if backup and not result:
                self.__backupFinder.remove(usedSourceFilePath)
 def _processTemplate(self, sourceFilePath, lineNumber, part, templateNameSpace):
     printInline('Process Template ' + os.path.basename(self.__templatePath) + ' [' + part + ']' + ' on file ' + sourceFilePath, indent = 2)
     source = self._readFile(sourceFilePath)
     codeToAdd = self.__loadTemplate(part, templateNameSpace)
     
     if codeToAdd:
         source = source[:lineNumber] + ["\n"] + [codeToAdd] + ["\n", "\n"] + source[lineNumber:]
         self._writeFile(sourceFilePath, source)
         printLine()
         return True
     else:
         printLine(' >>> EMPTY')
         return False
Beispiel #4
0
 def remove(self, originalPath):
     printInline('Remove File Backup of ' + originalPath, indent=2)
     backupPath = originalPath.replace(BackupFileFinder.DEFAULT_SUFFIX,
                                       self.getBackupSuffix())
     backupPath = backupPath.replace(
         BackupFileFinder.DEFAULT_SUFFIX.upper(), self.getBackupSuffix())
     if (backupPath == originalPath):
         backupPath = originalPath + self.getBackupSuffix()
     if os.path.exists(backupPath):
         os.remove(backupPath)
         printLine()
         return True
     else:
         printLine(' >>> NOT FOUND')
         return False
    def addCode(self, subroutineFullName, typeArgumentReferences,
                typeResultReferences, globalsReferences, callgraph, types):
        assertType(subroutineFullName, 'subroutineFullName',
                   SubroutineFullName)
        assertTypeAll(typeArgumentReferences, 'typeArgumentReferences',
                      VariableReference)
        assertTypeAll(typeResultReferences, 'typeResultReferences',
                      VariableReference)
        assertTypeAll(globalsReferences, 'globalsReferences',
                      VariableReference)
        assertType(callgraph, 'callgraph', CallGraph)
        assertType(types, 'types', TypeCollection)

        printLine('Create code in new test source file', indent=1)
        tempTestFile = os.path.join(self.__testSourceDir, self.TEMP_TEST_FILE)

        printLine('Create file ' + tempTestFile, indent=2)
        self._writeFile(tempTestFile, [])

        subroutine = self._findSubroutine(subroutineFullName)
        self._setTypesToSubroutineVariables(subroutine, types)
        templateNameSpace = ReplayTemplatesNameSpace(
            subroutine, typeArgumentReferences, typeResultReferences,
            globalsReferences, self.__testDataDir, callgraph,
            self._postProcessor)
        self._processTemplate(tempTestFile, 0, self.TEST_TEMPLATE_PART,
                              templateNameSpace)

        testModuleName = self.__findModuleNameInTestFile(tempTestFile)
        if testModuleName is not None:
            testFilePath = os.path.join(self.__testSourceDir,
                                        testModuleName + '.f90')
            printLine('Rename file to ' + testFilePath, indent=2)
            os.rename(tempTestFile, testFilePath)
Beispiel #6
0
 def create(self, originalPath):
     printInline('Create File Backup of ' + originalPath, indent=2)
     backupPath = originalPath
     if not backupPath.endswith(self.getBackupSuffix()):
         backupPath = backupPath.replace(BackupFileFinder.DEFAULT_SUFFIX,
                                         self.getBackupSuffix())
         backupPath = backupPath.replace(
             BackupFileFinder.DEFAULT_SUFFIX.upper(),
             self.getBackupSuffix())
     if not os.path.exists(backupPath):
         shutil.copyfile(originalPath, backupPath)
         printLine()
         return True
     elif not os.path.exists(originalPath):
         shutil.copyfile(backupPath, originalPath)
         printLine()
         return True
     else:
         printLine(' >>> ALREADY EXISTS')
         return False
Beispiel #7
0
 def restore(self):
     for backupFile in self.find():
         restoreFile = self.__getOriginalFile(backupFile)
         printLine('Restore ' + restoreFile, indent=1)
         os.rename(backupFile, restoreFile)
def main():
    argParser = argparse.ArgumentParser(description='Generate test code.');
    args = parseArguments(argParser);
    if not (args.restore or args.restoreCapture or args.export or args.capture or args.replay):
        argParser.error('No action requested, add -a/--restoreCapture and/or -b/--restore and/or -c/--capture and/or -e/--export and/or -r/--replay')

    config = loadFortranTestGeneratorConfiguration(args.configFile)
    if config is None:
        exit(3)
        
    backupSuffix = '.' + config[CFG_BACKUP_SUFFIX].lstrip('.')
    ftgPrefix = config[CFG_FTG_PREFIX]
    templatePath = config[CFG_TEMPLATE]
    testSourceDir = config[CFG_TEST_SOURCE_DIR]
    testDataBaseDir = config[CFG_TEST_DATA_BASE_DIR]
    modifySourceDirs = config[CFG_MODIFY_SOURCE_DIRS]
        
    sys.path.append(config[CFG_FCG_DIR])
        
    from fcgconfigurator import loadFortranCallGraphConfiguration, CFG_EXCLUDE_MODULES, CFG_IGNORE_GLOBALS_FROM_MODULES, CFG_IGNORE_DERIVED_TYPES, CFG_ASSEMBLER_DIRS,\
    CFG_SPECIAL_MODULE_FILES, CFG_CACHE_DIR, CFG_SOURCE_DIRS, CFG_SOURCE_FILES_PREPROCESSED, CFG_ABSTRACT_TYPES, CFG_ALWAYS_FULL_TYPES
    from source import SubroutineFullName, SourceFiles
    from backup import BackupFileFinder
    from postprocessor import CodePostProcessor
    from generator import CodeGeneratorSettings
    from combined import CombinedCodeGenerator 
    from assembler import GNUx86AssemblerCallGraphBuilder
    from treecache import CachedAssemblerCallGraphBuilder
    
    configFTG = {}
    if config[CFG_FCG_CONFIG_FILE] is not None:
        configFTG = loadFortranCallGraphConfiguration(config[CFG_FCG_CONFIG_FILE], incomplete=True)
    configFTG = loadFortranCallGraphConfiguration(config[CFG_FTG_CONFIG_FILE], baseConfig=configFTG) # Overwrite variables from FCG config file
    if configFTG is None:
        exit(3)
    config.update(configFTG)

    excludeModules = config[CFG_EXCLUDE_MODULES]
    ignoreGlobalsFromModuls = config[CFG_IGNORE_GLOBALS_FROM_MODULES]
    ignoreDerivedTypes = config[CFG_IGNORE_DERIVED_TYPES]
    alwaysFullTypes = config[CFG_ALWAYS_FULL_TYPES]
    abstractTypes = config[CFG_ABSTRACT_TYPES]
    sourceDirs = config[CFG_SOURCE_DIRS]

    graphBuilder = GNUx86AssemblerCallGraphBuilder(config[CFG_ASSEMBLER_DIRS], config[CFG_SPECIAL_MODULE_FILES])
    if config[CFG_CACHE_DIR]:
        graphBuilder = CachedAssemblerCallGraphBuilder(config[CFG_CACHE_DIR], graphBuilder)
    sourceFiles = SourceFiles(sourceDirs, config[CFG_SPECIAL_MODULE_FILES], config[CFG_SOURCE_FILES_PREPROCESSED])
    if modifySourceDirs is not None:
        modifySourceFiles = SourceFiles(modifySourceDirs, config[CFG_SPECIAL_MODULE_FILES])
        backupFinder = BackupFileFinder(modifySourceDirs, backupSuffix) 
    else:
        modifySourceFiles = sourceFiles
        backupFinder = BackupFileFinder(sourceDirs, backupSuffix) 

    if args.export or args.capture or args.replay:
        moduleName = args.module;
        subroutineName = args.subroutine;
        
        subroutineFullName = None
        
        if not moduleName:
            argParser.error('Missing Module (and Subroutine) name!');
        elif not subroutineName:
            if SubroutineFullName.validFullName(moduleName):
                subroutineFullName = SubroutineFullName(moduleName)
            else: 
                argParser.error('Missing Subroutine name!');
        elif SubroutineFullName.validParts(moduleName, subroutineName):
            subroutineFullName = SubroutineFullName.fromParts(moduleName, subroutineName)
        else:
            argParser.error('Invalid Module and/or Subroutine name!');
            
        if subroutineFullName is not None and not sourceFiles.existsSubroutine(subroutineFullName):
            argParser.error('Subroutine ' + str(subroutineFullName) + ' not found!');
        
    if args.restore:
        printLine('Restore all Backup Files')
        backupFinder.restore()
        sourceFiles.clearCache()
    elif args.restoreCapture:
        printLine('Restore Capture Backup Files')
        backupFinder.setBackupSuffixPrefix(BackupFileFinder.CAPTURE_SUFFIX_PREFIX)
        backupFinder.restore()
        sourceFiles.clearCache()
    elif modifySourceDirs is None or modifySourceDirs == sourceDirs:
        sourceFiles.setSpecialModuleFiles(backupFinder.extendSpecialModuleFiles(sourceFiles.getSpecialModuleFiles()))

    if args.export or args.capture or args.replay:
        printLine('Generate Code')
        postProcessor = CodePostProcessor()
        generatorSettings = CodeGeneratorSettings()
        generatorSettings.excludeModules = excludeModules
        generatorSettings.ignoreGlobalsFromModules = ignoreGlobalsFromModuls
        generatorSettings.fullTypes      = alwaysFullTypes
        generatorSettings.ignoredTypes   = ignoreDerivedTypes
        generatorSettings.ignorePrefix   = ftgPrefix
        generatorSettings.abstractTypes  = abstractTypes
        generatorSettings.measureTime    = args.measure
        generatorSettings.clearCache     = args.clearCache
        generator = CombinedCodeGenerator(args.capture, args.replay, sourceFiles, modifySourceFiles, templatePath, testSourceDir, testDataBaseDir, graphBuilder, postProcessor, backupFinder, generatorSettings)
        generator.generate(subroutineFullName)
    def generate(self, subroutineFullName):
        assertType(subroutineFullName, 'subroutineFullName', SubroutineFullName)

        if self._settings.ignorePrefix != '':
            self._settings.ignoreSubroutinesRegex = re.compile('^' + self._settings.ignorePrefix + '.*$')
        else:
            self._settings.ignoreSubroutinesRegex = None
            
        subroutine = self._findSubroutine(subroutineFullName)
        if subroutine is None:
            raise LookupError("Subroutine not found: " + str(subroutineFullName))

        if self._settings.measureTime: self.__initTime()
        
        printLine('Build Call Graph', indent = 1)
        callgraph = self.__graphBuilder.buildCallGraph(subroutineFullName, self._settings.clearCache)

        if self._settings.measureTime: self.__time(2)
        
        printLine('Find Interfaces and Types', indent = 1)
        useTraversal = UseTraversal(self._sourceFiles, self._settings.excludeModules, self._settings.abstractTypes)
        useTraversal.parseModules(callgraph.getRoot())
        interfaces = useTraversal.getInterfaces()
        types = useTraversal.getTypes()
        
        if self._settings.measureTime: self.__time(2)

        printLine('Analyse Source Code', indent = 1)
        argumentTracker = VariableTracker(self._sourceFiles, self._settings, interfaces, types, callGraphBuilder = self.__graphBuilder)
        
        printLine('Find References to Type Argument Members', indent = 2)
        typeArgumentReferences = argumentTracker.trackDerivedTypeArguments(callgraph)
        
        subroutine = self._findSubroutine(subroutineFullName)
        if subroutine.isFunction() and subroutine.getResultVariable().hasDerivedType():
            printLine('Find References to Type Result', indent = 2)
            typeResultReferences = argumentTracker.trackDerivedTypeResult(callgraph)
        else:
            typeResultReferences = []
        
        printLine('Find References to Global Variables', indent = 2)
        globalsTracker = GlobalVariableTracker(self._sourceFiles, self._settings, interfaces, types, callGraphBuilder = self.__graphBuilder)
        globalsReferences = globalsTracker.trackGlobalVariables(callgraph)
        
        sourceFile = subroutine.getSourceFile()
        sourceFilePath = sourceFile.getPath()
        if not os.path.isfile(sourceFile.getPath()):
            raise IOError("File not found: " + sourceFilePath);
        
        if self._settings.measureTime: self.__time(2)
        
        self.addCode(subroutineFullName, typeArgumentReferences, typeResultReferences, globalsReferences, callgraph, types)
        
        if self._settings.measureTime: self.__time(2, True, 1)