From nobody Mon Feb 9 16:45:21 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1490892488840857.6210429024028; Thu, 30 Mar 2017 09:48:08 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 69CA641A27; Thu, 30 Mar 2017 16:48:07 +0000 (UTC) Received: from colo-mx.corp.redhat.com (unknown [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 381BC8765A; Thu, 30 Mar 2017 16:48:07 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E14E35EC63; Thu, 30 Mar 2017 16:48:06 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id v2UGlbZb016948 for ; Thu, 30 Mar 2017 12:47:37 -0400 Received: by smtp.corp.redhat.com (Postfix) id 1F48F90EC3; Thu, 30 Mar 2017 16:47:37 +0000 (UTC) Received: from mx1.redhat.com (ext-mx09.extmail.prod.ext.phx2.redhat.com [10.5.110.38]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 150B5173A4 for ; Thu, 30 Mar 2017 16:47:37 +0000 (UTC) Received: from mail-qk0-f177.google.com (mail-qk0-f177.google.com [209.85.220.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 399A264D8E for ; Thu, 30 Mar 2017 16:47:35 +0000 (UTC) Received: by mail-qk0-f177.google.com with SMTP id r142so45346944qke.2 for ; Thu, 30 Mar 2017 09:47:35 -0700 (PDT) Received: from dawid-fedora.datto.lan ([47.19.105.250]) by smtp.gmail.com with ESMTPSA id j1sm1730322qkf.57.2017.03.30.09.47.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 30 Mar 2017 09:47:33 -0700 (PDT) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 69CA641A27 Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=datto.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=libvir-list-bounces@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 69CA641A27 Authentication-Results: mx1.redhat.com; dkim=fail reason="signature verification failed" (2048-bit key) header.d=datto-com.20150623.gappssmtp.com header.i=@datto-com.20150623.gappssmtp.com header.b="hnjPa3Py" DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 399A264D8E Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=datto.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dzamirski@datto.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 399A264D8E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=datto-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ivUrSMzN9szUzlw7f2+nxj33CnfV3CZG2MEy/vcE8dI=; b=hnjPa3PywvAa+Qqq4D7I1Y7b7TcixoykbKoi2kAnYWGrdD6g6acXV5n1+Pj+ZcMrlY d8nlDlNv0rLVbHZthm8RM3O9ok7T7AXg9XEtPiU391eOOk9AKQqVKYXIB423ag9W7KNb 72zu04CAGdfpvchcKCuQO/OqlhtfNJ2INnt+kL0+PNXSlWiZOZVaYajsR25E2nNXBswH 52f4gvDy5P34y/hTINR1NNl3KmbxfW9M0WmMNYs6aE+IuuMITtTTO0JBqoSrxd/Ugh+z hdqLsPU2emnkn5Qg92udxaN29qLpU8BmaTnaA2q0xexYs4Q09hM/vmtei6iP+MxfCFsO m4bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ivUrSMzN9szUzlw7f2+nxj33CnfV3CZG2MEy/vcE8dI=; b=HlqVzLATbkKk8vwdN6adUyROgaLg5avykpPYiJrjacBPhTt0ncrs0jmV2igYHscUfx ujro+M0h2vzCivo5vbuDx0CQBCTnwge73v06szP9H9Bk+bxf0QMfwmdUBgTuOWA6LbYi mQQ0yd8XIAfG5RXEwPpd+vWi/EmYBmfvV9VEaL9YkprN7Nsuh49dlxf9QcBvxdz1nHd9 vEwXp/xI7Bf8dKGlts17p6+Mv9pp/rOId/t+Jp0a6nV50AwsOmI7vODlzvBusCOc9NwZ i6e6c6qvpgVV9oZ7geOXpg54xUNmmPcEnlkTkZHUYhRGkAm3QSdPCGI4xoBn7yQxgvKr J0dQ== X-Gm-Message-State: AFeK/H1MMul2usob19dd5aJwfjD/nI6Yr9Hlhhv0yHNmcW3a48Ah7perUiVILYqnD0FgJPiA X-Received: by 10.55.209.216 with SMTP id o85mr746590qkl.180.1490892454086; Thu, 30 Mar 2017 09:47:34 -0700 (PDT) From: Dawid Zamirski To: libvir-list@redhat.com Date: Thu, 30 Mar 2017 12:47:25 -0400 Message-Id: <20170330164728.32215-9-dzamirski@datto.com> In-Reply-To: <20170330164728.32215-1-dzamirski@datto.com> References: <20170330164728.32215-1-dzamirski@datto.com> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 30 Mar 2017 16:47:35 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Thu, 30 Mar 2017 16:47:35 +0000 (UTC) for IP:'209.85.220.177' DOMAIN:'mail-qk0-f177.google.com' HELO:'mail-qk0-f177.google.com' FROM:'dzamirski@datto.com' RCPT:'' X-RedHat-Spam-Score: 0.869 (BAYES_50, DCC_REPUT_00_12, DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, RCVD_IN_SORBS_SPAM, SPF_PASS) 209.85.220.177 mail-qk0-f177.google.com 209.85.220.177 mail-qk0-f177.google.com X-Scanned-By: MIMEDefang 2.78 on 10.5.110.38 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: Sri Ramanujam Subject: [libvirt] [PATCH 08/11] hyperv: update wmi code generator. X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 30 Mar 2017 16:48:08 +0000 (UTC) X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch updates the code generator that outputs C headers and code for WMI classes. It has been updated to handle multiple versions (or namespaces) of the same class which were introduced with Hyperv 2012+ --- src/hyperv/hyperv_wmi_generator.py | 409 +++++++++++++++++++++++++--------= ---- 1 file changed, 284 insertions(+), 125 deletions(-) mode change 100755 =3D> 100644 src/hyperv/hyperv_wmi_generator.py diff --git a/src/hyperv/hyperv_wmi_generator.py b/src/hyperv/hyperv_wmi_gen= erator.py old mode 100755 new mode 100644 index 8c62882..c36abf2 --- a/src/hyperv/hyperv_wmi_generator.py +++ b/src/hyperv/hyperv_wmi_generator.py @@ -1,153 +1,308 @@ #!/usr/bin/env python =20 -# -# hyperv_wmi_generator.py: generates most of the WMI type mapping code -# -# Copyright (C) 2011 Matthias Bolte -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library. If not, see -# . -# - import sys import os import os.path =20 +separator =3D "/*" + ("*" * 50) + "*\n" +wmi_version_separator =3D "/" +wmi_classes_by_name =3D {} + +class WmiClass: + """Represents WMI class and provides methods to generate C code. + + This class holds one or more instances of WmiClassVersion because with= the + Windows 2012 release, Microsoft introduced "v2" version of Msvm_* fami= ly of + classes that need different URI for making wsman requests and also have + some additional/changed properties (though many of the properies are t= he + same as in "v1". Therefore, this class makes sure that C code is gener= ated + for each of them while avoiding name conflics, identifies common membe= rs, + and defined *_WmiInfo structs holding info about each version so the d= river + code can make the right choices based on which Hyper-v host it's conne= cted + to. + """ + + def __init__(self, name, versions =3D []): + self.name =3D name + self.versions =3D versions + self.common =3D None =20 =20 -separator =3D "/* " + ("* " * 37) + "*\n" + def prepare(self): + """Prepares the class for code generation =20 + Makes sure that "versioned" classes are sorted by version, identfi= es + common properies and ensures that they are aligned by name and + type in each version + """ + # sort vesioned classes by version in case input file did not have= them + # in order + self.versions =3D sorted(self.versions, key=3Dlambda cls: cls.vers= ion) =20 + # if there's more than one verion make sure first one has name suf= fixed + # because we'll generate "common" memeber and will the "base" name + if len(self.versions) > 1: + first =3D self.versions[0] + first.name =3D "%s_%s" % (first.name, first.version) =20 -class Class: - def __init__(self, name, properties): - self.name =3D name - self.properties =3D properties + # finally, identify common members in all versions and make sure t= hey + # are in the same order - to ensure C struc member alignment + self._align_property_members() + =20 =20 + def generate_classes_header(self): + """Generate C header code and return it as string + + Declares: + _Data - used as one of hypervObject->data members + _TypeInfo - used as wsman XmlSerializerInfo + - "inherits" hypervObject struct + """ =20 - def generate_header(self): name_upper =3D self.name.upper() =20 header =3D separator header +=3D " * %s\n" % self.name header +=3D " */\n" header +=3D "\n" - header +=3D "int hypervGet%sList(hypervPrivate *priv, virBufferPtr= query, %s **list);\n" \ - % (self.name.replace("_", ""), self.name) - header +=3D "\n" + header +=3D "#define %s_CLASSNAME \\\n" % name_upper + header +=3D " \"%s\"\n" % self.name header +=3D "\n" + header +=3D "#define %s_WQL_SELECT \\\n" % name_upper + header +=3D " \"SELECT * FROM %s \"\n" % self.name header +=3D "\n" + header +=3D "extern hypervWmiClassInfoListPtr %s_WmiInfo;\n\n" % s= elf.name + + header +=3D self._declare_data_structs() + header +=3D self._declare_hypervObject_struct() =20 return header =20 =20 + def generate_classes_source(self): + """Returns a C code string defining wsman data structs + + Defines: + _Data structs + _WmiInfo - list holding metadata (e.g. request URIs)= for + each known version of WMI class. + """ + + source =3D separator + source +=3D " * %s\n" % self.name + source +=3D " */\n" + + for cls in self.versions: + source +=3D "SER_START_ITEMS(%s_Data)\n" % cls.name + + for property in cls.properties: + source +=3D property.generate_classes_source(cls.name) + + source +=3D "SER_END_ITEMS(%s_Data);\n\n" % cls.name + + + source +=3D self._define_WmiInfo_struct() + source +=3D "\n\n" + + return source + + def generate_classes_typedef(self): - typedef =3D "typedef struct _%s_Data %s_Data;\n" % (self.name, sel= f.name) - typedef +=3D "typedef struct _%s %s;\n" % (self.name, self.name) + """Returns C string for typdefs""" =20 - return typedef + typedef =3D "typedef struct _%s %s;\n" % (self.name, self.name) =20 + if self.common is not None: + typedef +=3D "typedef struct _%s_Data %s_Data;\n" % (self.name= , self.name) =20 - def generate_classes_header(self): - name_upper =3D self.name.upper() + for cls in self.versions: + typedef +=3D "typedef struct _%s_Data %s_Data;\n" % (cls.name,= cls.name) =20 - header =3D separator - header +=3D " * %s\n" % self.name - header +=3D " */\n" - header +=3D "\n" - header +=3D "#define %s_RESOURCE_URI \\\n" % name_upper + return typedef =20 - if self.name.startswith("Win32_") or self.name.startswith("CIM_"): - header +=3D " \"http://schemas.microsoft.com/wbem/wsman/1/w= mi/root/cimv2/%s\"\n" % self.name - else: - header +=3D " \"http://schemas.microsoft.com/wbem/wsman/1/w= mi/root/virtualization/%s\"\n" % self.name =20 - header +=3D "\n" - header +=3D "#define %s_CLASSNAME \\\n" % name_upper - header +=3D " \"%s\"\n" % self.name - header +=3D "\n" - header +=3D "#define %s_WQL_SELECT \\\n" % name_upper - header +=3D " \"select * from %s \"\n" % self.name - header +=3D "\n" - header +=3D "struct _%s_Data {\n" % self.name =20 - for property in self.properties: - header +=3D property.generate_classes_header() + def _declare_data_structs(self): + """Returns string C code declaring data structs. + + The *_Data structs are members of hypervObject data union. Each on= e has + corresponding *_TypeInfo that is used for wsman unserialization of + response XML into the *_Data structs. If there's a "common" member= , it + won't have corresponding *_TypeInfo becuase this is a special case= only + used to provide a common "view" of v1, v2 etc members + """ + =20 + header =3D "" + if self.common is not None: + header +=3D "struct _%s_Data {\n" % self.name + for property in self.common: + header +=3D property.generate_classes_header() + header +=3D "};\n\n" + + # Declare actual data struct for each versions + for cls in self.versions: + header +=3D "#define %s_RESOURCE_URI \\\n" % cls.name.upper() + header +=3D " \"%s\"\n" % cls.uri_info.resourceUri=20 + header +=3D "\n" + header +=3D "struct _%s_Data {\n" % cls.name + for property in cls.properties: + header +=3D property.generate_classes_header() + header +=3D "};\n\n" + header +=3D "SER_DECLARE_TYPE(%s_Data);\n" % cls.name =20 - header +=3D "};\n" - header +=3D "\n" - header +=3D "SER_DECLARE_TYPE(%s_Data);\n" % self.name - header +=3D "\n" + return header + =20 + + def _declare_hypervObject_struct(self): + """Return string for C code declaring hypervObject instance""" + + header =3D "\n/* must match hypervObject */\n" header +=3D "struct _%s {\n" % self.name - header +=3D " XmlSerializerInfo *serializerInfo;\n" - header +=3D " %s_Data *data;\n" % self.name + header +=3D " union {\n" + + # if there's common use it as "common" else first and only version= is + # the "common" member + if self.common is not None: + header +=3D " %s_Data *common;\n" % self.name + else: + header +=3D " %s_Data *common;\n" % self.versions[0].na= me + + for cls in self.versions: + header +=3D " %s_Data *%s;\n" % (cls.name, cls.version) + + header +=3D " } data;\n" + header +=3D " hypervWmiClassInfoPtr info;\n" header +=3D " %s *next;\n" % self.name header +=3D "};\n" - header +=3D "\n" - header +=3D "\n" - header +=3D "\n" + + header +=3D "\n\n\n" =20 return header =20 =20 - def generate_source(self): - name_upper =3D self.name.upper() + def _define_WmiInfo_struct(self): + """Return string for C code defining *_WmiInfo struct =20 - source =3D separator - source +=3D " * %s\n" % self.name - source +=3D " */\n" - source +=3D "\n" - source +=3D "int\n" - source +=3D "hypervGet%sList(hypervPrivate *priv, virBufferPtr que= ry, %s **list)\n" \ - % (self.name.replace("_", ""), self.name) - source +=3D "{\n" - - if self.name.startswith("Win32_") or self.name.startswith("CIM_"): - source +=3D " return hypervEnumAndPull(priv, query, ROOT_CI= MV2,\n" - else: - source +=3D " return hypervEnumAndPull(priv, query, ROOT_VI= RTUALIZATION,\n" + Those structs hold info with meta-data needed to make wsman reques= ts for + each version of WMI class + """ =20 - source +=3D " %s_Data_TypeInfo,\n" % s= elf.name - source +=3D " %s_RESOURCE_URI,\n" % na= me_upper - source +=3D " %s_CLASSNAME,\n" % name_= upper - source +=3D " (hypervObject **)list);\= n" - source +=3D "}\n" - source +=3D "\n" - source +=3D "\n" - source +=3D "\n" + source =3D "hypervWmiClassInfoListPtr %s_WmiInfo =3D &(hypervWmiCl= assInfoList) {\n" % self.name + source +=3D " .count =3D %d,\n" % len(self.versions) + source +=3D " .objs =3D (hypervWmiClassInfoPtr []) {\n" + + for cls in self.versions: + source +=3D " &(hypervWmiClassInfo) {\n" + source +=3D " .name =3D %s_CLASSNAME,\n" % self.nam= e.upper() + source +=3D " .version =3D \"%s\",\n" % cls.version + source +=3D " .rootUri =3D %s,\n" % cls.uri_info.ro= otUri=20 + source +=3D " .resourceUri =3D %s_RESOURCE_URI,\n" = % cls.name.upper() + source +=3D " .serializerInfo =3D %s_Data_TypeInfo\= n" % cls.name + source +=3D " },\n" + + source +=3D " }\n" + source +=3D "};\n" =20 return source =20 =20 - def generate_classes_source(self): - name_upper =3D self.name.upper() + def _align_property_members(self): + """Identifies common properties in all class versions. =20 - source =3D separator - source +=3D " * %s\n" % self.name - source +=3D " */\n" - source +=3D "\n" - source +=3D "SER_START_ITEMS(%s_Data)\n" % self.name + Makes sure that properties in all versions are ordered with common=20 + members first and that they are in the same order. This makes the + generated C structs memory aligned and safe to access via the "com= mon" + struct that "shares" members with v1, v2 etc. + """ =20 - for property in self.properties: - source +=3D property.generate_classes_source(self.name) + num_classes =3D len(self.versions) + common =3D {} + property_info =3D {} =20 - source +=3D "SER_END_ITEMS(%s_Data);\n" % self.name - source +=3D "\n" - source +=3D "\n" - source +=3D "\n" + if num_classes < 2: + return + + # count property occurences in all class versions + for cls in self.versions: + for prop in cls.properties: + # consdered same if matches by name AND type + key =3D "%s_%s" % (prop.name, prop.type) + + if key in property_info: + property_info[key][1] +=3D 1 + else: + property_info[key] =3D [prop, 1] + + # isolate those that are common for all and keep track of their po= stions + pos =3D 0 + for key in property_info: + info =3D property_info[key] + # exists in all class versions + if info[1] =3D=3D num_classes: + common[info[0].name] =3D [info[0], pos] + pos +=3D 1 + + # alter each versions's property list so that common members are f= irst + # and in the same order as in the common dictionary + total =3D len(common) + for cls in self.versions: + index =3D 0 + count =3D len(cls.properties) + + while index < count: + prop =3D cls.properties[index] + + # it's a "common" proptery + if prop.name in common: + pos =3D common[prop.name][1] + + # move to the same position as in "common" dictionary + if index !=3D pos: + tmp =3D cls.properties[pos] + cls.properties[pos] =3D prop + cls.properties[index] =3D tmp + else: + index +=3D 1 + else: + index +=3D 1 + + # finally, get common properties as list sorted by position in dic= tionary + tmp =3D sorted(common.values(), key=3Dlambda x: x[1]) + self.common =3D []=20 + for x in tmp: + self.common.append(x[0]) + + + +class ClassUriInfo: + """Prepares URI information needed for wsman requests.""" + + def __init__(self, wmi_name, version): + self.rootUri =3D "ROOT_CIMV2" + self.resourceUri =3D None + baseUri =3D "http://schemas.microsoft.com/wbem/wsman/1/wmi/root/ci= mv2" + + if wmi_name.startswith("Msvm_"): + baseUri =3D "http://schemas.microsoft.com/wbem/wsman/1/wmi/roo= t/virtualization" + self.rootUri =3D "ROOT_VIRTUALIZATION" + + if version =3D=3D "v2": + baseUri +=3D "/v2" + self.rootUri =3D "ROOT_VIRTUALIZATION_V2" + + self.resourceUri =3D "%s/%s" % (baseUri, wmi_name) + + + +class WmiClassVersion: + """Represents specific verssion of WMI class.""" + + def __init__(self, name, version, properties, uri_info): + self.name =3D name + self.version =3D version + self.properties =3D properties + self.uri_info =3D uri_info =20 - return source =20 =20 class Property: @@ -155,9 +310,13 @@ class Property: "string" : "STR", "datetime" : "STR", "int8" : "INT8", + "sint8" : "INT8", "int16" : "INT16", + "sint16" : "INT16", "int32" : "INT32", + "sint32" : "INT32", "int64" : "INT64", + "sint64" : "INT64", "uint8" : "UINT8", "uint16" : "UINT16", "uint32" : "UINT32", @@ -189,8 +348,6 @@ class Property: return " SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \ % (Property.typemap[self.type], class_name.upper(), sel= f.name) =20 - - def open_and_print(filename): if filename.startswith("./"): print " GEN " + filename[2:] @@ -217,8 +374,15 @@ def parse_class(block): assert header_items[0] =3D=3D "class" =20 name =3D header_items[1] - properties =3D [] + version =3D "v1" + wmi_name =3D name + ns_separator =3D name.find(wmi_version_separator) + + if ns_separator !=3D -1: + version =3D name[:ns_separator] + wmi_name =3D name[ns_separator + 1:] + name =3D "%s_%s" % (wmi_name, version) =20 for line in block[1:]: # expected format: @@ -236,7 +400,13 @@ def parse_class(block): properties.append(Property(type=3Ditems[0], name=3Ditems[1], is_array=3Dis_array)) =20 - return Class(name=3Dname, properties=3Dproperties) + cls =3D WmiClassVersion(name=3Dname, version=3Dversion, properties=3Dp= roperties, + uri_info=3DClassUriInfo(wmi_name, version)) + + if wmi_name in wmi_classes_by_name: + wmi_classes_by_name[wmi_name].versions.append(cls) + else: + wmi_classes_by_name[wmi_name] =3D WmiClass(wmi_name, [cls]) =20 =20 =20 @@ -248,15 +418,13 @@ def main(): input_filename =3D os.path.join(os.getcwd(), "hyperv_wmi_generator= .input") output_dirname =3D os.getcwd() =20 - header =3D open_and_print(os.path.join(output_dirname, "hyperv_wmi.gen= erated.h")) - source =3D open_and_print(os.path.join(output_dirname, "hyperv_wmi.gen= erated.c")) + classes_typedef =3D open_and_print(os.path.join(output_dirname, "hyper= v_wmi_classes.generated.typedef")) classes_header =3D open_and_print(os.path.join(output_dirname, "hyperv= _wmi_classes.generated.h")) classes_source =3D open_and_print(os.path.join(output_dirname, "hyperv= _wmi_classes.generated.c")) =20 - # parse input file + number =3D 0 - classes_by_name =3D {} block =3D None =20 for line in file(input_filename, "rb").readlines(): @@ -268,7 +436,7 @@ def main(): line =3D line.lstrip().rstrip() =20 if len(line) < 1: - continue + continue =20 if line.startswith("class"): if block is not None: @@ -279,31 +447,22 @@ def main(): if block is not None: if line =3D=3D "end": if block[0][1].startswith("class"): - cls =3D parse_class(block) - classes_by_name[cls.name] =3D cls + parse_class(block) =20 block =3D None else: block.append((number, line)) =20 - # write output files - notice =3D "/* Generated by hyperv_wmi_generator.py */\n\n\n\n" - - header.write(notice) - source.write(notice) - classes_typedef.write(notice) - classes_header.write(notice) - classes_source.write(notice) - - names =3D classes_by_name.keys() + names =3D wmi_classes_by_name.keys() names.sort() =20 for name in names: - header.write(classes_by_name[name].generate_header()) - source.write(classes_by_name[name].generate_source()) - classes_typedef.write(classes_by_name[name].generate_classes_typed= ef()) - classes_header.write(classes_by_name[name].generate_classes_header= ()) - classes_source.write(classes_by_name[name].generate_classes_source= ()) + cls =3D wmi_classes_by_name[name] + cls.prepare() + + classes_typedef.write(cls.generate_classes_typedef()) + classes_header.write(cls.generate_classes_header()) + classes_source.write(cls.generate_classes_source()) =20 =20 =20 --=20 2.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list