[libvirt] [PATCH] esx: Reduce code duplication in generator

Matthias Bolte matthias.bolte at googlemail.com
Wed May 1 18:44:39 UTC 2013


---
 src/esx/esx_vi_generator.py |  430 ++++++++++++-------------------------------
 1 file changed, 118 insertions(+), 312 deletions(-)

diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 7130624..547eef6 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -440,8 +440,7 @@ class Type:
         return string
 
 
-
-class Object(Type):
+class GenericObject(Type):
     FEATURE__DYNAMIC_CAST = (1 << 1)
     FEATURE__LIST         = (1 << 2)
     FEATURE__DEEP_COPY    = (1 << 3)
@@ -450,16 +449,36 @@ class Object(Type):
     FEATURE__DESERIALIZE  = (1 << 6)
 
 
-    def __init__(self, name, extends, properties, features=0, extended_by=None):
+    def __init__(self, name, category, managed, generic_objects_by_name):
         Type.__init__(self, "struct", name)
-        self.extends = extends
-        self.features = features
-        self.properties = properties
-        self.extended_by = extended_by
-        self.candidate_for_dynamic_cast = False
+        self.category = category
+        self.managed = managed
+        self.generic_objects_by_name = generic_objects_by_name
+
+
+    def generate_comment(self):
+        comment = separator
+        comment += " * %s: %s\n" % (self.category, self.name)
+
+        if self.extends is not None:
+            comment += " * %s  extends %s\n" \
+                       % (' ' * len(self.category), self.extends)
+
+        first = True
 
         if self.extended_by is not None:
-            self.extended_by.sort()
+            for extended_by in self.extended_by:
+                if first:
+                    comment += " * %s  extended by %s\n" \
+                               % (' ' * len(self.category), extended_by)
+                    first = False
+                else:
+                    comment += " * %s              %s\n" \
+                               % (' ' * len(self.category), extended_by)
+
+        comment += " */\n\n"
+
+        return comment
 
 
     def generate_struct_members(self, add_banner=False, struct_gap=False):
@@ -469,7 +488,7 @@ class Object(Type):
             members += "\n"
 
         if self.extends is not None:
-            members += objects_by_name[self.extends] \
+            members += self.generic_objects_by_name[self.extends] \
                        .generate_struct_members(add_banner=True,
                                                 struct_gap=False) + "\n"
 
@@ -499,7 +518,7 @@ class Object(Type):
                           % (suffix, extended_by)
 
             for extended_by in self.extended_by:
-                source += objects_by_name[extended_by] \
+                source += self.generic_objects_by_name[extended_by] \
                           .generate_dispatch(suffix, False)
 
         return source
@@ -509,7 +528,7 @@ class Object(Type):
         source = ""
 
         if self.extends is not None:
-            source += objects_by_name[self.extends] \
+            source += self.generic_objects_by_name[self.extends] \
                       .generate_free_code(add_banner=True) + "\n"
 
         if self.extends is not None or add_banner:
@@ -535,7 +554,7 @@ class Object(Type):
         source = ""
 
         if self.extends is not None:
-            source += objects_by_name[self.extends] \
+            source += self.generic_objects_by_name[self.extends] \
                       .generate_validate_code(add_banner=True) + "\n"
 
         if self.extends is not None or add_banner:
@@ -547,7 +566,7 @@ class Object(Type):
             string = ""
 
             for property in self.properties:
-                string += property.generate_validate_code()
+                string += property.generate_validate_code(self.managed)
 
             if len(string) < 1:
                 source += "    /* no required properties */\n"
@@ -557,6 +576,20 @@ class Object(Type):
         return source
 
 
+
+class Object(GenericObject):
+    def __init__(self, name, extends, properties, features=0, extended_by=None):
+        GenericObject.__init__(self, name, 'VI Object', False, objects_by_name)
+        self.extends = extends
+        self.features = features
+        self.properties = properties
+        self.extended_by = extended_by
+        self.candidate_for_dynamic_cast = False
+
+        if self.extended_by is not None:
+            self.extended_by.sort()
+
+
     def generate_dynamic_cast_code(self, is_first=True):
         source = ""
 
@@ -642,23 +675,7 @@ class Object(Type):
 
 
     def generate_header(self):
