# HG changeset patch # User Laurent Bessard # Date 1381348823 -7200 # Node ID aee0a7eb833af5d26d11fc7fd97794a9913864fd # Parent 533741e5075c49f802d3fc6104401e0b5ce44ce1 Fixed pou variables instance information loading stylesheet diff -r 533741e5075c -r aee0a7eb833a PLCControler.py --- a/PLCControler.py Wed Oct 09 10:57:20 2013 +0200 +++ b/PLCControler.py Wed Oct 09 22:00:23 2013 +0200 @@ -189,85 +189,54 @@ # Helpers object for generating pou variable instance list #------------------------------------------------------------------------------- -def class_extraction(el, prt): - if prt in ["pou", "variable"]: - pou_type = POU_TYPES.get(el.text) - if pou_type is not None: - return pou_type - return VAR_CLASS_INFOS[el.text][1] - return { +def class_extraction(value): + class_type = { "configuration": ITEM_CONFIGURATION, "resource": ITEM_RESOURCE, "action": ITEM_ACTION, "transition": ITEM_TRANSITION, - "program": ITEM_PROGRAM}.get(prt) - -PARAM_VALUE_EXTRACTION = { - "name": lambda el, prt: el.text, - "class": class_extraction, - "type": lambda el, prt: None if el.text == "None" else el.text, - "edit": lambda el, prt: el.text == "True", - "debug": lambda el, prt: el.text == "True", - "variables": lambda el, prt: [ - compute_instance_tree(chld) - for chld in el]} - -def compute_instance_tree(tree): - return {el.tag: - PARAM_VALUE_EXTRACTION[el.tag](el, tree.tag) - for el in tree} - -class IsEdited(etree.XSLTExtension): - - def __init__(self, controller, debug): - etree.XSLTExtension.__init__(self) - self.Controller = controller - self.Debug = debug - - def execute(self, context, self_node, input_node, output_parent): - typename = input_node.get("name") - project = self.Controller.GetProject(self.Debug) - output_parent.text = str(project.getpou(typename) is not None) - -class IsDebugged(etree.XSLTExtension): - - def __init__(self, controller, debug): - etree.XSLTExtension.__init__(self) - self.Controller = controller - self.Debug = debug - - def execute(self, context, self_node, input_node, output_parent): - typename = input_node.get("name") - project = self.Controller.GetProject(self.Debug) - pou_infos = project.getpou(typename) - if pou_infos is not None: - self.apply_templates(context, pou_infos, output_parent) - return - - datatype_infos = self.Controller.GetDataType(typename, self.Debug) - if datatype_infos is not None: - self.apply_templates(context, datatype_infos, output_parent) - return - - output_parent.text = "False" - -class PouVariableClass(etree.XSLTExtension): - - def __init__(self, controller, debug): - etree.XSLTExtension.__init__(self) - self.Controller = controller - self.Debug = debug - - def execute(self, context, self_node, input_node, output_parent): - pou_infos = self.Controller.GetPou(input_node.get("name"), self.Debug) - if pou_infos is not None: - self.apply_templates(context, pou_infos, output_parent) - return - - self.process_children(context, output_parent) - -pou_variables_xslt = etree.parse( - os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt")) + "program": ITEM_PROGRAM}.get(value) + if class_type is not None: + return class_type + + pou_type = POU_TYPES.get(value) + if pou_type is not None: + return pou_type + + var_type = VAR_CLASS_INFOS.get(value) + if var_type is not None: + return var_type[1] + + return None + +class _VariablesTreeItemInfos(object): + __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"] + def __init__(self, *args): + for attr, value in zip(self.__slots__, args): + setattr(self, attr, value if value is not None else "") + def copy(self): + return _VariableTreeItem(*[getattr(self, attr) for attr in self.__slots__]) + +class VariablesTreeInfosFactory: + + def __init__(self): + self.Root = None + + def GetRoot(self): + return self.Root + + def SetRoot(self, context, *args): + self.Root = _VariablesTreeItemInfos( + *([''] + _translate_args( + [class_extraction, str] + [_BoolValue] * 2, + args) + [[]])) + + def AddVariable(self, context, *args): + if self.Root is not None: + self.Root.variables.append(_VariablesTreeItemInfos( + *(_translate_args( + [str, class_extraction, str] + [_BoolValue] * 2, + args) + [[]]))) #------------------------------------------------------------------------------- # Helpers object for generating instances path list @@ -799,20 +768,28 @@ pou_type = None project = self.GetProject(debug) if project is not None: + factory = VariablesTreeInfosFactory() + + parser = etree.XMLParser() + parser.resolvers.add(LibraryResolver(self, debug)) + pou_variable_xslt_tree = etree.XSLT( - pou_variables_xslt, extensions = { - ("pou_vars_ns", "is_edited"): IsEdited(self, debug), - ("pou_vars_ns", "is_debugged"): IsDebugged(self, debug), - ("pou_vars_ns", "pou_class"): PouVariableClass(self, debug)}) + etree.parse( + os.path.join(ScriptDirectory, "plcopen", "pou_variables.xslt"), + parser), + extensions = {("pou_vars_ns", name): getattr(factory, name) + for name in ["SetRoot", "AddVariable"]}) + obj = None words = tagname.split("::") if words[0] == "P": obj = self.GetPou(words[1], debug) - else: + elif words[0] != "D": obj = self.GetEditedElement(tagname, debug) if obj is not None: - return compute_instance_tree( - pou_variable_xslt_tree(obj).getroot()) + pou_variable_xslt_tree(obj) + return factory.GetRoot() + return None def GetInstanceList(self, root, name, debug = False): diff -r 533741e5075c -r aee0a7eb833a controls/PouInstanceVariablesPanel.py --- a/controls/PouInstanceVariablesPanel.py Wed Oct 09 10:57:20 2013 +0200 +++ b/controls/PouInstanceVariablesPanel.py Wed Oct 09 22:00:23 2013 +0200 @@ -244,27 +244,27 @@ self.PouInfos = None if self.PouInfos is not None: root = self.VariablesList.AddRoot("") - for var_infos in self.PouInfos["variables"]: - if var_infos.get("type", None) is not None: - text = "%(name)s (%(type)s)" % var_infos + for var_infos in self.PouInfos.variables: + if var_infos.type is not None: + text = "%s (%s)" % (var_infos.name, var_infos.type) else: - text = var_infos["name"] + text = var_infos.name right_images = [] - if var_infos["class"] in ITEMS_VARIABLE: - if (not USE_MPL and var_infos["debug"] and self.Debug and - (self.Controller.IsOfType(var_infos["type"], "ANY_NUM", True) or - self.Controller.IsOfType(var_infos["type"], "ANY_BIT", True))): + if var_infos.var_class in ITEMS_VARIABLE: + if (not USE_MPL and var_infos.debug and self.Debug and + (self.Controller.IsOfType(var_infos.type, "ANY_NUM", True) or + self.Controller.IsOfType(var_infos.type, "ANY_BIT", True))): right_images.append(self.InstanceGraphImage) - elif var_infos["edit"]: + elif var_infos.edit: right_images.append(self.EditImage) - if var_infos["debug"] and self.Debug: + if var_infos.debug and self.Debug: right_images.append(self.DebugInstanceImage) item = self.VariablesList.AppendItem(root, text) item.SetRightImages(right_images) - self.VariablesList.SetItemImage(item, self.ParentWindow.GetTreeImage(var_infos["class"])) + self.VariablesList.SetItemImage(item, self.ParentWindow.GetTreeImage(var_infos.var_class)) self.VariablesList.SetPyData(item, var_infos) self.RefreshInstanceChoice() @@ -281,7 +281,7 @@ self.InstanceChoice.Append(instance) if len(instances) == 1: self.PouInstance = instances[0] - if self.PouInfos["class"] in [ITEM_CONFIGURATION, ITEM_RESOURCE]: + if self.PouInfos.var_class in [ITEM_CONFIGURATION, ITEM_RESOURCE]: self.PouInstance = None self.InstanceChoice.SetSelection(0) elif self.PouInstance in instances: @@ -292,8 +292,8 @@ def RefreshButtons(self): enabled = self.InstanceChoice.GetSelection() != -1 - self.ParentButton.Enable(enabled and self.PouInfos["class"] != ITEM_CONFIGURATION) - self.DebugButton.Enable(enabled and self.PouInfos["debug"] and self.Debug) + self.ParentButton.Enable(enabled and self.PouInfos.var_class != ITEM_CONFIGURATION) + self.DebugButton.Enable(enabled and self.PouInfos.debug and self.Debug) root = self.VariablesList.GetRootItem() if root is not None and root.IsOk(): @@ -307,29 +307,29 @@ item, item_cookie = self.VariablesList.GetNextChild(root, item_cookie) def EditButtonCallback(self, infos): - var_class = infos["class"] + var_class = infos.var_class if var_class == ITEM_RESOURCE: tagname = self.Controller.ComputeConfigurationResourceName( self.InstanceChoice.GetStringSelection(), - infos["name"]) + infos.name) elif var_class == ITEM_TRANSITION: tagname = self.Controller.ComputePouTransitionName( self.PouTagName.split("::")[1], - infos["name"]) + infos.name) elif var_class == ITEM_ACTION: tagname = self.Controller.ComputePouActionName( self.PouTagName.split("::")[1], - infos["name"]) + infos.name) else: var_class = ITEM_POU - tagname = self.Controller.ComputePouName(infos["type"]) + tagname = self.Controller.ComputePouName(infos.type) self.ParentWindow.EditProjectElement(var_class, tagname) def DebugButtonCallback(self, infos): if self.InstanceChoice.GetSelection() != -1: - var_class = infos["class"] + var_class = infos.var_class var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(), - infos["name"]) + infos.name) if var_class in ITEMS_VARIABLE: self.ParentWindow.AddDebugVariable(var_path, force=True) elif var_class == ITEM_TRANSITION: @@ -338,35 +338,35 @@ var_path, self.Controller.ComputePouTransitionName( self.PouTagName.split("::")[1], - infos["name"])) + infos.name)) elif var_class == ITEM_ACTION: self.ParentWindow.OpenDebugViewer( var_class, var_path, self.Controller.ComputePouActionName( self.PouTagName.split("::")[1], - infos["name"])) + infos.name)) else: self.ParentWindow.OpenDebugViewer( var_class, var_path, - self.Controller.ComputePouName(infos["type"])) + self.Controller.ComputePouName(infos.type)) def DebugButtonDClickCallback(self, infos): if self.InstanceChoice.GetSelection() != -1: - if infos["class"] in ITEMS_VARIABLE: + if infos.var_class in ITEMS_VARIABLE: self.ParentWindow.AddDebugVariable( "%s.%s" % (self.InstanceChoice.GetStringSelection(), - infos["name"]), + infos.name), force=True, graph=True) def GraphButtonCallback(self, infos): if self.InstanceChoice.GetSelection() != -1: - if infos["class"] in ITEMS_VARIABLE: + if infos.var_class in ITEMS_VARIABLE: var_path = "%s.%s" % (self.InstanceChoice.GetStringSelection(), - infos["name"]) - self.ParentWindow.OpenDebugViewer(infos["class"], var_path, infos["type"]) + infos.name) + self.ParentWindow.OpenDebugViewer(infos.var_class, var_path, infos.type) def ShowInstanceChoicePopup(self): self.InstanceChoice.SetFocusFromKbd() @@ -395,7 +395,7 @@ def OnDebugButtonClick(self, event): if self.InstanceChoice.GetSelection() != -1: self.ParentWindow.OpenDebugViewer( - self.PouInfos["class"], + self.PouInfos.var_class, self.InstanceChoice.GetStringSelection(), self.PouTagName) event.Skip() @@ -413,20 +413,20 @@ if callback is not None: callback(item_infos) - elif item_infos["class"] not in ITEMS_VARIABLE: + elif item_infos.var_class not in ITEMS_VARIABLE: instance_path = self.InstanceChoice.GetStringSelection() - if item_infos["class"] == ITEM_RESOURCE: + if item_infos.var_class == ITEM_RESOURCE: if instance_path != "": tagname = self.Controller.ComputeConfigurationResourceName( instance_path, - item_infos["name"]) + item_infos.name) else: tagname = None else: - tagname = self.Controller.ComputePouName(item_infos["type"]) + tagname = self.Controller.ComputePouName(item_infos.type) if tagname is not None: if instance_path != "": - item_path = "%s.%s" % (instance_path, item_infos["name"]) + item_path = "%s.%s" % (instance_path, item_infos.name) else: item_path = None self.SetPouType(tagname, item_path) @@ -450,10 +450,10 @@ if callback is not None: callback(item_infos) - elif flags & CT.TREE_HITTEST_ONITEMLABEL and item_infos["class"] in ITEMS_VARIABLE: + elif flags & CT.TREE_HITTEST_ONITEMLABEL and item_infos.var_class in ITEMS_VARIABLE: self.ParentWindow.EnsureTabVisible( self.ParentWindow.DebugVariablePanel) - item_path = "%s.%s" % (instance_path, item_infos["name"]) + item_path = "%s.%s" % (instance_path, item_infos.name) data = wx.TextDataObject(str((item_path, "debug"))) dragSource = wx.DropSource(self.VariablesList) dragSource.SetData(data) diff -r 533741e5075c -r aee0a7eb833a plcopen/pou_variables.xslt --- a/plcopen/pou_variables.xslt Wed Oct 09 10:57:20 2013 +0200 +++ b/plcopen/pou_variables.xslt Wed Oct 09 22:00:23 2013 +0200 @@ -1,174 +1,299 @@ -<xsl:stylesheet version="1.0" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" - xmlns:ns="pou_vars_ns" - extension-element-prefixes="ns" - exclude-result-prefixes="ns"> +<?xml version="1.0"?> +<xsl:stylesheet xmlns:func="http://exslt.org/functions" xmlns:dyn="http://exslt.org/dynamic" xmlns:str="http://exslt.org/strings" xmlns:math="http://exslt.org/math" xmlns:exsl="http://exslt.org/common" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:yml="http://fdik.org/yml" xmlns:set="http://exslt.org/sets" xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" xmlns:ns="pou_vars_ns" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="ns" version="1.0" exclude-result-prefixes="ns"> + <xsl:output method="xml"/> + <xsl:variable name="space" select="' '"/> + <xsl:param name="autoindent" select="4"/> + <xsl:template match="text()"> + <xsl:param name="_indent" select="0"/> + </xsl:template> + <xsl:template mode="var_class" match="text()"> + <xsl:param name="_indent" select="0"/> + </xsl:template> + <xsl:template mode="var_type" match="text()"> + <xsl:param name="_indent" select="0"/> + </xsl:template> + <xsl:template mode="var_edit" match="text()"> + <xsl:param name="_indent" select="0"/> + </xsl:template> + <xsl:template mode="var_debug" match="text()"> + <xsl:param name="_indent" select="0"/> + </xsl:template> + <xsl:variable name="project"> + <xsl:copy-of select="document('project')/project/*"/> + </xsl:variable> + <xsl:variable name="stdlib"> + <xsl:copy-of select="document('stdlib')/stdlib/*"/> + </xsl:variable> + <xsl:variable name="extensions"> + <xsl:copy-of select="document('extensions')/extensions/*"/> + </xsl:variable> + <xsl:template name="add_root"> + <xsl:param name="_indent" select="0"/> + <xsl:param name="class"/> + <xsl:param name="type"/> + <xsl:param name="edit"> + <xsl:text>true</xsl:text> + </xsl:param> + <xsl:param name="debug"> + <xsl:text>true</xsl:text> + </xsl:param> + <xsl:value-of select="ns:SetRoot($class, $type, $edit, $debug)"/> + </xsl:template> <xsl:template match="ppx:pou"> - <pou> - <class><xsl:value-of select="@pouType"/></class> - <type><xsl:value-of select="@name"/></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - <variables> - <xsl:apply-templates select="ppx:interface"/> - <xsl:apply-templates select="ppx:actions/ppx:action | ppx:transitions/ppx:transition" mode="variable_list"/> - </variables> - </pou> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_root"> + <xsl:with-param name="class"> + <xsl:value-of select="@pouType"/> + </xsl:with-param> + <xsl:with-param name="type"> + <xsl:value-of select="@name"/> + </xsl:with-param> + </xsl:call-template> + <xsl:apply-templates select="ppx:interface"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + <xsl:apply-templates mode="variable_list" select="ppx:actions/ppx:action | ppx:transitions/ppx:transition"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> </xsl:template> <xsl:template match="ppx:action"> - <action> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - <variables> - <xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface"/> - </variables> - </action> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_root"> + <xsl:with-param name="class"> + <xsl:text>action</xsl:text> + </xsl:with-param> + </xsl:call-template> + <xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> </xsl:template> <xsl:template match="ppx:transition"> - <transition> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - <variables> - <xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface"/> - </variables> - </transition> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_root"> + <xsl:with-param name="class"> + <xsl:text>transition</xsl:text> + </xsl:with-param> + </xsl:call-template> + <xsl:apply-templates select="ancestor::ppx:pou/child::ppx:interface"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> </xsl:template> <xsl:template match="ppx:configuration"> - <configuration> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>False</xsl:text></debug> - <variables> - <xsl:apply-templates select="ppx:resource" mode="variable_list"/> - <xsl:apply-templates select="ppx:globalVars"/> - </variables> - </configuration> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_root"> + <xsl:with-param name="class"> + <xsl:text>configuration</xsl:text> + </xsl:with-param> + <xsl:with-param name="debug"> + <xsl:text>false</xsl:text> + </xsl:with-param> + </xsl:call-template> + <xsl:apply-templates mode="variable_list" select="ppx:resource"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + <xsl:apply-templates select="ppx:globalVars"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> </xsl:template> <xsl:template match="ppx:resource"> - <resource> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>False</xsl:text></debug> - <variables> - <xsl:apply-templates select="ppx:pouInstance | ppx:task/ppx:pouInstance" mode="variable_list"/> - <xsl:apply-templates select="ppx:globalVars"/> - </variables> - </resource> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_root"> + <xsl:with-param name="class"> + <xsl:text>resource</xsl:text> + </xsl:with-param> + <xsl:with-param name="debug"> + <xsl:text>false</xsl:text> + </xsl:with-param> + </xsl:call-template> + <xsl:apply-templates mode="variable_list" select="ppx:pouInstance | ppx:task/ppx:pouInstance"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + <xsl:apply-templates select="ppx:globalVars"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:template> + <xsl:template name="variables_infos"> + <xsl:param name="_indent" select="0"/> + <xsl:param name="var_class"/> + <xsl:for-each select="ppx:variable"> + <xsl:variable name="class"> + <xsl:apply-templates mode="var_class" select="ppx:type"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + <xsl:with-param name="default_class"> + <xsl:value-of select="$var_class"/> + </xsl:with-param> + </xsl:apply-templates> + </xsl:variable> + <xsl:variable name="type"> + <xsl:apply-templates mode="var_type" select="ppx:type"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:variable> + <xsl:variable name="edit"> + <xsl:apply-templates mode="var_edit" select="ppx:type"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:variable> + <xsl:variable name="debug"> + <xsl:apply-templates mode="var_debug" select="ppx:type"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:variable> + <xsl:value-of select="ns:AddVariable(@name, $class, $type, $edit, $debug)"/> + </xsl:for-each> </xsl:template> <xsl:template match="ppx:localVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'Local'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>Local</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:globalVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'Global'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>Global</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:externalVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'External'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>External</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:tempVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'Temp'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>Temp</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:inputVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'Input'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>Input</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:outputVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'Output'"/> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>Output</xsl:text> + </xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template match="ppx:inOutVars"> - <xsl:call-template name="variables_infos"> - <xsl:with-param name="var_class" select="'InOut'"/> - </xsl:call-template> - </xsl:template> - <xsl:template name="variables_infos"> - <xsl:param name="var_class"/> - <xsl:for-each select="ppx:variable"> - <variable> - <name><xsl:value-of select="@name"/></name> - <class> - <xsl:apply-templates mode="var_class"> - <xsl:with-param name="default_class"> - <xsl:value-of select="$var_class"/> - </xsl:with-param> - </xsl:apply-templates> - </class> - <type><xsl:apply-templates mode="var_type"/></type> - <edit><xsl:apply-templates mode="var_edit"/></edit> - <debug><xsl:apply-templates mode="var_debug"/></debug> - </variable> - </xsl:for-each> - </xsl:template> - <xsl:template match="ppx:transition" mode="variable_list"> - <transition> - <name><xsl:value-of select="@name"/></name> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - </transition> - </xsl:template> - <xsl:template match="ppx:action" mode="variable_list"> - <action> - <name><xsl:value-of select="@name"/></name> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - </action> - </xsl:template> - <xsl:template match="ppx:resource" mode="variable_list"> - <resource> - <name><xsl:value-of select="@name"/></name> - <class/> - <type><xsl:text>None</xsl:text></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>False</xsl:text></debug> - </resource> - </xsl:template> - <xsl:template match="ppx:pouInstance" mode="variable_list"> - <program> - <name><xsl:value-of select="@name"/></name> - <class/> - <type><xsl:value-of select="@typeName"/></type> - <edit><xsl:text>True</xsl:text></edit> - <debug><xsl:text>True</xsl:text></debug> - </program> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_class"> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="variables_infos"> + <xsl:with-param name="var_class"> + <xsl:text>InOut</xsl:text> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + <xsl:template name="add_variable"> + <xsl:param name="_indent" select="0"/> + <xsl:param name="name"/> + <xsl:param name="class"/> + <xsl:param name="type"/> + <xsl:param name="edit"> + <xsl:text>true</xsl:text> + </xsl:param> + <xsl:param name="debug"> + <xsl:text>true</xsl:text> + </xsl:param> + <xsl:value-of select="ns:AddVariable($name, $class, $type, $edit, $debug)"/> + </xsl:template> + <xsl:template mode="variable_list" match="ppx:action"> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_variable"> + <xsl:with-param name="name"> + <xsl:value-of select="@name"/> + </xsl:with-param> + <xsl:with-param name="class"> + <xsl:text>action</xsl:text> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + <xsl:template mode="variable_list" match="ppx:transition"> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_variable"> + <xsl:with-param name="name"> + <xsl:value-of select="@name"/> + </xsl:with-param> + <xsl:with-param name="class"> + <xsl:text>transition</xsl:text> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + <xsl:template mode="variable_list" match="ppx:resource"> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_variable"> + <xsl:with-param name="name"> + <xsl:value-of select="@name"/> + </xsl:with-param> + <xsl:with-param name="class"> + <xsl:text>resource</xsl:text> + </xsl:with-param> + <xsl:with-param name="debug"> + <xsl:text>false</xsl:text> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + <xsl:template mode="variable_list" match="ppx:pouInstance"> + <xsl:param name="_indent" select="0"/> + <xsl:call-template name="add_variable"> + <xsl:with-param name="name"> + <xsl:value-of select="@name"/> + </xsl:with-param> + <xsl:with-param name="class"> + <xsl:text>program</xsl:text> + </xsl:with-param> + <xsl:with-param name="type"> + <xsl:value-of select="@typeName"/> + </xsl:with-param> + </xsl:call-template> + </xsl:template> + <xsl:template mode="var_class" match="*[self::ppx:type or self::ppx:baseType]/ppx:derived"> + <xsl:param name="_indent" select="0"/> <xsl:param name="default_class"/> - <ns:pou_class> - <xsl:value-of select="$default_class"/> - </ns:pou_class> - </xsl:template> - <xsl:template match="ppx:pou" mode="var_class"> - <xsl:param name="default_class"/> + <xsl:variable name="type_name" select="@name"/> + <xsl:variable name="pou_infos"> + <xsl:copy-of select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="$pou_infos != ''"> + <xsl:apply-templates mode="var_class" select="exsl:node-set($pou_infos)"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="$default_class"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <xsl:template mode="var_class" match="ppx:pou"> + <xsl:param name="_indent" select="0"/> <xsl:value-of select="@pouType"/> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/*" mode="var_class"> + <xsl:template mode="var_class" match="*[self::ppx:type or self::ppx:baseType]/*"> + <xsl:param name="_indent" select="0"/> <xsl:param name="default_class"/> <xsl:value-of select="$default_class"/> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_type"> + <xsl:template mode="var_type" match="*[self::ppx:type or self::ppx:baseType]/ppx:derived"> + <xsl:param name="_indent" select="0"/> <xsl:value-of select="@name"/> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:array" mode="var_type"> + <xsl:template mode="var_type" match="*[self::ppx:type or self::ppx:baseType]/ppx:array"> + <xsl:param name="_indent" select="0"/> <xsl:text>ARRAY [</xsl:text> <xsl:for-each select="ppx:dimension"> <xsl:value-of select="@lower"/> @@ -176,44 +301,78 @@ <xsl:value-of select="@upper"/> </xsl:for-each> <xsl:text>] OF </xsl:text> - <xsl:apply-templates select="ppx:baseType" mode="var_type"/> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:string" mode="var_type"> + <xsl:apply-templates mode="var_type" select="ppx:baseType"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:template> + <xsl:template mode="var_type" match="*[self::ppx:type or self::ppx:baseType]/ppx:string"> + <xsl:param name="_indent" select="0"/> <xsl:text>STRING</xsl:text> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:wstring" mode="var_type"> + <xsl:template mode="var_type" match="*[self::ppx:type or self::ppx:baseType]/ppx:wstring"> + <xsl:param name="_indent" select="0"/> <xsl:text>WSTRING</xsl:text> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/*" mode="var_type"> + <xsl:template mode="var_type" match="*[self::ppx:type or self::ppx:baseType]/*"> + <xsl:param name="_indent" select="0"/> <xsl:value-of select="local-name()"/> </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_edit"> - <ns:is_edited/> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:array" mode="var_edit"> - <xsl:apply-templates select="ppx:baseType" mode="var_edit"/> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/*" mode="var_edit"> - <xsl:text>False</xsl:text> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:derived" mode="var_debug"> - <ns:is_debugged/> - </xsl:template> - <xsl:template match="ppx:pou" mode="var_debug"> - <xsl:text>True</xsl:text> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:array" mode="var_debug"> - <xsl:text>False</xsl:text> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/ppx:struct" mode="var_debug"> - <xsl:text>False</xsl:text> - </xsl:template> - <xsl:template match="*[self::ppx:type or self::ppx:baseType]/*" mode="var_debug"> - <xsl:text>True</xsl:text> - </xsl:template> - <xsl:template match="text()"/> - <xsl:template match="text()" mode="var_class"/> - <xsl:template match="text()" mode="var_type"/> - <xsl:template match="text()" mode="var_edit"/> - <xsl:template match="text()" mode="var_debug"/> -</xsl:stylesheet> \ No newline at end of file + <xsl:template mode="var_edit" match="*[self::ppx:type or self::ppx:baseType]/ppx:derived"> + <xsl:param name="_indent" select="0"/> + <xsl:variable name="type_name" select="@name"/> + <xsl:variable name="pou_infos"> + <xsl:copy-of select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="$pou_infos != ''"> + <xsl:text>true</xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>false</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <xsl:template mode="var_edit" match="*[self::ppx:type or self::ppx:baseType]/ppx:array"> + <xsl:param name="_indent" select="0"/> + <xsl:apply-templates mode="var_edit" select="ppx:baseType"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:template> + <xsl:template mode="var_edit" match="*[self::ppx:type or self::ppx:baseType]/*"> + <xsl:param name="_indent" select="0"/> + <xsl:text>false</xsl:text> + </xsl:template> + <xsl:template mode="var_debug" match="*[self::ppx:type or self::ppx:baseType]/ppx:derived"> + <xsl:param name="_indent" select="0"/> + <xsl:variable name="type_name" select="@name"/> + <xsl:variable name="datatype_infos"> + <xsl:copy-of select="exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]"/> + </xsl:variable> + <xsl:choose> + <xsl:when test="$datatype_infos != ''"> + <xsl:apply-templates mode="var_debug" select="exsl:node-set($datatype_infos)"> + <xsl:with-param name="_indent" select="$_indent + (1) * $autoindent"/> + </xsl:apply-templates> + </xsl:when> + <xsl:otherwise> + <xsl:text>false</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + <xsl:template mode="var_debug" match="ppx:pou"> + <xsl:param name="_indent" select="0"/> + <xsl:text>true</xsl:text> + </xsl:template> + <xsl:template mode="var_debug" match="*[self::ppx:type or self::ppx:baseType]/ppx:array"> + <xsl:param name="_indent" select="0"/> + <xsl:text>false</xsl:text> + </xsl:template> + <xsl:template mode="var_debug" match="*[self::ppx:type or self::ppx:baseType]/ppx:struct"> + <xsl:param name="_indent" select="0"/> + <xsl:text>false</xsl:text> + </xsl:template> + <xsl:template mode="var_debug" match="*[self::ppx:type or self::ppx:baseType]/*"> + <xsl:param name="_indent" select="0"/> + <xsl:text>true</xsl:text> + </xsl:template> +</xsl:stylesheet> diff -r 533741e5075c -r aee0a7eb833a plcopen/pou_variables.ysl2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plcopen/pou_variables.ysl2 Wed Oct 09 22:00:23 2013 +0200 @@ -0,0 +1,279 @@ +include yslt.yml2 +estylesheet xmlns:ppx="http://www.plcopen.org/xml/tc6_0201" + xmlns:xhtml="http://www.w3.org/1999/xhtml" + xmlns:ns="pou_vars_ns" + extension-element-prefixes="ns" + exclude-result-prefixes="ns" { + + template "text()"; + template "text()", mode="var_class"; + template "text()", mode="var_type"; + template "text()", mode="var_edit"; + template "text()", mode="var_debug"; + + variable "project" { + copy "document('project')/project/*"; + } + + variable "stdlib" { + copy "document('stdlib')/stdlib/*"; + } + variable "extensions" { + copy "document('extensions')/extensions/*"; + } + + function "add_root" { + param "class"; + param "type"; + param "edit" > true + param "debug" > true + value "ns:SetRoot($class, $type, $edit, $debug)"; + } + + template "ppx:pou" { + call "add_root" { + with "class" > «@pouType» + with "type" > «@name» + } + apply "ppx:interface"; + apply "ppx:actions/ppx:action | ppx:transitions/ppx:transition", mode="variable_list"; + } + + template "ppx:action" { + call "add_root" { + with "class" > action + } + apply "ancestor::ppx:pou/child::ppx:interface"; + } + + template "ppx:transition" { + call "add_root" { + with "class" > transition + } + apply "ancestor::ppx:pou/child::ppx:interface"; + } + + template "ppx:configuration" { + call "add_root" { + with "class" > configuration + with "debug" > false + } + apply "ppx:resource", mode="variable_list"; + apply "ppx:globalVars"; + } + + template "ppx:resource" { + call "add_root" { + with "class" > resource + with "debug" > false + } + apply "ppx:pouInstance | ppx:task/ppx:pouInstance", mode="variable_list"; + apply "ppx:globalVars"; + } + + function "variables_infos" { + param "var_class"; + foreach "ppx:variable" { + variable "class" { + apply "ppx:type", mode="var_class" { + with "default_class" > «$var_class» + } + } + variable "type" { + apply"ppx:type", mode="var_type"; + } + variable "edit" { + apply "ppx:type", mode="var_edit"; + } + variable "debug" { + apply "ppx:type", mode="var_debug"; + } + value "ns:AddVariable(@name, $class, $type, $edit, $debug)"; + } + } + + template "ppx:localVars" { + call "variables_infos" { + with "var_class" > Local + } + } + + template "ppx:globalVars" { + call "variables_infos" { + with "var_class" > Global + } + } + + template "ppx:externalVars" { + call "variables_infos" { + with "var_class" > External + } + } + + template "ppx:tempVars" { + call "variables_infos" { + with "var_class" > Temp + } + } + + template "ppx:inputVars" { + call "variables_infos" { + with "var_class" > Input + } + } + + template "ppx:outputVars" { + call "variables_infos" { + with "var_class" > Output + } + } + + template "ppx:inOutVars" { + call "variables_infos" { + with "var_class" > InOut + } + } + + function "add_variable" { + param "name"; + param "class"; + param "type"; + param "edit" > true + param "debug" > true + value "ns:AddVariable($name, $class, $type, $edit, $debug)"; + } + + template "ppx:action", mode="variable_list" { + call "add_variable" { + with "name" > «@name» + with "class" > action + } + } + + template "ppx:transition", mode="variable_list" { + call "add_variable" { + with "name" > «@name» + with "class" > transition + } + } + + template "ppx:resource", mode="variable_list" { + call "add_variable" { + with "name" > «@name» + with "class" > resource + with "debug" > false + } + } + + template "ppx:pouInstance", mode="variable_list" { + call "add_variable" { + with "name" > «@name» + with "class" > program + with "type" > «@typeName» + } + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_class" { + param "default_class"; + variable "type_name", "@name"; + variable "pou_infos" { + copy """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | + exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | + exsl:node-set($extensions)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"""; + } + choose { + when "$pou_infos != ''" { + apply "exsl:node-set($pou_infos)", mode="var_class"; + } + otherwise { + value "$default_class" + } + } + } + + template "ppx:pou", mode="var_class" { + value "@pouType"; + } + + template "*[self::ppx:type or self::ppx:baseType]/*" mode="var_class" { + param "default_class"; + value "$default_class"; + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_type" { + > «@name» + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:array", mode="var_type" { + > ARRAY [ + foreach "ppx:dimension" { + > «@lower»..«@upper» + } + > ] OF + apply "ppx:baseType", mode="var_type"; + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:string", mode="var_type" { + > STRING + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:wstring", mode="var_type" { + > WSTRING + } + + template "*[self::ppx:type or self::ppx:baseType]/*", mode="var_type" { + > «local-name()» + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_edit" { + variable "type_name", "@name"; + variable "pou_infos" { + copy "exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name]"; + } + choose { + when "$pou_infos != ''" > true + otherwise > false + } + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:array", mode="var_edit" { + apply "ppx:baseType", mode="var_edit"; + } + + template "*[self::ppx:type or self::ppx:baseType]/*", mode="var_edit" { + > false + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:derived", mode="var_debug" { + variable "type_name", "@name"; + variable "datatype_infos" { + copy """exsl:node-set($project)/ppx:project/ppx:types/ppx:pous/ppx:pou[@name=$type_name] | + exsl:node-set($project)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | + exsl:node-set($stdlib)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name] | + exsl:node-set($extensions)/ppx:project/ppx:types/ppx:dataTypes/ppx:dataType[@name=$type_name]"""; + } + choose { + when "$datatype_infos != ''" { + apply "exsl:node-set($datatype_infos)", mode="var_debug"; + } + otherwise > false + } + } + + template "ppx:pou", mode="var_debug" { + > true + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:array", mode="var_debug" { + > false + } + + template "*[self::ppx:type or self::ppx:baseType]/ppx:struct", mode="var_debug" { + > false + } + + template "*[self::ppx:type or self::ppx:baseType]/*", mode="var_debug" { + > true + } + +}