# HG changeset patch # User Laurent Bessard # Date 1368522754 -7200 # Node ID 1c7a4ad86aa1f7308be355975fcc196c3e816637 # Parent d81d99fd193227906eddc4bdad3d4aa982992678 Fixed PLC code generator when interface of an already used POU has changed diff -r d81d99fd1932 -r 1c7a4ad86aa1 PLCGenerator.py --- a/PLCGenerator.py Tue May 14 10:56:57 2013 +0200 +++ b/PLCGenerator.py Tue May 14 11:12:34 2013 +0200 @@ -902,7 +902,10 @@ block_infos = self.GetBlockType(block_type) if block_infos is None: raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name) - block_infos["generate"](self, instance, block_infos, body, None) + try: + block_infos["generate"](self, instance, block_infos, body, None) + except ValueError, e: + raise PLCGenException, e.message elif isinstance(instance, plcopen.commonObjects_connector): connector = instance.getname() if self.ComputedConnectors.get(connector, None): @@ -961,7 +964,10 @@ block_infos = self.GetBlockType(block_type) if block_infos is None: raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name) - paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order, to_inout))) + try: + paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order, to_inout))) + except ValueError, e: + raise PLCGenException, e.message elif isinstance(next, plcopen.commonObjects_continuation): name = next.getname() computed_value = self.ComputedConnectors.get(name, None) diff -r d81d99fd1932 -r 1c7a4ad86aa1 plcopen/structures.py --- a/plcopen/structures.py Tue May 14 10:56:57 2013 +0200 +++ b/plcopen/structures.py Tue May 14 11:12:34 2013 +0200 @@ -46,38 +46,59 @@ name = block.getinstanceName() type = block.gettypeName() executionOrderId = block.getexecutionOrderId() + input_variables = block.inputVariables.getvariable() + output_variables = block.outputVariables.getvariable() inout_variables = {} - for input_variable in block.inputVariables.getvariable(): - for output_variable in block.outputVariables.getvariable(): + for input_variable in input_variables: + for output_variable in output_variables: if input_variable.getformalParameter() == output_variable.getformalParameter(): inout_variables[input_variable.getformalParameter()] = "" + input_names = [input[0] for input in block_infos["inputs"]] + output_names = [output[0] for output in block_infos["outputs"]] if block_infos["type"] == "function": - output_variables = block.outputVariables.getvariable() if not generator.ComputedBlocks.get(block, False) and not order: generator.ComputedBlocks[block] = True - vars = [] + connected_vars = [] + input_connected = dict([("EN", None)] + + [(input_name, None) for input_name in input_names]) + for variable in input_variables: + parameter = variable.getformalParameter() + if input_connected.has_key(parameter): + input_connected[parameter] = variable + if input_connected["EN"] is None: + input_connected.pop("EN") + input_parameters = input_names + else: + input_parameters = ["EN"] + input_names one_input_connected = False - for i, variable in enumerate(block.inputVariables.getvariable()): - input_info = (generator.TagName, "block", block.getlocalId(), "input", i) - connections = variable.connectionPointIn.getconnections() - if connections is not None: - parameter = variable.getformalParameter() - if parameter != "EN": - one_input_connected = True - if inout_variables.has_key(parameter): - value = generator.ComputeExpression(body, connections, executionOrderId > 0, True) - inout_variables[parameter] = value + all_input_connected = True + for i, parameter in enumerate(input_parameters): + variable = input_connected.get(parameter) + if variable is not None: + input_info = (generator.TagName, "block", block.getlocalId(), "input", i) + connections = variable.connectionPointIn.getconnections() + if connections is not None: + if parameter != "EN": + one_input_connected = True + if inout_variables.has_key(parameter): + value = generator.ComputeExpression(body, connections, executionOrderId > 0, True) + inout_variables[parameter] = value + else: + value = generator.ComputeExpression(body, connections, executionOrderId > 0) + connected_vars.append(([(parameter, input_info), (" := ", ())], + generator.ExtractModifier(variable, value, input_info))) else: - value = generator.ComputeExpression(body, connections, executionOrderId > 0) - if len(output_variables) > 1: - vars.append([(parameter, input_info), - (" := ", ())] + generator.ExtractModifier(variable, value, input_info)) - else: - vars.append(generator.ExtractModifier(variable, value, input_info)) + all_input_connected = False + else: + all_input_connected = False + if len(output_variables) > 1 or not all_input_connected: + vars = [name + value for name, value in connected_vars] + else: + vars = [value for name, value in connected_vars] if one_input_connected: for i, variable in enumerate(output_variables): parameter = variable.getformalParameter() - if not inout_variables.has_key(parameter): + if not inout_variables.has_key(parameter) and parameter in output_names + ["ENO"]: if variable.getformalParameter() == "": variable_name = "%s%d"%(type, block.getlocalId()) else: @@ -103,67 +124,98 @@ generator.Program += [(");\n", ())] else: generator.Warnings.append(_("\"%s\" function cancelled in \"%s\" POU: No input connected")%(type, generator.TagName.split("::")[-1])) - if link: - connectionPoint = link.getposition()[-1] - else: - connectionPoint = None - for i, variable in enumerate(output_variables): - blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() - if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety(): - output_info = (generator.TagName, "block", block.getlocalId(), "output", i) - parameter = variable.getformalParameter() - if inout_variables.has_key(parameter): - output_value = inout_variables[parameter] - else: - if parameter == "": - output_name = "%s%d"%(type, block.getlocalId()) - else: - output_name = "%s%d_%s"%(type, block.getlocalId(), parameter) - output_value = [(output_name, output_info)] - return generator.ExtractModifier(variable, output_value, output_info) elif block_infos["type"] == "functionBlock": if not generator.ComputedBlocks.get(block, False) and not order: generator.ComputedBlocks[block] = True vars = [] - for i, variable in enumerate(block.inputVariables.getvariable()): - input_info = (generator.TagName, "block", block.getlocalId(), "input", i) - connections = variable.connectionPointIn.getconnections() - if connections is not None: - parameter = variable.getformalParameter() - value = generator.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter)) - vars.append([(parameter, input_info), - (" := ", ())] + generator.ExtractModifier(variable, value, input_info)) + offset_idx = 0 + for variable in input_variables: + parameter = variable.getformalParameter() + if parameter in input_names or parameter == "EN": + if parameter == "EN": + input_idx = 0 + offset_idx = 1 + else: + input_idx = offset_idx + input_names.index(parameter) + input_info = (generator.TagName, "block", block.getlocalId(), "input", input_idx) + connections = variable.connectionPointIn.getconnections() + if connections is not None: + value = generator.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter)) + vars.append([(parameter, input_info), + (" := ", ())] + generator.ExtractModifier(variable, value, input_info)) generator.Program += [(generator.CurrentIndent, ()), (name, (generator.TagName, "block", block.getlocalId(), "name")), ("(", ())] generator.Program += JoinList([(", ", ())], vars) generator.Program += [(");\n", ())] - if link: - connectionPoint = link.getposition()[-1] + + if link: + connectionPoint = link.getposition()[-1] + output_parameter = link.getformalParameter() + else: + connectionPoint = None + output_parameter = None + + output_variable = None + output_idx = 0 + if output_parameter is not None: + if output_parameter in output_names or output_parameter == "ENO": + for variable in output_variables: + if variable.getformalParameter() == output_parameter: + output_variable = variable + if output_parameter != "ENO": + output_idx = output_names.index(output_parameter) + else: + for i, variable in enumerate(output_variables): + blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() + if (not connectionPoint or + block.getx() + blockPointx == connectionPoint.getx() and + block.gety() + blockPointy == connectionPoint.gety()): + output_variable = variable + output_parameter = variable.getformalParameter() + output_idx = i + + if output_variable is not None: + if block_infos["type"] == "function": + output_info = (generator.TagName, "block", block.getlocalId(), "output", output_idx) + if inout_variables.has_key(output_parameter): + output_value = inout_variables[output_parameter] + else: + if output_parameter == "": + output_name = "%s%d"%(type, block.getlocalId()) + else: + output_name = "%s%d_%s"%(type, block.getlocalId(), output_parameter) + output_value = [(output_name, output_info)] + return generator.ExtractModifier(output_variable, output_value, output_info) + + if block_infos["type"] == "functionBlock": + output_info = (generator.TagName, "block", block.getlocalId(), "output", output_idx) + output_name = generator.ExtractModifier(output_variable, [("%s.%s"%(name, output_parameter), output_info)], output_info) + if to_inout: + variable_name = "%s_%s"%(name, output_parameter) + if not generator.IsAlreadyDefined(variable_name): + if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] is not None or generator.Interface[-1][2]: + generator.Interface.append(("VAR", None, False, [])) + if variable.connectionPointOut in generator.ConnectionTypes: + generator.Interface[-1][3].append( + (generator.ConnectionTypes[output_variable.connectionPointOut], variable_name, None, None)) + else: + generator.Interface[-1][3].append(("ANY", variable_name, None, None)) + generator.Program += [(generator.CurrentIndent, ()), + ("%s := "%variable_name, ())] + generator.Program += output_name + generator.Program += [(";\n", ())] + return [(variable_name, ())] + return output_name + if link is not None: + if output_parameter is None: + output_parameter = "" + if name: + blockname = "%s(%s)" % (name, type) else: - connectionPoint = None - for i, variable in enumerate(block.outputVariables.getvariable()): - blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY() - if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety(): - output_info = (generator.TagName, "block", block.getlocalId(), "output", i) - output_name = generator.ExtractModifier(variable, [("%s.%s"%(name, variable.getformalParameter()), output_info)], output_info) - if to_inout: - variable_name = "%s_%s"%(name, variable.getformalParameter()) - if not generator.IsAlreadyDefined(variable_name): - if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] is not None or generator.Interface[-1][2]: - generator.Interface.append(("VAR", None, False, [])) - if variable.connectionPointOut in generator.ConnectionTypes: - generator.Interface[-1][3].append((generator.ConnectionTypes[variable.connectionPointOut], variable_name, None, None)) - else: - generator.Interface[-1][3].append(("ANY", variable_name, None, None)) - generator.Program += [(generator.CurrentIndent, ()), - ("%s := "%variable_name, ())] - generator.Program += output_name - generator.Program += [(";\n", ())] - return [(variable_name, ())] - return output_name - if link is not None: - raise ValueError, _("No output variable found") + blockname = type + raise ValueError, _("No output %s variable found in block %s in POU %s. Connection must be broken") % \ + (output_parameter, blockname, generator.Name) def initialise_block(type, name, block = None): return [(type, name, None, None)]