-        header = separator
-        header += " * VI Object: %s\n" % self.name
-
-        if self.extends is not None:
-            header += " *            extends %s\n" % self.extends
-
-        first = True
-
-        if self.extended_by is not None:
-            for extended_by in self.extended_by:
-                if first:
-                    header += " *            extended by %s\n" % extended_by
-                    first = False
-                else:
-                    header += " *                        %s\n" % extended_by
-
-        header += " */\n\n"
+        header = self.generate_comment()
 
         # struct
         header += "struct _esxVI_%s {\n" % self.name
@@ -762,57 +779,37 @@ class Object(Type):
         source += "ESX_VI__TEMPLATE__ALLOC(%s)\n\n" % self.name
 
         # free
+        source += "/* esxVI_%s_Free */\n" % self.name
+
         if self.extended_by is None:
-            source += "/* esxVI_%s_Free */\n" % self.name
             source += "ESX_VI__TEMPLATE__FREE(%s,\n" % self.name
-            source += "{\n"
-
-            if self.features & Object.FEATURE__LIST:
-                if self.extends is not None:
-                    # avoid "dereferencing type-punned pointer will break
-                    # strict-aliasing rules" warnings
-                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
-                              % (self.extends, self.extends)
-                    source += "    esxVI_%s_Free(&next);\n" % self.extends
-                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
-                else:
-                    source += "    esxVI_%s_Free(&item->_next);\n\n" % self.name
-
-            source += self.generate_free_code()
-
-            source += "})\n\n"
         else:
-            source += "/* esxVI_%s_Free */\n" % self.name
             source += "ESX_VI__TEMPLATE__DYNAMIC_FREE(%s,\n" % self.name
             source += "{\n"
-
             source += self.generate_dispatch('FREE')
-
             source += "},\n"
-            source += "{\n"
 
-            if self.features & Object.FEATURE__LIST:
-                if self.extends is not None:
-                    # avoid "dereferencing type-punned pointer will break
-                    # strict-aliasing rules" warnings
-                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
-                              % (self.extends, self.extends)
-                    source += "    esxVI_%s_Free(&next);\n" % self.extends
-                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
-                else:
-                    source += "    esxVI_%s_Free(&item->_next);\n\n" % self.name
+        source += "{\n"
 
-            source += self.generate_free_code()
+        if self.features & Object.FEATURE__LIST:
+            if self.extends is not None:
+                # avoid "dereferencing type-punned pointer will break
+                # strict-aliasing rules" warnings
+                source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
+                          % (self.extends, self.extends)
+                source += "    esxVI_%s_Free(&next);\n" % self.extends
+                source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
+            else:
+                source += "    esxVI_%s_Free(&item->_next);\n\n" % self.name
 
-            source += "})\n\n"
+        source += self.generate_free_code()
+        source += "})\n\n"
 
         # validate
         source += "/* esxVI_%s_Validate */\n" % self.name
         source += "ESX_VI__TEMPLATE__VALIDATE(%s,\n" % self.name
         source += "{\n"
-
         source += self.generate_validate_code()
-
         source += "})\n\n"
 
         # dynamic cast
@@ -821,9 +818,7 @@ class Object(Type):
                 source += "/* esxVI_%s_DynamicCast */\n" % self.name
                 source += "ESX_VI__TEMPLATE__DYNAMIC_CAST(%s,\n" % self.name
                 source += "{\n"
-
                 source += self.generate_dynamic_cast_code()
-
                 source += "})\n\n"
             else:
                 report_error("cannot add dynamic cast support for an untyped object")
@@ -834,39 +829,25 @@ class Object(Type):
             source += "ESX_VI__TEMPLATE__LIST__APPEND(%s)\n\n" % self.name
 
         # deep copy
-        if self.extended_by is None:
-            if self.features & Object.FEATURE__DEEP_COPY:
-                source += "/* esxVI_%s_DeepCopy */\n" % self.name
-                source += "ESX_VI__TEMPLATE__DEEP_COPY(%s,\n" % self.name
-                source += "{\n"
-
-                source += self.generate_deep_copy_code()
-
-                source += "})\n\n"
+        if self.features & Object.FEATURE__DEEP_COPY:
+            source += "/* esxVI_%s_DeepCopy */\n" % self.name
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_DeepCopyList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__DEEP_COPY(%s)\n\n" \
-                              % self.name
-        else:
-            if self.features & Object.FEATURE__DEEP_COPY:
-                source += "/* esxVI_%s_DeepCopy */\n" % self.name
+            if self.extended_by is None:
+                source += "ESX_VI__TEMPLATE__DEEP_COPY(%s,\n" % self.name
+            else:
                 source += "ESX_VI__TEMPLATE__DYNAMIC_DEEP_COPY(%s,\n" % self.name
                 source += "{\n"
