Browse Source

removing pyUANamespace scripts since they are in a separate branch now

Stasik0 9 years ago
parent
commit
747cfc4cd4

+ 0 - 99
tools/pyUANamespace/generate_open62541CCode.py

@@ -1,99 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been 
-### contributed to the open62541 project by the author. All licensing 
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-from sys import argv, exit
-from os import path
-from ua_namespace import *
-from logger import *
-
-def usage():
-  print "Skript usage:"
-  print "generate_open62541CCode <namespace XML> [namespace.xml[ namespace.xml[...]]] <output file>"
-  print ""
-  print "generate_open62541CCode will first read all XML files passed on the command line, then " 
-  print "link and check the namespace. All nodes that fullfill the basic requirements will then be"
-  print "printed as C-Code intended to be included in the open62541 OPC-UA Server that will"
-  print "initialize the corresponding name space."
-
-if __name__ == '__main__':
-  # Check if the parameters given correspond to actual files
-  infiles = []
-  ouffile = ""
-  
-  GLOBAL_LOG_LEVEL = LOG_LEVEL_INFO
-  
-  if len(argv) < 2:
-    usage()
-    exit(1)
-  for filename in argv[1:-1]:
-    if path.exists(filename):
-      infiles.append(filename)
-    else:
-      log(None, "File " + str(filename) + " does not exist.", LOG_LEVEL_ERROR)
-      usage()
-      exit(1)
-
-  # Creating the header is tendious. We can skip the entire process if
-  # the header exists.
-  if path.exists(argv[-1]):
-    log(None, "File " + str(filename) + " does already exists.", LOG_LEVEL_INFO)
-    log(None, "Header generation will be skipped. Delete the header and rerun this script if necessary.", LOG_LEVEL_INFO)
-    exit(0)
-
-  # Open the output file
-  outfile = open(argv[-1], r"w+")
-
-  # Create a new namespace
-  # Note that the name is actually completely symbolic, it has no other
-  # function but to distinguish this specific class.
-  # A namespace class acts as a container for nodes. The nodes may belong
-  # to any number of different OPC-UA namespaces.
-  ns = opcua_namespace("open62541")
-
-  # Parse the XML files
-  for xmlfile in infiles:
-    log(None, "Parsing " + str(xmlfile), LOG_LEVEL_INFO)
-    ns.parseXML(xmlfile)
-
-  # Link the references in the namespace
-  log(None, "Linking namespace nodes and references", LOG_LEVEL_INFO)
-  ns.linkOpenPointers()
-
-  # Remove nodes that are not printable or contain parsing errors, such as
-  # unresolvable or no references or invalid NodeIDs
-  ns.sanitize()
-
-  # Parse Datatypes in order to find out what the XML keyed values actually
-  # represent.
-  # Ex. <rpm>123</rpm> is not encodable
-  #     only after parsing the datatypes, it is known that
-  #     rpm is encoded as a double
-  log(None, "Building datatype encoding rules", LOG_LEVEL_INFO)
-  ns.buildEncodingRules()
-
-  # Allocate/Parse the data values. In order to do this, we must have run
-  # buidEncodingRules.
-  log(None, "Allocating variables", LOG_LEVEL_INFO)
-  ns.allocateVariables()
-
-  # Create the C Code
-  log(None, "Generating Header", LOG_LEVEL_INFO)
-  for line in ns.printOpen62541Header():
-    outfile.write(line+"\n")
-
-  outfile.close()

+ 0 - 45
tools/pyUANamespace/logger.py

@@ -1,45 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been 
-### contributed to the open62541 project by the author. All licensing 
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-import inspect
-
-###
-### Tidy logging helpers
-###
-
-LOG_LEVEL_DEBUG  = 4
-LOG_LEVEL_INFO   = 2
-LOG_LEVEL_WARN   = 1
-LOG_LEVEL_ERROR  = 0
-LOG_LEVEL_SILENT = -1
-
-# Change the following to filter logging output
-GLOBAL_LOG_LEVEL = LOG_LEVEL_SILENT
-
-def log(callee, logstr, level=LOG_LEVEL_DEBUG):
-  prefixes = { LOG_LEVEL_DEBUG : "DBG: ",
-               LOG_LEVEL_INFO  : "INF: ",
-               LOG_LEVEL_WARN  : "WRN: ",
-               LOG_LEVEL_ERROR : "ERR: ",
-               LOG_LEVEL_SILENT: ""
-            }
-  if level <= GLOBAL_LOG_LEVEL:
-    if prefixes.has_key(level):
-      print str(prefixes[level]) + callee.__class__.__name__ + "." + inspect.stack()[1][3] +  "(): " + logstr
-    else:
-      print callee.__class__.__name__  + "." + inspect.stack()[1][3] + "(): " + logstr

