py_ext/PythonFileCTNMixin.py
changeset 1784 64beb9e9c749
parent 1777 c46ec818bdd7
child 1833 2269739dd098
equal deleted inserted replaced
1729:31e63e25b4cc 1784:64beb9e9c749
    21 #
    21 #
    22 # You should have received a copy of the GNU General Public License
    22 # You should have received a copy of the GNU General Public License
    23 # along with this program; if not, write to the Free Software
    23 # along with this program; if not, write to the Free Software
    24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
    25 
    25 
    26 import os, re
    26 import os
       
    27 import re
    27 from lxml import etree
    28 from lxml import etree
    28 import util.paths as paths
    29 import util.paths as paths
    29 
    30 
    30 from xmlclass import GenerateParserFromXSD
    31 from xmlclass import GenerateParserFromXSD
    31 
    32 
    32 from CodeFileTreeNode import CodeFile
    33 from CodeFileTreeNode import CodeFile
    33 from PythonEditor import PythonEditor
    34 from PythonEditor import PythonEditor
       
    35 
    34 
    36 
    35 class PythonFileCTNMixin(CodeFile):
    37 class PythonFileCTNMixin(CodeFile):
    36 
    38 
    37     CODEFILE_NAME = "PyFile"
    39     CODEFILE_NAME = "PyFile"
    38     SECTIONS_NAMES = [
    40     SECTIONS_NAMES = [
    57 
    59 
    58             pythonfile_xml = pythonfile_xml.replace(
    60             pythonfile_xml = pythonfile_xml.replace(
    59                 'xmlns="http://www.w3.org/2001/XMLSchema"',
    61                 'xmlns="http://www.w3.org/2001/XMLSchema"',
    60                 'xmlns:xhtml="http://www.w3.org/1999/xhtml"')
    62                 'xmlns:xhtml="http://www.w3.org/1999/xhtml"')
    61             for cre, repl in [
    63             for cre, repl in [
    62                 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
    64                     (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["),
    63                 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
    65                     (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]:
    64                 pythonfile_xml = cre.sub(repl, pythonfile_xml)
    66                 pythonfile_xml = cre.sub(repl, pythonfile_xml)
    65 
    67 
    66             try:
    68             try:
    67                 python_code, error = PythonParser.LoadXMLString(pythonfile_xml)
    69                 python_code, error = PythonParser.LoadXMLString(pythonfile_xml)
    68                 if error is None:
    70                 if error is None:
    83     def PythonFileName(self):
    85     def PythonFileName(self):
    84         return os.path.join(self.CTNPath(), "py_ext.xml")
    86         return os.path.join(self.CTNPath(), "py_ext.xml")
    85 
    87 
    86     PreSectionsTexts = {}
    88     PreSectionsTexts = {}
    87     PostSectionsTexts = {}
    89     PostSectionsTexts = {}
    88     def GetSection(self,section):
    90 
    89         return self.PreSectionsTexts.get(section,"") + "\n" + \
    91     def GetSection(self, section):
       
    92         return self.PreSectionsTexts.get(section, "") + "\n" + \
    90                getattr(self.CodeFile, section).getanyText() + "\n" + \
    93                getattr(self.CodeFile, section).getanyText() + "\n" + \
    91                self.PostSectionsTexts.get(section,"")
    94                self.PostSectionsTexts.get(section, "")
    92 
    95 
    93     def CTNGenerate_C(self, buildpath, locations):
    96     def CTNGenerate_C(self, buildpath, locations):
    94         # location string for that CTN
    97         # location string for that CTN
    95         location_str = "_".join(map(lambda x:str(x),
    98         location_str = "_".join(map(lambda x: str(x),
    96                                 self.GetCurrentLocation()))
    99                                 self.GetCurrentLocation()))
    97         configname = self.GetCTRoot().GetProjectConfigNames()[0]
   100         configname = self.GetCTRoot().GetProjectConfigNames()[0]
    98 
   101 
    99         pyextname = self.CTNName()
   102         pyextname = self.CTNName()
   100         varinfos = map(lambda variable : {
   103         varinfos = map(lambda variable: {
   101                     "name": variable.getname(),
   104             "name": variable.getname(),
   102                     "desc" : repr(variable.getdesc()),
   105             "desc": repr(variable.getdesc()),
   103                     "onchangecode" : '"'+variable.getonchange()+\
   106             "onchangecode": '"' + variable.getonchange() +
   104                                          "('"+variable.getname()+"')\"" \
   107             "('" + variable.getname() + "')\""
   105                                      if variable.getonchange() else '""',
   108             if variable.getonchange() else '""',
   106                     "onchange" : repr(variable.getonchange()) \
   109             "onchange": repr(variable.getonchange())
   107                                  if variable.getonchange() else None,
   110             if variable.getonchange() else None,
   108                     "opts" : repr(variable.getopts()),
   111             "opts": repr(variable.getopts()),
   109                     "configname" : configname.upper(),
   112             "configname": configname.upper(),
   110                     "uppername" : variable.getname().upper(),
   113             "uppername": variable.getname().upper(),
   111                     "IECtype" : variable.gettype(),
   114             "IECtype": variable.gettype(),
   112                     "pyextname" :pyextname},
   115             "pyextname": pyextname},
   113                     self.CodeFile.variables.variable)
   116                        self.CodeFile.variables.variable)
   114         # python side PLC global variables access stub
   117         # python side PLC global variables access stub
   115         globalstubs = "\n".join(["""\
   118         globalstubs = "\n".join([
       
   119             """\
   116 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\
   120 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\
   117     TypeTranslator["%(IECtype)s"]
   121     TypeTranslator["%(IECtype)s"]
   118 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s
   122 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s
   119 _PySafeGetPLCGlob_%(name)s.restype = None
   123 _PySafeGetPLCGlob_%(name)s.restype = None
   120 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
   124 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)]
   125     "%(name)s",
   129     "%(name)s",
   126     "%(IECtype)s",
   130     "%(IECtype)s",
   127     %(desc)s,
   131     %(desc)s,
   128     %(onchange)s,
   132     %(onchange)s,
   129     %(opts)s))
   133     %(opts)s))
   130 """ % varinfo
   134 """ % varinfo for varinfo in varinfos])
   131       for varinfo in varinfos])
       
   132 
   135 
   133         # Runtime calls (start, stop, init, and cleanup)
   136         # Runtime calls (start, stop, init, and cleanup)
   134         rtcalls = ""
   137         rtcalls = ""
   135         for section in self.SECTIONS_NAMES:
   138         for section in self.SECTIONS_NAMES:
   136             if section != "globals":
   139             if section != "globals":
   168 
   171 
   169 """ % locals()
   172 """ % locals()
   170 
   173 
   171         # write generated content to python file
   174         # write generated content to python file
   172         runtimefile_path = os.path.join(buildpath,
   175         runtimefile_path = os.path.join(buildpath,
   173             "runtime_%s.py"%location_str)
   176                                         "runtime_%s.py" % location_str)
   174         runtimefile = open(runtimefile_path, 'w')
   177         runtimefile = open(runtimefile_path, 'w')
   175         runtimefile.write(PyFileContent.encode('utf-8'))
   178         runtimefile.write(PyFileContent.encode('utf-8'))
   176         runtimefile.close()
   179         runtimefile.close()
   177 
   180 
   178         # C code for safe global variables access
   181         # C code for safe global variables access
   232     __%(name)s_notifier = __GET_GLOBAL_ON%(uppername)sCHANGE();
   235     __%(name)s_notifier = __GET_GLOBAL_ON%(uppername)sCHANGE();
   233     __SET_VAR(__%(name)s_notifier->,TRIG,,__BOOL_LITERAL(TRUE));
   236     __SET_VAR(__%(name)s_notifier->,TRIG,,__BOOL_LITERAL(TRUE));
   234     __SET_VAR(__%(name)s_notifier->,CODE,,__STRING_LITERAL(%(onchangelen)d,%(onchangecode)s));
   237     __SET_VAR(__%(name)s_notifier->,CODE,,__STRING_LITERAL(%(onchangelen)d,%(onchangecode)s));
   235 """
   238 """
   236         vardec = "\n".join([(vardecfmt + vardeconchangefmt
   239         vardec = "\n".join([(vardecfmt + vardeconchangefmt
   237                              if varinfo["onchange"] else vardecfmt)% varinfo
   240                              if varinfo["onchange"] else vardecfmt) % varinfo
   238                             for varinfo in varinfos])
   241                             for varinfo in varinfos])
   239         varret = "\n".join([varretfmt % varinfo for varinfo in varinfos])
   242         varret = "\n".join([varretfmt % varinfo for varinfo in varinfos])
   240         varpub = "\n".join([(varpubonchangefmt if varinfo["onchange"] else
   243         varpub = "\n".join([(varpubonchangefmt if varinfo["onchange"] else
   241                              varpubfmt) % varinfo
   244                              varpubfmt) % varinfo
   242                             for varinfo in varinfos])
   245                             for varinfo in varinfos])
   243         varinit = "\n".join([varinitonchangefmt % dict(
   246         varinit = "\n".join([varinitonchangefmt % dict(
   244                                 onchangelen = len(varinfo["onchangecode"]),**varinfo)
   247                                 onchangelen=len(varinfo["onchangecode"]), **varinfo)
   245                             for varinfo in varinfos if varinfo["onchange"]])
   248                             for varinfo in varinfos if varinfo["onchange"]])
   246 
   249 
   247         # TODO : use config name obtained from model instead of default
   250         # TODO : use config name obtained from model instead of default
   248         # "config.h". User cannot change config name, but project imported
   251         # "config.h". User cannot change config name, but project imported
   249         # or created in older beremiz vesion could use different name.
   252         # or created in older beremiz vesion could use different name.
   276 void __publish_%(location_str)s(void){
   279 void __publish_%(location_str)s(void){
   277 %(varpub)s
   280 %(varpub)s
   278 }
   281 }
   279 """ % locals()
   282 """ % locals()
   280 
   283 
   281         Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c"%location_str)
   284         Gen_PyCfile_path = os.path.join(buildpath, "PyCFile_%s.c" % location_str)
   282         pycfile = open(Gen_PyCfile_path,'w')
   285         pycfile = open(Gen_PyCfile_path, 'w')
   283         pycfile.write(PyCFileContent)
   286         pycfile.write(PyCFileContent)
   284         pycfile.close()
   287         pycfile.close()
   285 
   288 
   286         matiec_CFLAGS = '"-I%s"'%os.path.abspath(
   289         matiec_CFLAGS = '"-I%s"' % os.path.abspath(
   287             self.GetCTRoot().GetIECLibPath())
   290             self.GetCTRoot().GetIECLibPath())
   288 
   291 
   289         return ([(Gen_PyCfile_path, matiec_CFLAGS)],
   292         return ([(Gen_PyCfile_path, matiec_CFLAGS)],
   290                 "",
   293                 "",
   291                 True,
   294                 True,
   292                 ("runtime_%s.py"%location_str, file(runtimefile_path,"rb")))
   295                 ("runtime_%s.py" % location_str, file(runtimefile_path, "rb")))
   293