5 |
5 |
6 from CodeFileTreeNode import CodeFile |
6 from CodeFileTreeNode import CodeFile |
7 from PythonEditor import PythonEditor |
7 from PythonEditor import PythonEditor |
8 |
8 |
9 class PythonFileCTNMixin(CodeFile): |
9 class PythonFileCTNMixin(CodeFile): |
10 |
10 |
11 CODEFILE_NAME = "PyFile" |
11 CODEFILE_NAME = "PyFile" |
12 SECTIONS_NAMES = [ |
12 SECTIONS_NAMES = [ |
13 "globals", |
13 "globals", |
14 "init", |
14 "init", |
15 "cleanup", |
15 "cleanup", |
16 "start", |
16 "start", |
17 "stop"] |
17 "stop"] |
18 EditorType = PythonEditor |
18 EditorType = PythonEditor |
19 |
19 |
20 def __init__(self): |
20 def __init__(self): |
21 CodeFile.__init__(self) |
21 CodeFile.__init__(self) |
22 |
22 |
23 filepath = self.PythonFileName() |
23 filepath = self.PythonFileName() |
24 |
24 |
25 if os.path.isfile(filepath): |
25 if os.path.isfile(filepath): |
26 PythonParser = GenerateParserFromXSD( |
26 PythonParser = GenerateParserFromXSD( |
27 os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) |
27 os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) |
28 |
28 |
29 xmlfile = open(filepath, 'r') |
29 xmlfile = open(filepath, 'r') |
30 pythonfile_xml = xmlfile.read() |
30 pythonfile_xml = xmlfile.read() |
31 xmlfile.close() |
31 xmlfile.close() |
32 |
32 |
33 pythonfile_xml = pythonfile_xml.replace( |
33 pythonfile_xml = pythonfile_xml.replace( |
34 'xmlns="http://www.w3.org/2001/XMLSchema"', |
34 'xmlns="http://www.w3.org/2001/XMLSchema"', |
35 'xmlns:xhtml="http://www.w3.org/1999/xhtml"') |
35 'xmlns:xhtml="http://www.w3.org/1999/xhtml"') |
36 for cre, repl in [ |
36 for cre, repl in [ |
37 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), |
37 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), |
38 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: |
38 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: |
39 pythonfile_xml = cre.sub(repl, pythonfile_xml) |
39 pythonfile_xml = cre.sub(repl, pythonfile_xml) |
40 |
40 |
41 try: |
41 try: |
42 python_code, error = PythonParser.LoadXMLString(pythonfile_xml) |
42 python_code, error = PythonParser.LoadXMLString(pythonfile_xml) |
43 if error is None: |
43 if error is None: |
44 self.CodeFile.globals.setanyText(python_code.getanyText()) |
44 self.CodeFile.globals.setanyText(python_code.getanyText()) |
45 os.remove(filepath) |
45 os.remove(filepath) |
46 self.CreateCodeFileBuffer(False) |
46 self.CreateCodeFileBuffer(False) |
47 self.OnCTNSave() |
47 self.OnCTNSave() |
48 except Exception, exc: |
48 except Exception, exc: |
49 error = unicode(exc) |
49 error = unicode(exc) |
50 |
50 |
51 if error is not None: |
51 if error is not None: |
52 self.GetCTRoot().logger.write_error( |
52 self.GetCTRoot().logger.write_error( |
53 _("Couldn't import old %s file.") % CTNName) |
53 _("Couldn't import old %s file.") % self.CTNName()) |
54 |
54 |
55 def CodeFileName(self): |
55 def CodeFileName(self): |
56 return os.path.join(self.CTNPath(), "pyfile.xml") |
56 return os.path.join(self.CTNPath(), "pyfile.xml") |
57 |
57 |
58 def PythonFileName(self): |
58 def PythonFileName(self): |
59 return os.path.join(self.CTNPath(), "py_ext.xml") |
59 return os.path.join(self.CTNPath(), "py_ext.xml") |
60 |
60 |
61 PreSectionsTexts = {} |
61 PreSectionsTexts = {} |
62 PostSectionsTexts = {} |
62 PostSectionsTexts = {} |
63 def GetSection(self,section): |
63 def GetSection(self,section): |
64 return self.PreSectionsTexts.get(section,"") + "\n" + \ |
64 return self.PreSectionsTexts.get(section,"") + "\n" + \ |
65 getattr(self.CodeFile, section).getanyText() + "\n" + \ |
65 getattr(self.CodeFile, section).getanyText() + "\n" + \ |
66 self.PostSectionsTexts.get(section,"") |
66 self.PostSectionsTexts.get(section,"") |
67 |
67 |
68 |
68 |
69 def CTNGenerate_C(self, buildpath, locations): |
69 def CTNGenerate_C(self, buildpath, locations): |
70 # location string for that CTN |
70 # location string for that CTN |
71 location_str = "_".join(map(lambda x:str(x), |
71 location_str = "_".join(map(lambda x:str(x), |
72 self.GetCurrentLocation())) |
72 self.GetCurrentLocation())) |
73 configname = self.GetCTRoot().GetProjectConfigNames()[0] |
73 configname = self.GetCTRoot().GetProjectConfigNames()[0] |
74 |
74 |
75 |
75 |
76 # python side PLC global variables access stub |
76 # python side PLC global variables access stub |
77 globalstubs = "\n".join(["""\ |
77 globalstubs = "\n".join(["""\ |
78 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\ |
78 _%(name)s_ctype, _%(name)s_unpack, _%(name)s_pack = \\ |
79 TypeTranslator["%(IECtype)s"] |
79 TypeTranslator["%(IECtype)s"] |
80 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s |
80 _PySafeGetPLCGlob_%(name)s = PLCBinary.__SafeGetPLCGlob_%(name)s |
81 _PySafeGetPLCGlob_%(name)s.restype = None |
81 _PySafeGetPLCGlob_%(name)s.restype = None |
82 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] |
82 _PySafeGetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] |
83 _PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s |
83 _PySafeSetPLCGlob_%(name)s = PLCBinary.__SafeSetPLCGlob_%(name)s |
84 _PySafeSetPLCGlob_%(name)s.restype = None |
84 _PySafeSetPLCGlob_%(name)s.restype = None |
85 _PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] |
85 _PySafeSetPLCGlob_%(name)s.argtypes = [ctypes.POINTER(_%(name)s_ctype)] |
|
86 _PySafePLCGlobals.append(("%(name)s","%(IECtype)s")) |
86 """ % { "name": variable.getname(), |
87 """ % { "name": variable.getname(), |
87 "configname": configname.upper(), |
88 "configname": configname.upper(), |
88 "uppername": variable.getname().upper(), |
89 "uppername": variable.getname().upper(), |
89 "IECtype": variable.gettype()} |
90 "IECtype": variable.gettype()} |
90 for variable in self.CodeFile.variables.variable]) |
91 for variable in self.CodeFile.variables.variable]) |
99 rtcalls += ' ' + \ |
100 rtcalls += ' ' + \ |
100 sectiontext.replace('\n', '\n ')+"\n\n" |
101 sectiontext.replace('\n', '\n ')+"\n\n" |
101 else: |
102 else: |
102 rtcalls += " pass\n\n" |
103 rtcalls += " pass\n\n" |
103 |
104 |
104 globalsection = self.GetSection("globals") |
105 globalsection = self.GetSection("globals") |
|
106 |
|
107 pyextname = self.CTNName() |
105 |
108 |
106 PyFileContent = """\ |
109 PyFileContent = """\ |
107 #!/usr/bin/env python |
110 #!/usr/bin/env python |
108 # -*- coding: utf-8 -*- |
111 # -*- coding: utf-8 -*- |
109 ## Code generated by Beremiz python mixin confnode |
112 ## Code generated by Beremiz python mixin confnode |
110 ## |
113 ## |
111 |
114 |
112 ## Code for PLC global variable access |
115 ## Code for PLC global variable access |
113 from targets.typemapping import TypeTranslator |
116 from targets.typemapping import TypeTranslator |
114 import ctypes |
117 import ctypes |
|
118 _PyExtName = "%(pyextname)s" |
|
119 _PySafePLCGlobals = [] |
115 %(globalstubs)s |
120 %(globalstubs)s |
116 |
121 |
117 ## User code in "global" scope |
122 ## User code in "global" scope |
118 %(globalsection)s |
123 %(globalsection)s |
119 |
124 |
120 ## Beremiz python runtime calls |
125 ## Beremiz python runtime calls |
121 %(rtcalls)s |
126 %(rtcalls)s |
122 |
127 |
123 """ % locals() |
128 """ % locals() |
124 |
129 |
125 # write generated content to python file |
130 # write generated content to python file |
126 runtimefile_path = os.path.join(buildpath, |
131 runtimefile_path = os.path.join(buildpath, |
127 "runtime_%s.py"%location_str) |
132 "runtime_%s.py"%location_str) |
128 runtimefile = open(runtimefile_path, 'w') |
133 runtimefile = open(runtimefile_path, 'w') |
129 runtimefile.write(PyFileContent.encode('utf-8')) |
134 runtimefile.write(PyFileContent.encode('utf-8')) |
130 runtimefile.close() |
135 runtimefile.close() |
131 |
136 |
132 # C code for safe global variables access |
137 # C code for safe global variables access |
133 |
138 |
134 vardecfmt = """\ |
139 vardecfmt = """\ |
135 extern __IEC_%(IECtype)s_t %(configname)s__%(uppername)s; |
140 extern __IEC_%(IECtype)s_t %(configname)s__%(uppername)s; |
136 IEC_%(IECtype)s __%(name)s_rbuffer = __INIT_%(IECtype)s; |
141 IEC_%(IECtype)s __%(name)s_rbuffer = __INIT_%(IECtype)s; |
137 IEC_%(IECtype)s __%(name)s_wbuffer; |
142 IEC_%(IECtype)s __%(name)s_wbuffer; |
138 long __%(name)s_rlock = 0; |
143 long __%(name)s_rlock = 0; |
157 %(configname)s__%(uppername)s.value = __%(name)s_wbuffer; |
162 %(configname)s__%(uppername)s.value = __%(name)s_wbuffer; |
158 __%(name)s_wbuffer_written = 0; |
163 __%(name)s_wbuffer_written = 0; |
159 } |
164 } |
160 AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0); |
165 AtomicCompareExchange((long*)&__%(name)s_wlock, 1, 0); |
161 } |
166 } |
162 """ |
167 """ |
163 varpubfmt = """\ |
168 varpubfmt = """\ |
164 if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){ |
169 if(!AtomicCompareExchange(&__%(name)s_rlock, 0, 1)){ |
165 __%(name)s_rbuffer = %(configname)s__%(uppername)s.value; |
170 __%(name)s_rbuffer = %(configname)s__%(uppername)s.value; |
166 AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0); |
171 AtomicCompareExchange((long*)&__%(name)s_rlock, 1, 0); |
167 } |
172 } |
168 """ |
173 """ |
169 |
174 |
170 var_str = map("\n".join, zip(*[ |
175 var_str = map("\n".join, zip(*[ |
171 map(lambda f : f % varinfo, |
176 map(lambda f : f % varinfo, |
172 (vardecfmt, varretfmt, varpubfmt)) |
177 (vardecfmt, varretfmt, varpubfmt)) |
173 for varinfo in map(lambda variable : { |
178 for varinfo in map(lambda variable : { |