+ 0 - 133
tools/pyUANamespace/open62541_MacroHelper.py

@@ -1,133 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been 
-### contributed to the open62541 project by the author. All licensing 
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-from logger import *
-from ua_constants import *
-
-__unique_item_id = 0
-
-class open62541_MacroHelper():
-  def __init__(self):
-    pass
-
-  def getCreateExpandedNodeIDMacro(self, node):
-    if node.id().i != None:
-      return "UA_EXPANDEDNODEID_NUMERIC(" + str(node.id().ns) + ", " + str(node.id().i) + ")"
-    elif node.id().s != None:
-      return "UA_EXPANDEDNODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
-    elif node.id().b != None:
-      log(self, "NodeID Generation macro for bytestrings has not been implemented.")
-      return ""
-    elif node.id().g != None:
-      log(self, "NodeID Generation macro for guids has not been implemented.")
-      return ""
-    else:
-      return ""
-
-  def getCreateNodeIDMacro(self, node):
-    if node.id().i != None:
-      return "UA_NODEID_NUMERIC(" + str(node.id().ns) + ", " + str(node.id().i) + ")"
-    elif node.id().s != None:
-      return "UA_NODEID_STRING("  + str(node.id().ns) + ", " + node.id().s + ")"
-    elif node.id().b != None:
-      log(self, "NodeID Generation macro for bytestrings has not been implemented.")
-      return ""
-    elif node.id().g != None:
-      log(self, "NodeID Generation macro for guids has not been implemented.")
-      return ""
-    else:
-      return ""
-
-  def getCreateStandaloneReference(self, sourcenode, reference):
-  # As reference from open62541 (we need to alter the attributes)
-  #    #define ADDREFERENCE(NODEID, REFTYPE_NODEID, TARGET_EXPNODEID) do {     \
-  #        UA_AddReferencesItem item;                                      \
-  #        UA_AddReferencesItem_init(&item);                               \
-  #        item.sourceNodeId = NODEID;                                     \
-  #        item.referenceTypeId = REFTYPE_NODEID;                          \
-  #        item.isForward = UA_TRUE;                                       \
-  #        item.targetNodeId = TARGET_EXPNODEID;                           \
-  #        UA_Server_addReference(server, &item);                          \
-  #    } while(0)
-    code = []
-    refid = "ref_" + reference.getCodePrintableID()
-    code.append("UA_AddReferencesItem " + refid + ";")
-    code.append("UA_AddReferencesItem_init(&" + refid + ");")
-    code.append(refid + ".sourceNodeId = " + self.getCreateNodeIDMacro(sourcenode) + ";")
-    code.append(refid + ".referenceTypeId = " + self.getCreateNodeIDMacro(reference.referenceType()) + ";")
-    if reference.isForward():
-      code.append(refid + ".isForward = UA_TRUE;")
-    else:
-      code.append(refid + ".isForward = UA_FALSE;")
-    code.append(refid + ".targetNodeId = " + self.getCreateExpandedNodeIDMacro(reference.target()) + ";")
-    code.append("UA_Server_addReference(server, &" + refid + ");")
-    return code
-
-  def getCreateNode(self, node):
-    nodetype = ""
-    code = []
-
-    code.append("// Node: " + str(node) + ", " + str(node.browseName()))
-
-    if node.nodeClass() == NODE_CLASS_OBJECT:
-      nodetype = "UA_ObjectNode"
-    elif node.nodeClass() == NODE_CLASS_VARIABLE:
-      nodetype = "UA_VariableNode"
-    elif node.nodeClass() == NODE_CLASS_METHOD:
-      nodetype = "UA_MethodNode"
-    elif node.nodeClass() == NODE_CLASS_OBJECTTYPE:
-      nodetype = "UA_ObjectTypeNode"
-    elif node.nodeClass() == NODE_CLASS_REFERENCETYPE:
-      nodetype = "UA_ReferenceTypeNode"
-    elif node.nodeClass() == NODE_CLASS_VARIABLETYPE:
-      nodetype = "UA_VariableTypeNode"
-    elif node.nodeClass() == NODE_CLASS_DATATYPE:
-      nodetype = "UA_DataTypeNode"
-    elif node.nodeClass() == NODE_CLASS_VIEW:
-      nodetype = "UA_ViewNode"
-    elif node.nodeClass() == NODE_CLASS_METHODTYPE:
-      nodetype = "UA_MethodTypeNode"
-    else:
-      nodetype = "UA_NodeTypeNotFoundorGeneric"
-
-    code.append(nodetype + " *" + node.getCodePrintableID() + " = " + nodetype + "_new();")
-    code.append(node.getCodePrintableID() + "->browseName = UA_QUALIFIEDNAME_ALLOC(" +  str(node.id().ns) + ", \"" + node.browseName() + "\");")
-    code.append(node.getCodePrintableID() + "->displayName = UA_LOCALIZEDTEXT_ALLOC(\"en_US\", \"" +  node.displayName() + "\");")
-    code.append(node.getCodePrintableID() + "->description = UA_LOCALIZEDTEXT_ALLOC(\"en_US\", \"" +  node.description() + "\");")
-    code.append(node.getCodePrintableID() + "->writeMask = (UA_Int32) " +  str(node.__node_writeMask__) + ";")
-    code.append(node.getCodePrintableID() + "->userWriteMask = (UA_Int32) " + str(node.__node_userWriteMask__) + ";")
-    #FIXME: Allocate descriptions, etc.
-
-    if node.id().i != None:
-      code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = " + str(node.id().i) + ";")
-    elif node.id().b != None:
-      log(self, "ByteString IDs for nodes has not been implemented yet.", LOG_LEVEL_ERROR)
-      return []
-    elif node.id().g != None:
-      #<jpfr> the string is sth like { .length = 111, .data = <ptr> }
-      #<jpfr> there you _may_ alloc the <ptr> on the heap
-      #<jpfr> for the guid, just set it to {.data1 = 111, .data2 = 2222, ....
-      log(self, "GUIDs for nodes has not been implemented yet.", LOG_LEVEL_ERROR)
-      return []
-    elif node.id().s != None:
-      code.append(node.getCodePrintableID() + "->nodeId.identifier.numeric = UA_STRING_ALLOC(\"" + str(node.id().i) + "\");")
-    else:
-      log(self, "Node ID is not numeric, bytestring, guid or string. I do not know how to create c code for that...", LOG_LEVEL_ERROR)
-      return []
-
-    return code