-
                 source += self.generate_dispatch('DEEP_COPY')
-
                 source += "},\n"
-                source += "{\n"
-
-                source += self.generate_deep_copy_code()
 
-                source += "})\n\n"
+            source += "{\n"
+            source += self.generate_deep_copy_code()
+            source += "})\n\n"
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_DeepCopyList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__DEEP_COPY(%s)\n\n" \
-                              % self.name
+            if self.features & Object.FEATURE__LIST:
+                source += "/* esxVI_%s_DeepCopyList */\n" % self.name
+                source += "ESX_VI__TEMPLATE__LIST__DEEP_COPY(%s)\n\n" \
+                          % self.name
 
         # cast from any type
         if self.features & Object.FEATURE__ANY_TYPE:
@@ -879,9 +860,7 @@ class Object(Type):
                 source += "ESX_VI__TEMPLATE__DYNAMIC_CAST_FROM_ANY_TYPE(%s,\n" \
                           % self.name
                 source += "{\n"
-
                 source += self.generate_dispatch('CAST_FROM_ANY_TYPE')
-
                 source += "})\n\n"
 
             if self.features & Object.FEATURE__LIST:
@@ -890,75 +869,47 @@ class Object(Type):
                           % self.name
 
         # serialize
-        if self.extended_by is None:
-            if self.features & Object.FEATURE__SERIALIZE:
-                source += "/* esxVI_%s_Serialize */\n" % self.name
-                source += "ESX_VI__TEMPLATE__SERIALIZE(%s,\n" % self.name
-                source += "{\n"
-
-                source += self.generate_serialize_code()
-
-                source += "})\n\n"
+        if self.features & Object.FEATURE__SERIALIZE:
+            source += "/* esxVI_%s_Serialize */\n" % self.name
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_SerializeList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__SERIALIZE(%s)\n\n" \
-                              % self.name
-        else:
-            if self.features & Object.FEATURE__SERIALIZE:
-                source += "/* esxVI_%s_Serialize */\n" % self.name
+            if self.extended_by is None:
+                source += "ESX_VI__TEMPLATE__SERIALIZE(%s,\n" % self.name
+            else:
                 source += "ESX_VI__TEMPLATE__DYNAMIC_SERIALIZE(%s,\n" % self.name
                 source += "{\n"
-
                 source += self.generate_dispatch('SERIALIZE')
-
                 source += "},\n"
-                source += "{\n"
-
-                source += self.generate_serialize_code()
 
-                source += "})\n\n"
+            source += "{\n"
+            source += self.generate_serialize_code()
+            source += "})\n\n"
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_SerializeList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__SERIALIZE(%s)\n\n" \
-                              % self.name
+            if self.features & Object.FEATURE__LIST:
+                source += "/* esxVI_%s_SerializeList */\n" % self.name
+                source += "ESX_VI__TEMPLATE__LIST__SERIALIZE(%s)\n\n" \
+                          % self.name
 
         # deserialize
-        if self.extended_by is None:
-            if self.features & Object.FEATURE__DESERIALIZE:
-                source += "/* esxVI_%s_Deserialize */\n" % self.name
-                source += "ESX_VI__TEMPLATE__DESERIALIZE(%s,\n" % self.name
-                source += "{\n"
-
-                source += self.generate_deserialize_code()
-
-                source += "})\n\n"
+        if self.features & Object.FEATURE__DESERIALIZE:
+            source += "/* esxVI_%s_Deserialize */\n" % self.name
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_DeserializeList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" \
-                              % self.name
-        else:
-            if self.features & Object.FEATURE__DESERIALIZE:
-                source += "/* esxVI_%s_Deserialize */\n" % self.name
+            if self.extended_by is None:
+                source += "ESX_VI__TEMPLATE__DESERIALIZE(%s,\n" % self.name
+            else:
                 source += "ESX_VI__TEMPLATE__DYNAMIC_DESERIALIZE(%s,\n" \
                           % self.name
                 source += "{\n"
