Bug when using arithmetic functions (ADD, SUB, MUL, DIV) for TIME datatypes fixed.
authorlaurent
Tue, 05 Apr 2011 19:08:22 +0200
changeset 526 79900abdfa3c
parent 525 e8d5ab0855d3
child 527 e307e1b27828
Bug when using arithmetic functions (ADD, SUB, MUL, DIV) for TIME datatypes fixed.
PLCControler.py
PLCGenerator.py
graphics/FBD_Objects.py
plcopen/structures.py
--- a/PLCControler.py	Tue Apr 05 19:06:00 2011 +0200
+++ b/PLCControler.py	Tue Apr 05 19:08:22 2011 +0200
@@ -595,6 +595,7 @@
             pou = self.Project.getpou(name)
             if pou is not None:
                 pou.setpouType(pou_type)
+                self.Project.RefreshCustomBlockTypes()
                 self.BufferProject()
                 
     def GetPouXml(self, pou_name):
@@ -1211,15 +1212,25 @@
 
     # Function that returns the block definition associated to the block type given
     def GetBlockType(self, type, inputs = None, debug = False):
+        result_blocktype = None
         for category in BlockTypes + self.PluginTypes:
             for blocktype in category["list"]:
-                if inputs:
-                    block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
-                    same_inputs = inputs == block_inputs
-                else:
-                    same_inputs = True
-                if blocktype["name"] == type and same_inputs:
-                    return blocktype
+                if blocktype["name"] == type:
+                    if inputs is not None and inputs != "undefined":
+                        block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
+                        if reduce(lambda x, y: x and y, map(lambda x: x[0] == "ANY" or self.IsOfType(*x), zip(inputs, block_inputs))):
+                            return blocktype
+                    else:
+                        if result_blocktype is not None:
+                            if inputs == "undefined":
+                                return None
+                            else:
+                                result_blocktype["inputs"] = [(i[0], "ANY", i[2]) for i in result_blocktype["inputs"]]
+                                result_blocktype["outputs"] = [(o[0], "ANY", o[2]) for o in result_blocktype["outputs"]]
+                                return result_blocktype
+                        result_blocktype = blocktype
+        if result_blocktype is not None:
+            return result_blocktype
         project = self.GetProject(debug)
         if project is not None:
             return project.GetCustomBlockType(type, inputs)
--- a/PLCGenerator.py	Tue Apr 05 19:06:00 2011 +0200
+++ b/PLCGenerator.py	Tue Apr 05 19:08:22 2011 +0200
@@ -486,8 +486,8 @@
         self.Errors = errors
         self.Warnings = warnings
     
-    def GetBlockType(self, type):
-        return self.ParentGenerator.Controler.GetBlockType(type)
+    def GetBlockType(self, type, inputs=None):
+        return self.ParentGenerator.Controler.GetBlockType(type, inputs)
     
     def IndentLeft(self):
         if len(self.CurrentIndent) >= 2:
@@ -657,6 +657,7 @@
         body_content = body.getcontent()
         body_type = body_content["name"]
         if body_type in ["FBD", "LD", "SFC"]:
