ソースを参照

Generate nodemacros out of valid characters only (#581)

* Code generation: replace punctuation characters for macro identifiers

Fix #578. Replace punctuation characters with '_'

* Git commit id for out-of-tree builds

If the build directory is not a subdirectory of the source directory the
external command to read the GIT_COMMIT_ID failed.
The information was not available in the generated headers.
Thomas Ruschival 9 年 前
コミット
08b3fb8f70
共有2 個のファイルを変更した48 個の追加18 個の削除を含む
  1. 2 1
      CMakeLists.txt
  2. 46 17
      tools/pyUANamespace/open62541_MacroHelper.py

+ 2 - 1
CMakeLists.txt

@@ -19,7 +19,8 @@ find_package(Git)
 if(GIT_FOUND)
   execute_process(COMMAND ${GIT_EXECUTABLE} describe --abbrev=7 --dirty --always --tags
                   RESULT_VARIABLE res_var
-                  OUTPUT_VARIABLE GIT_COM_ID )
+                  OUTPUT_VARIABLE GIT_COM_ID
+				  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
     if(NOT ${res_var} EQUAL 0)
         set(GIT_COMMIT_ID "unknown--git-commit-id-unknown")
         message(STATUS "Git failed (not a repo, or no tags). Build will not contain git revision info." )

+ 46 - 17
tools/pyUANamespace/open62541_MacroHelper.py

@@ -18,13 +18,33 @@
 
 from logger import *
 from ua_constants import *
+import string
 
 __unique_item_id = 0
 
+
+def substitutePunctuationCharacters(input):
+  '''
+  replace punctuation characters in input
+  '''
+  # No punctuation characters <>!$
+  illegal_chars = list(string.punctuation)
+  # underscore is allowed
+  illegal_chars.remove('_')
+
+  illegal = "".join(illegal_chars)
+  substitution = ""
+  # Map all punctuation characters to underscore
+  for illegal_char in illegal_chars:
+      substitution = substitution + '_'
+
+  return input.translate(string.maketrans(illegal, substitution), illegal)
+
+
 class open62541_MacroHelper():
   def __init__(self, supressGenerationOfAttribute=[]):
     self.supressGenerationOfAttribute = supressGenerationOfAttribute
-    
+
   def getCreateExpandedNodeIDMacro(self, node):
     if node.id().i != None:
       return "UA_EXPANDEDNODEID_NUMERIC(" + str(node.id().ns) + ", " + str(node.id().i) + ")"
@@ -38,16 +58,25 @@ class open62541_MacroHelper():
       return ""
     else:
       return ""
-  
+
+
   def getNodeIdDefineString(self, node):
     code = []
     extrNs = node.browseName().split(":")
+    symbolic_name = ""
+    # strip all characters that would be illegal in C-Code
     if len(extrNs) > 1:
-      code.append("#define UA_NS"  + str(node.id().ns) + "ID_" + extrNs[1].upper() + " " + str(node.id().i))
+        nodename = extrNs[1]
     else:
-      code.append("#define UA_NS"  + str(node.id().ns) + "ID_" + extrNs[0].upper() + " " + str(node.id().i))
+        nodename = extrNs[0]
+
+    symbolic_name = substitutePunctuationCharacters(nodename)
+    if symbolic_name != nodename :
+        log(self, "Subsituted characters in browsename for nodeid " + str(node.id().i) + " while generating C-Code ", LOG_LEVEL_WARN)
+
+    code.append("#define UA_NS"  + str(node.id().ns) + "ID_" + symbolic_name.upper() + " " + str(node.id().i))
     return code
-  
+
   def getCreateNodeIDMacro(self, node):
     if node.id().i != None:
       return "UA_NODEID_NUMERIC(" + str(node.id().ns) + ", " + str(node.id().i) + ")"
@@ -70,7 +99,7 @@ class open62541_MacroHelper():
     else:
       code.append("UA_Server_addReference(server, " + self.getCreateNodeIDMacro(sourcenode) + ", " + self.getCreateNodeIDMacro(reference.referenceType()) + ", " + self.getCreateExpandedNodeIDMacro(reference.target()) + ", false);")
     return code
-                               
+
   def getCreateNodeNoBootstrap(self, node, parentNode, parentReference, unprintedNodes):
     code = []
     code.append("// Node: " + str(node) + ", " + str(node.browseName()))
@@ -95,11 +124,11 @@ class open62541_MacroHelper():
       code.append("/* undefined nodeclass */")
       return code;
 
-    # If this is a method, construct in/outargs for addMethod 
+    # If this is a method, construct in/outargs for addMethod
     #inputArguments.arrayDimensionsSize = 0;
     #inputArguments.arrayDimensions = NULL;
     #inputArguments.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
-    
+
     # Node ordering should have made sure that arguments, if they exist, have not been printed yet
     if node.nodeClass() == NODE_CLASS_METHOD:
       inArgVal = []
@@ -153,13 +182,13 @@ class open62541_MacroHelper():
 	  #if outArg.getValueFieldByAlias("ArrayDimensions") != None:
 	  #  code.append("outputArguments[" + str(argumentCnt) + "].arrayDimensions = " + str(outArg.getValueFieldByAlias("ArrayDimensions")) + ";")
 	  argumentCnt += 1
-	  
+
     # print the attributes struct
     code.append("UA_%sAttributes attr;" % nodetype)
-    code.append("UA_%sAttributes_init(&attr);" %  nodetype); 
+    code.append("UA_%sAttributes_init(&attr);" %  nodetype);
     code.append("attr.displayName = UA_LOCALIZEDTEXT(\"\", \"" + str(node.displayName()) + "\");")
     code.append("attr.description = UA_LOCALIZEDTEXT(\"\", \"" + str(node.description()) + "\");")
-    
+
     if nodetype in ["Variable", "VariableType"]:
       code = code + node.printOpen62541CCode_SubtypeEarly(bootstrapping = False)
     elif nodetype == "Method":
@@ -167,7 +196,7 @@ class open62541_MacroHelper():
 	code.append("attr.executable = true;")
       if node.userExecutable():
 	code.append("attr.userExecutable = true;")
-	
+
     code.append("UA_NodeId nodeId = " + str(self.getCreateNodeIDMacro(node)) + ";")
     if nodetype in ["Object", "Variable"]:
       code.append("UA_NodeId typeDefinition = UA_NODEID_NULL;") # todo instantiation of object and variable types
@@ -178,19 +207,19 @@ class open62541_MacroHelper():
       code.append("UA_QualifiedName nodeName = UA_QUALIFIEDNAME(" +  str(extrNs[0]) + ", \"" + extrNs[1] + "\");")
     else:
       code.append("UA_QualifiedName nodeName = UA_QUALIFIEDNAME(0, \"" + str(node.browseName()) + "\");")
-    
-    # In case of a MethodNode: Add in|outArg struct generation here. Mandates that namespace reordering was done using 
+
+    # In case of a MethodNode: Add in|outArg struct generation here. Mandates that namespace reordering was done using
     # Djikstra (check that arguments have not been printed). (@ichrispa)
     code.append("UA_Server_add%sNode(server, nodeId, parentNodeId, parentReferenceNodeId, nodeName" % nodetype)
-      
+
     if nodetype in ["Object", "Variable"]:
-      code.append("       , typeDefinition") 
+      code.append("       , typeDefinition")
     if nodetype != "Method":
       code.append("       , attr, NULL, NULL);")
     else:
       code.append("       , attr, (UA_MethodCallback) NULL, NULL, " + str(len(inArgVal)) + ", inputArguments,  " + str(len(outArgVal)) + ", outputArguments, NULL);")
     return code
-    
+
   def getCreateNodeBootstrap(self, node):
     nodetype = ""
     code = []