generate_namespace.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. from __future__ import print_function
  2. import inspect
  3. import sys
  4. import platform
  5. import getpass
  6. import time
  7. if len(sys.argv) != 3:
  8. print("Usage: python generate_namespace.py <path/to/NodeIds.csv> <outfile w/o extension>", file=sys.stdout)
  9. exit(0)
  10. # types that are to be excluded
  11. exclude_kinds = set(["Object","ObjectType","Variable","Method","ReferenceType"])
  12. exclude_types = set(["Number", "Integer", "UInteger", "Enumeration",
  13. "Image", "ImageBMP", "ImageGIF", "ImageJPG", "ImagePNG",
  14. "References", "BaseVariableType", "BaseDataVariableType",
  15. "PropertyType", "DataTypeDescriptionType", "DataTypeDictionaryType", "NamingRuleType",
  16. "IntegerId","Counter","Duration","NumericRange","Time","Date",
  17. "UtcTime", "LocaleId","UserTokenType",
  18. "ApplicationType","ApplicationInstanceCertificate",
  19. "ServerVendorCapabilityType","ServerStatusType","ServerDiagnosticsSummaryType",
  20. "SamplingIntervalDiagnosticsArrayType", "SamplingIntervalDiagnosticsType",
  21. "SubscriptionDiagnosticsArrayType", "SubscriptionDiagnosticsType",
  22. "SessionDiagnosticsArrayType", "SessionDiagnosticsVariableType",
  23. "SessionSecurityDiagnosticsArrayType", "SessionSecurityDiagnosticsType",
  24. "DataItemType", "AnalogItemType", "DiscreteItemType", "TwoStateDiscreteType",
  25. "MultiStateDiscreteType", "ProgramDiagnosticType", "StateVariableType", "FiniteStateVariableType",
  26. "TransitionVariableType", "FiniteTransitionVariableType", "BuildInfoType", "TwoStateVariableType",
  27. "ConditionVariableType", "MultiStateValueDiscreteType", "OptionSetType", "ArrayItemType",
  28. "YArrayItemType", "XYArrayItemType", "ImageItemType", "CubeItemType", "NDimensionArrayItemType"])
  29. fixed_size = ['UA_DeadbandType', 'UA_DataChangeTrigger', 'UA_Guid', 'UA_ApplicationType',
  30. 'UA_ComplexNumberType', 'UA_EnumeratedTestType', 'UA_BrowseResultMask',
  31. 'UA_TimeZoneDataType', 'UA_NodeClass', 'UA_IdType', 'UA_ServiceCounterDataType',
  32. 'UA_Float', 'UA_ModelChangeStructureVerbMask', 'UA_EndpointConfiguration',
  33. 'UA_NodeAttributesMask', 'UA_DataChangeFilter', 'UA_StatusCode', 'UA_MonitoringFilterResult',
  34. 'UA_OpenFileMode', 'UA_SecurityTokenRequestType', 'UA_ServerDiagnosticsSummaryDataType',
  35. 'UA_ElementOperand', 'UA_AggregateConfiguration', 'UA_UInt64', 'UA_FilterOperator',
  36. 'UA_ReadRawModifiedDetails', 'UA_ServerState', 'UA_FilterOperand', 'UA_SubscriptionAcknowledgement',
  37. 'UA_AttributeWriteMask', 'UA_SByte', 'UA_Int32', 'UA_Range', 'UA_Byte', 'UA_TimestampsToReturn',
  38. 'UA_UserTokenType', 'UA_Int16', 'UA_XVType', 'UA_AggregateFilterResult', 'UA_Boolean',
  39. 'UA_MessageSecurityMode', 'UA_AxisScaleEnumeration', 'UA_PerformUpdateType', 'UA_UInt16',
  40. 'UA_NotificationData', 'UA_DoubleComplexNumberType', 'UA_HistoryUpdateType', 'UA_MonitoringFilter',
  41. 'UA_NodeIdType', 'UA_BrowseDirection', 'UA_SamplingIntervalDiagnosticsDataType', 'UA_UInt32',
  42. 'UA_ChannelSecurityToken', 'UA_RedundancySupport', 'UA_MonitoringMode', 'UA_HistoryReadDetails',
  43. 'UA_ExceptionDeviationFormat', 'UA_ComplianceLevel', 'UA_DateTime', 'UA_Int64', 'UA_Double']
  44. f = open(sys.argv[1])
  45. input_str = f.read() + "\nInvalidType,0,DataType"
  46. input_str = input_str.replace('\r','')
  47. rows = map(lambda x:tuple(x.split(',')), input_str.split('\n'))
  48. f.close()
  49. fh = open(sys.argv[2] + ".h",'w')
  50. fc = open(sys.argv[2] + ".c",'w')
  51. def printh(string):
  52. print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fh)
  53. def printc(string):
  54. print(string % inspect.currentframe().f_back.f_locals, end='\n', file=fc)
  55. printh('''/**********************************************************
  56. * '''+sys.argv[2]+'''.hgen -- do not modify
  57. **********************************************************
  58. * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
  59. * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  60. **********************************************************/\n
  61. #ifndef ''' + sys.argv[2].upper() + '''_H_
  62. #define ''' + sys.argv[2].upper() + '''_H_\n
  63. #include "ua_util.h"
  64. #include "ua_types.h" // definition of UA_VTable and basic UA_Types
  65. #include "ua_types_generated.h"\n
  66. /**
  67. * @brief maps namespace zero nodeId to index into UA_VTable
  68. *
  69. * @param[in] ns0Id The namespace zero nodeId
  70. *
  71. * @retval UA_ERR_INVALID_VALUE whenever ns0Id could not be mapped
  72. * @retval the corresponding index into UA_VTable
  73. */\n
  74. UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id);\n
  75. extern const UA_VTable UA_;\n
  76. static UA_Int32 phantom_delete(void * p) { return UA_SUCCESS; }
  77. extern const UA_VTable UA_borrowed_;\n
  78. /**
  79. * @brief the set of possible indices into UA_VTable
  80. *
  81. * Enumerated type to define the types that the open62541 stack can handle
  82. */
  83. enum UA_VTableIndex_enum {''')
  84. printc('''/**********************************************************
  85. * '''+sys.argv[2]+'''.cgen -- do not modify
  86. **********************************************************
  87. * Generated from '''+sys.argv[1]+''' with script '''+sys.argv[0]+'''
  88. * on host '''+platform.uname()[1]+''' by user '''+getpass.getuser()+''' at '''+ time.strftime("%Y-%m-%d %I:%M:%S")+'''
  89. **********************************************************/\n
  90. #include "''' + sys.argv[2] + '''.h"\n
  91. UA_Int32 UA_ns0ToVTableIndex(const UA_NodeId *id) {
  92. UA_Int32 retval = UA_ERR_INVALID_VALUE;
  93. if(id->namespace != 0) return retval;
  94. switch (id->identifier.numeric) {''')
  95. i = 0
  96. for row in rows:
  97. if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
  98. continue
  99. if row[0] == "BaseDataType":
  100. name = "UA_Variant"
  101. elif row[0] == "Structure":
  102. name = "UA_ExtensionObject"
  103. else:
  104. name = "UA_" + row[0]
  105. printh("\t"+name.upper()+" = "+str(i)+",")
  106. printc('\tcase '+row[1]+': retval='+name.upper()+'; break; //'+row[2])
  107. i = i+1
  108. printh("};\n")
  109. printc('''\n}\nreturn retval;\n}\n
  110. const UA_VTable UA_ = {
  111. \t.getTypeIndex = UA_ns0ToVTableIndex,
  112. \t.types = (UA_VTable_Entry[]){''')
  113. for row in rows:
  114. if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
  115. continue
  116. if row[0] == "BaseDataType":
  117. name = "UA_Variant"
  118. elif row[0] == "Structure":
  119. name = "UA_ExtensionObject"
  120. else:
  121. name = "UA_" + row[0]
  122. printh('#define '+name.upper()+'_NS0 '+row[1])
  123. printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] +"}"+
  124. ",.name=(UA_Byte*)&\""+name+"\""+
  125. ",.new=(UA_Int32(*)(void **))"+name+"_new"+
  126. ",.init=(UA_Int32(*)(void *))"+name+"_init"+
  127. ",.copy=(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
  128. ",.delete=(UA_Int32(*)(void *))"+name+"_delete"+
  129. ",.deleteMembers=(UA_Int32(*)(void *))"+name+"_deleteMembers"+
  130. ",.memSize=" + ("sizeof("+name+")" if (name != "UA_InvalidType") else "0") +
  131. ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
  132. ",.encodings={{.calcSize=(UA_calcSize)"+ name +"_calcSizeBinary" +
  133. ",.encode=(UA_encode)"+name+ "_encodeBinary" +
  134. ",.decode=(UA_decode)"+name+"_decodeBinary}"+
  135. ",{.calcSize=(UA_calcSize)"+ name +"_calcSizeXml" +
  136. ",.encode=(UA_encode)"+name+ "_encodeXml" +
  137. ",.decode=(UA_decode)"+name+"_decodeXml}"+
  138. "}},")
  139. printc('''}};
  140. const UA_VTable UA_noDelete_ = {
  141. \t.getTypeIndex=UA_ns0ToVTableIndex,
  142. \t.types = (UA_VTable_Entry[]){''')
  143. for row in rows:
  144. if row[0] == "" or row[0] in exclude_types or row[2] in exclude_kinds:
  145. continue
  146. if row[0] == "BaseDataType":
  147. name = "UA_Variant"
  148. elif row[0] == "Structure":
  149. name = "UA_ExtensionObject"
  150. else:
  151. name = "UA_" + row[0]
  152. printc("\t{.typeId={UA_NODEIDTYPE_FOURBYTE,0,.identifier.numeric=" + row[1] +"}"+
  153. ",.name=(UA_Byte*)&\""+name+"\""+
  154. ",.new=(UA_Int32(*)(void **))"+name+"_new"+
  155. ",.init=(UA_Int32(*)(void *))"+name+"_init"+
  156. ",.copy=(UA_Int32(*)(void const * ,void*))"+name+"_copy"+
  157. ",.delete=(UA_Int32(*)(void *))phantom_delete"+
  158. ",.deleteMembers=(UA_Int32(*)(void *))phantom_delete"+
  159. ",.memSize=" + ("sizeof("+name+")" if (name != "UA_InvalidType") else "0") +
  160. ",.dynMembers=" + ("UA_FALSE" if (name in fixed_size) else "UA_TRUE") +
  161. ",.encodings={{.calcSize=(UA_calcSize)"+ name +"_calcSizeBinary" +
  162. ",.encode=(UA_encode)"+name+ "_encodeBinary" +
  163. ",.decode=(UA_decode)"+name+"_decodeBinary}"+
  164. ",{.calcSize=(UA_calcSize)"+ name +"_calcSizeXml" +
  165. ",.encode=(UA_encode)"+name+ "_encodeXml" +
  166. ",.decode=(UA_decode)"+name+"_decodeXml}"+
  167. "}},")
  168. printc("}};")
  169. printh('\n#endif /* OPCUA_NAMESPACE_0_H_ */')
  170. fh.close()
  171. fc.close()