+            undefined_blocks = []
             for instance in body.getcontentInstances():
                 if isinstance(instance, (plcopen.fbdObjects_inVariable, plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
                     expression = instance.getexpression()
@@ -741,57 +742,77 @@
                     else:
                         raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name)
                 elif isinstance(instance, plcopen.fbdObjects_block):
-                    block_infos = self.GetBlockType(instance.gettypeName())
+                    block_infos = self.GetBlockType(instance.gettypeName(), "undefined")
                     if block_infos is not None:
-                        undefined = {}
-                        for variable in instance.outputVariables.getvariable():
-                            output_name = variable.getformalParameter()
-                            if output_name == "ENO":
-                                for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
-                                    self.ConnectionTypes[connection] = "BOOL"
-                            else:
-                                for oname, otype, oqualifier in block_infos["outputs"]:
-                                    if output_name == oname:
-                                        if otype.startswith("ANY"):
-                                            if not undefined.has_key(otype):
-                                                undefined[otype] = []
-                                            undefined[otype].append(variable.connectionPointOut)
-                                        elif not self.ConnectionTypes.has_key(variable.connectionPointOut):
-                                            for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
-                                                self.ConnectionTypes[connection] = otype
+                        self.ComputeBlockInputTypes(instance, block_infos, body)
+                    else:
                         for variable in instance.inputVariables.getvariable():
-                            input_name = variable.getformalParameter()
-                            if input_name == "EN":
-                                for connection in self.ExtractRelatedConnections(variable.connectionPointIn):
-                                    self.ConnectionTypes[connection] = "BOOL"
-                            for iname, itype, iqualifier in block_infos["inputs"]:
-                                if input_name == iname:
-                                    connected = self.GetConnectedConnector(variable.connectionPointIn, body)
-                                    if itype.startswith("ANY"):
-                                        if not undefined.has_key(itype):
-                                            undefined[itype] = []
-                                        undefined[itype].append(variable.connectionPointIn)
-                                        if connected:
-                                            undefined[itype].append(connected)
-                                    else:
-                                        self.ConnectionTypes[variable.connectionPointIn] = itype
-                                        if connected and not self.ConnectionTypes.has_key(connected):
-                                            for connection in self.ExtractRelatedConnections(connected):
-                                                self.ConnectionTypes[connection] = itype
-                        for var_type, connections in undefined.items():
-                            related = []
-                            for connection in connections:
-                                if self.ConnectionTypes.has_key(connection):
-                                    var_type = self.ConnectionTypes[connection]
+                            connected = self.GetConnectedConnector(variable.connectionPointIn, body)
+                            if connected is not None:
+                                var_type = self.ConnectionTypes.get(connected, None)
+                                if var_type is not None:
+                                    self.ConnectionTypes[variable.connectionPointIn] = var_type
                                 else:
-                                    related.extend(self.ExtractRelatedConnections(connection))
-                            if var_type.startswith("ANY") and len(related) > 0:
-                                self.RelatedConnections.append(related)
-                            else:
-                                for connection in related:
-                                    self.ConnectionTypes[connection] = var_type
-                    else:
-                        raise PLCGenException, _("No informations found for \"%s\" block")%(instance.gettypeName())
+                                    related = self.ExtractRelatedConnections(connected)
+                                    related.append(variable.connectionPointIn)
+                                    self.RelatedConnections.append(related)
+                        undefined_blocks.append(instance)
+            for instance in undefined_blocks:
+                block_infos = self.GetBlockType(instance.gettypeName(), tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable()]))
+                if block_infos is not None:
+                    self.ComputeBlockInputTypes(instance, block_infos, body)
+                else:
+                    raise PLCGenException, _("No informations found for \"%s\" block")%(instance.gettypeName())
+                
+    def ComputeBlockInputTypes(self, instance, block_infos, body):
+        undefined = {}
+        for variable in instance.outputVariables.getvariable():
+            output_name = variable.getformalParameter()
+            if output_name == "ENO":
+                for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
+                    self.ConnectionTypes[connection] = "BOOL"
+            else:
+                for oname, otype, oqualifier in block_infos["outputs"]:
+                    if output_name == oname:
+                        if otype.startswith("ANY"):
+                            if not undefined.has_key(otype):
+                                undefined[otype] = []
+                            undefined[otype].append(variable.connectionPointOut)
+                        elif not self.ConnectionTypes.has_key(variable.connectionPointOut):
+                            for connection in self.ExtractRelatedConnections(variable.connectionPointOut):
+                                self.ConnectionTypes[connection] = otype
+        for variable in instance.inputVariables.getvariable():
+            input_name = variable.getformalParameter()
+            if input_name == "EN":
+                for connection in self.ExtractRelatedConnections(variable.connectionPointIn):
+                    self.ConnectionTypes[connection] = "BOOL"
+            else:
+                for iname, itype, iqualifier in block_infos["inputs"]:
+                    if input_name == iname:
+                        connected = self.GetConnectedConnector(variable.connectionPointIn, body)
+                        if itype.startswith("ANY"):
+                            if not undefined.has_key(itype):
+                                undefined[itype] = []
+                            undefined[itype].append(variable.connectionPointIn)
+                            if connected:
+                                undefined[itype].append(connected)
+                        else:
+                            self.ConnectionTypes[variable.connectionPointIn] = itype
+                            if connected and not self.ConnectionTypes.has_key(connected):
+                                for connection in self.ExtractRelatedConnections(connected):
+                                    self.ConnectionTypes[connection] = itype
+        for var_type, connections in undefined.items():
+            related = []
+            for connection in connections:
+                if self.ConnectionTypes.has_key(connection):
+                    var_type = self.ConnectionTypes[connection]
+                else:
+                    related.extend(self.ExtractRelatedConnections(connection))
+            if var_type.startswith("ANY") and len(related) > 0:
+                self.RelatedConnections.append(related)
+            else:
+                for connection in related:
+                    self.ConnectionTypes[connection] = var_type
 
     def ComputeProgram(self, pou):
         body = pou.getbody()
