# HG changeset patch # User laurent # Date 1259661328 -3600 # Node ID 649a8465148d93a1e957be0b21b05b2671d67163 # Parent 2ddf7bbd1f74788c5e75e35df8fe976ac2d0b195 Adding support for updating or removing located variables by their address or leading address numbers diff -r 2ddf7bbd1f74 -r 649a8465148d plcopen/plcopen.py --- a/plcopen/plcopen.py Tue Dec 01 10:53:24 2009 +0100 +++ b/plcopen/plcopen.py Tue Dec 01 10:55:28 2009 +0100 @@ -46,6 +46,15 @@ "P" : False, "P0" : False, "P1" : False, "SD" : True, "DS" : True, "SL" : True} +FILTER_ADDRESS_MODEL = "(%%[IQM](?:[XBWDL])?)(%s)((?:\.[0-9]+)*)" + +def update_address(address, address_model, new_leading): + result = address_model.match(address) + if result is None: + return address + groups = result.groups() + return groups[0] + new_leading + groups[2] + def _init_and_compare(function, v1, v2): if v1 is None: return v2 @@ -107,6 +116,17 @@ index = self.text.find(old_name, index + len(new_name)) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + startpos = 0 + result = address_model.search(self.text, startpos) + while result is not None: + groups = result.groups() + new_address = groups[0] + new_leading + groups[2] + self.text = self.text[:result.start()] + new_address + self.text[result.end():] + startpos = result.start() + len(new_address) + result = address_model.search(self.text, startpos) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = PLCOpenClasses.get("project", None) if cls: cls.singleLineAttributes = False @@ -323,6 +343,29 @@ 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(): + pou.updateElementAddress(address_model, new_leading) + for configuration in self.instances.configurations.getconfiguration(): + configuration.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + + def removeVariableByAddress(self, address): + for pou in self.types.getpouElements(): + pou.removeVariableByAddress(address) + for configuration in self.instances.configurations.getconfiguration(): + 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(): + pou.removeVariableByFilter(address_model) + for configuration in self.instances.configurations.getconfiguration(): + configuration.removeVariableByFilter(address_model) + setattr(cls, "removeVariableByFilter", removeVariableByFilter) + def RefreshDataTypeHierarchy(self): self.EnumeratedDataTypeValues = {} self.CustomDataTypeRange = {} @@ -687,20 +730,93 @@ cls = PLCOpenClasses.get("configurations_configuration", None) if cls: def updateElementName(self, old_name, new_name): + for varlist in self.getglobalVars(): + for var in varlist.getvariable(): + var_address = var.getaddress() + if var_address is not None: + if var_address == oldname: + var.setaddress(new_name) + if var.getname() == old_name: + var.setname(new_name) for resource in self.getresource(): resource.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + for varlist in self.getglobalVars(): + for var in varlist.getvariable(): + var_address = var.getaddress() + if var_address is not None: + var.setaddress(update_address(var_address, address_model, new_leading)) + for resource in self.getresource(): + resource.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + + def removeVariableByAddress(self, address): + for varlist in self.getglobalVars(): + variables = varlist.getvariable() + for i in xrange(len(variables)-1, -1, -1): + if variables[i].getaddress() == address: + variables.pop(i) + setattr(cls, "removeVariableByAddress", removeVariableByAddress) + + def removeVariableByFilter(self, address_model): + for varlist in self.getglobalVars(): + variables = varlist.getvariable() + for i in xrange(len(variables)-1, -1, -1): + var_address = variables[i].getaddress() + if var_address is not None: + result = address_model.match(var_address) + if result is not None: + variables.pop(i) + setattr(cls, "removeVariableByFilter", removeVariableByFilter) cls = PLCOpenClasses.get("configuration_resource", None) if cls: def updateElementName(self, old_name, new_name): + for varlist in self.getglobalVars(): + for var in varlist.getvariable(): + var_address = var.getaddress() + if var_address is not None: + if var_address == oldname: + var.setaddress(new_name) + if var.getname() == old_name: + var.setname(new_name) for instance in self.getpouInstance(): instance.updateElementName(old_name, new_name) for task in self.gettask(): task.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + for varlist in self.getglobalVars(): + for var in varlist.getvariable(): + var_address = var.getaddress() + if var_address is not None: + var.setaddress(update_address(var_address, address_model, new_leading)) + for task in self.gettask(): + task.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + + def removeVariableByAddress(self, address): + for varlist in self.getglobalVars(): + variables = varlist.getvariable() + for i in xrange(len(variables)-1, -1, -1): + if variables[i].getaddress() == address: + variables.pop(i) + setattr(cls, "removeVariableByAddress", removeVariableByAddress) + + def removeVariableByFilter(self, address_model): + for varlist in self.getglobalVars(): + variables = varlist.getvariable() + for i in xrange(len(variables)-1, -1, -1): + var_address = variables[i].getaddress() + if var_address is not None: + result = address_model.match(var_address) + if result is not None: + variables.pop(i) + setattr(cls, "removeVariableByFilter", removeVariableByFilter) + cls = PLCOpenClasses.get("resource_task", None) if cls: def compatibility(self, tree): @@ -730,10 +846,19 @@ def updateElementName(self, old_name, new_name): if self.single == old_name: self.single = new_name + if self.interval == old_name: + self.interval = new_name for instance in self.getpouInstance(): instance.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + if self.single is not None: + self.single = update_address(self.single, address_model, new_leading) + if self.interval is not None: + self.interval = update_address(self.interval, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = PLCOpenClasses.get("pouInstance", None) if cls: def compatibility(self, tree): @@ -1092,6 +1217,12 @@ if self.interface: for content in self.interface.getcontent(): for var in content["value"].getvariable(): + var_address = var.getaddress() + if var_address is not None: + if var_address == oldname: + var.setaddress(new_name) + if var.getname() == old_name: + var.setname(new_name) var_type_content = var.gettype().getcontent() if var_type_content["name"] == "derived": if var_type_content["value"].getname() == old_name: @@ -1103,6 +1234,41 @@ transition.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + if self.interface: + for content in self.interface.getcontent(): + for var in content["value"].getvariable(): + var_address = var.getaddress() + if var_address is not None: + var.setaddress(update_address(var_address, address_model, new_leading)) + self.body[0].updateElementAddress(address_model, new_leading) + for action in self.getactionList(): + action.updateElementAddress(address_model, new_leading) + for transition in self.gettransitionList(): + transition.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + + def removeVariableByAddress(self, address): + if self.interface: + for content in self.interface.getcontent(): + variables = content["value"].getvariable() + for i in xrange(len(variables)-1, -1, -1): + if variables[i].getaddress() == address: + variables.pop(i) + setattr(cls, "removeVariableByAddress", removeVariableByAddress) + + def removeVariableByFilter(self, address_model): + if self.interface: + for content in self.interface.getcontent(): + variables = content["value"].getvariable() + for i in xrange(len(variables)-1, -1, -1): + var_address = variables[i].getaddress() + if var_address is not None: + result = address_model.match(var_address) + if result is not None: + variables.pop(i) + setattr(cls, "removeVariableByFilter", removeVariableByFilter) + def setbodyType(self, type): if type == "IL": self.body.setcontent({"name" : "IL", "value" : PLCOpenClasses["formattedText"]()}) @@ -1173,6 +1339,10 @@ self.body.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.body.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + def hasblock(self, name): if self.getbodyType() in ["FBD", "LD", "SFC"]: for instance in self.getinstances(): @@ -1201,6 +1371,10 @@ self.body.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.body.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + def hasblock(self, name): if self.getbodyType() in ["FBD", "LD", "SFC"]: for instance in self.getinstances(): @@ -1368,6 +1542,14 @@ element["value"].updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + if self.content["name"] in ["IL", "ST"]: + self.content["value"].updateElementAddress(address_model, new_leading) + else: + for element in self.content["value"].getcontent(): + element["value"].updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + def getx(self): return self.position.getx() @@ -1477,6 +1659,9 @@ def _updateElementName(self, old_name, new_name): pass +def _updateElementAddress(self, address_model, new_leading): + pass + _connectionsFunctions = { "bbox": {"none": _getBoundingBox, "single": _getBoundingBoxSingle, @@ -1501,6 +1686,7 @@ setattr(cls, "setx", setx) setattr(cls, "sety", sety) setattr(cls, "updateElementName", _updateElementName) + setattr(cls, "updateElementAddress", _updateElementAddress) setattr(cls, "getBoundingBox", _connectionsFunctions["bbox"][connectionPointInType]) setattr(cls, "translate", _connectionsFunctions["translate"][connectionPointInType]) setattr(cls, "filterConnections", _connectionsFunctions["filter"][connectionPointInType]) @@ -1658,6 +1844,10 @@ self.content.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.content.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("block", "fbdObjects_block") if cls: def getBoundingBox(self): @@ -1720,6 +1910,10 @@ self.variable = new_name setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.variable = update_address(self.variable, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("coil", "ldObjects_coil", "single") if cls: setattr(cls, "getinfos", _getldelementinfosFunction("coil")) @@ -1729,6 +1923,10 @@ self.variable = new_name setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.variable = update_address(self.variable, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("step", "sfcObjects_step", "single") if cls: def getinfos(self): @@ -1825,6 +2023,15 @@ content["value"].updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + if self.condition: + content = self.condition.getcontent() + if content["name"] == "reference": + content["value"].setname(update_address(content["value"].getname(), address_model, new_leading)) + elif content["name"] == "inline": + content["value"].updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + def getconnections(self): if self.condition: content = self.condition.getcontent() @@ -1901,6 +2108,13 @@ self.inline.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + if self.reference: + self.reference.setname(update_address(self.reference.getname(), address_model, new_leading)) + if self.inline: + self.inline.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("actionBlock", "commonObjects_actionBlock", "single") if cls: def compatibility(self, tree): @@ -1963,6 +2177,11 @@ action.updateElementName(old_name, new_name) setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + for action in self.action: + action.updateElementAddress(address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("inVariable", "fbdObjects_inVariable") if cls: setattr(cls, "getinfos", _getvariableinfosFunction("input", False, True)) @@ -1972,6 +2191,10 @@ self.expression = new_name setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.expression = update_address(self.expression, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("outVariable", "fbdObjects_outVariable", "single") if cls: setattr(cls, "getinfos", _getvariableinfosFunction("output", True, False)) @@ -1981,6 +2204,10 @@ self.expression = new_name setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.expression = update_address(self.expression, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("inOutVariable", "fbdObjects_inOutVariable", "single") if cls: setattr(cls, "getinfos", _getvariableinfosFunction("inout", True, True)) @@ -1990,6 +2217,10 @@ self.expression = new_name setattr(cls, "updateElementName", updateElementName) + def updateElementAddress(self, address_model, new_leading): + self.expression = update_address(self.expression, address_model, new_leading) + setattr(cls, "updateElementAddress", updateElementAddress) + cls = _initElementClass("continuation", "commonObjects_continuation") if cls: setattr(cls, "getinfos", _getconnectorinfosFunction("continuation"))