# HG changeset patch # User Laurent Bessard # Date 1377796721 -7200 # Node ID f02ba5b83811ba48bdcc1422253f1aa75ed6b6dc # Parent 40117d02601b896134fe9d5e7583d7f891ae0135 Fixed datatype and configuration editing in xmlclass refactoring diff -r 40117d02601b -r f02ba5b83811 PLCControler.py --- a/PLCControler.py Thu Aug 29 00:28:39 2013 +0200 +++ b/PLCControler.py Thu Aug 29 19:18:41 2013 +0200 @@ -1232,7 +1232,7 @@ else: tempvar.setaddress(None) if var['Documentation'] != "": - ft = plcopen.formattedText() + ft = PLCOpenParser.CreateElement("documentation", "variable") ft.setanyText(var['Documentation']) tempvar.setdocumentation(ft) @@ -1366,7 +1366,7 @@ if project is not None: # Found the resource corresponding to name resource = project.getconfigurationResource(config_name, name) - if resource: + if resource is not None: # Extract variables from every varLists for varlist in resource.getglobalVars(): for var in varlist.getvariable(): @@ -1483,7 +1483,7 @@ pou.interface = PLCOpenParser.CreateElement("interface", "pou") # If there isn't any return type yet, add it return_type_obj = pou.interface.getreturnType() - if not return_type_obj: + if return_type_obj is None: return_type_obj = PLCOpenParser.CreateElement("returnType", "interface") pou.interface.setreturnType(return_type_obj) # Change return type @@ -1500,12 +1500,12 @@ self.Project.RefreshCustomBlockTypes() def UpdateProjectUsedPous(self, old_name, new_name): - if self.Project: + if self.Project is not None: self.Project.updateElementName(old_name, new_name) def UpdateEditedElementUsedVariable(self, tagname, old_name, new_name): pou = self.GetEditedElement(tagname) - if pou: + if pou is not None: pou.updateElementName(old_name, new_name) # Return the return type of the pou given by its name @@ -1938,21 +1938,23 @@ derived_datatype.setname(infos["base_type"]) datatype.baseType.setcontent(derived_datatype) elif infos["type"] == "Subrange": - datatype.baseType.setcontent(PLCOpenParser.CreateElement( + subrange = PLCOpenParser.CreateElement( "subrangeUnsigned" if infos["base_type"] in GetSubTypes("ANY_UINT") - else "subrangeSigned", "dataType")) + else "subrangeSigned", "dataType") + datatype.baseType.setcontent(subrange) subrange.range.setlower(infos["min"]) subrange.range.setupper(infos["max"]) if infos["base_type"] in self.GetBaseTypes(): subrange.baseType.setcontent( - PLCOpenParser.CreateElement(infos["base_type"])) + PLCOpenParser.CreateElement(infos["base_type"], "dataType")) else: derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") derived_datatype.setname(infos["base_type"]) subrange.baseType.setcontent(derived_datatype) elif infos["type"] == "Enumerated": enumerated = PLCOpenParser.CreateElement("enum", "dataType") + datatype.baseType.setcontent(enumerated) values = PLCOpenParser.CreateElement("values", "enum") enumerated.setvalues(values) for i, enum_value in enumerate(infos["values"]): @@ -1962,9 +1964,9 @@ values.setvalue([value]) else: values.appendvalue(value) - datatype.baseType.setcontent(enumerated) elif infos["type"] == "Array": array = PLCOpenParser.CreateElement("array", "dataType") + datatype.baseType.setcontent(array) for i, dimension in enumerate(infos["dimensions"]): dimension_range = PLCOpenParser.CreateElement("dimension", "array") dimension_range.setlower(dimension[0]) @@ -1982,9 +1984,9 @@ derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") derived_datatype.setname(infos["base_type"]) array.baseType.setcontent(derived_datatype) - datatype.baseType.setcontent(array) elif infos["type"] == "Structure": struct = PLCOpenParser.CreateElement("struct", "dataType") + datatype.baseType.setcontent(struct) for i, element_infos in enumerate(infos["elements"]): element = PLCOpenParser.CreateElement("variable", "struct") element.setname(element_infos["Name"]) @@ -1993,6 +1995,7 @@ if element_infos["Type"][0] == "array": array_type, base_type_name, dimensions = element_infos["Type"] array = PLCOpenParser.CreateElement("array", "dataType") + element_type.setcontent(array) for j, dimension in enumerate(dimensions): dimension_range = PLCOpenParser.CreateElement("dimension", "array") dimension_range.setlower(dimension[0]) @@ -2010,7 +2013,6 @@ derived_datatype = PLCOpenParser.CreateElement("derived", "dataType") derived_datatype.setname(base_type_name) array.baseType.setcontent(derived_datatype) - element_type.setcontent(array) elif element_infos["Type"] in self.GetBaseTypes(): element_type.setcontent( PLCOpenParser.CreateElement( @@ -2030,7 +2032,6 @@ struct.setvariable([element]) else: struct.appendvariable(element) - datatype.baseType.setcontent(struct) if infos["initial"] != "": if datatype.initialValue is None: datatype.initialValue = PLCOpenParser.CreateElement("initialValue", "dataType") @@ -2705,18 +2706,13 @@ variable.text = value contact.setvariable(variable) elif param == "type": - if value == CONTACT_NORMAL: - contact.setnegated(False) - contact.setedge("none") - elif value == CONTACT_REVERSE: - contact.setnegated(True) - contact.setedge("none") - elif value == CONTACT_RISING: - contact.setnegated(False) - contact.setedge("rising") - elif value == CONTACT_FALLING: - contact.setnegated(False) - contact.setedge("falling") + negated, edge = { + CONTACT_NORMAL: (False, "none"), + CONTACT_REVERSE: (True, "none"), + CONTACT_RISING: (False, "rising"), + CONTACT_FALLING: (False, "falling")}[value] + contact.setnegated(negated) + contact.setedge(edge) elif param == "height": contact.setheight(value) elif param == "width": @@ -2755,30 +2751,16 @@ variable.text = value coil.setvariable(variable) elif param == "type": - if value == COIL_NORMAL: - coil.setnegated(False) - coil.setstorage("none") - coil.setedge("none") - elif value == COIL_REVERSE: - coil.setnegated(True) - coil.setstorage("none") - coil.setedge("none") - elif value == COIL_SET: - coil.setnegated(False) - coil.setstorage("set") - coil.setedge("none") - elif value == COIL_RESET: - coil.setnegated(False) - coil.setstorage("reset") - coil.setedge("none") - elif value == COIL_RISING: - coil.setnegated(False) - coil.setstorage("none") - coil.setedge("rising") - elif value == COIL_FALLING: - coil.setnegated(False) - coil.setstorage("none") - coil.setedge("falling") + negated, storage, edge = { + COIL_NORMAL: (False, "none", "none"), + COIL_REVERSE: (True, "none", "none"), + COIL_SET: (False, "set", "none"), + COIL_RESET: (False, "reset", "none"), + COIL_RISING: (False, "none", "rising"), + COIL_FALLING: (False, "none", "falling")}[value] + coil.setnegated(negated) + coil.setstorage(storage) + coil.setedge(edge) elif param == "height": coil.setheight(value) elif param == "width": @@ -3046,7 +3028,8 @@ resource.setpouInstance([]) task_list = {} for task in tasks: - new_task = plcopen.resource_task() + new_task = PLCOpenParser.CreateElement("task", "resource") + resource.appendtask(new_task) new_task.setname(task["Name"]) if task["Triggering"] == "Interrupt": new_task.setsingle(task["Single"]) @@ -3066,12 +3049,16 @@ new_task.setpriority(int(task["Priority"])) if task["Name"] != "": task_list[task["Name"]] = new_task - resource.appendtask(new_task) for instance in instances: - new_instance = plcopen.pouInstance() + task = task_list.get(instance["Task"]) + if task is not None: + new_instance = PLCOpenParser.CreateElement("pouInstance", "task") + task.appendpouInstance(new_instance) + else: + new_instance = PLCOpenParser.CreateElement("pouInstance", "resource") + resource.appendpouInstance(new_instance) new_instance.setname(instance["Name"]) new_instance.settypeName(instance["Type"]) - task_list.get(instance["Task"], resource).appendpouInstance(new_instance) def GetEditedResourceInfos(self, tagname, debug = False): resource = self.GetEditedElement(tagname, debug) diff -r 40117d02601b -r f02ba5b83811 plcopen/plcopen.py --- a/plcopen/plcopen.py Thu Aug 29 00:28:39 2013 +0200 +++ b/plcopen/plcopen.py Thu Aug 29 19:18:41 2013 +0200 @@ -127,11 +127,13 @@ def LoadProject(filepath): project_file = open(filepath) - project_xml = project_file.read()\ - .replace("http://www.plcopen.org/xml/tc6.xsd", - "http://www.plcopen.org/xml/tc6_0201")\ - .replace("", "]]>") + project_xml = project_file.read().replace( + "http://www.plcopen.org/xml/tc6.xsd", + "http://www.plcopen.org/xml/tc6_0201") + for cre, repl in [ + (re.compile("(?)(?:)(?!)"), "]]>")]: + project_xml = cre.sub(repl, project_xml) project_file.close() return etree.fromstring(project_xml, PLCOpenParser) @@ -148,7 +150,7 @@ cls = PLCOpenParser.GetElementClass("formattedText") if cls: def updateElementName(self, old_name, new_name): - text = self.text + text = self.getanyText() index = text.find(old_name) while index != -1: if index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_"): @@ -158,11 +160,11 @@ else: text = text[:index] + new_name + text[index + len(old_name):] index = text.find(old_name, index + len(new_name)) - self.text = text + self.setanyText(text) setattr(cls, "updateElementName", updateElementName) def updateElementAddress(self, address_model, new_leading): - text = self.text + text = self.getanyText() startpos = 0 result = address_model.search(text, startpos) while result is not None: @@ -171,11 +173,11 @@ text = text[:result.start()] + new_address + text[result.end():] startpos = result.start() + len(new_address) result = address_model.search(self.text, startpos) - self.text = text + self.setanyText(text) setattr(cls, "updateElementAddress", updateElementAddress) def hasblock(self, block_type): - text = self.text.upper() + text = self.getanyText().upper() index = text.find(block_type.upper()) while index != -1: if (not (index > 0 and (text[index - 1].isalnum() or text[index - 1] == "_")) and @@ -326,7 +328,7 @@ def getconfigurations(self): configurations = self.instances.configurations.getconfiguration() - if configurations: + if configurations is not None: return configurations return [] setattr(cls, "getconfigurations", getconfigurations) @@ -360,7 +362,7 @@ def getconfigurationResource(self, config_name, name): configuration = self.getconfiguration(config_name) - if configuration: + if configuration is not None: for resource in configuration.getresource(): if resource.getname() == name: return resource @@ -369,7 +371,7 @@ def addconfigurationResource(self, config_name, name): configuration = self.getconfiguration(config_name) - if configuration: + 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) @@ -380,7 +382,7 @@ def removeconfigurationResource(self, config_name, name): configuration = self.getconfiguration(config_name) - if configuration: + if configuration is not None: found = False for idx, resource in enumerate(configuration.getresource()): if resource.getname() == name: @@ -447,7 +449,7 @@ self.CustomDataTypeRange[name] = range base_type = basetype_content.baseType.getcontent() if base_type.__class__ == DefaultElementClass: - self.CustomTypeHierarchy[name] = basetype.getLocalTag() + self.CustomTypeHierarchy[name] = base_type.getLocalTag() else: self.CustomTypeHierarchy[name] = base_type.getname() else: @@ -880,7 +882,7 @@ if location != "": var.setaddress(location) if description != "": - ft = PLCOpenParser.CreateElement("formattedText") + ft = PLCOpenParser.CreateElement("documentation", "variable") ft.setanyText(description) var.setdocumentation(ft) globalvars[-1].appendvariable(var) @@ -1081,7 +1083,7 @@ new_datatype = PLCOpenParser.CreateElement("dataType", "dataTypes") self.dataTypes.appenddataType(new_datatype) new_datatype.setname(name) - new_datatype.baseType.setcontent(PLCOpenParser.CreateElement("BOOL")) + new_datatype.baseType.setcontent(PLCOpenParser.CreateElement("BOOL", "dataType")) setattr(cls, "appenddataTypeElement", appenddataTypeElement) def insertdataTypeElement(self, index, dataType): @@ -1183,9 +1185,9 @@ search_result = [] content_name = self.content.getLocalTag() if content_name in ["derived", "array", "enum", "subrangeSigned", "subrangeUnsigned"]: - search_result.extend(self.content["value"].Search(criteria, parent_infos)) + search_result.extend(self.content.Search(criteria, parent_infos + ["base"])) elif content_name == "struct": - for i, element in enumerate(self.content["value"].getvariable()): + for i, element in enumerate(self.content.getvariable()): search_result.extend(element.Search(criteria, parent_infos + ["struct", i])) else: if content_name in ["string", "wstring"]: @@ -1194,6 +1196,17 @@ return search_result setattr(cls, "Search", Search) +cls = PLCOpenParser.GetElementClass("derived", "dataType") +if cls: + def updateElementName(self, old_name, new_name): + if self.name == old_name: + self.name = new_name + setattr(cls, "updateElementName", updateElementName) + + def Search(self, criteria, parent_infos=[]): + return [(tuple(parent_infos),) + result for result in TestTextElement(self.name, criteria)] + setattr(cls, "Search", Search) + cls = PLCOpenParser.GetElementClass("array", "dataType") if cls: setattr(cls, "updateElementName", _updateBaseTypeElementName) @@ -1233,7 +1246,7 @@ def Search(self, criteria, parent_infos=[]): search_result = [] - for i, value in enumerate(self.values.getvalue()): + for i, value in enumerate(self.xpath("ppx:values/ppx:value", namespaces=PLCOpenParser.NSMAP)): for result in TestTextElement(value.getname(), criteria): search_result.append((tuple(parent_infos + ["value", i]),) + result) return search_result @@ -1245,7 +1258,7 @@ def setdescription(self, description): doc = self.getdocumentation() if doc is None: - doc = PLCOpenParser.CreateElement("formattedText") + doc = PLCOpenParser.CreateElement("documentation", "pou") self.setdocumentation(doc) doc.setanyText(description) setattr(cls, "setdescription", setdescription) @@ -1359,16 +1372,21 @@ if self.interface is None: self.interface = PLCOpenParser.CreateElement("interface", "pou") content = self.interface.getcontent() - if len(content) == 0 or content[-1]["name"] != var_class: - self.appendcontent(PLCOpenParser.CreateElement(var_class, "interface")) + if len(content) == 0: + varlist = PLCOpenParser.CreateElement(var_class, "interface") + self.interface.setcontent([varlist]) + elif content[-1] != var_class: + varlist = PLCOpenParser.CreateElement(var_class, "interface") + content[-1].addnext(varlist) else: - varlist = content[-1]["value"] + varlist = content[-1] variables = varlist.getvariable() if varlist.getconstant() or varlist.getretain() or len(variables) > 0 and variables[0].getaddress(): - self.appendcontent(PLCOpenParser.CreateElement(var_class, "interface")) + varlist = PLCOpenParser.CreateElement(var_class, "interface") + content[-1].addnext(varlist) var = PLCOpenParser.CreateElement("variable", "varListPlain") var.setname(name) - var_type_obj = PLCOpenParser.CreateElement("dataType") + var_type_obj = PLCOpenParser.CreateElement("type", "variable") if var_type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]: var_type_obj.setcontent(PLCOpenParser.CreateElement( var_type.lower() if var_type in ["STRING", "WSTRING"] @@ -1381,18 +1399,18 @@ if location != "": var.setaddress(location) if description != "": - ft = PLCOpenParser.GetElementClass("formattedText")() + ft = PLCOpenParser.CreateElement("documentation", "variable") ft.setanyText(description) var.setdocumentation(ft) - content[-1]["value"].appendvariable(var) + varlist.appendvariable(var) setattr(cls, "addpouVar", addpouVar) def changepouVar(self, old_type, old_name, new_type, new_name): if self.interface is not None: content = self.interface.getcontent() for varlist in content: - variables = varlist["value"].getvariable() + variables = varlist.getvariable() for var in variables: if var.getname() == old_name: vartype_content = var.gettype().getcontent() @@ -1785,7 +1803,7 @@ setattr(cls, "compileelementExecutionOrder", compileelementExecutionOrder) def setelementExecutionOrder(self, instance, new_executionOrder): - if self.contentLgetLocalTag() == "FBD": + if self.content.getLocalTag() == "FBD": old_executionOrder = instance.getexecutionOrderId() if old_executionOrder is not None and old_executionOrder != 0 and new_executionOrder != 0: for element in self.content.getcontent(): @@ -2148,7 +2166,7 @@ _getexecutionOrder(self, specific_values) specific_values["negated"] = self.getnegated() specific_values["edge"] = self.getedge() - if type == "coil": + if ld_element_type == "coil": specific_values["storage"] = self.getstorage() infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) @@ -2350,9 +2368,9 @@ condition = self.getconditionContent() specific_values["condition_type"] = condition["type"] if specific_values["condition_type"] == "connection": - specific_values["connection"] = _getconnectioninfos(self, condition["value"], True) + specific_values["connection"] = _getconnectioninfos(self, condition, True) else: - specific_values["condition"] = condition["value"] + specific_values["condition"] = condition infos["inputs"].append(_getconnectioninfos(self, self.connectionPointIn, True)) infos["outputs"].append(_getconnectioninfos(self, self.connectionPointOut)) return infos diff -r 40117d02601b -r f02ba5b83811 xmlclass/xmlclass.py --- a/xmlclass/xmlclass.py Thu Aug 29 00:28:39 2013 +0200 +++ b/xmlclass/xmlclass.py Thu Aug 29 19:18:41 2013 +0200 @@ -536,17 +536,16 @@ def GenerateAnyInfos(infos): + def GetTextElement(tree): + if infos["namespace"][0] == "##any": + return tree.xpath("p")[0] + return tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0] + def ExtractAny(tree): - if infos["namespace"][0] == "##any": - return tree.xpath("p/text()")[0] - return tree.xpath("ns:p/text()", namespaces={"ns": infos["namespace"][0]})[0] + return GetTextElement(tree).text def GenerateAny(tree, value): - if infos["namespace"][0] == "##any": - p = tree.xpath("p")[0] - else: - p = tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0] - p.text = etree.CDATA(value) + GetTextElement(tree).text = etree.CDATA(value) def InitialAny(): if infos["namespace"][0] == "##any": @@ -1395,7 +1394,9 @@ return attribute_infos["attr_type"]["extract"](value, extract=False) elif attribute_infos.has_key("fixed"): return attribute_infos["attr_type"]["extract"](attribute_infos["fixed"], extract=False) - return attribute_infos["attr_type"]["initial"]() + elif attribute_infos.has_key("default"): + return attribute_infos["attr_type"]["extract"](attribute_infos["default"], extract=False) + return None elif elements.has_key(name): element_infos = elements[name] @@ -1460,13 +1461,17 @@ self.remove(element) if value is not None: - previous_elements_xpath = "|".join(map( - lambda x: "%s:%s" % (factory.TargetNamespace, x) - if x != "content" - else elements["content"]["elmt_type"]["choices_xpath"](), - elements.keys()[elements.keys().index(name)])) - - insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP)) + element_idx = elements.keys().index(name) + if element_idx > 0: + previous_elements_xpath = "|".join(map( + lambda x: "%s:%s" % (factory.TargetNamespace, x) + if x != "content" + else elements["content"]["elmt_type"]["choices_xpath"](), + elements.keys()[:element_idx])) + + insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP)) + else: + insertion_point = 0 if not isinstance(value, ListType): value = [value]