@@ -857,8 +878,8 @@
                 elif isinstance(instance, plcopen.fbdObjects_block):
                     block_type = instance.gettypeName()
                     self.ParentGenerator.GeneratePouProgram(block_type)
-                    block_infos = self.GetBlockType(block_type)
-                    block_infos["generate"](self, instance, body, None)
+                    block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable()]))
+                    block_infos["generate"](self, instance, block_infos, body, None)
                 elif isinstance(instance, plcopen.commonObjects_connector):
                     connector = instance.getname()
                     if self.ComputedConnectors.get(connector, None):
@@ -912,8 +933,8 @@
             elif isinstance(next, plcopen.fbdObjects_block):
                 block_type = next.gettypeName()
                 self.ParentGenerator.GeneratePouProgram(block_type)
-                block_infos = self.GetBlockType(block_type)
-                paths.append(str(block_infos["generate"](self, next, body, connection, order)))
+                block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable()]))
+                paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order)))
             elif isinstance(next, plcopen.commonObjects_continuation):
                 name = next.getname()
                 computed_value = self.ComputedConnectors.get(name, None)
--- a/graphics/FBD_Objects.py	Tue Apr 05 19:06:00 2011 +0200
+++ b/graphics/FBD_Objects.py	Tue Apr 05 19:08:22 2011 +0200
@@ -188,19 +188,24 @@
     
     def GetConnectionResultType(self, connector, connectortype):
         resulttype = connectortype
+        undefined = True
         for input in self.Inputs:
             name = input.GetName()
+            undefined = undefined and input.GetType(True) == "ANY"
             if input != connector and (name.startswith("IN") or name in ["MN", "MX"]):
                 inputtype = input.GetConnectedType()
                 if resulttype is None or inputtype is not None and self.IsOfType(inputtype, resulttype):
                     resulttype = inputtype
         for output in self.Outputs:
             name = output.GetName()
+            undefined = undefined and output.GetType(True) == "ANY"
             if output != connector and name == "OUT" and not self.IsEndType(output.GetType()):
                 outputtype = output.GetConnectedType()
                 if resulttype is None or outputtype is not None and self.IsOfType(outputtype, resulttype):
                     resulttype = outputtype
-        return resulttype
+        if not undefined:
+            return resulttype
+        return "ANY"
     
     # Returns all the block connectors
     def GetConnectors(self):
--- a/plcopen/structures.py	Tue Apr 05 19:06:00 2011 +0200
+++ b/plcopen/structures.py	Tue Apr 05 19:08:22 2011 +0200
@@ -42,12 +42,11 @@
     else :
         return mylist
 
-def generate_block(generator, block, body, link, order=False):
+def generate_block(generator, block, block_infos, body, link, order=False):
     body_type = body.getcontent()["name"]
     name = block.getinstanceName()
     type = block.gettypeName()
     executionOrderId = block.getexecutionOrderId()
-    block_infos = generator.GetBlockType(type)
     if block_infos["type"] == "function":
         output_variables = block.outputVariables.getvariable()
         if not generator.ComputedBlocks.get(block, False) and not order: