# HG changeset patch # User Laurent Bessard # Date 1378158398 -7200 # Node ID fcca121a000f10e878b8c5a433d85bf15a99b605 # Parent 8e1ee07bdff8efaefe1761ab39c55568d781aa3e Removed dictionaries storing enumerated datatypes values, subrange datatypes range and project datatype hierarchy from model diff -r 8e1ee07bdff8 -r fcca121a000f PLCControler.py --- a/PLCControler.py Mon Sep 02 09:41:15 2013 +0200 +++ b/PLCControler.py Mon Sep 02 23:46:38 2013 +0200 @@ -735,7 +735,7 @@ def DataTypeIsUsed(self, name, debug = False): project = self.GetProject(debug) if project is not None: - return project.ElementIsUsed(name) or project.DataTypeIsDerived(name) + return project.ElementIsUsed(name) return False # Return if pou given by name is used by another pou @@ -981,7 +981,6 @@ datatype.setname(new_name) self.Project.updateElementName(old_name, new_name) self.Project.RefreshElementUsingTree() - self.Project.RefreshDataTypeHierarchy() self.BufferProject() # Change the name of a pou @@ -1691,19 +1690,46 @@ datatypes.extend(category["list"]) return datatypes - # Return Base Type of given possible derived type - def GetBaseType(self, type, debug = False): - project = self.GetProject(debug) - if project is not None: - result = project.GetBaseType(type) + # Return Data Type Object + def GetDataType(self, typename, debug = False): + project = self.GetProject(debug) + if project is not None: + result = project.getdataType(typename) if result is not None: return result for confnodetype in self.ConfNodeTypes: - result = confnodetype["types"].GetBaseType(type) + result = confnodetype["types"].getdataType(typename) if result is not None: return result return None + # Return Data Type Object Base Type + def GetDataTypeBaseType(self, datatype): + basetype_content = datatype.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type in ["array", "subrangeSigned", "subrangeUnsigned"]: + basetype = basetype_content.baseType.getcontent() + basetype_type = basetype.getLocalTag() + return (basetype.getname() if basetype_type == "derived" + else basetype_type.upper()) + elif basetype_content_type == "derived": + return basetype_content_type.getname() + return None + + # Return Base Type of given possible derived type + def GetBaseType(self, typename, debug = False): + if TypeHierarchy.has_key(typename): + return typename + + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype = self.GetDataTypeBaseType(datatype) + if basetype is not None: + return self.GetBaseType(basetype, debug) + return typename + + return None + def GetBaseTypes(self): ''' return the list of datatypes defined in IEC 61131-3. @@ -1712,93 +1738,124 @@ ''' return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")] - def IsOfType(self, type, reference, debug = False): - if reference is None: + def IsOfType(self, typename, reference, debug = False): + if reference is None or typename == reference: return True - elif type == reference: - return True - elif type in TypeHierarchy: - return self.IsOfType(TypeHierarchy[type], reference) - else: - project = self.GetProject(debug) - if project is not None and project.IsOfType(type, reference): - return True - for confnodetype in self.ConfNodeTypes: - if confnodetype["types"].IsOfType(type, reference): - return True + + basetype = TypeHierarchy.get(typename) + if basetype is not None: + return self.IsOfType(basetype, reference) + + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype = self.GetDataTypeBaseType(datatype) + if basetype is not None: + return self.IsOfType(basetype, reference, debug) + return False - def IsEndType(self, type): - if type is not None: - return not type.startswith("ANY") + def IsEndType(self, typename): + if typename is not None: + return not typename.startswith("ANY") return True - def IsLocatableType(self, type, debug = False): - if isinstance(type, TupleType): - return False - if self.GetBlockType(type) is not None: + def IsLocatableType(self, typename, debug = False): + if isinstance(typename, TupleType) or self.GetBlockType(type) is not None: return False - project = self.GetProject(debug) - if project is not None: - datatype = project.getdataType(type) - if datatype is None: - datatype = self.GetConfNodeDataType(type) - if datatype is not None: - return project.IsLocatableType(datatype) + + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype_content = datatype.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type in ["enum", "struct"]: + return False + elif basetype_content_type == "derived": + return self.IsLocatableType(basetype_content.getname()) + elif basetype_content_name == "array": + array_base_type = basetype_content.baseType.getcontent() + if array_base_type.getLocalTag() == "derived": + return self.IsLocatableType(array_base_type.getname(), debug) + return True - def IsEnumeratedType(self, type, debug = False): - project = self.GetProject(debug) - if project is not None: - datatype = project.getdataType(type) - if datatype is None: - datatype = self.GetConfNodeDataType(type) - if datatype is not None: - basetype_content = datatype.baseType.getcontent() - return basetype_content.getLocalTag() == "enum" + def IsEnumeratedType(self, typename, debug = False): + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype_content = datatype.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type == "derived": + return self.IsEnumeratedType(basetype_content_type, debug) + return basetype_content_type == "enum" return False - def IsNumType(self, type, debug = False): - return self.IsOfType(type, "ANY_NUM", debug) or\ - self.IsOfType(type, "ANY_BIT", debug) + def IsSubrangeType(self, typename, exclude=None, debug = False): + if typename == exclude: + return False + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype_content = datatype.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type == "derived": + return self.IsSubrangeType(basetype_content_type, exclude, debug) + elif basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: + return not self.IsOfType( + self.GetDataTypeBaseType(datatype), exclude) + return False + + def IsNumType(self, typename, debug = False): + return self.IsOfType(typename, "ANY_NUM", debug) or\ + self.IsOfType(typename, "ANY_BIT", debug) - def GetDataTypeRange(self, type, debug = False): - if type in DataTypeRange: - return DataTypeRange[type] + def GetDataTypeRange(self, typename, debug = False): + range = DataTypeRange.get(typename) + if range is not None: + return range + datatype = self.GetDataType(typename, debug) + if datatype is not None: + basetype_content = datatype.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type in ["subrangeSigned", "subrangeUnsigned"]: + return (basetype_content.range.getlower(), + basetype_content.range.getupper()) + elif basetype_content_type == "derived": + return self.GetDataTypeRange(basetype_content.getname(), debug) + return None + + # Return Subrange types + def GetSubrangeBaseTypes(self, exclude, debug = False): + subrange_basetypes = DataTypeRange.keys() + project = self.GetProject(debug) + if project is not None: + subrange_basetypes.extend( + [datatype.getname() for datatype in project.getdataTypes() + if self.IsSubrangeType(datatype.getname(), exclude, debug)]) + for confnodetype in self.ConfNodeTypes: + subrange_basetypes.extend( + [datatype.getname() for datatype in confnodetype["types"].getdataTypes() + if self.IsSubrangeType(datatype.getname(), exclude, debug)]) + return subrange_basetypes + + # Return Enumerated Values + def GetEnumeratedDataValues(self, typename = None, debug = False): + values = [] + if typename is not None: + datatype_obj = self.GetDataType(typename, debug) + if datatype_obj is not None: + basetype_content = datatype_obj.baseType.getcontent() + basetype_content_type = basetype_content.getLocalTag() + if basetype_content_type == "enum": + return [value.getname() + for value in basetype_content.xpath( + "ppx:values/ppx:value", + namespaces=PLCOpenParser.NSMAP)] + elif basetype_content_type == "derived": + return self.GetEnumeratedDataValues(basetype_content.getname(), debug) else: project = self.GetProject(debug) if project is not None: - result = project.GetDataTypeRange(type) - if result is not None: - return result + values.extend(project.GetEnumeratedDataTypeValues()) for confnodetype in self.ConfNodeTypes: - result = confnodetype["types"].GetDataTypeRange(type) - if result is not None: - return result - return None - - # Return Subrange types - def GetSubrangeBaseTypes(self, exclude, debug = False): - subrange_basetypes = [] - project = self.GetProject(debug) - if project is not None: - subrange_basetypes.extend(project.GetSubrangeBaseTypes(exclude)) - for confnodetype in self.ConfNodeTypes: - subrange_basetypes.extend(confnodetype["types"].GetSubrangeBaseTypes(exclude)) - return DataTypeRange.keys() + subrange_basetypes - - # Return Enumerated Values - def GetEnumeratedDataValues(self, type = None, debug = False): - values = [] - project = self.GetProject(debug) - if project is not None: - values.extend(project.GetEnumeratedDataTypeValues(type)) - if type is None and len(values) > 0: - return values - for confnodetype in self.ConfNodeTypes: - values.extend(confnodetype["types"].GetEnumeratedDataTypeValues(type)) - if type is None and len(values) > 0: - return values + values.extend(confnodetype["types"].GetEnumeratedDataTypeValues()) return values #------------------------------------------------------------------------------- @@ -2031,7 +2088,6 @@ datatype.initialValue.setvalue(infos["initial"]) else: datatype.initialValue = None - self.Project.RefreshDataTypeHierarchy() self.Project.RefreshElementUsingTree() self.BufferProject() @@ -3100,7 +3156,6 @@ return _("Project file syntax error:\n\n") + str(e) self.SetFilePath(filepath) self.Project.RefreshElementUsingTree() - self.Project.RefreshDataTypeHierarchy() self.Project.RefreshCustomBlockTypes() ## To remove when project buffering ready diff -r 8e1ee07bdff8 -r fcca121a000f plcopen/plcopen.py --- a/plcopen/plcopen.py Mon Sep 02 09:41:15 2013 +0200 +++ b/plcopen/plcopen.py Mon Sep 02 23:46:38 2013 +0200 @@ -241,9 +241,6 @@ cls = PLCOpenParser.GetElementClass("project") if cls: - cls.EnumeratedDataTypeValues = {} - cls.CustomDataTypeRange = {} - cls.CustomTypeHierarchy = {} cls.ElementUsingTree = {} cls.CustomBlockTypes = OrderedDict() @@ -256,106 +253,98 @@ setattr(cls, "getname", getname) def getfileHeader(self): - fileheader = {} - for name, value in [("companyName", self.fileHeader.getcompanyName()), - ("companyURL", self.fileHeader.getcompanyURL()), - ("productName", self.fileHeader.getproductName()), - ("productVersion", self.fileHeader.getproductVersion()), - ("productRelease", self.fileHeader.getproductRelease()), - ("creationDateTime", self.fileHeader.getcreationDateTime()), - ("contentDescription", self.fileHeader.getcontentDescription())]: - if value is not None: - fileheader[name] = value - else: - fileheader[name] = "" - return fileheader + fileheader_obj = self.fileHeader + return { + attr: value if value is not None else "" + for attr, value in [ + ("companyName", fileheader_obj.getcompanyName()), + ("companyURL", fileheader_obj.getcompanyURL()), + ("productName", fileheader_obj.getproductName()), + ("productVersion", fileheader_obj.getproductVersion()), + ("productRelease", fileheader_obj.getproductRelease()), + ("creationDateTime", fileheader_obj.getcreationDateTime()), + ("contentDescription", fileheader_obj.getcontentDescription())] + } setattr(cls, "getfileHeader", getfileHeader) def setfileHeader(self, fileheader): - if fileheader.has_key("companyName"): - self.fileHeader.setcompanyName(fileheader["companyName"]) - if fileheader.has_key("companyURL"): - self.fileHeader.setcompanyURL(fileheader["companyURL"]) - if fileheader.has_key("productName"): - self.fileHeader.setproductName(fileheader["productName"]) - if fileheader.has_key("productVersion"): - self.fileHeader.setproductVersion(fileheader["productVersion"]) - if fileheader.has_key("productRelease"): - self.fileHeader.setproductRelease(fileheader["productRelease"]) - if fileheader.has_key("creationDateTime"): - self.fileHeader.setcreationDateTime(fileheader["creationDateTime"]) - if fileheader.has_key("contentDescription"): - self.fileHeader.setcontentDescription(fileheader["contentDescription"]) + fileheader_obj = self.fileHeader + for attr, value in fileheader.iteritems(): + setattr(fileheader_obj, attr, value) setattr(cls, "setfileHeader", setfileHeader) def getcontentHeader(self): - contentheader = {} - for name, value in [("projectName", self.contentHeader.getname()), - ("projectVersion", self.contentHeader.getversion()), - ("modificationDateTime", self.contentHeader.getmodificationDateTime()), - ("organization", self.contentHeader.getorganization()), - ("authorName", self.contentHeader.getauthor()), - ("language", self.contentHeader.getlanguage())]: - if value is not None: - contentheader[name] = value - else: - contentheader[name] = "" + contentheader_obj = self.contentHeader + contentheader = { + attr: value if value is not None else "" + for attr, value in [ + ("projectName", contentheader_obj.getname()), + ("projectVersion", contentheader_obj.getversion()), + ("modificationDateTime", contentheader_obj.getmodificationDateTime()), + ("organization", contentheader_obj.getorganization()), + ("authorName", contentheader_obj.getauthor()), + ("language", contentheader_obj.getlanguage())] + } contentheader["pageSize"] = self.contentHeader.getpageSize() contentheader["scaling"] = self.contentHeader.getscaling() return contentheader setattr(cls, "getcontentHeader", getcontentHeader) def setcontentHeader(self, contentheader): - if contentheader.has_key("projectName"): - self.contentHeader.setname(contentheader["projectName"]) - if contentheader.has_key("projectVersion"): - self.contentHeader.setversion(contentheader["projectVersion"]) - if contentheader.has_key("modificationDateTime"): - self.contentHeader.setmodificationDateTime(contentheader["modificationDateTime"]) - if contentheader.has_key("organization"): - self.contentHeader.setorganization(contentheader["organization"]) - if contentheader.has_key("authorName"): - self.contentHeader.setauthor(contentheader["authorName"]) - if contentheader.has_key("language"): - self.contentHeader.setlanguage(contentheader["language"]) - if contentheader.has_key("pageSize"): - self.contentHeader.setpageSize(*contentheader["pageSize"]) - if contentheader.has_key("scaling"): - self.contentHeader.setscaling(contentheader["scaling"]) + contentheader_obj = self.contentHeader + for attr, value in contentheader.iteritems(): + if attr == "projectName": + contentheader_obj.setname(value) + elif attr == "projectVersion": + contentheader_obj.setversion(value) + elif attr == "pageSize": + contentheader_obj.setpageSize(*contentheader["pageSize"]) + elif attr == "scaling": + contentheader_obj.setscaling(contentheader["scaling"]) + else: + setattr(contentheader_obj, attr, value) setattr(cls, "setcontentHeader", setcontentHeader) + def gettypeElement(self, element_type, name=None): + filter = "[@name='%s']" % name if name is not None else "" + elements = self.xpath("ppx:types/ppx:%(element_type)ss/ppx:%(element_type)s%(filter)s" % locals(), + namespaces=PLCOpenParser.NSMAP) + if name is None: + return elements + elif len(elements) == 1: + return elements[0] + return None + setattr(cls, "gettypeElement", gettypeElement) + def getdataTypes(self): - return self.types.getdataTypeElements() + return self.getdataType() setattr(cls, "getdataTypes", getdataTypes) - def getdataType(self, name): - return self.types.getdataTypeElement(name) + def getdataType(self, name=None): + return self.gettypeElement("dataType", name) setattr(cls, "getdataType", getdataType) def appenddataType(self, name): - if self.CustomTypeHierarchy.has_key(name): + if self.getdataType(name) is not None: raise ValueError, "\"%s\" Data Type already exists !!!"%name self.types.appenddataTypeElement(name) - self.AddCustomDataType(self.getdataType(name)) setattr(cls, "appenddataType", appenddataType) def insertdataType(self, index, datatype): self.types.insertdataTypeElement(index, datatype) - self.AddCustomDataType(datatype) setattr(cls, "insertdataType", insertdataType) def removedataType(self, name): self.types.removedataTypeElement(name) - self.RefreshDataTypeHierarchy() self.RefreshElementUsingTree() setattr(cls, "removedataType", removedataType) def getpous(self): - return self.types.getpouElements() + return self.getpou() setattr(cls, "getpous", getpous) - def getpou(self, name): - return self.types.getpouElement(name) + def getpou(self, name=None): + return self.gettypeElement("pou", name) setattr(cls, "getpou", getpou) def appendpou(self, name, pou_type, body_type): @@ -375,54 +364,51 @@ setattr(cls, "removepou", removepou) def getconfigurations(self): - configurations = self.instances.configurations.getconfiguration() - if configurations is not None: + return self.getconfiguration() + setattr(cls, "getconfigurations", getconfigurations) + + def getconfiguration(self, name=None): + configurations = self.xpath( + "ppx:instances/ppx:configurations/ppx:configuration%s" % + ("[@name='%s']" % name if name is not None else ""), + namespaces=PLCOpenParser.NSMAP) + if name is None: return configurations - return [] - setattr(cls, "getconfigurations", getconfigurations) - - def getconfiguration(self, name): - for configuration in self.instances.configurations.getconfiguration(): - if configuration.getname() == name: - return configuration + elif len(configurations) == 1: + return configurations[0] return None setattr(cls, "getconfiguration", getconfiguration) def addconfiguration(self, name): - for configuration in self.instances.configurations.getconfiguration(): - if configuration.getname() == name: - raise ValueError, _("\"%s\" configuration already exists !!!")%name + if self.getconfiguration(name) is not None: + raise ValueError, _("\"%s\" configuration already exists !!!") % name new_configuration = PLCOpenParser.CreateElement("configuration", "configurations") new_configuration.setname(name) self.instances.configurations.appendconfiguration(new_configuration) setattr(cls, "addconfiguration", addconfiguration) def removeconfiguration(self, name): - found = False - for idx, configuration in enumerate(self.instances.configurations.getconfiguration()): - if configuration.getname() == name: - self.instances.configurations.removeconfiguration(idx) - found = True - break - if not found: - raise ValueError, ("\"%s\" configuration doesn't exist !!!")%name + configuration = self.getconfiguration(name) + if configuration is None: + raise ValueError, ("\"%s\" configuration doesn't exist !!!") % name + self.instances.configurations.remove(configuration) setattr(cls, "removeconfiguration", removeconfiguration) def getconfigurationResource(self, config_name, name): + resources = self.xpath( + "ppx:instances/ppx:configurations/ppx:configuration[@name='%s']/ppx:resource[@name='%s']" % + (config_name, name), + namespaces=PLCOpenParser.NSMAP) + if len(resources) == 1: + return resources[0] + return None + setattr(cls, "getconfigurationResource", getconfigurationResource) + + def addconfigurationResource(self, config_name, name): + if self.getconfigurationResource(config_name, name) is not None: + raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!") % (name, config_name) configuration = self.getconfiguration(config_name) if configuration is not None: - for resource in configuration.getresource(): - if resource.getname() == name: - return resource - return None - setattr(cls, "getconfigurationResource", getconfigurationResource) - - def addconfigurationResource(self, config_name, name): - configuration = self.getconfiguration(config_name) - if configuration is not None: - for resource in configuration.getresource(): - if resource.getname() == name: - raise ValueError, _("\"%s\" resource already exists in \"%s\" configuration !!!")%(name, config_name) new_resource = PLCOpenParser.CreateElement("resource", "configuration") new_resource.setname(name) configuration.appendresource(new_resource) @@ -430,85 +416,48 @@ def removeconfigurationResource(self, config_name, name): configuration = self.getconfiguration(config_name) + found = False if configuration is not None: - found = False - for idx, resource in enumerate(configuration.getresource()): - if resource.getname() == name: - configuration.removeresource(idx) - found = True - break - if not found: - raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name) + resource = self.getconfigurationResource(config_name, name) + if resource is not None: + configuration.remove(resource) + found = True + if not found: + raise ValueError, _("\"%s\" resource doesn't exist in \"%s\" configuration !!!")%(name, config_name) setattr(cls, "removeconfigurationResource", removeconfigurationResource) def updateElementName(self, old_name, new_name): - for datatype in self.types.getdataTypeElements(): + for datatype in self.getdataTypes(): datatype.updateElementName(old_name, new_name) - for pou in self.types.getpouElements(): + for pou in self.getpous(): pou.updateElementName(old_name, new_name) - for configuration in self.instances.configurations.getconfiguration(): + for configuration in self.getconfigurations(): configuration.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) def updateElementAddress(self, old_leading, new_leading): address_model = re.compile(FILTER_ADDRESS_MODEL % old_leading) - for pou in self.types.getpouElements(): + for pou in self.getpous(): pou.updateElementAddress(address_model, new_leading) - for configuration in self.instances.configurations.getconfiguration(): + for configuration in self.getconfigurations(): configuration.updateElementAddress(address_model, new_leading) setattr(cls, "updateElementAddress", updateElementAddress) def removeVariableByAddress(self, address): - for pou in self.types.getpouElements(): + for pou in self.getpous(): pou.removeVariableByAddress(address) - for configuration in self.instances.configurations.getconfiguration(): + for configuration in self.getconfigurations(): configuration.removeVariableByAddress(address) setattr(cls, "removeVariableByAddress", removeVariableByAddress) def removeVariableByFilter(self, leading): address_model = re.compile(FILTER_ADDRESS_MODEL % leading) - for pou in self.types.getpouElements(): + for pou in self.getpous(): pou.removeVariableByFilter(address_model) - for configuration in self.instances.configurations.getconfiguration(): + for configuration in self.getconfigurations(): configuration.removeVariableByFilter(address_model) setattr(cls, "removeVariableByFilter", removeVariableByFilter) - def RefreshDataTypeHierarchy(self): - self.EnumeratedDataTypeValues = {} - self.CustomDataTypeRange = {} - self.CustomTypeHierarchy = {} - for datatype in self.getdataTypes(): - self.AddCustomDataType(datatype) - setattr(cls, "RefreshDataTypeHierarchy", RefreshDataTypeHierarchy) - - def AddCustomDataType(self, datatype): - name = datatype.getname() - basetype_content = datatype.getbaseType().getcontent() - basetype_content_name = basetype_content.getLocalTag() - if basetype_content.__class__ == DefaultElementClass: - self.CustomTypeHierarchy[name] = basetype_content_name - elif basetype_content_name in ["string", "wstring"]: - self.CustomTypeHierarchy[name] = basetype_content_name.upper() - elif basetype_content_name == "derived": - self.CustomTypeHierarchy[name] = basetype_content.getname() - elif basetype_content_name in ["subrangeSigned", "subrangeUnsigned"]: - range = (basetype_content.range.getlower(), - basetype_content.range.getupper()) - self.CustomDataTypeRange[name] = range - base_type = basetype_content.baseType.getcontent() - if base_type.__class__ == DefaultElementClass: - self.CustomTypeHierarchy[name] = base_type.getLocalTag() - else: - self.CustomTypeHierarchy[name] = base_type.getname() - else: - if basetype_content_name == "enum": - values = [] - for value in basetype_content.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP): - values.append(value.getname()) - self.EnumeratedDataTypeValues[name] = values - self.CustomTypeHierarchy[name] = "ANY_DERIVED" - setattr(cls, "AddCustomDataType", AddCustomDataType) - # Update Block types with user-defined pou added def RefreshCustomBlockTypes(self): # Reset the tree of user-defined pou cross-use @@ -613,59 +562,12 @@ setattr(cls, "RefreshElementUsingTree", RefreshElementUsingTree) - def GetParentType(self, type): - if self.CustomTypeHierarchy.has_key(type): - return self.CustomTypeHierarchy[type] - elif TypeHierarchy.has_key(type): - return TypeHierarchy[type] - return None - setattr(cls, "GetParentType", GetParentType) - - def GetBaseType(self, type): - parent_type = self.GetParentType(type) - if parent_type is not None: - if parent_type.startswith("ANY"): - return type - else: - return self.GetBaseType(parent_type) - return None - setattr(cls, "GetBaseType", GetBaseType) - - def GetSubrangeBaseTypes(self, exclude): - derived = [] - for type in self.CustomTypeHierarchy.keys(): - for base_type in DataTypeRange.keys(): - if self.IsOfType(type, base_type) and not self.IsOfType(type, exclude): - derived.append(type) - break - return derived - setattr(cls, "GetSubrangeBaseTypes", GetSubrangeBaseTypes) - - """ - returns true if the given data type is the same that "reference" meta-type or one of its types. - """ - def IsOfType(self, type, reference): - if reference is None: - return True - elif type == reference: - return True - else: - parent_type = self.GetParentType(type) - if parent_type is not None: - return self.IsOfType(parent_type, reference) - return False - setattr(cls, "IsOfType", IsOfType) - # Return if pou given by name is used by another pou def ElementIsUsed(self, name): elements = self.ElementUsingTree.get(name, None) return elements is not None setattr(cls, "ElementIsUsed", ElementIsUsed) - def DataTypeIsDerived(self, name): - return name in self.CustomTypeHierarchy.values() - setattr(cls, "DataTypeIsDerived", DataTypeIsDerived) - # Return if pou given by name is directly or undirectly used by the reference pou def ElementIsUsedBy(self, name, reference): elements = self.ElementUsingTree.get(name, set()) @@ -682,27 +584,12 @@ return False setattr(cls, "ElementIsUsedBy", ElementIsUsedBy) - def GetDataTypeRange(self, type): - if self.CustomDataTypeRange.has_key(type): - return self.CustomDataTypeRange[type] - elif DataTypeRange.has_key(type): - return DataTypeRange[type] - else: - parent_type = self.GetParentType(type) - if parent_type is not None: - return self.GetDataTypeRange(parent_type) - return None - setattr(cls, "GetDataTypeRange", GetDataTypeRange) - - def GetEnumeratedDataTypeValues(self, type = None): - if type is None: - all_values = [] - for values in self.EnumeratedDataTypeValues.values(): - all_values.extend(values) - return all_values - elif self.EnumeratedDataTypeValues.has_key(type): - return self.EnumeratedDataTypeValues[type] - return [] + def GetEnumeratedDataTypeValues(self): + return [ + value.getname() + for value in self.xpath( + "ppx:types/ppx:dataTypes/ppx:dataType/ppx:baseType/ppx:enum/ppx:values/ppx:value", + namespaces=PLCOpenParser.NSMAP)] setattr(cls, "GetEnumeratedDataTypeValues", GetEnumeratedDataTypeValues) # Function that returns the block definition associated to the block type given @@ -734,17 +621,17 @@ # Return Function Block types checking for recursion def GetCustomFunctionBlockTypes(self, exclude = None): if exclude is not None: - return [customblocktype for name,customblocktype in self.CustomBlockTypes.iteritems() + return [name for name,customblocktype in self.CustomBlockTypes.iteritems() if (customblocktype["type"] == "functionBlock" and name != exclude and not self.ElementIsUsedBy(exclude, name))] - return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues() + return [name for customblocktype in self.CustomBlockTypes.itervalues() if customblocktype["type"] == "functionBlock"] setattr(cls, "GetCustomFunctionBlockTypes", GetCustomFunctionBlockTypes) # Return Block types checking for recursion def GetCustomBlockResource(self): - return [customblocktype for customblocktype in self.CustomBlockTypes.itervalues() + return [customblocktype["name"] for customblocktype in self.CustomBlockTypes.itervalues() if customblocktype["type"] == "program"] setattr(cls, "GetCustomBlockResource", GetCustomBlockResource) @@ -759,25 +646,6 @@ return customdatatypes setattr(cls, "GetCustomDataTypes", GetCustomDataTypes) - # Return if Data Type can be used for located variables - def IsLocatableType(self, datatype): - basetype_content = datatype.baseType.getcontent() - basetype_content_name = basetype_content.getLocalTag() - if basetype_content_name in ["enum", "struct"]: - return False - elif basetype_content_name == "derived": - base_type = self.getdataType(basetype_content.getname()) - if base_type is not None: - return self.IsLocatableType(base_type) - elif basetype_content_name == "array": - array_base_type = basetype_content.baseType.getcontent() - if array_base_type == DefaultElementClass and array_base_type.getLocalTag() not in ["string", "wstring"]: - base_type = self.getdataType(array_base_type.getname()) - if base_type is not None: - return self.IsLocatableType(base_type) - return True - setattr(cls, "IsLocatableType", IsLocatableType) - def Search(self, criteria, parent_infos=[]): result = self.types.Search(criteria, parent_infos) for configuration in self.instances.configurations.getconfiguration(): @@ -2480,7 +2348,7 @@ def filterConnections(self, connections): _filterConnectionsSingle(self, connections) condition_connection = self.getconditionConnection() - if condition_connection: + if condition_connection is not None: _filterConnections(condition_connection, self.localId, connections) setattr(cls, "filterConnections", filterConnections) @@ -2489,13 +2357,13 @@ if self.connectionPointIn is not None: connections_end = _updateConnectionsId(self.connectionPointIn, translation) condition_connection = self.getconditionConnection() - if condition_connection: + if condition_connection is not None: connections_end.extend(_updateConnectionsId(condition_connection, translation)) return _getconnectionsdefinition(self, connections_end) setattr(cls, "updateConnectionsId", updateConnectionsId) def updateElementName(self, old_name, new_name): - if self.condition: + if self.condition is not None: content = self.condition.getcontent() content_name = content.getLocalTag() if content_name == "reference": @@ -2506,7 +2374,7 @@ setattr(cls, "updateElementName", updateElementName) def updateElementAddress(self, address_model, new_leading): - if self.condition: + if self.condition is not None: content = self.condition.getcontent() content_name = content.getLocalTag() if content_name == "reference": @@ -2517,7 +2385,7 @@ def getconnections(self): condition_connection = self.getconditionConnection() - if condition_connection: + if condition_connection is not None: return condition_connection.getconnections() return None setattr(cls, "getconnections", getconnections)