File diff suppressed because it is too large
+ 0 - 1082
tools/pyUANamespace/ua_builtin_types.py


+ 0 - 57
tools/pyUANamespace/ua_constants.py

@@ -1,57 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been 
-### contributed to the open62541 project by the author. All licensing 
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-NODE_CLASS_GENERERIC        = 0
-NODE_CLASS_OBJECT           = 1
-NODE_CLASS_VARIABLE         = 2
-NODE_CLASS_METHOD           = 4
-NODE_CLASS_OBJECTTYPE       = 8
-NODE_CLASS_VARIABLETYPE     = 16
-NODE_CLASS_REFERENCETYPE    = 32
-NODE_CLASS_DATATYPE         = 64
-NODE_CLASS_VIEW             = 128
-
-# Not in OPC-UA, but exists in XML
-NODE_CLASS_METHODTYPE       = 256
-
-##
-## Numeric codes used to encode binary type fields:
-##
-BUILTINTYPE_TYPEID_EXTENSIONOBJECT = 1
-BUILTINTYPE_TYPEID_LOCALIZEDTEXT = 2
-BUILTINTYPE_TYPEID_EXPANDEDNODEID = 3
-BUILTINTYPE_TYPEID_NODEID = 4
-BUILTINTYPE_TYPEID_DATETIME = 5
-BUILTINTYPE_TYPEID_QUALIFIEDNAME = 6
-BUILTINTYPE_TYPEID_STATUSCODE = 7
-BUILTINTYPE_TYPEID_GUID = 8
-BUILTINTYPE_TYPEID_BOOLEAN = 9
-BUILTINTYPE_TYPEID_BYTE = 10
-BUILTINTYPE_TYPEID_SBYTE = 11
-BUILTINTYPE_TYPEID_INT16 = 12
-BUILTINTYPE_TYPEID_UINT16 = 13
-BUILTINTYPE_TYPEID_INT32 = 14
-BUILTINTYPE_TYPEID_UINT32 = 15
-BUILTINTYPE_TYPEID_INT64 = 16
-BUILTINTYPE_TYPEID_UINT64 = 17
-BUILTINTYPE_TYPEID_FLOAT = 18
-BUILTINTYPE_TYPEID_DOUBLE = 19
-BUILTINTYPE_TYPEID_STRING = 20
-BUILTINTYPE_TYPEID_XMLELEMENT = 21
-BUILTINTYPE_TYPEID_BYTESTRING = 22
-BUILTINTYPE_TYPEID_DIAGNOSTICINFO = 23