-
                 source += self.generate_dispatch('DESERIALIZE')
-
                 source += "},\n"
-                source += "{\n"
-
-                source += self.generate_deserialize_code()
 
-                source += "})\n\n"
+            source += "{\n"
+            source += self.generate_deserialize_code()
+            source += "})\n\n"
 
-                if self.features & Object.FEATURE__LIST:
-                    source += "/* esxVI_%s_DeserializeList */\n" % self.name
-                    source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" \
-                              % self.name
+            if self.features & Object.FEATURE__LIST:
+                source += "/* esxVI_%s_DeserializeList */\n" % self.name
+                source += "ESX_VI__TEMPLATE__LIST__DESERIALIZE(%s)\n\n" \
+                          % self.name
 
         source += "\n\n"
 
@@ -966,12 +917,10 @@ class Object(Type):
 
 
 
-class ManagedObject(Type):
-    FEATURE__LIST = (1 << 2)
-
-
+class ManagedObject(GenericObject):
     def __init__(self, name, extends, properties, features=0, extended_by=None):
-        Type.__init__(self, "struct", name)
+        GenericObject.__init__(self, name, 'VI Managed Object', True,
+                               managed_objects_by_name)
         self.extends = extends
         self.features = features
         self.properties = properties
@@ -981,100 +930,6 @@ class ManagedObject(Type):
             self.extended_by.sort()
 
 
-    def generate_struct_members(self, add_banner=False, struct_gap=False):
-        members = ""
-
-        if struct_gap:
-            members += "\n"
-
-        if self.extends is not None:
-            members += managed_objects_by_name[self.extends] \
-                       .generate_struct_members(add_banner=True) + "\n"
-
-        if self.extends is not None or add_banner:
-            members += "    /* %s */\n" % self.name
-
-        for property in self.properties:
-            members += property.generate_struct_member()
-
-        if len(self.properties) < 1:
-            members += "    /* no properties */\n"
-
-        return members
-
-
-    def generate_dispatch(self, suffix, is_first=True):
-        source = ""
-
-        if self.extended_by is not None:
-            if not is_first:
-                source += "\n"
-
-            source += "    /* %s */\n" % self.name
-
-            for extended_by in self.extended_by:
-                source += "    ESX_VI__TEMPLATE__DISPATCH__%s(%s)\n" \
-                          % (suffix, extended_by)
-
-            for extended_by in self.extended_by:
-                source += managed_objects_by_name[extended_by] \
-                          .generate_dispatch(suffix, False)
-
-        return source
-
-
-    def generate_free_code(self, add_banner=False):
-        source = ""
-
-        if self.extends is not None:
-            source += managed_objects_by_name[self.extends] \
-                      .generate_free_code(add_banner=True) + "\n"
-
-        if self.extends is not None or add_banner:
-            source += "    /* %s */\n" % self.name
-
-        if len(self.properties) < 1:
-            source += "    /* no properties */\n"
-        else:
-            string = ""
-
-            for property in self.properties:
-                string += property.generate_free_code()
-
-            if len(string) < 1:
-                source += "    /* no properties to be freed */\n"
-            else:
-                source += string
-
-        return source
-
-
-    def generate_validate_code(self, add_banner=False):
-        source = ""
-
-        if self.extends is not None:
-            source += managed_objects_by_name[self.extends] \
-                      .generate_validate_code(add_banner=True) + "\n"
-
-        if self.extends is not None or add_banner:
-            source += "    /* %s */\n" % self.name
-
-        if len(self.properties) < 1:
-            source += "    /* no properties */\n"
-        else:
-            string = ""
-
-            for property in self.properties:
-                string += property.generate_validate_code(managed=True)
-
-            if len(string) < 1:
-                source += "    /* no required properties */\n"
-            else:
-                source += string
-
-        return source
-
-
     def generate_lookup_code1(self, add_banner=False):
         source = ""
 
@@ -1127,30 +982,6 @@ class ManagedObject(Type):
         return source
 
 
