85 <xsd:complexType> |
85 <xsd:complexType> |
86 <xsd:choice minOccurs="0"> |
86 <xsd:choice minOccurs="0"> |
87 """+targets.GetTargetChoices()+""" |
87 """+targets.GetTargetChoices()+""" |
88 </xsd:choice> |
88 </xsd:choice> |
89 </xsd:complexType> |
89 </xsd:complexType> |
90 </xsd:element> |
90 </xsd:element>"""+((""" |
91 <xsd:element name="Libraries" minOccurs="0">"""+((""" |
91 <xsd:element name="Libraries" minOccurs="0"> |
92 <xsd:complexType> |
92 <xsd:complexType> |
93 """+"\n".join(['<xsd:attribute name='+ |
93 """+"\n".join(['<xsd:attribute name='+ |
94 '"Enable_'+ libname + '_Library" '+ |
94 '"Enable_'+ libname + '_Library" '+ |
95 'type="xsd:boolean" use="optional" default="true"/>' |
95 'type="xsd:boolean" use="optional" default="true"/>' |
96 for libname,lib in features.libraries])+""" |
96 for libname,lib in features.libraries])+""" |
97 </xsd:complexType>""") if len(features.libraries)>0 else '<xsd:complexType/>') + """ |
97 </xsd:complexType> |
98 </xsd:element> |
98 </xsd:element>""") if len(features.libraries)>0 else '') + """ |
99 </xsd:sequence> |
99 </xsd:sequence> |
100 <xsd:attribute name="URI_location" type="xsd:string" use="optional" default=""/> |
100 <xsd:attribute name="URI_location" type="xsd:string" use="optional" default=""/> |
101 <xsd:attribute name="Disable_Extensions" type="xsd:boolean" use="optional" default="false"/> |
101 <xsd:attribute name="Disable_Extensions" type="xsd:boolean" use="optional" default="false"/> |
102 </xsd:complexType> |
102 </xsd:complexType> |
103 </xsd:element> |
103 </xsd:element> |
104 </xsd:schema> |
104 </xsd:schema> |
105 """ |
105 """ |
106 EditorType = ProjectNodeEditor |
106 EditorType = ProjectNodeEditor |
107 |
107 |
108 def __init__(self, frame, logger): |
108 def __init__(self, frame, logger): |
109 PLCControler.__init__(self) |
109 PLCControler.__init__(self) |
110 |
110 |
111 self.MandatoryParams = None |
111 self.MandatoryParams = None |
112 self._builder = None |
112 self._builder = None |
113 self._connector = None |
113 self._connector = None |
114 self.DispatchDebugValuesTimer = None |
114 self.DispatchDebugValuesTimer = None |
115 self.DebugValuesBuffers = [] |
115 self.DebugValuesBuffers = [] |
116 self.DebugTicks = [] |
116 self.DebugTicks = [] |
117 self.SetAppFrame(frame, logger) |
117 self.SetAppFrame(frame, logger) |
118 |
118 |
119 self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")) |
119 self.iec2c_path = os.path.join(base_folder, "matiec", "iec2c"+(".exe" if wx.Platform == '__WXMSW__' else "")) |
120 self.ieclib_path = os.path.join(base_folder, "matiec", "lib") |
120 self.ieclib_path = os.path.join(base_folder, "matiec", "lib") |
121 |
121 |
122 # Setup debug information |
122 # Setup debug information |
123 self.IECdebug_datas = {} |
123 self.IECdebug_datas = {} |
124 self.IECdebug_lock = Lock() |
124 self.IECdebug_lock = Lock() |
125 |
125 |
126 self.DebugTimer=None |
126 self.DebugTimer=None |
145 |
145 |
146 def __del__(self): |
146 def __del__(self): |
147 if self.DebugTimer: |
147 if self.DebugTimer: |
148 self.DebugTimer.cancel() |
148 self.DebugTimer.cancel() |
149 self.KillDebugThread() |
149 self.KillDebugThread() |
150 |
150 |
151 def LoadLibraries(self): |
151 def LoadLibraries(self): |
152 self.Libraries = [] |
152 self.Libraries = [] |
153 TypeStack=[] |
153 TypeStack=[] |
154 for libname,clsname in features.libraries: |
154 for libname,clsname in features.libraries: |
155 if self.BeremizRoot.Libraries is None or getattr(self.BeremizRoot.Libraries, "Enable_"+libname+"_Library"): |
155 if self.BeremizRoot.Libraries is None or getattr(self.BeremizRoot.Libraries, "Enable_"+libname+"_Library"): |
156 Lib = GetClassImporter(clsname)()(self, libname, TypeStack) |
156 Lib = GetClassImporter(clsname)()(self, libname, TypeStack) |
157 TypeStack.append(Lib.GetTypes()) |
157 TypeStack.append(Lib.GetTypes()) |
158 self.Libraries.append(Lib) |
158 self.Libraries.append(Lib) |
159 |
159 |
160 def SetAppFrame(self, frame, logger): |
160 def SetAppFrame(self, frame, logger): |
161 self.AppFrame = frame |
161 self.AppFrame = frame |
162 self.logger = logger |
162 self.logger = logger |
163 self.StatusTimer = None |
163 self.StatusTimer = None |
164 if self.DispatchDebugValuesTimer is not None: |
164 if self.DispatchDebugValuesTimer is not None: |
165 self.DispatchDebugValuesTimer.Stop() |
165 self.DispatchDebugValuesTimer.Stop() |
166 self.DispatchDebugValuesTimer = None |
166 self.DispatchDebugValuesTimer = None |
167 |
167 |
168 if frame is not None: |
168 if frame is not None: |
169 |
169 |
170 # Timer to pull PLC status |
170 # Timer to pull PLC status |
171 self.StatusTimer = wx.Timer(self.AppFrame, -1) |
171 self.StatusTimer = wx.Timer(self.AppFrame, -1) |
172 self.AppFrame.Bind(wx.EVT_TIMER, |
172 self.AppFrame.Bind(wx.EVT_TIMER, |
173 self.PullPLCStatusProc, self.StatusTimer) |
173 self.PullPLCStatusProc, self.StatusTimer) |
174 |
174 |
175 if self._connector is not None: |
175 if self._connector is not None: |
176 frame.LogViewer.SetLogSource(self._connector) |
176 frame.LogViewer.SetLogSource(self._connector) |
177 self.StatusTimer.Start(milliseconds=500, oneShot=False) |
177 self.StatusTimer.Start(milliseconds=500, oneShot=False) |
178 |
178 |
179 # Timer to dispatch debug values to consumers |
179 # Timer to dispatch debug values to consumers |
180 self.DispatchDebugValuesTimer = wx.Timer(self.AppFrame, -1) |
180 self.DispatchDebugValuesTimer = wx.Timer(self.AppFrame, -1) |
181 self.AppFrame.Bind(wx.EVT_TIMER, |
181 self.AppFrame.Bind(wx.EVT_TIMER, |
182 self.DispatchDebugValuesProc, self.DispatchDebugValuesTimer) |
182 self.DispatchDebugValuesProc, self.DispatchDebugValuesTimer) |
183 |
183 |
184 self.RefreshConfNodesBlockLists() |
184 self.RefreshConfNodesBlockLists() |
185 |
185 |
186 def ResetAppFrame(self, logger): |
186 def ResetAppFrame(self, logger): |
187 if self.AppFrame is not None: |
187 if self.AppFrame is not None: |
188 self.AppFrame.Unbind(wx.EVT_TIMER, self.StatusTimer) |
188 self.AppFrame.Unbind(wx.EVT_TIMER, self.StatusTimer) |
189 self.StatusTimer = None |
189 self.StatusTimer = None |
190 self.AppFrame = None |
190 self.AppFrame = None |
191 |
191 |
192 self.logger = logger |
192 self.logger = logger |
193 |
193 |
194 def CTNName(self): |
194 def CTNName(self): |
195 return "Project" |
195 return "Project" |
196 |
196 |
240 target = self.Parser.CreateElement("TargetType", "BeremizRoot") |
240 target = self.Parser.CreateElement("TargetType", "BeremizRoot") |
241 temp_root.setTargetType(target) |
241 temp_root.setTargetType(target) |
242 target_name = self.GetDefaultTargetName() |
242 target_name = self.GetDefaultTargetName() |
243 target.setcontent(self.Parser.CreateElement(target_name, "TargetType")) |
243 target.setcontent(self.Parser.CreateElement(target_name, "TargetType")) |
244 return target |
244 return target |
245 |
245 |
246 def GetParamsAttributes(self, path = None): |
246 def GetParamsAttributes(self, path = None): |
247 params = ConfigTreeNode.GetParamsAttributes(self, path) |
247 params = ConfigTreeNode.GetParamsAttributes(self, path) |
248 if params[0]["name"] == "BeremizRoot": |
248 if params[0]["name"] == "BeremizRoot": |
249 for child in params[0]["children"]: |
249 for child in params[0]["children"]: |
250 if child["name"] == "TargetType" and child["value"] == '': |
250 if child["name"] == "TargetType" and child["value"] == '': |
251 child.update(self.GetTarget().getElementInfos("TargetType")) |
251 child.update(self.GetTarget().getElementInfos("TargetType")) |
252 return params |
252 return params |
253 |
253 |
254 def SetParamsAttribute(self, path, value): |
254 def SetParamsAttribute(self, path, value): |
255 if path.startswith("BeremizRoot.TargetType.") and self.BeremizRoot.getTargetType().getcontent() is None: |
255 if path.startswith("BeremizRoot.TargetType.") and self.BeremizRoot.getTargetType().getcontent() is None: |
256 self.BeremizRoot.setTargetType(self.GetTarget()) |
256 self.BeremizRoot.setTargetType(self.GetTarget()) |
257 res = ConfigTreeNode.SetParamsAttribute(self, path, value) |
257 res = ConfigTreeNode.SetParamsAttribute(self, path, value) |
258 if path.startswith("BeremizRoot.Libraries."): |
258 if path.startswith("BeremizRoot.Libraries."): |
259 wx.CallAfter(self.RefreshConfNodesBlockLists) |
259 wx.CallAfter(self.RefreshConfNodesBlockLists) |
260 return res |
260 return res |
261 |
261 |
262 # helper func to check project path write permission |
262 # helper func to check project path write permission |
263 def CheckProjectPathPerm(self, dosave=True): |
263 def CheckProjectPathPerm(self, dosave=True): |
264 if CheckPathPerm(self.ProjectPath): |
264 if CheckPathPerm(self.ProjectPath): |
265 return True |
265 return True |
266 if self.AppFrame is not None: |
266 if self.AppFrame is not None: |
267 dialog = wx.MessageDialog(self.AppFrame, |
267 dialog = wx.MessageDialog(self.AppFrame, |
268 _('You must have permission to work on the project\nWork on a project copy ?'), |
268 _('You must have permission to work on the project\nWork on a project copy ?'), |
269 _('Error'), |
269 _('Error'), |
270 wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) |
270 wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) |
271 answer = dialog.ShowModal() |
271 answer = dialog.ShowModal() |
272 dialog.Destroy() |
272 dialog.Destroy() |
273 if answer == wx.ID_YES: |
273 if answer == wx.ID_YES: |
274 if self.SaveProjectAs(): |
274 if self.SaveProjectAs(): |
275 self.AppFrame.RefreshTitle() |
275 self.AppFrame.RefreshTitle() |
276 self.AppFrame.RefreshFileMenu() |
276 self.AppFrame.RefreshFileMenu() |
277 self.AppFrame.RefreshPageTitles() |
277 self.AppFrame.RefreshPageTitles() |
278 return True |
278 return True |
279 return False |
279 return False |
280 |
280 |
281 def _getProjectFilesPath(self, project_path=None): |
281 def _getProjectFilesPath(self, project_path=None): |
282 if project_path is not None: |
282 if project_path is not None: |
283 return os.path.join(project_path, "project_files") |
283 return os.path.join(project_path, "project_files") |
284 projectfiles_path = os.path.join(self.GetProjectPath(), "project_files") |
284 projectfiles_path = os.path.join(self.GetProjectPath(), "project_files") |
285 if not os.path.exists(projectfiles_path): |
285 if not os.path.exists(projectfiles_path): |
286 os.mkdir(projectfiles_path) |
286 os.mkdir(projectfiles_path) |
287 return projectfiles_path |
287 return projectfiles_path |
288 |
288 |
289 def AddProjectDefaultConfiguration(self, config_name="config", res_name="resource1"): |
289 def AddProjectDefaultConfiguration(self, config_name="config", res_name="resource1"): |
290 self.ProjectAddConfiguration(config_name) |
290 self.ProjectAddConfiguration(config_name) |
291 self.ProjectAddConfigurationResource(config_name, res_name) |
291 self.ProjectAddConfigurationResource(config_name, res_name) |
292 |
292 |
293 def NewProject(self, ProjectPath, BuildPath=None): |
293 def NewProject(self, ProjectPath, BuildPath=None): |
442 self.GetIECProgramsAndVariables() |
442 self.GetIECProgramsAndVariables() |
443 LibIECCflags = '"-I%s" -Wno-unused-function'%os.path.abspath(self.GetIECLibPath()) |
443 LibIECCflags = '"-I%s" -Wno-unused-function'%os.path.abspath(self.GetIECLibPath()) |
444 LocatedCCodeAndFlags=[] |
444 LocatedCCodeAndFlags=[] |
445 Extras=[] |
445 Extras=[] |
446 for lib in self.Libraries: |
446 for lib in self.Libraries: |
447 res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags) |
447 res=lib.Generate_C(buildpath,self._VariablesList,LibIECCflags) |
448 LocatedCCodeAndFlags.append(res[:2]) |
448 LocatedCCodeAndFlags.append(res[:2]) |
449 if len(res)>2: |
449 if len(res)>2: |
450 Extras.extend(res[2:]) |
450 Extras.extend(res[2:]) |
451 return map(list,zip(*LocatedCCodeAndFlags))+[tuple(Extras)] |
451 return map(list,zip(*LocatedCCodeAndFlags))+[tuple(Extras)] |
452 |
452 |
453 # Update PLCOpenEditor ConfNode Block types from loaded confnodes |
453 # Update PLCOpenEditor ConfNode Block types from loaded confnodes |
454 def RefreshConfNodesBlockLists(self): |
454 def RefreshConfNodesBlockLists(self): |
455 if getattr(self, "Children", None) is not None: |
455 if getattr(self, "Children", None) is not None: |
456 self.ClearConfNodeTypes() |
456 self.ClearConfNodeTypes() |
457 self.AddConfNodeTypesList(self.GetLibrariesTypes()) |
457 self.AddConfNodeTypesList(self.GetLibrariesTypes()) |
458 if self.AppFrame is not None: |
458 if self.AppFrame is not None: |
459 self.AppFrame.RefreshLibraryPanel() |
459 self.AppFrame.RefreshLibraryPanel() |
460 self.AppFrame.RefreshEditor() |
460 self.AppFrame.RefreshEditor() |
461 |
461 |
462 # Update a PLCOpenEditor Pou variable location |
462 # Update a PLCOpenEditor Pou variable location |
463 def UpdateProjectVariableLocation(self, old_leading, new_leading): |
463 def UpdateProjectVariableLocation(self, old_leading, new_leading): |
464 self.Project.updateElementAddress(old_leading, new_leading) |
464 self.Project.updateElementAddress(old_leading, new_leading) |
465 self.BufferProject() |
465 self.BufferProject() |
466 if self.AppFrame is not None: |
466 if self.AppFrame is not None: |
467 self.AppFrame.RefreshTitle() |
467 self.AppFrame.RefreshTitle() |
468 self.AppFrame.RefreshPouInstanceVariablesPanel() |
468 self.AppFrame.RefreshPouInstanceVariablesPanel() |
469 self.AppFrame.RefreshFileMenu() |
469 self.AppFrame.RefreshFileMenu() |
470 self.AppFrame.RefreshEditMenu() |
470 self.AppFrame.RefreshEditMenu() |
471 wx.CallAfter(self.AppFrame.RefreshEditor) |
471 wx.CallAfter(self.AppFrame.RefreshEditor) |
472 |
472 |
473 def GetVariableLocationTree(self): |
473 def GetVariableLocationTree(self): |
474 ''' |
474 ''' |
475 This function is meant to be overridden by confnodes. |
475 This function is meant to be overridden by confnodes. |
476 |
476 |
477 It should returns an list of dictionaries |
477 It should returns an list of dictionaries |
478 |
478 |
479 - IEC_type is an IEC type like BOOL/BYTE/SINT/... |
479 - IEC_type is an IEC type like BOOL/BYTE/SINT/... |
480 - location is a string of this variable's location, like "%IX0.0.0" |
480 - location is a string of this variable's location, like "%IX0.0.0" |
481 ''' |
481 ''' |
482 children = [] |
482 children = [] |
483 for child in self.IECSortedChildren(): |
483 for child in self.IECSortedChildren(): |
484 children.append(child.GetVariableLocationTree()) |
484 children.append(child.GetVariableLocationTree()) |
485 return children |
485 return children |
486 |
486 |
487 def ConfNodePath(self): |
487 def ConfNodePath(self): |
488 return os.path.split(__file__)[0] |
488 return os.path.split(__file__)[0] |
489 |
489 |
490 def CTNPath(self, CTNName=None): |
490 def CTNPath(self, CTNName=None): |
491 return self.ProjectPath |
491 return self.ProjectPath |
492 |
492 |
493 def ConfNodeXmlFilePath(self, CTNName=None): |
493 def ConfNodeXmlFilePath(self, CTNName=None): |
494 return os.path.join(self.CTNPath(CTNName), "beremiz.xml") |
494 return os.path.join(self.CTNPath(CTNName), "beremiz.xml") |
495 |
495 |
496 def ParentsTypesFactory(self): |
496 def ParentsTypesFactory(self): |
497 return self.ConfNodeTypesFactory() |
497 return self.ConfNodeTypesFactory() |
513 if CheckPathPerm(self.ProjectPath): |
513 if CheckPathPerm(self.ProjectPath): |
514 self.DefaultBuildPath = os.path.join(self.ProjectPath, "build") |
514 self.DefaultBuildPath = os.path.join(self.ProjectPath, "build") |
515 # Create a build path in temp folder |
515 # Create a build path in temp folder |
516 else: |
516 else: |
517 self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build") |
517 self.DefaultBuildPath = os.path.join(tempfile.mkdtemp(), os.path.basename(self.ProjectPath), "build") |
518 |
518 |
519 if not os.path.exists(self.DefaultBuildPath): |
519 if not os.path.exists(self.DefaultBuildPath): |
520 os.makedirs(self.DefaultBuildPath) |
520 os.makedirs(self.DefaultBuildPath) |
521 return self.DefaultBuildPath |
521 return self.DefaultBuildPath |
522 |
522 |
523 def _getExtraFilesPath(self): |
523 def _getExtraFilesPath(self): |
524 return os.path.join(self._getBuildPath(), "extra_files") |
524 return os.path.join(self._getBuildPath(), "extra_files") |
525 |
525 |
526 def _getIECcodepath(self): |
526 def _getIECcodepath(self): |
527 # define name for IEC code file |
527 # define name for IEC code file |
528 return os.path.join(self._getBuildPath(), "plc.st") |
528 return os.path.join(self._getBuildPath(), "plc.st") |
529 |
529 |
530 def _getIECgeneratedcodepath(self): |
530 def _getIECgeneratedcodepath(self): |
531 # define name for IEC generated code file |
531 # define name for IEC generated code file |
532 return os.path.join(self._getBuildPath(), "generated_plc.st") |
532 return os.path.join(self._getBuildPath(), "generated_plc.st") |
533 |
533 |
534 def _getIECrawcodepath(self): |
534 def _getIECrawcodepath(self): |
535 # define name for IEC raw code file |
535 # define name for IEC raw code file |
536 return os.path.join(self.CTNPath(), "raw_plc.st") |
536 return os.path.join(self.CTNPath(), "raw_plc.st") |
537 |
537 |
538 def GetLocations(self): |
538 def GetLocations(self): |
539 locations = [] |
539 locations = [] |
540 filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h") |
540 filepath = os.path.join(self._getBuildPath(),"LOCATED_VARIABLES.h") |
541 if os.path.isfile(filepath): |
541 if os.path.isfile(filepath): |
542 # IEC2C compiler generate a list of located variables : LOCATED_VARIABLES.h |
542 # IEC2C compiler generate a list of located variables : LOCATED_VARIABLES.h |
544 # each line of LOCATED_VARIABLES.h declares a located variable |
544 # each line of LOCATED_VARIABLES.h declares a located variable |
545 lines = [line.strip() for line in location_file.readlines()] |
545 lines = [line.strip() for line in location_file.readlines()] |
546 # This regular expression parses the lines genereated by IEC2C |
546 # This regular expression parses the lines genereated by IEC2C |
547 LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)") |
547 LOCATED_MODEL = re.compile("__LOCATED_VAR\((?P<IEC_TYPE>[A-Z]*),(?P<NAME>[_A-Za-z0-9]*),(?P<DIR>[QMI])(?:,(?P<SIZE>[XBWDL]))?,(?P<LOC>[,0-9]*)\)") |
548 for line in lines: |
548 for line in lines: |
549 # If line match RE, |
549 # If line match RE, |
550 result = LOCATED_MODEL.match(line) |
550 result = LOCATED_MODEL.match(line) |
551 if result: |
551 if result: |
552 # Get the resulting dict |
552 # Get the resulting dict |
553 resdict = result.groupdict() |
553 resdict = result.groupdict() |
554 # rewrite string for variadic location as a tuple of integers |
554 # rewrite string for variadic location as a tuple of integers |
555 resdict['LOC'] = tuple(map(int,resdict['LOC'].split(','))) |
555 resdict['LOC'] = tuple(map(int,resdict['LOC'].split(','))) |
556 # set located size to 'X' if not given |
556 # set located size to 'X' if not given |
557 if not resdict['SIZE']: |
557 if not resdict['SIZE']: |
558 resdict['SIZE'] = 'X' |
558 resdict['SIZE'] = 'X' |
559 # finally store into located variable list |
559 # finally store into located variable list |
560 locations.append(resdict) |
560 locations.append(resdict) |
561 return locations |
561 return locations |
562 |
562 |
563 def GetConfNodeGlobalInstances(self): |
563 def GetConfNodeGlobalInstances(self): |
564 return self._GlobalInstances() |
564 return self._GlobalInstances() |
565 |
565 |
566 def _Generate_SoftPLC(self): |
566 def _Generate_SoftPLC(self): |
|
567 if self._Generate_PLC_ST(): |
|
568 return self._Compile_ST_to_SoftPLC() |
|
569 return False |
|
570 |
|
571 def _Generate_PLC_ST(self): |
567 """ |
572 """ |
568 Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C |
573 Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2C |
569 @param buildpath: path where files should be created |
574 @param buildpath: path where files should be created |
570 """ |
575 """ |
571 |
576 |
572 # Update PLCOpenEditor ConfNode Block types before generate ST code |
577 # Update PLCOpenEditor ConfNode Block types before generate ST code |
573 self.RefreshConfNodesBlockLists() |
578 self.RefreshConfNodesBlockLists() |
574 |
579 |
575 self.logger.write(_("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n")) |
580 self.logger.write(_("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n")) |
576 buildpath = self._getBuildPath() |
|
577 # ask PLCOpenEditor controller to write ST/IL/SFC code file |
581 # ask PLCOpenEditor controller to write ST/IL/SFC code file |
578 program, errors, warnings = self.GenerateProgram(self._getIECgeneratedcodepath()) |
582 program, errors, warnings = self.GenerateProgram(self._getIECgeneratedcodepath()) |
579 if len(warnings) > 0: |
583 if len(warnings) > 0: |
580 self.logger.write_warning(_("Warnings in ST/IL/SFC code generator :\n")) |
584 self.logger.write_warning(_("Warnings in ST/IL/SFC code generator :\n")) |
581 for warning in warnings: |
585 for warning in warnings: |
597 self.ProgramOffset += 1 |
601 self.ProgramOffset += 1 |
598 plc_file.close() |
602 plc_file.close() |
599 plc_file = open(self._getIECcodepath(), "a") |
603 plc_file = open(self._getIECcodepath(), "a") |
600 plc_file.write(open(self._getIECgeneratedcodepath(), "r").read()) |
604 plc_file.write(open(self._getIECgeneratedcodepath(), "r").read()) |
601 plc_file.close() |
605 plc_file.close() |
602 |
606 return True |
|
607 |
|
608 def _Compile_ST_to_SoftPLC(self): |
603 self.logger.write(_("Compiling IEC Program into C code...\n")) |
609 self.logger.write(_("Compiling IEC Program into C code...\n")) |
|
610 buildpath = self._getBuildPath() |
604 |
611 |
605 # Now compile IEC code into many C files |
612 # Now compile IEC code into many C files |
606 # files are listed to stdout, and errors to stderr. |
613 # files are listed to stdout, and errors to stderr. |
607 status, result, err_result = ProcessLogger( |
614 status, result, err_result = ProcessLogger( |
608 self.logger, |
615 self.logger, |
609 "\"%s\" -f -I \"%s\" -T \"%s\" \"%s\""%( |
616 "\"%s\" -f -I \"%s\" -T \"%s\" \"%s\""%( |
610 self.iec2c_path, |
617 self.iec2c_path, |
611 self.ieclib_path, |
618 self.ieclib_path, |
612 buildpath, |
619 buildpath, |
613 self._getIECcodepath()), |
620 self._getIECcodepath()), |
614 no_stdout=True, no_stderr=True).spin() |
621 no_stdout=True, no_stderr=True).spin() |
615 if status: |
622 if status: |
616 # Failed ! |
623 # Failed ! |
617 |
624 |
618 # parse iec2c's error message. if it contains a line number, |
625 # parse iec2c's error message. if it contains a line number, |
619 # then print those lines from the generated IEC file. |
626 # then print those lines from the generated IEC file. |
620 for err_line in err_result.split('\n'): |
627 for err_line in err_result.split('\n'): |
621 self.logger.write_warning(err_line + "\n") |
628 self.logger.write_warning(err_line + "\n") |
622 |
629 |
623 m_result = MATIEC_ERROR_MODEL.match(err_line) |
630 m_result = MATIEC_ERROR_MODEL.match(err_line) |
624 if m_result is not None: |
631 if m_result is not None: |
625 first_line, first_column, last_line, last_column, error = m_result.groups() |
632 first_line, first_column, last_line, last_column, error = m_result.groups() |
626 first_line, last_line = int(first_line), int(last_line) |
633 first_line, last_line = int(first_line), int(last_line) |
627 |
634 |
628 last_section = None |
635 last_section = None |
629 f = open(self._getIECcodepath()) |
636 f = open(self._getIECcodepath()) |
630 |
637 |
631 for i, line in enumerate(f.readlines()): |
638 for i, line in enumerate(f.readlines()): |
632 i = i + 1 |
639 i = i + 1 |
741 ProgramsListAttributeName = ["num", "C_path", "type"] |
748 ProgramsListAttributeName = ["num", "C_path", "type"] |
742 VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"] |
749 VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"] |
743 self._ProgramList = [] |
750 self._ProgramList = [] |
744 self._VariablesList = [] |
751 self._VariablesList = [] |
745 self._IECPathToIdx = {} |
752 self._IECPathToIdx = {} |
746 |
753 |
747 # Separate sections |
754 # Separate sections |
748 ListGroup = [] |
755 ListGroup = [] |
749 for line in open(csvfile,'r').xreadlines(): |
756 for line in open(csvfile,'r').xreadlines(): |
750 strippedline = line.strip() |
757 strippedline = line.strip() |
751 if strippedline.startswith("//"): |
758 if strippedline.startswith("//"): |
752 # Start new section |
759 # Start new section |
753 ListGroup.append([]) |
760 ListGroup.append([]) |
754 elif len(strippedline) > 0 and len(ListGroup) > 0: |
761 elif len(strippedline) > 0 and len(ListGroup) > 0: |
755 # append to this section |
762 # append to this section |
756 ListGroup[-1].append(strippedline) |
763 ListGroup[-1].append(strippedline) |
757 |
764 |
758 # first section contains programs |
765 # first section contains programs |
759 for line in ListGroup[0]: |
766 for line in ListGroup[0]: |
760 # Split and Maps each field to dictionnary entries |
767 # Split and Maps each field to dictionnary entries |
761 attrs = dict(zip(ProgramsListAttributeName,line.strip().split(';'))) |
768 attrs = dict(zip(ProgramsListAttributeName,line.strip().split(';'))) |
762 # Truncate "C_path" to remove conf an ressources names |
769 # Truncate "C_path" to remove conf an ressources names |
763 attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:]) |
770 attrs["C_path"] = '__'.join(attrs["C_path"].split(".",2)[1:]) |
764 # Push this dictionnary into result. |
771 # Push this dictionnary into result. |
765 self._ProgramList.append(attrs) |
772 self._ProgramList.append(attrs) |
766 |
773 |
767 # second section contains all variables |
774 # second section contains all variables |
768 config_FBs = {} |
775 config_FBs = {} |
769 for line in ListGroup[1]: |
776 for line in ListGroup[1]: |
770 # Split and Maps each field to dictionnary entries |
777 # Split and Maps each field to dictionnary entries |
771 attrs = dict(zip(VariablesListAttributeName,line.strip().split(';'))) |
778 attrs = dict(zip(VariablesListAttributeName,line.strip().split(';'))) |
906 IECGenRes = self._Generate_SoftPLC() |
913 IECGenRes = self._Generate_SoftPLC() |
907 self.ShowMethod("_showIECcode", True) |
914 self.ShowMethod("_showIECcode", True) |
908 |
915 |
909 # If IEC code gen fail, bail out. |
916 # If IEC code gen fail, bail out. |
910 if not IECGenRes: |
917 if not IECGenRes: |
911 self.logger.write_error(_("IEC-61131-3 code generation failed !\n")) |
918 self.logger.write_error(_("PLC code generation failed !\n")) |
912 self.ResetBuildMD5() |
919 self.ResetBuildMD5() |
913 return False |
920 return False |
914 |
921 |
915 # Reset variable and program list that are parsed from |
922 # Reset variable and program list that are parsed from |
916 # CSV file generated by IEC2C compiler. |
923 # CSV file generated by IEC2C compiler. |
917 self.ResetIECProgramsAndVariables() |
924 self.ResetIECProgramsAndVariables() |
918 |
925 |
|
926 # Collect platform specific C code |
|
927 # Code and other files from extension |
|
928 if not self._Generate_runtime(): |
|
929 return False |
|
930 |
|
931 # Get current or fresh builder |
|
932 builder = self.GetBuilder() |
|
933 if builder is None: |
|
934 self.logger.write_error(_("Fatal : cannot get builder.\n")) |
|
935 self.ResetBuildMD5() |
|
936 return False |
|
937 |
|
938 # Build |
|
939 try: |
|
940 if not builder.build() : |
|
941 self.logger.write_error(_("C Build failed.\n")) |
|
942 return False |
|
943 except Exception, exc: |
|
944 self.logger.write_error(_("C Build crashed !\n")) |
|
945 self.logger.write_error(traceback.format_exc()) |
|
946 self.ResetBuildMD5() |
|
947 return False |
|
948 |
|
949 self.logger.write(_("Successfully built.\n")) |
|
950 # Update GUI status about need for transfer |
|
951 self.CompareLocalAndRemotePLC() |
|
952 return True |
|
953 |
|
954 def _Generate_runtime(self): |
|
955 buildpath = self._getBuildPath() |
|
956 |
919 # Generate C code and compilation params from confnode hierarchy |
957 # Generate C code and compilation params from confnode hierarchy |
920 try: |
958 try: |
921 CTNLocationCFilesAndCFLAGS, CTNLDFLAGS, CTNExtraFiles = self._Generate_C( |
959 CTNLocationCFilesAndCFLAGS, CTNLDFLAGS, CTNExtraFiles = self._Generate_C( |
922 buildpath, |
960 buildpath, |
923 self.PLCGeneratedLocatedVars) |
961 self.PLCGeneratedLocatedVars) |
924 except Exception, exc: |
962 except Exception, exc: |
925 self.logger.write_error(_("Runtime extensions C code generation failed !\n")) |
963 self.logger.write_error(_("Runtime IO extensions C code generation failed !\n")) |
926 self.logger.write_error(traceback.format_exc()) |
964 self.logger.write_error(traceback.format_exc()) |
927 self.ResetBuildMD5() |
965 self.ResetBuildMD5() |
928 return False |
966 return False |
929 |
967 |
930 # Generate C code and compilation params from liraries |
968 # Generate C code and compilation params from liraries |
931 try: |
969 try: |
932 LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath) |
970 LibCFilesAndCFLAGS, LibLDFLAGS, LibExtraFiles = self.GetLibrariesCCode(buildpath) |
933 except Exception, exc: |
971 except Exception, exc: |
934 self.logger.write_error(_("Runtime extensions C code generation failed !\n")) |
972 self.logger.write_error(_("Runtime library extensions C code generation failed !\n")) |
935 self.logger.write_error(traceback.format_exc()) |
973 self.logger.write_error(traceback.format_exc()) |
936 self.ResetBuildMD5() |
974 self.ResetBuildMD5() |
937 return False |
975 return False |
938 |
976 |
939 self.LocationCFilesAndCFLAGS = CTNLocationCFilesAndCFLAGS + LibCFilesAndCFLAGS |
977 self.LocationCFilesAndCFLAGS = CTNLocationCFilesAndCFLAGS + LibCFilesAndCFLAGS |
940 self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS |
978 self.LDFLAGS = CTNLDFLAGS + LibLDFLAGS |
941 ExtraFiles = CTNExtraFiles + LibExtraFiles |
979 ExtraFiles = CTNExtraFiles + LibExtraFiles |
942 |
980 |
943 # Get temporary directory path |
981 # Get temporary directory path |
944 extrafilespath = self._getExtraFilesPath() |
982 extrafilespath = self._getExtraFilesPath() |
945 # Remove old directory |
983 # Remove old directory |
946 if os.path.exists(extrafilespath): |
984 if os.path.exists(extrafilespath): |
947 shutil.rmtree(extrafilespath) |
985 shutil.rmtree(extrafilespath) |
976 except Exception, exc: |
1014 except Exception, exc: |
977 self.logger.write_error(name+_(" generation failed !\n")) |
1015 self.logger.write_error(name+_(" generation failed !\n")) |
978 self.logger.write_error(traceback.format_exc()) |
1016 self.logger.write_error(traceback.format_exc()) |
979 self.ResetBuildMD5() |
1017 self.ResetBuildMD5() |
980 return False |
1018 return False |
981 |
|
982 self.logger.write(_("C code generated successfully.\n")) |
1019 self.logger.write(_("C code generated successfully.\n")) |
983 |
|
984 # Get current or fresh builder |
|
985 builder = self.GetBuilder() |
|
986 if builder is None: |
|
987 self.logger.write_error(_("Fatal : cannot get builder.\n")) |
|
988 self.ResetBuildMD5() |
|
989 return False |
|
990 |
|
991 # Build |
|
992 try: |
|
993 if not builder.build() : |
|
994 self.logger.write_error(_("C Build failed.\n")) |
|
995 return False |
|
996 except Exception, exc: |
|
997 self.logger.write_error(_("C Build crashed !\n")) |
|
998 self.logger.write_error(traceback.format_exc()) |
|
999 self.ResetBuildMD5() |
|
1000 return False |
|
1001 |
|
1002 self.logger.write(_("Successfully built.\n")) |
|
1003 # Update GUI status about need for transfer |
|
1004 self.CompareLocalAndRemotePLC() |
|
1005 return True |
1020 return True |
1006 |
1021 |
1007 def ShowError(self, logger, from_location, to_location): |
1022 def ShowError(self, logger, from_location, to_location): |
1008 chunk_infos = self.GetChunkInfos(from_location, to_location) |
1023 chunk_infos = self.GetChunkInfos(from_location, to_location) |
1009 for infos, (start_row, start_col) in chunk_infos: |
1024 for infos, (start_row, start_col) in chunk_infos: |
1010 start = (from_location[0] - start_row, from_location[1] - start_col) |
1025 start = (from_location[0] - start_row, from_location[1] - start_col) |
1011 end = (to_location[0] - start_row, to_location[1] - start_col) |
1026 end = (to_location[0] - start_row, to_location[1] - start_col) |
1012 if self.AppFrame is not None: |
1027 if self.AppFrame is not None: |
1013 self.AppFrame.ShowError(infos, start, end) |
1028 self.AppFrame.ShowError(infos, start, end) |
1014 |
1029 |
1015 _IECCodeView = None |
1030 _IECCodeView = None |
1016 def _showIECcode(self): |
1031 def _showIECcode(self): |
1017 self._OpenView("IEC code") |
1032 self._OpenView("IEC code") |
1018 |
1033 |
1019 _IECRawCodeView = None |
1034 _IECRawCodeView = None |
1020 def _editIECrawcode(self): |
1035 def _editIECrawcode(self): |
1021 self._OpenView("IEC raw code") |
1036 self._OpenView("IEC raw code") |
1022 |
1037 |
1023 _ProjectFilesView = None |
1038 _ProjectFilesView = None |
1024 def _OpenProjectFiles(self): |
1039 def _OpenProjectFiles(self): |
1025 self._OpenView("Project Files") |
1040 self._OpenView("Project Files") |
1026 |
1041 |
1027 _FileEditors = {} |
1042 _FileEditors = {} |
1028 def _OpenFileEditor(self, filepath): |
1043 def _OpenFileEditor(self, filepath): |
1029 self._OpenView(filepath) |
1044 self._OpenView(filepath) |
1030 |
1045 |
1031 def _OpenView(self, name=None, onlyopened=False): |
1046 def _OpenView(self, name=None, onlyopened=False): |
1032 if name == "IEC code": |
1047 if name == "IEC code": |
1033 if self._IECCodeView is None: |
1048 if self._IECCodeView is None: |
1034 plc_file = self._getIECcodepath() |
1049 plc_file = self._getIECcodepath() |
1035 |
1050 |
1036 self._IECCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name) |
1051 self._IECCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, None, instancepath=name) |
1037 self._IECCodeView.SetTextSyntax("ALL") |
1052 self._IECCodeView.SetTextSyntax("ALL") |
1038 self._IECCodeView.SetKeywords(IEC_KEYWORDS) |
1053 self._IECCodeView.SetKeywords(IEC_KEYWORDS) |
1039 try: |
1054 try: |
1040 text = file(plc_file).read() |
1055 text = file(plc_file).read() |
1041 except: |
1056 except: |
1042 text = '(* No IEC code have been generated at that time ! *)' |
1057 text = '(* No IEC code have been generated at that time ! *)' |
1043 self._IECCodeView.SetText(text = text) |
1058 self._IECCodeView.SetText(text = text) |
1044 self._IECCodeView.SetIcon(GetBitmap("ST")) |
1059 self._IECCodeView.SetIcon(GetBitmap("ST")) |
1045 setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor) |
1060 setattr(self._IECCodeView, "_OnClose", self.OnCloseEditor) |
1046 |
1061 |
1047 if self._IECCodeView is not None: |
1062 if self._IECCodeView is not None: |
1048 self.AppFrame.EditProjectElement(self._IECCodeView, name) |
1063 self.AppFrame.EditProjectElement(self._IECCodeView, name) |
1049 |
1064 |
1050 return self._IECCodeView |
1065 return self._IECCodeView |
1051 |
1066 |
1052 elif name == "IEC raw code": |
1067 elif name == "IEC raw code": |
1053 if self._IECRawCodeView is None: |
1068 if self._IECRawCodeView is None: |
1054 controler = MiniTextControler(self._getIECrawcodepath(), self) |
1069 controler = MiniTextControler(self._getIECrawcodepath(), self) |
1055 |
1070 |
1056 self._IECRawCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name) |
1071 self._IECRawCodeView = IECCodeViewer(self.AppFrame.TabsOpened, "", self.AppFrame, controler, instancepath=name) |
1057 self._IECRawCodeView.SetTextSyntax("ALL") |
1072 self._IECRawCodeView.SetTextSyntax("ALL") |
1058 self._IECRawCodeView.SetKeywords(IEC_KEYWORDS) |
1073 self._IECRawCodeView.SetKeywords(IEC_KEYWORDS) |
1059 self._IECRawCodeView.RefreshView() |
1074 self._IECRawCodeView.RefreshView() |
1060 self._IECRawCodeView.SetIcon(GetBitmap("ST")) |
1075 self._IECRawCodeView.SetIcon(GetBitmap("ST")) |
1061 setattr(self._IECRawCodeView, "_OnClose", self.OnCloseEditor) |
1076 setattr(self._IECRawCodeView, "_OnClose", self.OnCloseEditor) |
1062 |
1077 |
1063 if self._IECRawCodeView is not None: |
1078 if self._IECRawCodeView is not None: |
1064 self.AppFrame.EditProjectElement(self._IECRawCodeView, name) |
1079 self.AppFrame.EditProjectElement(self._IECRawCodeView, name) |
1065 |
1080 |
1066 return self._IECRawCodeView |
1081 return self._IECRawCodeView |
1067 |
1082 |
1068 elif name == "Project Files": |
1083 elif name == "Project Files": |
1069 if self._ProjectFilesView is None: |
1084 if self._ProjectFilesView is None: |
1070 self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True) |
1085 self._ProjectFilesView = FileManagementPanel(self.AppFrame.TabsOpened, self, name, self._getProjectFilesPath(), True) |
1071 |
1086 |
1072 extensions = [] |
1087 extensions = [] |
1073 for extension, name, editor in features.file_editors: |
1088 for extension, name, editor in features.file_editors: |
1074 if extension not in extensions: |
1089 if extension not in extensions: |
1075 extensions.append(extension) |
1090 extensions.append(extension) |
1076 self._ProjectFilesView.SetEditableFileExtensions(extensions) |
1091 self._ProjectFilesView.SetEditableFileExtensions(extensions) |
1077 |
1092 |
1078 if self._ProjectFilesView is not None: |
1093 if self._ProjectFilesView is not None: |
1079 self.AppFrame.EditProjectElement(self._ProjectFilesView, name) |
1094 self.AppFrame.EditProjectElement(self._ProjectFilesView, name) |
1080 |
1095 |
1081 return self._ProjectFilesView |
1096 return self._ProjectFilesView |
1082 |
1097 |
1083 elif name is not None and name.find("::") != -1: |
1098 elif name is not None and name.find("::") != -1: |
1084 filepath, editor_name = name.split("::") |
1099 filepath, editor_name = name.split("::") |
1085 if not self._FileEditors.has_key(filepath): |
1100 if not self._FileEditors.has_key(filepath): |
1086 if os.path.isfile(filepath): |
1101 if os.path.isfile(filepath): |
1087 file_extension = os.path.splitext(filepath)[1] |
1102 file_extension = os.path.splitext(filepath)[1] |
1088 |
1103 |
1089 editors = dict([(edit_name, edit_class) |
1104 editors = dict([(edit_name, edit_class) |
1090 for extension, edit_name, edit_class in features.file_editors |
1105 for extension, edit_name, edit_class in features.file_editors |
1091 if extension == file_extension]) |
1106 if extension == file_extension]) |
1092 |
1107 |
1093 if editor_name == "": |
1108 if editor_name == "": |
1094 if len(editors) == 1: |
1109 if len(editors) == 1: |
1095 editor_name = editors.keys()[0] |
1110 editor_name = editors.keys()[0] |
1096 elif len(editors) > 0: |
1111 elif len(editors) > 0: |
1097 names = editors.keys() |
1112 names = editors.keys() |
1098 dialog = wx.SingleChoiceDialog(self.AppFrame, |
1113 dialog = wx.SingleChoiceDialog(self.AppFrame, |
1099 _("Select an editor:"), _("Editor selection"), |
1114 _("Select an editor:"), _("Editor selection"), |
1100 names, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
1115 names, wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL) |
1101 if dialog.ShowModal() == wx.ID_OK: |
1116 if dialog.ShowModal() == wx.ID_OK: |
1102 editor_name = names[dialog.GetSelection()] |
1117 editor_name = names[dialog.GetSelection()] |
1103 dialog.Destroy() |
1118 dialog.Destroy() |
1104 |
1119 |
1105 if editor_name != "": |
1120 if editor_name != "": |
1106 name = "::".join([filepath, editor_name]) |
1121 name = "::".join([filepath, editor_name]) |
1107 |
1122 |
1108 editor = editors[editor_name]() |
1123 editor = editors[editor_name]() |
1109 self._FileEditors[filepath] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame) |
1124 self._FileEditors[filepath] = editor(self.AppFrame.TabsOpened, self, name, self.AppFrame) |
1110 self._FileEditors[filepath].SetIcon(GetBitmap("FILE")) |
1125 self._FileEditors[filepath].SetIcon(GetBitmap("FILE")) |
1111 if isinstance(self._FileEditors[filepath], DebugViewer): |
1126 if isinstance(self._FileEditors[filepath], DebugViewer): |
1112 self._FileEditors[filepath].SetDataProducer(self) |
1127 self._FileEditors[filepath].SetDataProducer(self) |
1113 |
1128 |
1114 if self._FileEditors.has_key(filepath): |
1129 if self._FileEditors.has_key(filepath): |
1115 editor = self._FileEditors[filepath] |
1130 editor = self._FileEditors[filepath] |
1116 self.AppFrame.EditProjectElement(editor, editor.GetTagName()) |
1131 self.AppFrame.EditProjectElement(editor, editor.GetTagName()) |
1117 |
1132 |
1118 return self._FileEditors.get(filepath) |
1133 return self._FileEditors.get(filepath) |
1119 else: |
1134 else: |
1120 return ConfigTreeNode._OpenView(self, self.CTNName(), onlyopened) |
1135 return ConfigTreeNode._OpenView(self, self.CTNName(), onlyopened) |
1121 |
1136 |
1122 def OnCloseEditor(self, view): |
1137 def OnCloseEditor(self, view): |
1307 self.ReArmDebugRegisterTimer() |
1322 self.ReArmDebugRegisterTimer() |
1308 |
1323 |
1309 def ForceDebugIECVariable(self, IECPath, fvalue): |
1324 def ForceDebugIECVariable(self, IECPath, fvalue): |
1310 if not self.IECdebug_datas.has_key(IECPath): |
1325 if not self.IECdebug_datas.has_key(IECPath): |
1311 return |
1326 return |
1312 |
1327 |
1313 self.IECdebug_lock.acquire() |
1328 self.IECdebug_lock.acquire() |
1314 |
1329 |
1315 # If no entry exist, create a new one with a fresh WeakKeyDictionary |
1330 # If no entry exist, create a new one with a fresh WeakKeyDictionary |
1316 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1331 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1317 IECdebug_data[2] = "Forced" |
1332 IECdebug_data[2] = "Forced" |
1318 IECdebug_data[3] = fvalue |
1333 IECdebug_data[3] = fvalue |
1319 |
1334 |
1320 self.IECdebug_lock.release() |
1335 self.IECdebug_lock.release() |
1321 |
1336 |
1322 self.ReArmDebugRegisterTimer() |
1337 self.ReArmDebugRegisterTimer() |
1323 |
1338 |
1324 def ReleaseDebugIECVariable(self, IECPath): |
1339 def ReleaseDebugIECVariable(self, IECPath): |
1325 if not self.IECdebug_datas.has_key(IECPath): |
1340 if not self.IECdebug_datas.has_key(IECPath): |
1326 return |
1341 return |
1327 |
1342 |
1328 self.IECdebug_lock.acquire() |
1343 self.IECdebug_lock.acquire() |
1329 |
1344 |
1330 # If no entry exist, create a new one with a fresh WeakKeyDictionary |
1345 # If no entry exist, create a new one with a fresh WeakKeyDictionary |
1331 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1346 IECdebug_data = self.IECdebug_datas.get(IECPath, None) |
1332 IECdebug_data[2] = "Registered" |
1347 IECdebug_data[2] = "Registered" |
1333 IECdebug_data[3] = None |
1348 IECdebug_data[3] = None |
1334 |
1349 |
1335 self.IECdebug_lock.release() |
1350 self.IECdebug_lock.release() |
1336 |
1351 |
1337 self.ReArmDebugRegisterTimer() |
1352 self.ReArmDebugRegisterTimer() |
1338 |
1353 |
1339 def CallWeakcallables(self, IECPath, function_name, *cargs): |
1354 def CallWeakcallables(self, IECPath, function_name, *cargs): |
1340 data_tuple = self.IECdebug_datas.get(IECPath, None) |
1355 data_tuple = self.IECdebug_datas.get(IECPath, None) |
1341 if data_tuple is not None: |
1356 if data_tuple is not None: |
1342 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1357 WeakCallableDict, data_log, status, fvalue, buffer_list = data_tuple |
1343 #data_log.append((debug_tick, value)) |
1358 #data_log.append((debug_tick, value)) |