31
|
1 |
import wx
|
|
2 |
import wx.stc as stc
|
|
3 |
import os, sys, shutil
|
|
4 |
from CppSTC import CppSTC
|
|
5 |
from plugger import PlugTemplate
|
45
|
6 |
import tempfile
|
31
|
7 |
|
|
8 |
class _Cfile:
|
|
9 |
XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
|
|
10 |
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
45
|
11 |
<xsd:element name="C_Extension">
|
31
|
12 |
<xsd:complexType>
|
45
|
13 |
<xsd:attribute name="C_Files" type="xsd:string" use="required" default="myfile.c"/>
|
|
14 |
<xsd:attribute name="CFLAGS" type="xsd:string" use="required"/>
|
|
15 |
<xsd:attribute name="LDFLAGS" type="xsd:string" use="required"/>
|
31
|
16 |
</xsd:complexType>
|
|
17 |
</xsd:element>
|
|
18 |
</xsd:schema>
|
|
19 |
"""
|
|
20 |
def __init__(self):
|
45
|
21 |
self.CheckCFilesExist()
|
|
22 |
|
|
23 |
def CheckCFilesExist(self):
|
|
24 |
for CFile in self.CFileNames():
|
|
25 |
if not os.path.isfile(CFile):
|
|
26 |
f = open(CFile, 'w')
|
|
27 |
f.write("/*Empty*/")
|
|
28 |
f.close()
|
31
|
29 |
|
45
|
30 |
def CFileBaseNames(self):
|
|
31 |
"""
|
|
32 |
Returns list of C files base names, out of C_Extension.C_Files, coma separated list
|
|
33 |
"""
|
|
34 |
return map(str.strip,str(self.C_Extension.getC_Files()).split(','))
|
|
35 |
|
|
36 |
def CFileName(self, fn):
|
|
37 |
return os.path.join(self.PlugPath(),fn)
|
|
38 |
|
|
39 |
def CFileNames(self):
|
|
40 |
"""
|
|
41 |
Returns list of full C files paths, out of C_Extension.C_Files, coma separated list
|
|
42 |
"""
|
|
43 |
return map(self.CFileName, self.CFileBaseNames())
|
31
|
44 |
|
|
45 |
def SetParamsAttribute(self, path, value, logger):
|
45
|
46 |
"""
|
|
47 |
Take actions if C_Files changed
|
|
48 |
"""
|
|
49 |
# Get a C files list before changes
|
|
50 |
oldnames = self.CFileNames()
|
|
51 |
# Apply changes
|
31
|
52 |
res = PlugTemplate.SetParamsAttribute(self, path, value, logger)
|
45
|
53 |
# If changes was about C files,
|
|
54 |
if path == "C_Extension.C_Files":
|
|
55 |
# Create files if did not exist
|
|
56 |
self.CheckCFilesExist()
|
|
57 |
# Get new list
|
|
58 |
newnames = self.CFileNames()
|
|
59 |
# Move unused files into trash (temporary directory)
|
|
60 |
for oldfile in oldnames:
|
|
61 |
if oldfile not in newnames:
|
|
62 |
# define new "trash" name
|
|
63 |
trashname = os.path.join(tempfile.gettempdir(),os.path.basename(oldfile))
|
|
64 |
# move the file
|
|
65 |
shutil.move(oldfile, trashname)
|
|
66 |
# warn user
|
|
67 |
logger.write_warning("\"%s\" moved to \"%s\"\n"%(oldfile, trashname))
|
31
|
68 |
return value, False
|
|
69 |
return res
|
|
70 |
|
45
|
71 |
_Views = {}
|
31
|
72 |
def _OpenView(self, logger):
|
45
|
73 |
lst = self.CFileBaseNames()
|
31
|
74 |
|
45
|
75 |
dlg = wx.MultiChoiceDialog( self.GetPlugRoot().AppFrame,
|
|
76 |
"Pick some fruit from\nthis list",
|
|
77 |
"wx.MultiChoiceDialog", lst)
|
31
|
78 |
|
45
|
79 |
if (dlg.ShowModal() == wx.ID_OK):
|
|
80 |
selections = dlg.GetSelections()
|
|
81 |
for selected in [lst[x] for x in selections]:
|
|
82 |
if selected not in self._Views:
|
|
83 |
# keep track of selected name as static for later close
|
|
84 |
def _onclose(evt, sel = selected):
|
|
85 |
self.SaveCView(sel)
|
|
86 |
self._Views.pop(sel)
|
|
87 |
evt.Skip()
|
|
88 |
New_View = wx.Frame(self.GetPlugRoot().AppFrame,-1)
|
|
89 |
New_View.Bind(wx.EVT_CLOSE, _onclose)
|
|
90 |
ed = CppSTC(New_View, wx.NewId())
|
|
91 |
ed.SetText(open(self.CFileName(selected)).read())
|
|
92 |
ed.EmptyUndoBuffer()
|
|
93 |
ed.Colourise(0, -1)
|
|
94 |
ed.SetMarginType(1, stc.STC_MARGIN_NUMBER)
|
|
95 |
ed.SetMarginWidth(1, 25)
|
|
96 |
New_View.ed = ed
|
|
97 |
New_View.Show()
|
|
98 |
self._Views[selected] = New_View
|
31
|
99 |
|
45
|
100 |
dlg.Destroy()
|
|
101 |
|
|
102 |
|
|
103 |
PluginMethods = [("Edit C File",_OpenView), ("Import C File",_OpenView)]
|
|
104 |
|
|
105 |
def SaveCView(self, name):
|
|
106 |
f = open(self.CFileName(name),'w')
|
|
107 |
f.write(self._Views[name].ed.GetText())
|
|
108 |
f.close()
|
|
109 |
|
31
|
110 |
def OnPlugSave(self):
|
45
|
111 |
for name in self._Views:
|
|
112 |
self.SaveCView(name)
|
31
|
113 |
return True
|
|
114 |
|
|
115 |
def PlugGenerate_C(self, buildpath, locations, logger):
|
|
116 |
"""
|
|
117 |
Generate C code
|
|
118 |
@param current_location: Tupple containing plugin IEC location : %I0.0.4.5 => (0,0,4,5)
|
|
119 |
@param locations: List of complete variables locations \
|
|
120 |
[{"IEC_TYPE" : the IEC type (i.e. "INT", "STRING", ...)
|
|
121 |
"NAME" : name of the variable (generally "__IW0_1_2" style)
|
|
122 |
"DIR" : direction "Q","I" or "M"
|
|
123 |
"SIZE" : size "X", "B", "W", "D", "L"
|
|
124 |
"LOC" : tuple of interger for IEC location (0,1,2,...)
|
|
125 |
}, ...]
|
|
126 |
@return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
|
|
127 |
"""
|
|
128 |
current_location = self.GetCurrentLocation()
|
|
129 |
# define a unique name for the generated C file
|
45
|
130 |
location_str = "_".join(map(lambda x:str(x), current_location))
|
|
131 |
res = []
|
|
132 |
for CFile in self.CFileBaseNames():
|
|
133 |
Gen_Cfile_path = os.path.join(buildpath, location_str + "_" + os.path.splitext(CFile)[0] + "_CFile.c" )
|
|
134 |
f = open(Gen_Cfile_path,'w')
|
|
135 |
f.write("/* Header generated by Beremiz c_ext plugin */\n")
|
|
136 |
f.write("#include \"iec_std_lib.h\"\n")
|
|
137 |
f.write("#define EXT_C_INIT __init_%s\n"%location_str)
|
|
138 |
f.write("#define EXT_C_CLEANUP __init_%s\n"%location_str)
|
|
139 |
f.write("#define EXT_C_PUBLISH __init_%s\n"%location_str)
|
|
140 |
f.write("#define EXT_C_RETRIVE __init_%s\n"%location_str)
|
|
141 |
for loc in locations:
|
|
142 |
f.write(loc["IEC_TYPE"]+" "+loc["NAME"]+";\n")
|
|
143 |
f.write("/* End of header generated by Beremiz c_ext plugin */\n\n")
|
|
144 |
src_file = open(self.CFileName(CFile),'r')
|
|
145 |
f.write(src_file.read())
|
|
146 |
src_file.close()
|
|
147 |
f.close()
|
|
148 |
res.append((Gen_Cfile_path,str(self.C_Extension.getCFLAGS())))
|
|
149 |
return res,str(self.C_Extension.getLDFLAGS())
|
31
|
150 |
|
|
151 |
class RootClass:
|
|
152 |
|
|
153 |
PlugChildsTypes = [("C_File",_Cfile)]
|
|
154 |
|
|
155 |
def PlugGenerate_C(self, buildpath, locations, logger):
|
|
156 |
return [],""
|
|
157 |
|
|
158 |
|