-    def generate_comment(self):
-        comment = separator
-        comment += " * VI Managed Object: %s\n" % self.name
-
-        if self.extends is not None:
-            comment += " *                    extends %s\n" % self.extends
-
-        first = True
-
-        if self.extended_by is not None:
-            for extended_by in self.extended_by:
-                if first:
-                    comment += " *                    extended by %s\n" \
-                               % extended_by
-                    first = False
-                else:
-                    comment += " *                                %s\n" \
-                               % extended_by
-
-        comment += " */\n\n"
-
-        return comment
-
-
     def generate_header(self):
         header = self.generate_comment()
 
@@ -1169,7 +1000,6 @@ class ManagedObject(Type):
                           "/* required */\n")
         header += "\n"
         header += self.generate_struct_members()
-
         header += "};\n\n"
 
         # functions
@@ -1213,53 +1043,32 @@ class ManagedObject(Type):
         source += "ESX_VI__TEMPLATE__ALLOC(%s)\n\n" % self.name
 
         # free
+        source += "/* esxVI_%s_Free */\n" % self.name
+
         if self.extended_by is None:
-            source += "/* esxVI_%s_Free */\n" % self.name
             source += "ESX_VI__TEMPLATE__FREE(%s,\n" % self.name
-            source += "{\n"
-
-            if self.features & ManagedObject.FEATURE__LIST:
-                if self.extends is not None:
-                    # avoid "dereferencing type-punned pointer will break
-                    # strict-aliasing rules" warnings
-                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
-                              % (self.extends, self.extends)
-                    source += "    esxVI_%s_Free(&next);\n" % self.extends
-                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
-                else:
-                    source += "    esxVI_%s_Free(&item->_next);\n" % self.name
-
-            source += "    esxVI_ManagedObjectReference_Free(&item->_reference);\n\n"
-
-            source += self.generate_free_code()
-
-            source += "})\n\n"
         else:
-            source += "/* esxVI_%s_Free */\n" % self.name
             source += "ESX_VI__TEMPLATE__DYNAMIC_FREE(%s,\n" % self.name
             source += "{\n"
-
             source += self.generate_dispatch('FREE')
-
             source += "},\n"
-            source += "{\n"
-
-            if self.features & ManagedObject.FEATURE__LIST:
-                if self.extends is not None:
-                    # avoid "dereferencing type-punned pointer will break
-                    # strict-aliasing rules" warnings
-                    source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
-                              % (self.extends, self.extends)
-                    source += "    esxVI_%s_Free(&next);\n" % self.extends
-                    source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
-                else:
-                    source += "    esxVI_%s_Free(&item->_next);\n" % self.name
 
-            source += "    esxVI_ManagedObjectReference_Free(&item->_reference);\n\n"
+        source += "{\n"
 
-            source += self.generate_free_code()
+        if self.features & ManagedObject.FEATURE__LIST:
+            if self.extends is not None:
+                # avoid "dereferencing type-punned pointer will break
+                # strict-aliasing rules" warnings
+                source += "    esxVI_%s *next = (esxVI_%s *)item->_next;\n\n" \
+                          % (self.extends, self.extends)
+                source += "    esxVI_%s_Free(&next);\n" % self.extends
+                source += "    item->_next = (esxVI_%s *)next;\n\n" % self.name
+            else:
+                source += "    esxVI_%s_Free(&item->_next);\n" % self.name
 
-            source += "})\n\n"
+        source += "    esxVI_ManagedObjectReference_Free(&item->_reference);\n\n"
+        source += self.generate_free_code()
+        source += "})\n\n"
 
         # validate
         source += "/* esxVI_%s_Validate */\n" % self.name
@@ -1319,8 +1128,6 @@ class Enum(Type):
         header = separator
         header += " * VI Enum: %s\n" % self.name
         header += " */\n\n"
-
-        # enum
         header += "enum _esxVI_%s {\n" % self.name
         header += "    esxVI_%s_Undefined = 0,\n" % self.name
 
@@ -1354,7 +1161,6 @@ class Enum(Type):
         source = separator
         source += " * VI Enum: %s\n" % self.name
         source += " */\n\n"
-
         source += "static const esxVI_Enumeration _esxVI_%s_Enumeration = {\n" \
                   % self.name
         source += "    esxVI_Type_%s, {\n" % self.name
-- 
1.7.9.5




More information about the libvir-list mailing list