changeset 57:c969b004d8c0

"since_sdk" for classes and enumerations
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 10 Aug 2025 13:20:30 +0200
parents 2059b5216851
children 34fa909facd3
files CodeGeneration/ParseOrthancSDK.py
diffstat 1 files changed, 46 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/CodeGeneration/ParseOrthancSDK.py	Sun Aug 10 11:15:57 2025 +0200
+++ b/CodeGeneration/ParseOrthancSDK.py	Sun Aug 10 13:20:30 2025 +0200
@@ -108,6 +108,23 @@
                     result = result + ' ' + line
         return result.replace('@brief ', '')
 
+def InjectSinceSdk(target, node):
+    since_sdk = None
+
+    for child in node.get_children():
+        if child.kind == clang.cindex.CursorKind.ANNOTATE_ATTR:
+            s = child.spelling.split(' ')
+            if s[0] == 'ORTHANC_PLUGIN_SINCE_SDK':
+                assert(len(s) == 2)
+                version = s[1].split('.')
+                assert(len(version) == 3)
+                assert(since_sdk == None)  # Cannot be defined multiple time
+                since_sdk = [ int(version[0]), int(version[1]), int(version[2]) ]
+
+    if since_sdk != None:
+        target['since_sdk'] = since_sdk
+
+
 for node in tu.cursor.get_children():
     # Only consider the Orthanc SDK
     path = node.location.file.name
@@ -133,24 +150,34 @@
                         raise Exception('Enumeration value without documentation: %s' % item.spelling)
 
                     key = item.spelling[len(name + '_'):]
-                    values.append({
+                    value = {
                         'key' : key,
                         'value' : item.enum_value,
                         'documentation' : ParseEnumValueDocumentation(item.raw_comment),
-                    })
+                    }
+
+                    InjectSinceSdk(value, item)
+                    values.append(value)
 
                 elif (item.kind == clang.cindex.CursorKind.ENUM_CONSTANT_DECL and
                       item.spelling == '_%s_INTERNAL' % name):
                     pass
 
+                elif (item.kind == clang.cindex.CursorKind.ANNOTATE_ATTR and
+                      item.spelling.startswith('ORTHANC_PLUGIN_SINCE_SDK ')):
+                    pass
+
                 else:
                     raise Exception('Ignoring unknown enumeration item: %s' % item.spelling)
 
-            enumerations[name] = {
+            value = {
                 'values' : values,
                 'documentation' : ParseEnumerationDocumentation(node.raw_comment),
             }
 
+            InjectSinceSdk(value, node)
+            enumerations[name] = value
+
         elif node.spelling == '':  # Unnamed enumeration (presumbaly "_OrthancPluginService")
             pass
 
@@ -163,11 +190,14 @@
             node.spelling != '_OrthancPluginContext_t'):
 
             name = node.spelling[len('_') : -len('_t')]
-            classes[name] = {
+            value = {
                 'name' : name,
                 'methods' : [ ],
             }
 
+            InjectSinceSdk(value, node)
+            classes[name] = value
+
         elif node.spelling in [ '',  # This is an internal structure to call Orthanc SDK
                                 '_OrthancPluginContext_t' ]:
             pass
@@ -444,17 +474,6 @@
             countAllFunctions += 1
             continue
 
-        since_sdk = None
-        for annotate in filter(lambda x: x.kind == clang.cindex.CursorKind.ANNOTATE_ATTR,
-                               node.get_children()):
-            s = annotate.spelling.split(' ')
-            if s[0] == 'ORTHANC_PLUGIN_SINCE_SDK':
-                assert(len(s) == 2)
-                version = s[1].split('.')
-                assert(len(version) == 3)
-                assert(since_sdk == None)
-                since_sdk = [ int(version[0]), int(version[1]), int(version[2]) ]
-
         args = list(filter(lambda x: x.kind == clang.cindex.CursorKind.PARM_DECL,
                            node.get_children()))
 
@@ -507,9 +526,10 @@
                     'c_function' : node.spelling,
                     'const' : args[0].type.get_pointee().is_const_qualified(),
                     'documentation' : doc,
-                    'since_sdk' : since_sdk,
                     }
 
+                InjectSinceSdk(method, node)
+
                 if not EncodeArguments(method, args[1:]):
                     pass
                 elif EncodeResultType(method, returnBufferType, node.result_type):
@@ -530,9 +550,10 @@
             f = {
                 'c_function' : node.spelling,
                 'documentation' : doc,
-                'since_sdk' : since_sdk,
             }
 
+            InjectSinceSdk(f, node)
+
             if not EncodeArguments(f, args):
                 pass
             elif EncodeResultType(f, returnBufferType, node.result_type):
@@ -549,11 +570,17 @@
 def FlattenEnumerations():
     result = []
     for (name, content) in enumerations.items():
-        result.append({
+        item = {
             'name' : name,
             'values' : content['values'],
             'documentation' : content['documentation'],
-            })
+        }
+
+        if 'since_sdk' in content:
+            item['since_sdk'] = content['since_sdk']
+
+        result.append(item)
+
     return result
 
 def FlattenDictionary(source):