diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py index f5709632cd4ceac1c9d92e9f5b3be3d764ccbc89..b8c84d63a1acdf65b57d992fab7e592e3fb972eb 100644 --- a/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py +++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/fesaTemplates.py @@ -662,6 +662,7 @@ override WARNFLAGS += # Additional compiler flags COMPILER_FLAGS += -I$(SILECS_PATH)/include -I$(SILECS_PATH)/include/silecs-communication/interface/core +COMPILER_FLAGS += -I./generated-silecs/cpp COMPILER_FLAGS += LINKER_FLAGS += diff --git a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py index 75d9a874b61890d7c50160c6d1603f330ac5ed0c..08db72a0eac0deeb261c71830021eebb3f639d58 100644 --- a/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py +++ b/silecs-codegen/src/xml/fesa/fesa_3_0_0/generateSourceCode.py @@ -186,17 +186,20 @@ def genCppSource(className, silecsRoot, fesaRoot, sourcePath,logTopics): iecommon.logInfo('Source file for '+className+' generated successfully', logTopics) def genCppFiles(className, workspacePath, silecsDesignFilePath,logTopics={'errorlog': True}): - fesaCommonDirectory = iefiles.getFesa3CommonDirectory(workspacePath,className) - iecommon.logInfo("fesaCommonDirectory:" + fesaCommonDirectory,logTopics) - if not os.path.exists(fesaCommonDirectory ): - os.makedirs(fesaCommonDirectory) + generatedCodeFolder = workspacePath + '/' + className + '/generated-silecs/cpp/' + className + '/GeneratedCode' + generatedCodeFolderNorm = os.path.normpath(generatedCodeFolder) + + iecommon.logInfo("generated code folder:" + generatedCodeFolderNorm,logTopics) + + if not os.path.exists(generatedCodeFolderNorm ): + os.makedirs(generatedCodeFolderNorm) silecsDesignFilePath = iefiles.getSilecsDesignFilePath(workspacePath,className) fesaDesignFilePath = workspacePath + "/" + className + "/src/" + className + ".design" silecsRoot = libxml2.parseFile(silecsDesignFilePath) fesaRoot = libxml2.parseFile(fesaDesignFilePath) - genHSource(className, silecsRoot, fesaRoot, fesaCommonDirectory,logTopics) - genCppSource(className, silecsRoot, fesaRoot, fesaCommonDirectory,logTopics) + genHSource(className, silecsRoot, fesaRoot, generatedCodeFolderNorm,logTopics) + genCppSource(className, silecsRoot, fesaRoot, generatedCodeFolderNorm,logTopics) diff --git a/silecs-codegen/src/xml/iefiles.py b/silecs-codegen/src/xml/iefiles.py index 6b52f876f664c0cd2734aa10220359026f0dc5a1..4626532fb9e0e2c763caac70fc47392da2e4fcf9 100644 --- a/silecs-codegen/src/xml/iefiles.py +++ b/silecs-codegen/src/xml/iefiles.py @@ -123,11 +123,6 @@ def getDuWrapperFile(workspacePath, deployName, controllerName ): def getDuDesignWrapperFile(workspacePath, deployName, designName): return getDuWrapperSourceDirectory(workspacePath, deployName) + "/" + getDuWrapperFileName(designName) -#--- FESA --- -def getFesa3CommonDirectory(workspacePath, designName): - fesa3ClassPath = workspacePath + '/' + designName + '/src/' + designName + '/Common' - fesa3ClassPathNorm = os.path.normpath(fesa3ClassPath) - return fesa3ClassPathNorm def getProjectDirectory(workspacePath, designName): path = workspacePath + '/' + designName diff --git a/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py b/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py new file mode 100644 index 0000000000000000000000000000000000000000..542940ef5a27813a70ccb2e7d832a77a352296df --- /dev/null +++ b/silecs-codegen/src/xml/migration/2_0_xto2_1_x.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import sys + +from migrationBase import MigrationBase +from migration2_0_Xto2_1_X.migrators import * + +import libxml2 +import sys +import FileUtils +import shutil + +class Migration(MigrationBase): + def __init__(self, arguments): + super(Migration, self).__init__() + + def migrateClass(self, context, projectDir ): + modified = fesaClassIncludeHeaderMigrator(context,self.silecsDocument) + removeSilecsGenCode(context, self.silecsDocument) + # modified |= designBlockRegisterMigrator(context) + return modified + + +if __name__ == "__main__": + migration = Migration(sys.argv) + migration.migrate() + migration.updateFESAMakeSpecific() diff --git a/silecs-codegen/src/xml/migration/FileUtils.py b/silecs-codegen/src/xml/migration/FileUtils.py index e1f3b78ca44a677bf8a04a394218592ef9e4adb7..dbb1f16c81550142f881e403f1167220f40d7263 100644 --- a/silecs-codegen/src/xml/migration/FileUtils.py +++ b/silecs-codegen/src/xml/migration/FileUtils.py @@ -25,15 +25,38 @@ def write(string, filePath): f.write(string) def backupFile(fileName): + if not os.path.isfile(fileName): + return src = fileName dst = fileName + ".backup" - print("Original file backed up by adding '.backup'") - shutil.copyfile(src, dst) - + os.rename(src, dst) + print("Backed up old file: " + dst) + def getExtension(fileName): '''Returns the file extension, dot included''' return fileName[fileName.rfind('.'):] -def getProjectDir(fesaDocument): - absPath = os.path.abspath(fesaDocument) +def getProjectDir(file_in_project): + absPath = os.path.abspath(file_in_project) return os.path.dirname(os.path.dirname(absPath)) + +def getFesaSourceFiles(fesaClassName, projectDir): + fesaCodeFolder = os.path.join(projectDir,"src",fesaClassName) + if not os.path.exists(fesaCodeFolder): + return [] + if not os.path.isdir(fesaCodeFolder): + return [] + sourceFiles = [] + for root, subdirs, files in os.walk(fesaCodeFolder): + for file in files: + if file.endswith(".cpp") or file.endswith(".h"): + print os.path.join(root,file) + sourceFiles.append(os.path.join(root,file)) + return sourceFiles + +def replaceInFile(filePath,searchString,replaceWithString): + with open(filePath, 'r') as file : + filedata = file.read() + filedata = filedata.replace(searchString, replaceWithString) + with open(filePath, 'w') as file: + file.write(filedata) \ No newline at end of file diff --git a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/__init__.py b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py new file mode 100644 index 0000000000000000000000000000000000000000..20c6f5dda9c7c87bb59518c58bc8eed592592dbf --- /dev/null +++ b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/migrators.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import libxml2 +import FileUtils +import os + +def fesaClassIncludeHeaderMigrator(context,silecsDocument): + modified = False + silecsClassNodes = context.xpathEval("//SILECS-Class") + if not silecsClassNodes: + raise Exception('Node "SILECS-Class" not found') + silecsClassNodes = silecsClassNodes[0] + silecsClassName = silecsClassNodes.prop("name") + projectDir = FileUtils.getProjectDir(silecsDocument) + sourceFiles = FileUtils.getFesaSourceFiles(silecsClassName, projectDir) + + searchString = "<" + os.path.join(silecsClassName,"Common",silecsClassName) + ".h>" + replaceString = "<" + os.path.join(silecsClassName,"GeneratedCode",silecsClassName) + ".h>" + for sourceFile in sourceFiles: + FileUtils.replaceInFile(sourceFile,searchString,replaceString) + modified = True + return modified + +def removeSilecsGenCode(context, silecsDocument): + silecsClassNodes = context.xpathEval("//SILECS-Class") + if not silecsClassNodes: + raise Exception('Node "SILECS-Class" not found') + silecsClassNodes = silecsClassNodes[0] + silecsClassName = silecsClassNodes.prop("name") + projectDir = FileUtils.getProjectDir(silecsDocument) + commonFolder = os.path.join(projectDir,"src",silecsClassName,"Common") + cppFile = os.path.join(commonFolder,silecsClassName + ".cpp") + hppFile = os.path.join(commonFolder,silecsClassName + ".h") + if os.path.isfile(cppFile): + os.remove(cppFile) + if os.path.isfile(hppFile): + os.remove(hppFile) diff --git a/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py new file mode 100644 index 0000000000000000000000000000000000000000..d8d804debcfbe01930a28857e479ca56ec689f47 --- /dev/null +++ b/silecs-codegen/src/xml/migration/migration2_0_Xto2_1_X/testMigration.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# Copyright 2016 CERN and GSI +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +from test.testBase import * + +import libxml2 +from migration.migration2_0_Xto2_1_X.migrators import * +import inspect #get caller name + +def runTests(): + print("nothing so far") + #testdesignValueTypeMigrator() + #testdesignBlockRegisterMigrator() + # print deployDoc # for debugging diff --git a/silecs-codegen/src/xml/migration/migrationBase.py b/silecs-codegen/src/xml/migration/migrationBase.py index dd53b6067685e1e2613104ae87cbfdc13e56eb9d..eea70a06dc60e2ba737201897fabf94740154d44 100644 --- a/silecs-codegen/src/xml/migration/migrationBase.py +++ b/silecs-codegen/src/xml/migration/migrationBase.py @@ -31,6 +31,8 @@ class MigrationBase(object): results = self.parser.parse_args() self.versionOld = results.versionOld self.versionNew = results.versionNew + self.silecsDocument = results.silecsDocument + self.xmlSchema = results.xmlSchema def fixSilecsVersion(self, context): root = context.xpathEval("/*")[0] @@ -45,18 +47,23 @@ class MigrationBase(object): print("Info: Replaced old silecs-xmlSchema") def backupOldFESAMakeSpecific(self): - results = self.parser.parse_args() - silecsDocument = results.silecsDocument - projectDir = FileUtils.getProjectDir(silecsDocument) - makeSpecific = projectDir + "/Makefile.specific" + projectDir = FileUtils.getProjectDir(self.silecsDocument) + makeSpecific = os.path.join(projectDir,"Makefile.specific") + FileUtils.backupFile(makeSpecific) + + def updateFESAMakeSpecific(self): + projectDir = FileUtils.getProjectDir(self.silecsDocument) + makeSpecific = os.path.join(projectDir,"Makefile.specific") if os.path.isfile(makeSpecific): - os.rename(makeSpecific, makeSpecific + ".backup") - print("Backed up old FESA Make.specific file: " + makeSpecific) + oldComm = "silecs-communication-cpp/" + self.versionOld + newComm = "silecs-communication-cpp/" + self.versionNew + FileUtils.replaceInFile(makeSpecific,oldComm,newComm) + oldSnap7 = "snap7/" + self.versionOld + newSnap7 = "snap7/" + self.versionNew + FileUtils.replaceInFile(makeSpecific,oldSnap7,newSnap7) def removeGenCode(self): - results = self.parser.parse_args() - silecsDocument = results.silecsDocument - projectDir = FileUtils.getProjectDir(silecsDocument) + projectDir = FileUtils.getProjectDir(self.silecsDocument) clientFolder = projectDir + "/generated/client" controllerFolder = projectDir + "/generated/controller" wrapperFolder = projectDir + "/generated/wrapper" @@ -71,24 +78,21 @@ class MigrationBase(object): print("removed generation folder: " + wrapperFolder) def migrate(self): - results = self.parser.parse_args() - silecsDocument = results.silecsDocument - xmlSchema = results.xmlSchema print("INFO: Migration %s --> %s " % (self.versionOld, self.versionNew)) #project directory path - projectDir = FileUtils.getProjectDir(silecsDocument) + projectDir = FileUtils.getProjectDir(self.silecsDocument) # Design - extension = FileUtils.getExtension(silecsDocument) + extension = FileUtils.getExtension(self.silecsDocument) modified = False if extension == '.silecsdesign': - context = self._parse(silecsDocument) + context = self._parse(self.silecsDocument) modified = self.migrateClass(context, projectDir) # Deploy elif extension == '.silecsdeploy': - context = self._parse(silecsDocument) + context = self._parse(self.silecsDocument) modified = self.migrateDeployUnit(context, projectDir) # Unknown @@ -97,13 +101,13 @@ class MigrationBase(object): # only chaning the version or the schema does not count as modification --> no backup needed self.fixSilecsVersion(context) - self.fixXMLScheman(context,xmlSchema) + self.fixXMLScheman(context,self.xmlSchema) if modified: - self._saveAndBackupFile(context, silecsDocument) + self._saveAndBackupFile(context, self.silecsDocument) else: - self._saveFile(context, silecsDocument) + self._saveFile(context, self.silecsDocument) - print('File %r successfully migrated' % silecsDocument) + print('File %r successfully migrated' % self.silecsDocument) def migrateClass(self, context, projectDir): return False