+ 0 - 629
tools/pyUANamespace/ua_namespace.py

@@ -1,629 +0,0 @@
-#!/usr/bin/env/python
-# -*- coding: utf-8 -*-
-
-###
-### Author:  Chris Iatrou (ichrispa@core-vector.net)
-### Version: rev 13
-###
-### This program was created for educational purposes and has been 
-### contributed to the open62541 project by the author. All licensing 
-### terms for this source is inherited by the terms and conditions
-### specified for by the open62541 project (see the projects readme
-### file for more information on the LGPL terms and restrictions).
-###
-### This program is not meant to be used in a production environment. The
-### author is not liable for any complications arising due to the use of
-### this program.
-###
-
-
-from time import struct_time, strftime, strptime, mktime
-from struct import pack as structpack
-
-from logger import *;
-from ua_builtin_types import *;
-from ua_node_types import *;
-from open62541_MacroHelper import open62541_MacroHelper
-
-def getNextElementNode(xmlvalue):
-  if xmlvalue == None:
-    return None
-  xmlvalue = xmlvalue.nextSibling
-  while not xmlvalue == None and not xmlvalue.nodeType == xmlvalue.ELEMENT_NODE:
-    xmlvalue = xmlvalue.nextSibling
-  return xmlvalue
-
-###
-### Namespace Organizer
-###
-
-class opcua_namespace():
-  """ Class holding and managing a set of OPCUA nodes.
-
-      This class handles parsing XML description of namespaces, instantiating
-      nodes, linking references, graphing the namespace and compiling a binary
-      representation.
-
-      Note that nodes assigned to this class are not restricted to having a
-      single namespace ID. This class represents the entire physical address
-      space of the binary representation and all nodes that are to be included
-      in that segment of memory.
-  """
-  nodes = []
-  nodeids = {}
-  aliases = {}
-  __linkLater__ = []
-  __binaryIndirectPointers__ = []
-  name = ""
-  knownNodeTypes = ""
-
-  def __init__(self, name):
-    self.nodes = []
-    self.knownNodeTypes = ['variable', 'object', 'method', 'referencetype', \
-                           'objecttype', 'variabletype', 'methodtype', \
-                           'datatype', 'referencetype', 'aliases']
-    self.name = name
-    self.nodeids = {}
-    self.aliases = {}
-    self.__binaryIndirectPointers__ = []
-
-  def linkLater(self, pointer):
-    """ Called by nodes or references who have parsed an XML reference to a
-        node represented by a string.
-
-        No return value
-
-        XML String representations of references have the form 'i=xy' or
-        'ns=1;s="This unique Node"'. Since during the parsing of this attribute
-        only a subset of nodes are known/parsed, this reference string cannot be
-        linked when encountered.
-
-        References register themselves with the namespace to have their target
-        attribute (string) parsed by linkOpenPointers() when all nodes are
-        created, so that target can be dereferenced an point to an actual node.
-    """
-    self.__linkLater__.append(pointer)
-
-  def getUnlinkedPointers(self):
-    """ Return the list of references registered for linking during the next call
-        of linkOpenPointers()
-    """
-    return self.__linkLater__
-
-  def unlinkedItemCount(self):
-    """ Returns the number of unlinked references that will be processed during
-        the next call of linkOpenPointers()
-    """
-    return len(self.__linkLater__)
-
-  def buildAliasList(self, xmlelement):
-    """ Parses the <Alias> XML Element present in must XML NodeSet definitions.
-
-        No return value
-
-        Contents the Alias element are stored in a dictionary for further
-        dereferencing during pointer linkage (see linkOpenPointer()).
-    """
-    if not xmlelement.tagName == "Aliases":
-      log(self, "XMLElement passed is not an Aliaslist", LOG_LEVEL_ERROR)
-      return
-    for al in xmlelement.childNodes:
-      if al.nodeType == al.ELEMENT_NODE:
-        if al.hasAttribute("Alias"):
-          aliasst = al.getAttribute("Alias")
-          aliasnd = unicode(al.firstChild.data)
-          if not self.aliases.has_key(aliasst):
-            self.aliases[aliasst] = aliasnd
-            log(self, "Added new alias \"" + str(aliasst) + "\" == \"" + str(aliasnd) + "\"")
-          else:
-            if self.aliases[aliasst] != aliasnd:
-              log(self, "Alias definitions for " + aliasst + " differ. Have " + self.aliases[aliasst] + " but XML defines " + aliasnd + ". Keeping current definition.", LOG_LEVEL_ERROR)
-
-  def getNodeByBrowseName(self, idstring):
-    """ Returns the first node in the nodelist whose browseName matches idstring.
-    """
-    matches = []
-    for n in self.nodes:
-      if idstring==str(n.browseName()):
-        matches.append(n)
-    if len(matches) > 1:
-      log(self, "Found multiple nodes with same ID!?", LOG_LEVEL_ERROR)
-    if len(matches) == 0:
-      return None
-    else:
-      return matches[0]
-
-  def getNodeByIDString(self, idstring):
-    """ Returns the first node in the nodelist whose id string representation
-        matches idstring.
-    """
-    matches = []
-    for n in self.nodes:
-      if idstring==str(n.id()):
-        matches.append(n)
-    if len(matches) > 1:
-      log(self, "Found multiple nodes with same ID!?", LOG_LEVEL_ERROR)
-    if len(matches) == 0:
-      return None
-    else:
-      return matches[0]
-
-  def createNode(self, ndtype, xmlelement):
-    """ createNode is instantiates a node described by xmlelement, its type being
-        defined by the string ndtype.
-
-        No return value
-
-        If the xmlelement is an <Alias>, the contents will be parsed and stored
-        for later dereferencing during pointer linking (see linkOpenPointers).
-
-        Recognized types are:
-        * UAVariable
-        * UAObject
-        * UAMethod
-        * UAView
-        * UAVariableType
-        * UAObjectType
-        * UAMethodType
-        * UAReferenceType
-        * UADataType
-
-        For every recognized type, an appropriate node class is added to the node
-        list of the namespace. The NodeId of the given node is created and parsing
-        of the node attributes and elements is delegated to the parseXML() and
-        parseXMLSubType() functions of the instantiated class.
-
-        If the NodeID attribute is non-unique in the node list, the creation is
-        deferred and an error is logged.
-    """
-    if not isinstance(xmlelement, dom.Element):
-      log(self,  "Error: Can not create node from invalid XMLElement", LOG_LEVEL_ERROR)
-      return
-
-    # An ID is manditory for everything but aliases!
-    id = None
-    for idname in ['NodeId', 'NodeID', 'nodeid']:
-      if xmlelement.hasAttribute(idname):
-        id = xmlelement.getAttribute(idname)
-    if ndtype == 'aliases':
-      self.buildAliasList(xmlelement)
-      return
-    elif id == None:
-      log(self,  "Error: XMLElement has no id, node will not be created!", LOG_LEVEL_INFO)
-      return
-    else:
-      id = opcua_node_id_t(id)
-
-    if self.nodeids.has_key(str(id)):
-      log(self,  "Error: XMLElement with duplicate ID " + str(id) + " found, node will not be created!", LOG_LEVEL_ERROR)
-      return
-
-    node = None
-    if (ndtype == 'variable'):
-      node = opcua_node_variable_t(id, self)
-    elif (ndtype == 'object'):
-      node = opcua_node_object_t(id, self)
-    elif (ndtype == 'method'):
-      node = opcua_node_method_t(id, self)
-    elif (ndtype == 'objecttype'):
-      node = opcua_node_objectType_t(id, self)
-    elif (ndtype == 'variabletype'):
-      node = opcua_node_variableType_t(id, self)
-    elif (ndtype == 'methodtype'):
-      node = opcua_node_methodType_t(id, self)
-    elif (ndtype == 'datatype'):
-      node = opcua_node_dataType_t(id, self)
-    elif (ndtype == 'referencetype'):
-      node = opcua_node_referenceType_t(id, self)
-    else:
-      log(self,  "No node constructor for type " + ndtype, LOG_LEVEL_ERROR)
-
-    if node != None:
-      node.parseXML(xmlelement)
-
-    self.nodes.append(node)
-    self.nodeids[str(node.id())] = node
-
-  def registerBinaryIndirectPointer(self, node):
-    """ Appends a node to the list of nodes that should be contained in the
-        first 765 bytes (255 pointer slots a 3 bytes) in the binary
-        representation (indirect referencing space).
-
-        This function is reserved for references and dataType pointers.
-    """
-    if not node in self.__binaryIndirectPointers__:
-      self.__binaryIndirectPointers__.append(node)
-    return self.__binaryIndirectPointers__.index(node)
-
-  def getBinaryIndirectPointerIndex(self, node):
-    """ Returns the slot/index of a pointer in the indirect referencing space
-        (first 765 Bytes) of the binary representation.
-    """
-    if not node in self.__binaryIndirectPointers__:
-      return -1
-    return self.__binaryIndirectPointers__.index(node)
-
-
-  def parseXML(self, xmldoc):
-    """ Reads an XML Namespace definition and instantiates node.
-
-        No return value
-
-        parseXML open the file xmldoc using xml.dom.minidom and searches for
-        the first UANodeSet Element. For every Element encountered, createNode
-        is called to instantiate a node of the appropriate type.
-    """
-    typedict = {}
-    UANodeSet = dom.parse(xmldoc).getElementsByTagName("UANodeSet")
-    if len(UANodeSet) == 0:
-      log(self,  "Error: No NodeSets found", LOG_LEVEL_ERROR)
-      return
-    if len(UANodeSet) != 1:
-      log(self,  "Error: Found more than 1 Nodeset in XML File", LOG_LEVEL_ERROR)
-
-    UANodeSet = UANodeSet[0]
-    for nd in UANodeSet.childNodes:
-      if nd.nodeType != nd.ELEMENT_NODE:
-        continue
-
-      ndType = nd.tagName.lower()
-      if ndType[:2] == "ua":
-        ndType = ndType[2:]
-      elif not ndType in self.knownNodeTypes:
-        log(self, "XML Element or NodeType " + ndType + " is unknown and will be ignored", LOG_LEVEL_WARN)
-        continue
-
-      if not typedict.has_key(ndType):
-        typedict[ndType] = 1
-      else:
-        typedict[ndType] = typedict[ndType] + 1
-
-      self.createNode(ndType, nd)
-    log(self, "Currently " + str(len(self.nodes)) + " nodes in address space. Type distribution for this run was: " + str(typedict))
-
-  def linkOpenPointers(self):
-    """ Substitutes symbolic NodeIds in references for actual node instances.
-
-        No return value
-
-        References that have registered themselves with linkLater() to have
-        their symbolic NodeId targets ("ns=2; i=32") substited for an actual
-        node will be iterated by this function. For each reference encountered
-        in the list of unlinked/open references, the target string will be
-        evaluated and searched for in the node list of this namespace. If found,
-        the target attribute of the reference will be substituted for the
-        found node.
-
-        If a reference fails to get linked, it will remain in the list of
-        unlinked references. The individual items in this list can be
-        retrieved using getUnlinkedPointers().
-    """
-    linked = []
-
-    log(self,  str(self.unlinkedItemCount()) + " pointers need to get linked.")
-    for l in self.__linkLater__:
-      targetLinked = False
-      if not l.target() == None and not isinstance(l.target(), opcua_node_t):
-        if isinstance(l.target(),str) or isinstance(l.target(),unicode):
-          # If is not a node ID, it should be an alias. Try replacing it
-          # with a proper node ID
-          if l.target() in self.aliases:
-            l.target(self.aliases[l.target()])
-          # If the link is a node ID, try to find it hopening that no ass has
-          # defined more than one kind of id for that sucker
-          if l.target()[:2] == "i=" or l.target()[:2] == "g=" or \
-             l.target()[:2] == "b=" or l.target()[:2] == "s=" or \
-             l.target()[:3] == "ns=" :
-            tgt = self.getNodeByIDString(str(l.target()))
-            if tgt == None:
-              log(self, "Failed to link pointer to target (node not found) " + l.target(), LOG_LEVEL_ERROR)
-            else:
-              l.target(tgt)
-              targetLinked = True
-          else:
-            log(self, "Failed to link pointer to target (target not Alias or Node) " + l.target(), LOG_LEVEL_ERROR)
-        else:
-          log(self, "Failed to link pointer to target (don't know dummy type + " + str(type(l.target())) + " +) " + str(l.target()), LOG_LEVEL_ERROR)
-      else:
-        log(self, "Pointer has null target: " + str(l), LOG_LEVEL_ERROR)
-
-
-      referenceLinked = False
-      if not l.referenceType() == None:
-        if l.referenceType() in self.aliases:
-          l.referenceType(self.aliases[l.referenceType()])
-        if l.referenceType()[:2] == "i=" or l.referenceType()[:2] == "g=" or \
-           l.referenceType()[:2] == "b=" or l.referenceType()[:2] == "s=":
-          tgt = self.getNodeByIDString(str(l.referenceType()))
-          if tgt == None:
-            log(self, "Failed to link reference type to target (node not found) " + l.referenceType(), LOG_LEVEL_ERROR)
-          else:
-            l.referenceType(tgt)
-            referenceLinked = True
-      else:
-        referenceLinked = True
-
-      if referenceLinked == True and targetLinked == True:
-        linked.append(l)
-
-    # References marked as "not forward" must be inverted (removed from source node, assigned to target node and relinked)
-    log(self, "Inverting reference direction for all references with isForward==False attribute (is this correct!?)", LOG_LEVEL_WARN)
-    for n in self.nodes:
-      for r in n.getReferences():
-        if r.isForward() == False:
-          tgt = r.target()
-          if isinstance(tgt, opcua_node_t):
-            nref = opcua_referencePointer_t(n, parentNode=tgt)
-            nref.referenceType(r.referenceType())
-            tgt.addReference(nref)
-
-    # Create inverse references for all nodes
-    log(self, "Updating all referencedBy fields in nodes for inverse lookups.")
-    for n in self.nodes:
-      n.updateInverseReferences()
-
-    for l in linked:
-      self.__linkLater__.remove(l)
-
-    if len(self.__linkLater__) != 0:
-      log(self, str(len(self.__linkLater__)) + " could not be linked.", LOG_LEVEL_WARN)
-
-  def sanitize(self):
-    remove = []
-    log(self, "Sanitizing nodes and references...")
-    for n in self.nodes:
-      if n.sanitize() == False:
-        remove.append(n)
-    if not len(remove) == 0:
-      log(self, str(len(remove)) + " nodes will be removed because they failed sanitation.", LOG_LEVEL_WARN)
-    # FIXME: Some variable ns=0 nodes fail because they don't have DataType fields...
-    #        How should this be handles!?
-    log(self, "Not actually removing nodes... it's unclear if this is valid or not", LOG_LEVEL_WARN)
-
-  def getRoot(self):
-    """ Returns the first node instance with the browseName "Root".
-    """
-    return self.getNodeByBrowseName("Root")
-
-  def buildEncodingRules(self):
-    """ Calls buildEncoding() for all DataType nodes (opcua_node_dataType_t).
-
-        No return value
-    """
-    stat = {True: 0, False: 0}
-    for n in self.nodes:
-      if isinstance(n, opcua_node_dataType_t):
-        n.buildEncoding()
-        stat[n.isEncodable()] = stat[n.isEncodable()] + 1
-    log(self, "Type definitions built/passed: " +  str(stat), LOG_LEVEL_DEBUG)
-
-  def allocateVariables(self):
-    for n in self.nodes:
-      if isinstance(n, opcua_node_variable_t):
-        n.allocateValue()
-
-  def printDot(self, filename="namespace.dot"):
-    """ Outputs a graphiz/dot description of all nodes in the namespace.
-
-        Output will written into filename to be parsed by dot/neato...
-
-        Note that for namespaces with more then 20 nodes the reference structure
-        will lead to a mostly illegible and huge graph. Use printDotGraphWalk()
-        for plotting specific portions of a large namespace.
-    """
-    file=open(filename, 'w+')
-
-    file.write("digraph ns {\n")
-    for n in self.nodes:
-      file.write(n.printDot())
-    file.write("}\n")
-    file.close()
-
-  def printDotGraphWalk(self, depth=1, filename="out.dot", rootNode=None, followInverse = False, excludeNodeIds=[]):
-    """ Outputs a graphiz/dot description the nodes centered around rootNode.
-
-        References beginning from rootNode will be followed for depth steps. If
-        "followInverse = True" is passed, then inverse (not Forward) references
-        will also be followed.
-
-        Nodes can be excluded from the graph by passing a list of NodeIds as
-        string representation using excludeNodeIds (ex ["i=53", "ns=2;i=453"]).
-
-        Output is written into filename to be parsed by dot/neato/srfp...
-    """
-    iter = depth
-    processed = []
-    if rootNode == None or \
-       not isinstance(rootNode, opcua_node_t) or \
-       not rootNode in self.nodes:
-      root = self.getRoot()
-    else:
-      root = rootNode
-
-    file=open(filename, 'w+')
-
-    if root == None:
-      return
-
-    file.write("digraph ns {\n")
-    file.write(root.printDot())
-    refs=[]
-    if followInverse == True:
-      refs = root.getReferences(); # + root.getInverseReferences()
-    else:
-      for ref in root.getReferences():
-        if ref.isForward():
-          refs.append(ref)
-    while iter > 0:
-      tmp = []
-      for ref in refs:
-        if isinstance(ref.target(), opcua_node_t):
-          tgt = ref.target()
-          if not str(tgt.id()) in excludeNodeIds:
-            if not tgt in processed:
-              file.write(tgt.printDot())
-              processed.append(tgt)
-              if ref.isForward() == False and followInverse == True:
-                tmp = tmp + tgt.getReferences(); # + tgt.getInverseReferences()
-              elif ref.isForward() == True :
-                tmp = tmp + tgt.getReferences();
-      refs = tmp
-      iter = iter - 1
-
-    file.write("}\n")
-    file.close()
-
-  def printOpen62541Header(self):
-    unPrintedNodes = []
-    unPrintedRefs  = []
-    code = []
-
-    # Some macros (UA_EXPANDEDNODEID_MACRO()...) are easily created, but
-    # bulky. This class will help to offload some code.
-    codegen = open62541_MacroHelper()
-
-    # 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.
-    unPrintedNodes = unPrintedNodes + self.nodes
-    for n in self.nodes:
-      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)
-    code.append("/* WARNING: This is a generated file.\n * Any manual changes will be overwritten.\n */")
-
-    # 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)
-
-    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 code
-
-###
-### Testing
-###
-
-class testing:
-  def __init__(self):
-    self.namespace = opcua_namespace("testing")
-
-    log(self, "Phase 1: Reading XML file nodessets")
-    self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
-    #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
-    #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
-    #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
-
-    log(self, "Phase 2: Linking address space references and datatypes")
-    self.namespace.linkOpenPointers()
-    self.namespace.sanitize()
-
-    log(self, "Phase 3: Comprehending DataType encoding rules")
-    self.namespace.buildEncodingRules()
-
-    log(self, "Phase 4: Allocating variable value data")
-    self.namespace.allocateVariables()
-
-    bin = self.namespace.buildBinary()
-    f = open("binary.base64","w+")
-    f.write(bin.encode("base64"))
-    f.close()
-
-    allnodes = self.namespace.nodes;
-    ns = [self.namespace.getRoot()]
-
-    i = 0
-    print "Starting depth search on " + str(len(allnodes)) + " nodes starting with from " + str(ns)
-    while (len(ns) < len(allnodes)):
-      i = i + 1;
-      tmp = [];
-      print "Iteration: " + str(i)
-      for n in ns:
-        tmp.append(n)
-        for r in n.getReferences():
-          if (not r.target() in tmp):
-           tmp.append(r.target())
-      print "...tmp, " + str(len(tmp)) + " nodes discovered"
-      ns = []
-      for n in tmp:
-        ns.append(n)
-      print "...done, " + str(len(ns)) + " nodes discovered"
-
-    log(self, "Phase 5: Printing pretty graph")
-    self.namespace.printDotGraphWalk(depth=1, rootNode=self.namespace.getNodeByIDString("i=84"), followInverse=False, excludeNodeIds=["i=29", "i=22", "i=25"])
-    #self.namespace.printDot()
-
-class testing_open62541_header:
-  def __init__(self):
-    self.namespace = opcua_namespace("testing")
-
-    log(self, "Phase 1: Reading XML file nodessets")
-    self.namespace.parseXML("Opc.Ua.NodeSet2.xml")
-    #self.namespace.parseXML("Opc.Ua.NodeSet2.Part4.xml")
-    #self.namespace.parseXML("Opc.Ua.NodeSet2.Part5.xml")
-    #self.namespace.parseXML("Opc.Ua.SimulationNodeSet2.xml")
-
-    log(self, "Phase 2: Linking address space references and datatypes")
-    self.namespace.linkOpenPointers()
-    self.namespace.sanitize()
-
-    log(self, "Phase 3: Calling C Printers")
-    code = self.namespace.printOpen62541Header()
-
-    codeout = open("./open62541_namespace.c", "w+")
-    for line in code:
-      codeout.write(line + "\n")
-    codeout.close()
-    return
-
-# Call testing routine if invoked standalone.
-# For better debugging, it is advised to import this file using an interactive
-# python shell and instantiating a namespace.
-#
-# import ua_types.py as ua; ns=ua.testing().namespace
-if __name__ == '__main__':
-  tst = testing_open62541_header()

File diff suppressed because it is too large
+ 0 - 1488
tools/pyUANamespace/ua_node_types.py