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 = """<?xml version="1.0" encoding="ISO-8859-1" ?>
etisserant@31:     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
lbessard@145:       <xsd:element name="CExtension">
etisserant@31:         <xsd:complexType>
etisserant@45:           <xsd:attribute name="CFLAGS" type="xsd:string" use="required"/>
etisserant@45:           <xsd:attribute name="LDFLAGS" type="xsd:string" use="required"/>
etisserant@31:         </xsd:complexType>
etisserant@31:       </xsd:element>
etisserant@31:     </xsd:schema>
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 <stdio.h>\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