def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""): unPrintedNodes = [] unPrintedRefs = [] code = [] header = [] # Reorder our nodes to produce a bare minimum of bootstrapping dependencies log(self, "Reordering nodes for minimal dependencies during printing.") self.reorderNodesMinDependencies() # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but # bulky. This class will help to offload some code. codegen = open62541_MacroHelper(supressGenerationOfAttribute=supressGenerationOfAttribute) # Populate the unPrinted-Lists with everything we have. # Every Time a nodes printfunction is called, it will pop itself and # all printed references from these lists. for n in self.nodes: if not n in printedExternally: unPrintedNodes.append(n) else: log(self, "Node " + str(n.id()) + " is being ignored.", LOG_LEVEL_DEBUG) for n in unPrintedNodes: for r in n.getReferences(): if (r.target() != None) and (r.target().id() != None) and (r.parent() != None): unPrintedRefs.append(r) log(self, str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) + "References need to get printed.", LOG_LEVEL_DEBUG) header.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") header.append('#ifndef '+outfilename.upper()+'_H_') header.append('#define '+outfilename.upper()+'_H_') header.append('#ifdef UA_NO_AMALGAMATION') header.append('#include "server/ua_server_internal.h"') header.append('#include "server/ua_nodes.h"') header.append('#include "ua_util.h"') header.append('#include "ua_types.h"') header.append('#include "ua_types_encoding_binary.h"') header.append('#include "ua_types_generated_encoding_binary.h"') header.append('#include "ua_transport_generated_encoding_binary.h"') header.append('#else') header.append('#include "open62541.h"') header.append('#define NULL ((void *)0)') header.append('#endif') code.append('#include "'+outfilename+'.h"') code.append("UA_INLINE void "+outfilename+"(UA_Server *server) {") # Before printing nodes, we need to request additional namespace arrays from the server for nsid in self.namespaceIdentifiers: if nsid == 0 or nsid==1: continue else: name = self.namespaceIdentifiers[nsid] name = name.replace("\"","\\\"") code.append("UA_Server_addNamespace(server, \"" + name.encode('UTF-8') + "\");") # Find all references necessary to create the namespace and # "Bootstrap" them so all other nodes can safely use these referencetypes whenever # they can locate both source and target of the reference. log(self, "Collecting all references used in the namespace.", LOG_LEVEL_DEBUG) refsUsed = [] for n in self.nodes: # Since we are already looping over all nodes, use this chance to print NodeId defines if n.id().ns != 0: nc = n.nodeClass() if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW: header = header + codegen.getNodeIdDefineString(n) # Now for the actual references... for r in n.getReferences(): # Only print valid refernces in namespace 0 (users will not want their refs bootstrapped) if not r.referenceType() in refsUsed and r.referenceType() != None and r.referenceType().id().ns == 0: refsUsed.append(r.referenceType()) log(self, str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.", LOG_LEVEL_DEBUG) for r in refsUsed: code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs); header.append("extern void "+outfilename+"(UA_Server *server);\n") header.append("#endif /* "+outfilename.upper()+"_H_ */") # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes! # Nodes remove themselves from this list when printed. log(self, "Printing all other nodes.", LOG_LEVEL_DEBUG) for n in self.nodes: code = code + n.printOpen62541CCode(unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute) if len(unPrintedNodes) != 0: log(self, "" + str(len(unPrintedNodes)) + " nodes could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing suceeded for all nodes", LOG_LEVEL_DEBUG) if len(unPrintedRefs) != 0: log(self, "Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.", LOG_LEVEL_DEBUG) tmprefs = [] for r in unPrintedRefs: if not (r.target() not in unPrintedNodes) and not (r.parent() in unPrintedNodes): if not isinstance(r.parent(), opcua_node_t): log(self, "Reference has no parent!", LOG_LEVEL_DEBUG) elif not isinstance(r.parent().id(), opcua_node_id_t): log(self, "Parents nodeid is not a nodeID!", LOG_LEVEL_DEBUG) else: if (len(tmprefs) == 0): code.append("// Creating leftover references:") code = code + codegen.getCreateStandaloneReference(r.parent(), r) code.append("") tmprefs.append(r) # Remove printed refs from list for r in tmprefs: unPrintedRefs.remove(r) if len(unPrintedRefs) != 0: log(self, "" + str(len(unPrintedRefs)) + " references could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing succeeded for all references", LOG_LEVEL_DEBUG) code.append("}") return (header,code)
def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""): unPrintedNodes = [] unPrintedRefs = [] code = [] header = [] # Reorder our nodes to produce a bare minimum of bootstrapping dependencies logger.debug( "Reordering nodes for minimal dependencies during printing.") self.reorderNodesMinDependencies() # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but # bulky. This class will help to offload some code. codegen = open62541_MacroHelper( supressGenerationOfAttribute=supressGenerationOfAttribute) # Populate the unPrinted-Lists with everything we have. # Every Time a nodes printfunction is called, it will pop itself and # all printed references from these lists. for n in self.nodes: if not n in printedExternally: unPrintedNodes.append(n) else: logger.debug("Node " + str(n.id()) + " is being ignored.") for n in unPrintedNodes: for r in n.getReferences(): if (r.target() != None) and (r.target().id() != None) and (r.parent() != None): unPrintedRefs.append(r) logger.debug( str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) + "References need to get printed.") header.append( "/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */" ) code.append( "/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */" ) header.append('#ifndef ' + outfilename.upper() + '_H_') header.append('#define ' + outfilename.upper() + '_H_') header.append('#ifdef UA_NO_AMALGAMATION') header.append('#include "server/ua_server_internal.h"') header.append('#include "server/ua_nodes.h"') header.append(' #include "ua_util.h"') header.append(' #include "ua_types.h"') header.append(' #include "ua_types_encoding_binary.h"') header.append(' #include "ua_types_generated_encoding_binary.h"') header.append(' #include "ua_transport_generated_encoding_binary.h"') header.append('#else') header.append(' #include "open62541.h"') header.append('#endif') header.append('') header.append('/* Definition that (in userspace models) may be ') header.append(' * - not included in the amalgamated header or') header.append(' * - not part of public headers or') header.append( ' * - not exported in the shared object in combination with any of the above' ) header.append(' * but are required for value encoding.') header.append( ' * NOTE: Userspace UA_(decode|encode)Binary /wo amalgamations requires UA_EXPORT to be appended to the appropriate definitions. */' ) header.append('#ifndef UA_ENCODINGOFFSET_BINARY') header.append('# define UA_ENCODINGOFFSET_BINARY 2') header.append('#endif') header.append('#ifndef NULL') header.append(' #define NULL ((void *)0)') header.append('#endif') header.append('#ifndef UA_malloc') header.append(' #define UA_malloc(_p_size) malloc(_p_size)') header.append('#endif') header.append('#ifndef UA_free') header.append(' #define UA_free(_p_ptr) free(_p_ptr)') header.append('#endif') code.append('#include "' + outfilename + '.h"') code.append("UA_INLINE UA_StatusCode " + outfilename + "(UA_Server *server) {") code.append('UA_StatusCode retval = UA_STATUSCODE_GOOD; ') code.append( 'if(retval == UA_STATUSCODE_GOOD){retval = UA_STATUSCODE_GOOD;} //ensure that retval is used' ) # Before printing nodes, we need to request additional namespace arrays from the server for nsid in self.namespaceIdentifiers: if nsid == 0 or nsid == 1: continue else: name = self.namespaceIdentifiers[nsid] name = name.replace("\"", "\\\"") code.append( "if (UA_Server_addNamespace(server, \"{0}\") != {1})\n return UA_STATUSCODE_BADUNEXPECTEDERROR;" .format(name, nsid)) # Find all references necessary to create the namespace and # "Bootstrap" them so all other nodes can safely use these referencetypes whenever # they can locate both source and target of the reference. logger.debug("Collecting all references used in the namespace.") refsUsed = [] for n in self.nodes: # Since we are already looping over all nodes, use this chance to print NodeId defines if n.id().ns != 0: nc = n.nodeClass() if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW: header = header + codegen.getNodeIdDefineString(n) # Now for the actual references... for r in n.getReferences(): # Only print valid references in namespace 0 (users will not want their refs bootstrapped) if not r.referenceType() in refsUsed and r.referenceType( ) != None and r.referenceType().id().ns == 0: refsUsed.append(r.referenceType()) logger.debug( str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped." ) for r in refsUsed: code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs) header.append("extern UA_StatusCode " + outfilename + "(UA_Server *server);\n") header.append("#endif /* " + outfilename.upper() + "_H_ */") # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes! # Nodes remove themselves from this list when printed. logger.debug("Printing all other nodes.") for n in self.nodes: code = code + n.printOpen62541CCode( unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute) if len(unPrintedNodes) != 0: logger.warn("" + str(len(unPrintedNodes)) + " nodes could not be translated to code.") else: logger.debug("Printing suceeded for all nodes") if len(unPrintedRefs) != 0: logger.debug("Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.") tmprefs = [] for r in unPrintedRefs: if not (r.target() not in unPrintedNodes) and not ( r.parent() in unPrintedNodes): if not isinstance(r.parent(), opcua_node_t): logger.debug("Reference has no parent!") elif not isinstance(r.parent().id(), opcua_node_id_t): logger.debug("Parents nodeid is not a nodeID!") else: if (len(tmprefs) == 0): code.append("// Creating leftover references:") code = code + codegen.getCreateStandaloneReference( r.parent(), r) code.append("") tmprefs.append(r) # Remove printed refs from list for r in tmprefs: unPrintedRefs.remove(r) if len(unPrintedRefs) != 0: logger.warn("" + str(len(unPrintedRefs)) + " references could not be translated to code.") else: logger.debug("Printing succeeded for all references") code.append("return UA_STATUSCODE_GOOD;") code.append("}") return (header, code)
def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""): unPrintedNodes = [] unPrintedRefs = [] code = [] header = [] # Reorder our nodes to produce a bare minimum of bootstrapping dependencies log(self, "Reordering nodes for minimal dependencies during printing.") self.reorderNodesMinDependencies() # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but # bulky. This class will help to offload some code. codegen = open62541_MacroHelper( supressGenerationOfAttribute=supressGenerationOfAttribute) # Populate the unPrinted-Lists with everything we have. # Every Time a nodes printfunction is called, it will pop itself and # all printed references from these lists. for n in self.nodes: if not n in printedExternally: unPrintedNodes.append(n) else: log(self, "Node " + str(n.id()) + " is being ignored.", LOG_LEVEL_DEBUG) for n in unPrintedNodes: for r in n.getReferences(): if (r.target() != None) and (r.target().id() != None) and (r.parent() != None): unPrintedRefs.append(r) log( self, str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) + "References need to get printed.", LOG_LEVEL_DEBUG) header.append( "/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */" ) code.append( "/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */" ) header.append('#ifndef ' + outfilename.upper() + '_H_') header.append('#define ' + outfilename.upper() + '_H_') header.append('#ifdef UA_NO_AMALGAMATION') header.append('#include "server/ua_server_internal.h"') header.append('#include "server/ua_nodes.h"') header.append('#include "ua_util.h"') header.append('#include "ua_types.h"') header.append('#else') header.append('#include "open62541.h"') header.append('#define UA_NULL ((void *)0)') header.append('#endif') code.append('#include "' + outfilename + '.h"') code.append("UA_INLINE void " + outfilename + "(UA_Server *server) {") # Find all references necessary to create the namespace and # "Bootstrap" them so all other nodes can safely use these referencetypes whenever # they can locate both source and target of the reference. log(self, "Collecting all references used in the namespace.", LOG_LEVEL_DEBUG) refsUsed = [] for n in self.nodes: # Since we are already looping over all nodes, use this chance to print NodeId defines if n.id().ns != 0: nc = n.nodeClass() if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW: header = header + codegen.getNodeIdDefineString(n) # Now for the actual references... for r in n.getReferences(): # Only print valid refernces in namespace 0 (users will not want their refs bootstrapped) if not r.referenceType() in refsUsed and r.referenceType( ) != None and r.referenceType().id().ns == 0: refsUsed.append(r.referenceType()) log( self, str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.", LOG_LEVEL_DEBUG) for r in refsUsed: code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs) header.append("extern void " + outfilename + "(UA_Server *server);\n") header.append("#endif /* " + outfilename.upper() + "_H_ */") # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes! # Nodes remove themselves from this list when printed. log(self, "Printing all other nodes.", LOG_LEVEL_DEBUG) for n in self.nodes: code = code + n.printOpen62541CCode( unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute) if len(unPrintedNodes) != 0: log( self, "" + str(len(unPrintedNodes)) + " nodes could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing suceeded for all nodes", LOG_LEVEL_DEBUG) if len(unPrintedRefs) != 0: log( self, "Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.", LOG_LEVEL_DEBUG) tmprefs = [] for r in unPrintedRefs: if not (r.target() not in unPrintedNodes) and not ( r.parent() in unPrintedNodes): if not isinstance(r.parent(), opcua_node_t): log(self, "Reference has no parent!", LOG_LEVEL_DEBUG) elif not isinstance(r.parent().id(), opcua_node_id_t): log(self, "Parents nodeid is not a nodeID!", LOG_LEVEL_DEBUG) else: if (len(tmprefs) == 0): code.append("// Creating leftover references:") code = code + codegen.getCreateStandaloneReference( r.parent(), r) code.append("") tmprefs.append(r) # Remove printed refs from list for r in tmprefs: unPrintedRefs.remove(r) if len(unPrintedRefs) != 0: log( self, "" + str(len(unPrintedRefs)) + " references could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing succeeded for all references", LOG_LEVEL_DEBUG) code.append("}") return (header, code)
def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""): unPrintedNodes = [] unPrintedRefs = [] code = [] header = [] # Reorder our nodes to produce a bare minimum of bootstrapping dependencies logger.debug("Reordering nodes for minimal dependencies during printing.") self.reorderNodesMinDependencies() # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but # bulky. This class will help to offload some code. codegen = open62541_MacroHelper(supressGenerationOfAttribute=supressGenerationOfAttribute) # Populate the unPrinted-Lists with everything we have. # Every Time a nodes printfunction is called, it will pop itself and # all printed references from these lists. for n in self.nodes: if not n in printedExternally: unPrintedNodes.append(n) else: logger.debug("Node " + str(n.id()) + " is being ignored.") for n in unPrintedNodes: for r in n.getReferences(): if (r.target() != None) and (r.target().id() != None) and (r.parent() != None): unPrintedRefs.append(r) logger.debug( str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) + "References need to get printed." ) header.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") header.append("#ifndef " + outfilename.upper() + "_H_") header.append("#define " + outfilename.upper() + "_H_") header.append("#ifdef UA_NO_AMALGAMATION") header.append('#include "server/ua_server_internal.h"') header.append('#include "server/ua_nodes.h"') header.append(' #include "ua_util.h"') header.append(' #include "ua_types.h"') header.append(' #include "ua_types_encoding_binary.h"') header.append(' #include "ua_types_generated_encoding_binary.h"') header.append(' #include "ua_transport_generated_encoding_binary.h"') header.append("#else") header.append(' #include "open62541.h"') header.append("#endif") header.append("") header.append("/* Definition that (in userspace models) may be ") header.append(" * - not included in the amalgamated header or") header.append(" * - not part of public headers or") header.append(" * - not exported in the shared object in combination with any of the above") header.append(" * but are required for value encoding.") header.append( " * NOTE: Userspace UA_(decode|encode)Binary /wo amalgamations requires UA_EXPORT to be appended to the appropriate definitions. */" ) header.append("#ifndef UA_ENCODINGOFFSET_BINARY") header.append("# define UA_ENCODINGOFFSET_BINARY 2") header.append("#endif") header.append("#ifndef NULL") header.append(" #define NULL ((void *)0)") header.append("#endif") header.append("#ifndef UA_malloc") header.append(" #define UA_malloc(_p_size) malloc(_p_size)") header.append("#endif") header.append("#ifndef UA_free") header.append(" #define UA_free(_p_ptr) free(_p_ptr)") header.append("#endif") code.append('#include "' + outfilename + '.h"') code.append("UA_INLINE UA_StatusCode " + outfilename + "(UA_Server *server) {") code.append("UA_StatusCode retval = UA_STATUSCODE_GOOD; ") # Before printing nodes, we need to request additional namespace arrays from the server for nsid in self.namespaceIdentifiers: if nsid == 0 or nsid == 1: continue else: name = self.namespaceIdentifiers[nsid] name = name.replace('"', '\\"') code.append( 'if (UA_Server_addNamespace(server, "{0}") != {1})\n return UA_STATUSCODE_BADUNEXPECTEDERROR;'.format( name, nsid ) ) # Find all references necessary to create the namespace and # "Bootstrap" them so all other nodes can safely use these referencetypes whenever # they can locate both source and target of the reference. logger.debug("Collecting all references used in the namespace.") refsUsed = [] for n in self.nodes: # Since we are already looping over all nodes, use this chance to print NodeId defines if n.id().ns != 0: nc = n.nodeClass() if nc != NODE_CLASS_OBJECT and nc != NODE_CLASS_VARIABLE and nc != NODE_CLASS_VIEW: header = header + codegen.getNodeIdDefineString(n) # Now for the actual references... for r in n.getReferences(): # Only print valid references in namespace 0 (users will not want their refs bootstrapped) if not r.referenceType() in refsUsed and r.referenceType() != None and r.referenceType().id().ns == 0: refsUsed.append(r.referenceType()) logger.debug( str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped." ) for r in refsUsed: code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs) header.append("extern UA_StatusCode " + outfilename + "(UA_Server *server);\n") header.append("#endif /* " + outfilename.upper() + "_H_ */") # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes! # Nodes remove themselves from this list when printed. logger.debug("Printing all other nodes.") for n in self.nodes: code = code + n.printOpen62541CCode( unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute ) if len(unPrintedNodes) != 0: logger.warn("" + str(len(unPrintedNodes)) + " nodes could not be translated to code.") else: logger.debug("Printing suceeded for all nodes") if len(unPrintedRefs) != 0: logger.debug("Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.") tmprefs = [] for r in unPrintedRefs: if not (r.target() not in unPrintedNodes) and not (r.parent() in unPrintedNodes): if not isinstance(r.parent(), opcua_node_t): logger.debug("Reference has no parent!") elif not isinstance(r.parent().id(), opcua_node_id_t): logger.debug("Parents nodeid is not a nodeID!") else: if len(tmprefs) == 0: code.append("// Creating leftover references:") code = code + codegen.getCreateStandaloneReference(r.parent(), r) code.append("") tmprefs.append(r) # Remove printed refs from list for r in tmprefs: unPrintedRefs.remove(r) if len(unPrintedRefs) != 0: logger.warn("" + str(len(unPrintedRefs)) + " references could not be translated to code.") else: logger.debug("Printing succeeded for all references") code.append("return UA_STATUSCODE_GOOD;") code.append("}") return (header, code)
def printOpen62541Header(self, printedExternally=[], supressGenerationOfAttribute=[], outfilename=""): unPrintedNodes = [] unPrintedRefs = [] code = [] header = [] # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but # bulky. This class will help to offload some code. codegen = open62541_MacroHelper(supressGenerationOfAttribute=supressGenerationOfAttribute) # Populate the unPrinted-Lists with everything we have. # Every Time a nodes printfunction is called, it will pop itself and # all printed references from these lists. for n in self.nodes: if not n in printedExternally: unPrintedNodes.append(n) else: log(self, "Node " + str(n.id()) + " is being ignored.", LOG_LEVEL_DEBUG) for n in unPrintedNodes: for r in n.getReferences(): if (r.target() != None) and (r.target().id() != None) and (r.parent() != None): unPrintedRefs.append(r) log(self, str(len(unPrintedNodes)) + " Nodes, " + str(len(unPrintedRefs)) + "References need to get printed.", LOG_LEVEL_DEBUG) header.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n\n */") header.append("#ifndef "+outfilename.upper()+"_H_") header.append("#define "+outfilename.upper()+"_H_") header.append('#include "server/ua_server_internal.h"') header.append('#include "server/ua_nodes.h"') header.append('#include "ua_types.h"') header.append("extern void "+outfilename+"(UA_Server *server);\n") header.append("#endif /* "+outfilename.upper()+"_H_ */") code.append('#include "'+outfilename+'.h"') code.append("inline void "+outfilename+"(UA_Server *server) {") # Find all references necessary to create the namespace and # "Bootstrap" them so all other nodes can safely use these referencetypes whenever # they can locate both source and target of the reference. log(self, "Collecting all references used in the namespace.", LOG_LEVEL_DEBUG) refsUsed = [] for n in self.nodes: for r in n.getReferences(): if not r.referenceType() in refsUsed: refsUsed.append(r.referenceType()) log(self, str(len(refsUsed)) + " reference types are used in the namespace, which will now get bootstrapped.", LOG_LEVEL_DEBUG) for r in refsUsed: code = code + r.printOpen62541CCode(unPrintedNodes, unPrintedRefs); # Note to self: do NOT - NOT! - try to iterate over unPrintedNodes! # Nodes remove themselves from this list when printed. log(self, "Printing all other nodes.", LOG_LEVEL_DEBUG) for n in self.nodes: code = code + n.printOpen62541CCode(unPrintedNodes, unPrintedRefs, supressGenerationOfAttribute=supressGenerationOfAttribute) if len(unPrintedNodes) != 0: log(self, "" + str(len(unPrintedNodes)) + " nodes could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing suceeded for all nodes", LOG_LEVEL_DEBUG) if len(unPrintedRefs) != 0: log(self, "Attempting to print " + str(len(unPrintedRefs)) + " unprinted references.", LOG_LEVEL_DEBUG) tmprefs = [] for r in unPrintedRefs: if not (r.target() not in unPrintedNodes) and not (r.parent() in unPrintedNodes): if not isinstance(r.parent(), opcua_node_t): log(self, "Reference has no parent!", LOG_LEVEL_DEBUG) elif not isinstance(r.parent().id(), opcua_node_id_t): log(self, "Parents nodeid is not a nodeID!", LOG_LEVEL_DEBUG) else: if (len(tmprefs) == 0): code.append("// Creating leftover references:") code = code + codegen.getCreateStandaloneReference(r.parent(), r) code.append("") tmprefs.append(r) # Remove printed refs from list for r in tmprefs: unPrintedRefs.remove(r) if len(unPrintedRefs) != 0: log(self, "" + str(len(unPrintedRefs)) + " references could not be translated to code.", LOG_LEVEL_WARN) else: log(self, "Printing succeeded for all references", LOG_LEVEL_DEBUG) code.append("}") return (header,code)