andrej@1511: #!/usr/bin/env python
andrej@1511: # -*- coding: utf-8 -*-
andrej@1511:
andrej@1511: # This file is part of Beremiz, a Integrated Development Environment for
andrej@1511: # programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
andrej@1511: #
andrej@1511: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
andrej@1511: #
andrej@1511: # See COPYING file for copyrights details.
andrej@1511: #
andrej@1511: # This program is free software; you can redistribute it and/or
andrej@1511: # modify it under the terms of the GNU General Public License
andrej@1511: # as published by the Free Software Foundation; either version 2
andrej@1511: # of the License, or (at your option) any later version.
andrej@1511: #
andrej@1511: # This program is distributed in the hope that it will be useful,
andrej@1511: # but WITHOUT ANY WARRANTY; without even the implied warranty of
andrej@1511: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrej@1511: # GNU General Public License for more details.
andrej@1511: #
andrej@1511: # You should have received a copy of the GNU General Public License
andrej@1511: # along with this program; if not, write to the Free Software
andrej@1511: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Laurent@1124:
andrej@1853: from __future__ import absolute_import
lbessard@145: import os
laurent@401:
andrej@1853: from c_ext.CFileEditor import CFileEditor
Laurent@1096: from CodeFileTreeNode import CodeFile
laurent@630:
andrej@1736:
Laurent@1096: class CFile(CodeFile):
etisserant@31: XSD = """
etisserant@31:
lbessard@145:
etisserant@31:
etisserant@45:
etisserant@45:
etisserant@31:
etisserant@31:
etisserant@31:
etisserant@31: """
Laurent@1124: CODEFILE_NAME = "CFile"
Laurent@1124: SECTIONS_NAMES = [
Laurent@1124: "includes",
Laurent@1124: "globals",
Laurent@1124: "initFunction",
Laurent@1124: "cleanUpFunction",
Laurent@1124: "retrieveFunction",
Laurent@1124: "publishFunction"]
laurent@656: EditorType = CFileEditor
andrej@1735:
laurent@781: def GetIconName(self):
laurent@781: return "Cfile"
laurent@738:
Laurent@1096: def CodeFileName(self):
Edouard@718: return os.path.join(self.CTNPath(), "cfile.xml")
andrej@1735:
Edouard@718: def CTNGenerate_C(self, buildpath, locations):
etisserant@31: """
etisserant@31: Generate C code
Edouard@717: @param current_location: Tupple containing confnode IEC location : %I0.0.4.5 => (0,0,4,5)
etisserant@31: @param locations: List of complete variables locations \
etisserant@31: [{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
etisserant@31: "NAME" : name of the variable (generally "__IW0_1_2" style)
etisserant@31: "DIR" : direction "Q","I" or "M"
etisserant@31: "SIZE" : size "X", "B", "W", "D", "L"
etisserant@31: "LOC" : tuple of interger for IEC location (0,1,2,...)
etisserant@31: }, ...]
etisserant@31: @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
etisserant@31: """
etisserant@31: current_location = self.GetCurrentLocation()
etisserant@31: # define a unique name for the generated C file
laurent@401: location_str = "_".join(map(str, current_location))
andrej@1735:
Edouard@717: text = "/* Code generated by Beremiz c_ext confnode */\n\n"
Laurent@1114: text += "#include \n\n"
andrej@1735:
lbessard@145: # Adding includes
lbessard@145: text += "/* User includes */\n"
Laurent@1315: text += self.CodeFile.includes.getanyText().strip()
lbessard@145: text += "\n"
andrej@1735:
Laurent@1114: text += '#include "iec_types_all.h"\n\n'
andrej@1735:
lbessard@145: # Adding variables
Laurent@1096: config = self.GetCTRoot().GetProjectConfigNames()[0]
lbessard@145: text += "/* User variables reference */\n"
Laurent@1096: for variable in self.CodeFile.variables.variable:
Laurent@1096: var_infos = {
Laurent@1096: "name": variable.getname(),
Laurent@1096: "global": "%s__%s" % (config.upper(),
Laurent@1096: variable.getname().upper()),
Laurent@1096: "type": "__IEC_%s_t" % variable.gettype()}
Laurent@1096: text += "extern %(type)s %(global)s;\n" % var_infos
Laurent@1096: text += "#define %(name)s %(global)s.value\n" % var_infos
lbessard@145: text += "\n"
andrej@1735:
lbessard@145: # Adding user global variables and routines
lbessard@145: text += "/* User internal user variables and routines */\n"
Laurent@1315: text += self.CodeFile.globals.getanyText().strip()
Laurent@1114: text += "\n"
andrej@1735:
Edouard@717: # Adding Beremiz confnode functions
Edouard@717: text += "/* Beremiz confnode functions */\n"
andrej@1734: text += "int __init_%s(int argc,char **argv)\n{\n" % location_str
Laurent@1315: text += self.CodeFile.initFunction.getanyText().strip()
Laurent@1119: text += " return 0;\n}\n\n"
andrej@1735:
andrej@1734: text += "void __cleanup_%s(void)\n{\n" % location_str
Laurent@1315: text += self.CodeFile.cleanUpFunction.getanyText().strip()
lbessard@145: text += "\n}\n\n"
andrej@1735:
andrej@1734: text += "void __retrieve_%s(void)\n{\n" % location_str
Laurent@1315: text += self.CodeFile.retrieveFunction.getanyText().strip()
lbessard@145: text += "\n}\n\n"
andrej@1735:
andrej@1734: text += "void __publish_%s(void)\n{\n" % location_str
Laurent@1315: text += self.CodeFile.publishFunction.getanyText().strip()
lbessard@145: text += "\n}\n\n"
andrej@1735:
andrej@1734: Gen_Cfile_path = os.path.join(buildpath, "CFile_%s.c" % location_str)
andrej@1740: cfile = open(Gen_Cfile_path, 'w')
lbessard@145: cfile.write(text)
lbessard@145: cfile.close()
andrej@1735:
andrej@1734: matiec_CFLAGS = '"-I%s"' % os.path.abspath(self.GetCTRoot().GetIECLibPath())
andrej@1735:
andrej@1740: return [(Gen_Cfile_path, str(self.CExtension.getCFLAGS() + matiec_CFLAGS))], str(self.CExtension.getLDFLAGS()), True