def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], encode_binary_size=32000): outfilebase = basename(outfilename) # Printing functions outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8') outfilec = StringIO() def writeh(line): print(unicode(line), end='\n', file=outfileh) def writec(line): print(unicode(line), end='\n', file=outfilec) additionalHeaders = "" if len(typesArray) > 0: for arr in set(typesArray): if arr == "UA_TYPES": continue additionalHeaders += """#include "%s_generated.h"\n""" % arr.lower( ) # Print the preamble of the generated code writeh("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #ifndef %s_H_ #define %s_H_ """ % (outfilebase.upper(), outfilebase.upper())) if internal_headers: writeh(""" #ifdef UA_NO_AMALGAMATION # include "ua_server.h" # include "ua_types_encoding_binary.h" #else # include "open62541.h" /* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ # ifndef UA_Nodestore_remove //this definition is needed to hide this code in the amalgamated .c file typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, const UA_Byte **bufEnd); UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *type, UA_Byte **bufPos, const UA_Byte **bufEnd, UA_exchangeEncodeBuffer exchangeCallback, void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *type, size_t customTypesSize, const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; size_t UA_calcSizeBinary(void *p, const UA_DataType *type); const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId); # endif // UA_Nodestore_remove #endif %s """ % (additionalHeaders)) else: writeh(""" #include "open62541.h" """) writeh(""" _UA_BEGIN_DECLS extern UA_StatusCode %s(UA_Server *server); _UA_END_DECLS #endif /* %s_H_ */""" % \ (outfilebase, outfilebase.upper())) writec("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #include "%s.h" """ % (outfilebase)) # Loop over the sorted nodes logger.info("Reordering nodes for minimal dependencies during printing") sorted_nodes = sortNodes(nodeset) logger.info("Writing code for nodes and references") functionNumber = 0 parentreftypes = getSubTypesOf( nodeset, nodeset.getNodeByBrowseName("HierarchicalReferences")) parentreftypes = list(map(lambda x: x.id, parentreftypes)) printed_ids = set() for node in sorted_nodes: printed_ids.add(node.id) parentref = node.popParentRef(parentreftypes) if not node.hidden: writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */") code_global = [] code = generateNodeCode_begin(node, nodeset, generate_ns0, parentref, encode_binary_size, code_global) if code is None: writec("/* Ignored. No parent */") nodeset.hide_node(node.id) continue else: if len(code_global) > 0: writec("\n".join(code_global)) writec("\n") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_begin(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec(code) # Print inverse references leading to this node for ref in node.references: if ref.target not in printed_ids: continue if node.hidden and nodeset.nodes[ref.target].hidden: continue writec(generateReferenceCode(ref)) if node.hidden: continue writec("return retVal;") if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_finish(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec("return " + generateNodeCode_finish(node)) if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}") functionNumber = functionNumber + 1 writec(""" UA_StatusCode %s(UA_Server *server) { UA_StatusCode retVal = UA_STATUSCODE_GOOD;""" % (outfilebase)) # Generate namespaces (don't worry about duplicates) writec("/* Use namespace ids generated by the server */") writec("UA_UInt16 ns[" + str(len(nodeset.namespaces)) + "];") for i, nsid in enumerate(nodeset.namespaces): nsid = nsid.replace("\"", "\\\"") writec("ns[" + str(i) + "] = UA_Server_addNamespace(server, \"" + nsid + "\");") for i in range(0, functionNumber): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_begin(server, ns);") for i in reversed(range(0, functionNumber)): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_finish(server, ns);") writec("return retVal;\n}") outfileh.flush() os.fsync(outfileh) outfileh.close() fullCode = outfilec.getvalue() outfilec.close() outfilec = codecs.open(outfilename + ".c", r"w+", encoding='utf-8') outfilec.write(fullCode) outfilec.flush() os.fsync(outfilec) outfilec.close()
def generateOpen62541Code(nodeset, outfilename, internal_headers=False, typesArray=[]): outfilebase = basename(outfilename) # Printing functions outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8') outfilec = StringIO() def writeh(line): print(unicode(line), end='\n', file=outfileh) def writec(line): print(unicode(line), end='\n', file=outfilec) additionalHeaders = "" if len(typesArray) > 0: for arr in set(typesArray): if arr == "UA_TYPES": continue # remove ua_ prefix if exists typeFile = arr.lower() typeFile = typeFile[typeFile.startswith("ua_") and len("ua_"):] additionalHeaders += """#include "%s_generated.h"\n""" % typeFile # Print the preamble of the generated code writeh("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #ifndef %s_H_ #define %s_H_ """ % (outfilebase.upper(), outfilebase.upper())) if internal_headers: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" /* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ # ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, const UA_Byte **bufEnd); UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *type, UA_Byte **bufPos, const UA_Byte **bufEnd, UA_exchangeEncodeBuffer exchangeCallback, void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *type, size_t customTypesSize, const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; size_t UA_calcSizeBinary(void *p, const UA_DataType *type); const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId); # endif // UA_INTERNAL #else // UA_ENABLE_AMALGAMATION # include <open62541/server.h> #endif %s """ % (additionalHeaders)) else: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" #else # include <open62541/server.h> #endif %s """ % (additionalHeaders)) writeh(""" _UA_BEGIN_DECLS extern UA_StatusCode %s(UA_Server *server); _UA_END_DECLS #endif /* %s_H_ */""" % \ (outfilebase, outfilebase.upper())) writec("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #include "%s.h" """ % (outfilebase)) # Loop over the sorted nodes logger.info("Reordering nodes for minimal dependencies during printing") sorted_nodes = sortNodes(nodeset) logger.info("Writing code for nodes and references") functionNumber = 0 printed_ids = set() reftypes_functionNumbers = set() for node in sorted_nodes: printed_ids.add(node.id) if not node.hidden: writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */") code_global = [] code = generateNodeCode_begin(node, nodeset, code_global) if code is None: writec("/* Ignored. No parent */") nodeset.hide_node(node.id) continue else: if len(code_global) > 0: writec("\n".join(code_global)) writec("\n") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_begin(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode) or isinstance( node.parent, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec(code) # Print inverse references leading to this node for ref in node.references: if ref.target not in printed_ids: continue if node.hidden and nodeset.nodes[ref.target].hidden: continue if node.parent is not None and ref.target == node.parent.id \ and ref.referenceType == node.parentReference.id: # Skip parent reference continue writec(generateReferenceCode(ref)) if node.hidden: continue writec("return retVal;") if isinstance(node, MethodNode) or isinstance(node.parent, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_finish(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode) or isinstance(node.parent, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec("return " + generateNodeCode_finish(node)) if isinstance(node, MethodNode) or isinstance(node.parent, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}") # ReferenceTypeNodes have to be _finished immediately. The _begin phase # of other nodes might depend on the subtyping information of the # referencetype to be complete. if isinstance(node, ReferenceTypeNode): reftypes_functionNumbers.add(functionNumber) functionNumber = functionNumber + 1 # Load generated types for arr in set(typesArray): if arr == "UA_TYPES": continue writec("\nstatic UA_DataTypeArray custom" + arr + " = {") writec(" NULL,") writec(" " + arr + "_COUNT,") writec(" " + arr + "\n};") writec(""" UA_StatusCode %s(UA_Server *server) { UA_StatusCode retVal = UA_STATUSCODE_GOOD;""" % (outfilebase)) # Generate namespaces (don't worry about duplicates) writec("/* Use namespace ids generated by the server */") writec("UA_UInt16 ns[" + str(len(nodeset.namespaces)) + "];") for i, nsid in enumerate(nodeset.namespaces): nsid = nsid.replace("\"", "\\\"") writec("ns[" + str(i) + "] = UA_Server_addNamespace(server, \"" + nsid + "\");") # Add generated types to the server writec("\n/* Load custom datatype definitions into the server */") for arr in set(typesArray): if arr == "UA_TYPES": continue writec("if(" + arr + "_COUNT > 0) {") writec("custom" + arr + ".next = UA_Server_getConfig(server)->customDataTypes;") writec("UA_Server_getConfig(server)->customDataTypes = &custom" + arr + ";\n") writec("}") if functionNumber > 0: for i in range(0, functionNumber): writec( "if((retVal = function_{outfilebase}_{idx}_begin(server, ns)) != UA_STATUSCODE_GOOD) return retVal;" .format(outfilebase=outfilebase, idx=str(i))) if i in reftypes_functionNumbers: writec( "if((retVal = function_{outfilebase}_{idx}_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;" .format(outfilebase=outfilebase, idx=str(i))) for i in reversed(range(0, functionNumber)): if i in reftypes_functionNumbers: continue writec( "if((retVal = function_{outfilebase}_{idx}_finish(server, ns)) != UA_STATUSCODE_GOOD) return retVal;" .format(outfilebase=outfilebase, idx=str(i))) writec("return retVal;\n}") outfileh.flush() os.fsync(outfileh) outfileh.close() fullCode = outfilec.getvalue() outfilec.close() outfilec = codecs.open(outfilename + ".c", r"w+", encoding='utf-8') outfilec.write(fullCode) outfilec.flush() os.fsync(outfilec) outfilec.close()
def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], max_string_length=0): outfilebase = basename(outfilename) # Printing functions outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8') outfilec = StringIO() def writeh(line): print(unicode(line), end='\n', file=outfileh) def writec(line): print(unicode(line), end='\n', file=outfilec) additionalHeaders = "" if len(typesArray) > 0: for arr in set(typesArray): if arr == "UA_TYPES": continue additionalHeaders += """#include "%s_generated.h"\n""" % arr.lower( ) # Print the preamble of the generated code writeh("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #ifndef %s_H_ #define %s_H_ """ % (outfilebase.upper(), outfilebase.upper())) if internal_headers: writeh(""" #ifdef UA_NO_AMALGAMATION #include "ua_server.h" #include "ua_types_encoding_binary.h" %s #else #include "open62541.h" #endif """ % (additionalHeaders)) else: writeh(""" #include "open62541.h" """) writeh(""" extern UA_StatusCode %s(UA_Server *server); #endif /* %s_H_ */""" % \ (outfilebase, outfilebase.upper())) writec("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #include "%s.h" """ % (outfilebase)) parentrefs = getSubTypesOf( nodeset, nodeset.getNodeByBrowseName("HierarchicalReferences")) parentrefs = list(map(lambda x: x.id, parentrefs)) # Loop over the sorted nodes logger.info("Reordering nodes for minimal dependencies during printing") sorted_nodes = reorderNodesMinDependencies(nodeset) logger.info("Writing code for nodes and references") functionNumber = 0 for node in sorted_nodes: # Print node if not node.hidden: writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */") code = generateNodeCode_begin(node, nodeset, max_string_length, generate_ns0, parentrefs) if code is None: writec("/* Ignored. No parent */") nodeset.hide_node(node.id) continue else: writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_begin(UA_Server *server, UA_UInt16* ns) {\n") writec(code) # Print inverse references leading to this node for ref in node.printRefs: writec(generateReferenceCode(ref)) writec("return retVal;\n}") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_finish(UA_Server *server, UA_UInt16* ns) {\n") code = generateNodeCode_finish(node) writec("return " + code + "\n}\n") functionNumber = functionNumber + 1 writec(""" UA_StatusCode %s(UA_Server *server) { UA_StatusCode retVal = UA_STATUSCODE_GOOD;""" % (outfilebase)) # Generate namespaces (don't worry about duplicates) writec("/* Use namespace ids generated by the server */") writec("UA_UInt16 ns[" + str(len(nodeset.namespaces)) + "];") for i, nsid in enumerate(nodeset.namespaces): nsid = nsid.replace("\"", "\\\"") writec("ns[" + str(i) + "] = UA_Server_addNamespace(server, \"" + nsid + "\");") for i in range(0, functionNumber): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_begin(server, ns);") for i in reversed(range(0, functionNumber)): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_finish(server, ns);") writec("return retVal;\n}") outfileh.close() fullCode = outfilec.getvalue() outfilec.close() outfilec = codecs.open(outfilename + ".c", r"w+", encoding='utf-8') outfilec.write(fullCode) outfilec.close()
def generateOpen62541Code(nodeset, outfilename, generate_ns0=False, internal_headers=False, typesArray=[], encode_binary_size=32000): outfilebase = basename(outfilename) # Printing functions outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8') outfilec = StringIO() def writeh(line): print(unicode(line), end='\n', file=outfileh) def writec(line): print(unicode(line), end='\n', file=outfilec) additionalHeaders = "" if len(typesArray) > 0: for arr in set(typesArray): if arr == "UA_TYPES": continue additionalHeaders += """#include "%s_generated.h"\n""" % arr.lower() # Print the preamble of the generated code writeh("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #ifndef %s_H_ #define %s_H_ """ % (outfilebase.upper(), outfilebase.upper())) if internal_headers: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" /* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ # ifndef UA_Nodestore_remove //this definition is needed to hide this code in the amalgamated .c file typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, const UA_Byte **bufEnd); UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *type, UA_Byte **bufPos, const UA_Byte **bufEnd, UA_exchangeEncodeBuffer exchangeCallback, void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *type, size_t customTypesSize, const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; size_t UA_calcSizeBinary(void *p, const UA_DataType *type); const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId); # endif // UA_Nodestore_remove #else // UA_ENABLE_AMALGAMATION # include "ua_server.h" #endif %s """ % (additionalHeaders)) else: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" #else # include "ua_server.h" #endif %s """ % (additionalHeaders)) writeh(""" _UA_BEGIN_DECLS extern UA_StatusCode %s(UA_Server *server); _UA_END_DECLS #endif /* %s_H_ */""" % \ (outfilebase, outfilebase.upper())) writec("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #include "%s.h" """ % (outfilebase)) # Loop over the sorted nodes logger.info("Reordering nodes for minimal dependencies during printing") sorted_nodes = sortNodes(nodeset) logger.info("Writing code for nodes and references") functionNumber = 0 parentreftypes = getSubTypesOf(nodeset, nodeset.getNodeByBrowseName("HierarchicalReferences")) parentreftypes = list(map(lambda x: x.id, parentreftypes)) printed_ids = set() for node in sorted_nodes: printed_ids.add(node.id) parentref = node.popParentRef(parentreftypes) if not node.hidden: writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */") code_global = [] code = generateNodeCode_begin(node, nodeset, generate_ns0, parentref, encode_binary_size, code_global) if code is None: writec("/* Ignored. No parent */") nodeset.hide_node(node.id) continue else: if len(code_global) > 0: writec("\n".join(code_global)) writec("\n") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_begin(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec(code) # Print inverse references leading to this node for ref in node.references: if ref.target not in printed_ids: continue if node.hidden and nodeset.nodes[ref.target].hidden: continue writec(generateReferenceCode(ref)) if node.hidden: continue writec("return retVal;") if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}"); writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_finish(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec("return " + generateNodeCode_finish(node)) if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}"); functionNumber = functionNumber + 1 writec(""" UA_StatusCode %s(UA_Server *server) { UA_StatusCode retVal = UA_STATUSCODE_GOOD;""" % (outfilebase)) # Generate namespaces (don't worry about duplicates) writec("/* Use namespace ids generated by the server */") writec("UA_UInt16 ns[" + str(len(nodeset.namespaces)) + "];") for i, nsid in enumerate(nodeset.namespaces): nsid = nsid.replace("\"", "\\\"") writec("ns[" + str(i) + "] = UA_Server_addNamespace(server, \"" + nsid + "\");") for i in range(0, functionNumber): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_begin(server, ns);") for i in reversed(range(0, functionNumber)): writec("retVal |= function_" + outfilebase + "_" + str(i) + "_finish(server, ns);") writec("return retVal;\n}") outfileh.flush() os.fsync(outfileh) outfileh.close() fullCode = outfilec.getvalue() outfilec.close() outfilec = codecs.open(outfilename + ".c", r"w+", encoding='utf-8') outfilec.write(fullCode) outfilec.flush() os.fsync(outfilec) outfilec.close()
def generateOpen62541Code(nodeset, outfilename, internal_headers=False, typesArray=[]): outfilebase = basename(outfilename) # Printing functions outfileh = codecs.open(outfilename + ".h", r"w+", encoding='utf-8') outfilec = StringIO() def writeh(line): print(unicode(line), end='\n', file=outfileh) def writec(line): print(unicode(line), end='\n', file=outfilec) additionalHeaders = "" if len(typesArray) > 0: for arr in set(typesArray): if arr == "UA_TYPES": continue # remove ua_ prefix if exists typeFile = arr.lower() typeFile = typeFile[typeFile.startswith("ua_") and len("ua_"):] additionalHeaders += """#include "%s_generated.h"\n""" % typeFile # Print the preamble of the generated code writeh("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #ifndef %s_H_ #define %s_H_ """ % (outfilebase.upper(), outfilebase.upper())) if internal_headers: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" /* The following declarations are in the open62541.c file so here's needed when compiling nodesets externally */ # ifndef UA_INTERNAL //this definition is needed to hide this code in the amalgamated .c file typedef UA_StatusCode (*UA_exchangeEncodeBuffer)(void *handle, UA_Byte **bufPos, const UA_Byte **bufEnd); UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *type, UA_Byte **bufPos, const UA_Byte **bufEnd, UA_exchangeEncodeBuffer exchangeCallback, void *exchangeHandle) UA_FUNC_ATTR_WARN_UNUSED_RESULT; UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *type, size_t customTypesSize, const UA_DataType *customTypes) UA_FUNC_ATTR_WARN_UNUSED_RESULT; size_t UA_calcSizeBinary(void *p, const UA_DataType *type); const UA_DataType * UA_findDataTypeByBinary(const UA_NodeId *typeId); # endif // UA_INTERNAL #else // UA_ENABLE_AMALGAMATION # include <open62541/server.h> #endif %s """ % (additionalHeaders)) else: writeh(""" #ifdef UA_ENABLE_AMALGAMATION # include "open62541.h" #else # include <open62541/server.h> #endif %s """ % (additionalHeaders)) writeh(""" _UA_BEGIN_DECLS extern UA_StatusCode %s(UA_Server *server); _UA_END_DECLS #endif /* %s_H_ */""" % \ (outfilebase, outfilebase.upper())) writec("""/* WARNING: This is a generated file. * Any manual changes will be overwritten. */ #include "%s.h" """ % (outfilebase)) # Loop over the sorted nodes logger.info("Reordering nodes for minimal dependencies during printing") sorted_nodes = sortNodes(nodeset) logger.info("Writing code for nodes and references") functionNumber = 0 printed_ids = set() for node in sorted_nodes: printed_ids.add(node.id) if not node.hidden: writec("\n/* " + str(node.displayName) + " - " + str(node.id) + " */") code_global = [] code = generateNodeCode_begin(node, nodeset, code_global) if code is None: writec("/* Ignored. No parent */") nodeset.hide_node(node.id) continue else: if len(code_global) > 0: writec("\n".join(code_global)) writec("\n") writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_begin(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec(code) # Print inverse references leading to this node for ref in node.references: if ref.target not in printed_ids: continue if node.hidden and nodeset.nodes[ref.target].hidden: continue if node.parent is not None and ref.target == node.parent.id \ and ref.referenceType == node.parentReference.id: # Skip parent reference continue writec(generateReferenceCode(ref)) if node.hidden: continue writec("return retVal;") if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}"); writec("\nstatic UA_StatusCode function_" + outfilebase + "_" + str(functionNumber) + "_finish(UA_Server *server, UA_UInt16* ns) {") if isinstance(node, MethodNode): writec("#ifdef UA_ENABLE_METHODCALLS") writec("return " + generateNodeCode_finish(node)) if isinstance(node, MethodNode): writec("#else") writec("return UA_STATUSCODE_GOOD;") writec("#endif /* UA_ENABLE_METHODCALLS */") writec("}"); functionNumber = functionNumber + 1 writec(""" UA_StatusCode %s(UA_Server *server) { UA_StatusCode retVal = UA_STATUSCODE_GOOD;""" % (outfilebase)) # Generate namespaces (don't worry about duplicates) writec("/* Use namespace ids generated by the server */") writec("UA_UInt16 ns[" + str(len(nodeset.namespaces)) + "];") for i, nsid in enumerate(nodeset.namespaces): nsid = nsid.replace("\"", "\\\"") writec("ns[" + str(i) + "] = UA_Server_addNamespace(server, \"" + nsid + "\");") if functionNumber > 0: # concatenate method calls with "&&" operator. # The first method which does not return UA_STATUSCODE_GOOD (=0) will cause aborting # the remaining calls and retVal will be set to that error code. writec("bool dummy = (") for i in range(0, functionNumber): writec("!(retVal = function_{outfilebase}_{idx}_begin(server, ns)) &&".format( outfilebase=outfilebase, idx=str(i))) for i in reversed(range(0, functionNumber)): writec("!(retVal = function_{outfilebase}_{idx}_finish(server, ns)) {concat}".format( outfilebase=outfilebase, idx=str(i), concat= "&&" if i>0 else "")) # use (void)(dummy) to avoid unused variable error. writec("); (void)(dummy);") writec("return retVal;\n}") outfileh.flush() os.fsync(outfileh) outfileh.close() fullCode = outfilec.getvalue() outfilec.close() outfilec = codecs.open(outfilename + ".c", r"w+", encoding='utf-8') outfilec.write(fullCode) outfilec.flush() os.fsync(outfilec) outfilec.close()