generate_namespace.py 9.2 KB

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