mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-14 08:35:15 +00:00
4ecb723b9e
https://www.gnu.org/licenses/gpl-howto.html recommends that the 'If not, see <url>.' phrase be a separate sentence. * tests/securityselinuxhelper.c: Remove doubled line. * tests/securityselinuxtest.c: Likewise. * globally: s/; If/. If/
312 lines
9.2 KiB
Python
Executable File
312 lines
9.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
#
|
|
# hyperv_wmi_generator.py: generates most of the WMI type mapping code
|
|
#
|
|
# Copyright (C) 2011 Matthias Bolte <matthias.bolte@googlemail.com>
|
|
#
|
|
# 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
|
|
# <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
import sys
|
|
import os
|
|
import os.path
|
|
|
|
|
|
|
|
separator = "/* " + ("* " * 37) + "*\n"
|
|
|
|
|
|
|
|
class Class:
|
|
def __init__(self, name, properties):
|
|
self.name = name
|
|
self.properties = properties
|
|
|
|
|
|
def generate_header(self):
|
|
name_upper = self.name.upper()
|
|
|
|
header = separator
|
|
header += " * %s\n" % self.name
|
|
header += " */\n"
|
|
header += "\n"
|
|
header += "int hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list);\n" \
|
|
% (self.name.replace("_", ""), self.name)
|
|
header += "\n"
|
|
header += "\n"
|
|
header += "\n"
|
|
|
|
return header
|
|
|
|
|
|
def generate_classes_typedef(self):
|
|
typedef = "typedef struct _%s_Data %s_Data;\n" % (self.name, self.name)
|
|
typedef += "typedef struct _%s %s;\n" % (self.name, self.name)
|
|
|
|
return typedef
|
|
|
|
|
|
def generate_classes_header(self):
|
|
name_upper = self.name.upper()
|
|
|
|
header = separator
|
|
header += " * %s\n" % self.name
|
|
header += " */\n"
|
|
header += "\n"
|
|
header += "#define %s_RESOURCE_URI \\\n" % name_upper
|
|
|
|
if self.name.startswith("Win32_"):
|
|
header += " \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n" % self.name
|
|
else:
|
|
header += " \"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/%s\"\n" % self.name
|
|
|
|
header += "\n"
|
|
header += "#define %s_CLASSNAME \\\n" % name_upper
|
|
header += " \"%s\"\n" % self.name
|
|
header += "\n"
|
|
header += "#define %s_WQL_SELECT \\\n" % name_upper
|
|
header += " \"select * from %s \"\n" % self.name
|
|
header += "\n"
|
|
header += "struct _%s_Data {\n" % self.name
|
|
|
|
for property in self.properties:
|
|
header += property.generate_classes_header()
|
|
|
|
header += "};\n"
|
|
header += "\n"
|
|
header += "SER_DECLARE_TYPE(%s_Data);\n" % self.name
|
|
header += "\n"
|
|
header += "struct _%s {\n" % self.name
|
|
header += " XmlSerializerInfo *serializerInfo;\n"
|
|
header += " %s_Data *data;\n" % self.name
|
|
header += " %s *next;\n" % self.name
|
|
header += "};\n"
|
|
header += "\n"
|
|
header += "\n"
|
|
header += "\n"
|
|
|
|
return header
|
|
|
|
|
|
def generate_source(self):
|
|
name_upper = self.name.upper()
|
|
|
|
source = separator
|
|
source += " * %s\n" % self.name
|
|
source += " */\n"
|
|
source += "\n"
|
|
source += "int\n"
|
|
source += "hypervGet%sList(hypervPrivate *priv, virBufferPtr query, %s **list)\n" \
|
|
% (self.name.replace("_", ""), self.name)
|
|
source += "{\n"
|
|
|
|
if self.name.startswith("Win32_"):
|
|
source += " return hypervEnumAndPull(priv, query, ROOT_CIMV2,\n"
|
|
else:
|
|
source += " return hypervEnumAndPull(priv, query, ROOT_VIRTUALIZATION,\n"
|
|
|
|
source += " %s_Data_TypeInfo,\n" % self.name
|
|
source += " %s_RESOURCE_URI,\n" % name_upper
|
|
source += " %s_CLASSNAME,\n" % name_upper
|
|
source += " (hypervObject **)list);\n"
|
|
source += "}\n"
|
|
source += "\n"
|
|
source += "\n"
|
|
source += "\n"
|
|
|
|
return source
|
|
|
|
|
|
def generate_classes_source(self):
|
|
name_upper = self.name.upper()
|
|
|
|
source = separator
|
|
source += " * %s\n" % self.name
|
|
source += " */\n"
|
|
source += "\n"
|
|
source += "SER_START_ITEMS(%s_Data)\n" % self.name
|
|
|
|
for property in self.properties:
|
|
source += property.generate_classes_source(self.name)
|
|
|
|
source += "SER_END_ITEMS(%s_Data);\n" % self.name
|
|
source += "\n"
|
|
source += "\n"
|
|
source += "\n"
|
|
|
|
return source
|
|
|
|
|
|
class Property:
|
|
typemap = {"boolean" : "BOOL",
|
|
"string" : "STR",
|
|
"datetime" : "STR",
|
|
"int8" : "INT8",
|
|
"int16" : "INT16",
|
|
"int32" : "INT32",
|
|
"int64" : "INT64",
|
|
"uint8" : "UINT8",
|
|
"uint16" : "UINT16",
|
|
"uint32" : "UINT32",
|
|
"uint64" : "UINT64"}
|
|
|
|
|
|
def __init__(self, type, name, is_array):
|
|
if type not in Property.typemap:
|
|
report_error("unhandled property type %s" % type)
|
|
|
|
self.type = type
|
|
self.name = name
|
|
self.is_array = is_array
|
|
|
|
|
|
def generate_classes_header(self):
|
|
if self.is_array:
|
|
return " XML_TYPE_DYN_ARRAY %s;\n" % self.name
|
|
else:
|
|
return " XML_TYPE_%s %s;\n" \
|
|
% (Property.typemap[self.type], self.name)
|
|
|
|
|
|
def generate_classes_source(self, class_name):
|
|
if self.is_array:
|
|
return " SER_NS_DYN_ARRAY(%s_RESOURCE_URI, \"%s\", 0, 0, %s),\n" \
|
|
% (class_name.upper(), self.name, self.type)
|
|
else:
|
|
return " SER_NS_%s(%s_RESOURCE_URI, \"%s\", 1),\n" \
|
|
% (Property.typemap[self.type], class_name.upper(), self.name)
|
|
|
|
|
|
|
|
def open_and_print(filename):
|
|
if filename.startswith("./"):
|
|
print " GEN " + filename[2:]
|
|
else:
|
|
print " GEN " + filename
|
|
|
|
return open(filename, "wb")
|
|
|
|
|
|
|
|
def report_error(message):
|
|
print "error: " + message
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
def parse_class(block):
|
|
# expected format: class <name>
|
|
header_items = block[0][1].split()
|
|
|
|
if len(header_items) != 2:
|
|
report_error("line %d: invalid block header" % (number))
|
|
|
|
assert header_items[0] == "class"
|
|
|
|
name = header_items[1]
|
|
|
|
properties = []
|
|
|
|
for line in block[1:]:
|
|
# expected format: <type> <name>
|
|
items = line[1].split()
|
|
|
|
if len(items) != 2:
|
|
report_error("line %d: invalid property" % line[0])
|
|
|
|
if items[1].endswith("[]"):
|
|
items[1] = items[1][:-2]
|
|
is_array = True
|
|
else:
|
|
is_array = False
|
|
|
|
properties.append(Property(type=items[0], name=items[1],
|
|
is_array=is_array))
|
|
|
|
return Class(name=name, properties=properties)
|
|
|
|
|
|
|
|
def main():
|
|
if "srcdir" in os.environ:
|
|
input_filename = os.path.join(os.environ["srcdir"], "hyperv/hyperv_wmi_generator.input")
|
|
output_dirname = os.path.join(os.environ["srcdir"], "hyperv")
|
|
else:
|
|
input_filename = os.path.join(os.getcwd(), "hyperv_wmi_generator.input")
|
|
output_dirname = os.getcwd()
|
|
|
|
header = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.h"))
|
|
source = open_and_print(os.path.join(output_dirname, "hyperv_wmi.generated.c"))
|
|
classes_typedef = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.typedef"))
|
|
classes_header = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.h"))
|
|
classes_source = open_and_print(os.path.join(output_dirname, "hyperv_wmi_classes.generated.c"))
|
|
|
|
# parse input file
|
|
number = 0
|
|
classes_by_name = {}
|
|
block = None
|
|
|
|
for line in file(input_filename, "rb").readlines():
|
|
number += 1
|
|
|
|
if "#" in line:
|
|
line = line[:line.index("#")]
|
|
|
|
line = line.lstrip().rstrip()
|
|
|
|
if len(line) < 1:
|
|
continue
|
|
|
|
if line.startswith("class"):
|
|
if block is not None:
|
|
report_error("line %d: nested block found" % (number))
|
|
else:
|
|
block = []
|
|
|
|
if block is not None:
|
|
if line == "end":
|
|
if block[0][1].startswith("class"):
|
|
cls = parse_class(block)
|
|
classes_by_name[cls.name] = cls
|
|
|
|
block = None
|
|
else:
|
|
block.append((number, line))
|
|
|
|
# write output files
|
|
notice = "/* 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 = classes_by_name.keys()
|
|
names.sort()
|
|
|
|
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_typedef())
|
|
classes_header.write(classes_by_name[name].generate_classes_header())
|
|
classes_source.write(classes_by_name[name].generate_classes_source())
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|