2010-11-13 18:34:57 +03:00
#!/usr/bin/env python
2010-03-06 19:56:28 +03:00
#
# esx_vi_generator.py: generates most of the SOAP type mapping code
#
2011-04-10 15:27:56 +04:00
# Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte@googlemail.com>
2010-03-06 19:56:28 +03:00
#
# 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
2012-07-27 02:58:02 +04:00
# License along with this library; if not, see
# <http://www.gnu.org/licenses/>.
2010-03-06 19:56:28 +03:00
#
import sys
import os
import os . path
2010-04-13 16:25:52 +04:00
OCCURRENCE__REQUIRED_ITEM = " r "
OCCURRENCE__REQUIRED_LIST = " rl "
OCCURRENCE__OPTIONAL_ITEM = " o "
OCCURRENCE__OPTIONAL_LIST = " ol "
OCCURRENCE__IGNORED = " i "
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
valid_occurrences = [ OCCURRENCE__REQUIRED_ITEM ,
OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_ITEM ,
OCCURRENCE__OPTIONAL_LIST ,
OCCURRENCE__IGNORED ]
2010-03-06 19:56:28 +03:00
2011-05-01 13:51:19 +04:00
autobind_names = set ( )
2011-05-01 10:05:58 +04:00
2011-05-01 23:57:42 +04:00
separator = " /* " + ( " * " * 37 ) + " * \n "
2010-04-13 16:25:52 +04:00
2011-05-01 10:05:58 +04:00
def aligned ( left , right , length = 59 ) :
while len ( left ) < length :
2011-04-10 15:26:47 +04:00
left + = " "
return left + right
2010-04-13 16:25:52 +04:00
2011-05-01 13:29:40 +04:00
class Member :
def __init__ ( self , type , occurrence ) :
2010-04-13 16:25:52 +04:00
self . type = type
self . occurrence = occurrence
def is_enum ( self ) :
return self . type in predefined_enums or self . type in enums_by_name
2011-05-01 12:43:17 +04:00
def is_object ( self ) :
return self . type in predefined_objects or self . type in objects_by_name
def is_type_generated ( self ) :
return self . type in enums_by_name or self . type in objects_by_name
2011-05-01 13:29:40 +04:00
def get_occurrence_comment ( self ) :
if self . occurrence == OCCURRENCE__REQUIRED_ITEM :
return " /* required */ "
elif self . occurrence == OCCURRENCE__REQUIRED_LIST :
return " /* required, list */ "
elif self . occurrence == OCCURRENCE__OPTIONAL_ITEM :
return " /* optional */ "
elif self . occurrence == OCCURRENCE__OPTIONAL_LIST :
return " /* optional, list */ "
raise ValueError ( " unknown occurrence value ' %s ' " % self . occurrence )
class Parameter ( Member ) :
def __init__ ( self , type , name , occurrence ) :
Member . __init__ ( self , type , occurrence )
if ' : ' in name and name . startswith ( " _this " ) :
2011-05-01 13:51:19 +04:00
self . name , self . autobind_name = name . split ( " : " )
2011-05-01 13:29:40 +04:00
else :
self . name = name
2011-05-01 13:51:19 +04:00
self . autobind_name = None
2011-05-01 13:29:40 +04:00
2011-05-01 23:57:42 +04:00
def generate_parameter ( self , is_last = False , is_header = True , offset = 0 ) :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2011-05-01 23:57:42 +04:00
raise ValueError ( " invalid function parameter occurrence value ' %s ' "
% self . occurrence )
2011-05-01 13:51:19 +04:00
elif self . autobind_name is not None :
2010-04-13 16:25:52 +04:00
return " "
else :
string = " "
string + = " " * offset
string + = " %s %s " % ( self . get_type_string ( ) , self . name )
if is_last :
if is_header :
string + = " ); "
else :
string + = " ), "
else :
string + = " , "
2011-04-10 15:26:47 +04:00
return aligned ( string , self . get_occurrence_comment ( ) + " \n " )
2010-04-13 16:25:52 +04:00
def generate_return ( self , offset = 0 , end_of_line = " ; " ) :
if self . occurrence == OCCURRENCE__IGNORED :
2011-05-01 23:57:42 +04:00
raise ValueError ( " invalid function parameter occurrence value ' %s ' "
% self . occurrence )
2010-04-13 16:25:52 +04:00
else :
string = " "
string + = " " * offset
2011-05-01 23:57:42 +04:00
string + = " %s %s ) %s " \
% ( self . get_type_string ( True ) , self . name , end_of_line )
2010-04-13 16:25:52 +04:00
2011-04-10 15:26:47 +04:00
return aligned ( string , self . get_occurrence_comment ( ) + " \n " )
2010-04-13 16:25:52 +04:00
def generate_require_code ( self ) :
if self . occurrence in [ OCCURRENCE__REQUIRED_ITEM ,
OCCURRENCE__REQUIRED_LIST ] :
return " ESX_VI__METHOD__PARAMETER__REQUIRE( %s ) \n " % self . name
else :
return " "
def generate_serialize_code ( self ) :
if self . occurrence in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2011-05-01 23:57:42 +04:00
return " ESX_VI__METHOD__PARAMETER__SERIALIZE_LIST( %s , %s ) \n " \
% ( self . type , self . name )
2010-04-13 16:25:52 +04:00
elif self . type == " String " :
2011-05-01 23:57:42 +04:00
return " ESX_VI__METHOD__PARAMETER__SERIALIZE_VALUE(String, %s ) \n " \
% self . name
2010-04-13 16:25:52 +04:00
else :
2011-05-01 23:57:42 +04:00
return " ESX_VI__METHOD__PARAMETER__SERIALIZE( %s , %s ) \n " \
% ( self . type , self . name )
2010-04-13 16:25:52 +04:00
2011-05-01 13:29:40 +04:00
def get_type_string ( self , as_return_value = False ) :
2010-08-29 21:17:10 +04:00
string = " "
2010-04-13 16:25:52 +04:00
if self . type == " String " and \
self . occurrence not in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2010-08-29 21:17:10 +04:00
if as_return_value :
string + = " char * "
else :
string + = " const char * "
2010-04-13 16:25:52 +04:00
elif self . is_enum ( ) :
2010-08-29 21:17:10 +04:00
string + = " esxVI_ %s " % self . type
2010-04-13 16:25:52 +04:00
else :
2010-08-29 21:17:10 +04:00
string + = " esxVI_ %s * " % self . type
if as_return_value :
string + = " * "
return string
2010-04-13 16:25:52 +04:00
def get_occurrence_short_enum ( self ) :
if self . occurrence == OCCURRENCE__REQUIRED_ITEM :
return " RequiredItem "
elif self . occurrence == OCCURRENCE__REQUIRED_LIST :
return " RequiredList "
elif self . occurrence == OCCURRENCE__OPTIONAL_ITEM :
return " OptionalItem "
elif self . occurrence == OCCURRENCE__OPTIONAL_LIST :
return " OptionalList "
raise ValueError ( " unknown occurrence value ' %s ' " % self . occurrence )
class Method :
def __init__ ( self , name , parameters , returns ) :
self . name = name
self . parameters = [ ]
self . autobind_parameter = None
self . returns = returns
for parameter in parameters :
2011-05-01 13:51:19 +04:00
if parameter . autobind_name is None :
2010-04-13 16:25:52 +04:00
self . parameters . append ( parameter )
else :
self . autobind_parameter = parameter
def generate_header ( self ) :
header = " int esxVI_ %s \n " % self . name
header + = " (esxVI_Context *ctx "
if len ( self . parameters ) > 0 or self . returns is not None :
header + = " , \n "
for parameter in self . parameters [ : - 1 ] :
header + = parameter . generate_parameter ( )
if self . returns is None :
2011-05-01 23:57:42 +04:00
header + = self . parameters [ - 1 ] . generate_parameter ( is_last = True )
2010-04-13 16:25:52 +04:00
else :
header + = self . parameters [ - 1 ] . generate_parameter ( )
header + = self . returns . generate_return ( )
else :
header + = " ); \n "
header + = " \n "
return header
def generate_source ( self ) :
source = " /* esxVI_ %s */ \n " % self . name
source + = " ESX_VI__METHOD( %s , " % self . name
if self . autobind_parameter is not None :
2011-05-01 13:51:19 +04:00
autobind_names . add ( self . autobind_parameter . autobind_name )
source + = " %s , \n " % self . autobind_parameter . autobind_name
2010-04-13 16:25:52 +04:00
else :
source + = " /* explicit _this */, \n "
source + = " (esxVI_Context *ctx "
if len ( self . parameters ) > 0 or self . returns is not None :
source + = " , \n "
for parameter in self . parameters [ : - 1 ] :
2011-05-01 23:57:42 +04:00
source + = parameter . generate_parameter ( is_header = False ,
offset = 9 )
2010-04-13 16:25:52 +04:00
if self . returns is None :
2011-05-01 23:57:42 +04:00
source + = self . parameters [ - 1 ] . generate_parameter ( is_last = True ,
is_header = False ,
offset = 9 )
2010-04-13 16:25:52 +04:00
else :
2011-05-01 23:57:42 +04:00
source + = self . parameters [ - 1 ] . generate_parameter ( is_header = False ,
offset = 9 )
source + = self . returns . generate_return ( offset = 9 ,
end_of_line = " , " )
2010-04-13 16:25:52 +04:00
else :
source + = " ), \n "
if self . returns is None :
2010-08-29 21:17:10 +04:00
source + = " void, /* nothing */, None, \n "
elif self . returns . type == " String " :
2011-05-01 23:57:42 +04:00
source + = " String, Value, %s , \n " \
% self . returns . get_occurrence_short_enum ( )
2010-04-13 16:25:52 +04:00
else :
2011-05-01 23:57:42 +04:00
source + = " %s , /* nothing */, %s , \n " \
% ( self . returns . type ,
self . returns . get_occurrence_short_enum ( ) )
2010-04-13 16:25:52 +04:00
source + = " { \n "
if self . autobind_parameter is not None :
source + = self . autobind_parameter . generate_require_code ( )
for parameter in self . parameters :
source + = parameter . generate_require_code ( )
source + = " }, \n "
source + = " { \n "
if self . autobind_parameter is not None :
source + = self . autobind_parameter . generate_serialize_code ( )
for parameter in self . parameters :
source + = parameter . generate_serialize_code ( )
source + = " }) \n \n \n \n "
return source
2011-05-01 13:29:40 +04:00
class Property ( Member ) :
2010-03-06 19:56:28 +03:00
def __init__ ( self , type , name , occurrence ) :
2011-05-01 13:29:40 +04:00
Member . __init__ ( self , type , occurrence )
2011-05-01 12:43:17 +04:00
2011-05-01 13:29:40 +04:00
self . name = name
2011-05-01 12:43:17 +04:00
2010-03-06 19:56:28 +03:00
def generate_struct_member ( self ) :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2010-03-06 19:56:28 +03:00
return " /* FIXME: %s is currently ignored */ \n " % self . name
else :
string = " %s %s ; " % ( self . get_type_string ( ) , self . name )
2011-04-10 15:26:47 +04:00
return aligned ( string , self . get_occurrence_comment ( ) + " \n " )
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_free_code ( self ) :
if self . type == " String " and \
2010-04-13 16:25:52 +04:00
self . occurrence not in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ,
OCCURRENCE__IGNORED ] :
2010-03-06 19:56:28 +03:00
return " VIR_FREE(item-> %s ); \n " % self . name
elif self . is_enum ( ) :
return " "
else :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2010-03-06 19:56:28 +03:00
return " /* FIXME: %s is currently ignored */ \n " % self . name
else :
return " esxVI_ %s _Free(&item-> %s ); \n " % ( self . type , self . name )
2010-04-13 16:25:52 +04:00
2011-04-10 15:27:56 +04:00
def generate_validate_code ( self , managed = False ) :
if managed :
macro = " ESX_VI__TEMPLATE__PROPERTY__MANAGED_REQUIRE "
else :
macro = " ESX_VI__TEMPLATE__PROPERTY__REQUIRE "
2010-04-13 16:25:52 +04:00
if self . occurrence in [ OCCURRENCE__REQUIRED_ITEM ,
OCCURRENCE__REQUIRED_LIST ] :
2011-04-10 15:27:56 +04:00
return " %s ( %s ) \n " % ( macro , self . name )
2010-04-13 16:25:52 +04:00
elif self . occurrence == OCCURRENCE__IGNORED :
2010-03-06 19:56:28 +03:00
return " /* FIXME: %s is currently ignored */ \n " % self . name
else :
return " "
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_deep_copy_code ( self ) :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2010-03-06 19:56:28 +03:00
return " /* FIXME: %s is currently ignored */ \n " % self . name
2010-04-13 16:25:52 +04:00
elif self . occurrence in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_LIST( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
elif self . type == " String " :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, %s ) \n " \
% self . name
2010-04-07 13:23:53 +04:00
elif self . is_enum ( ) :
return " (*dest)-> %s = src-> %s ; \n " % ( self . name , self . name )
2010-03-06 19:56:28 +03:00
else :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_serialize_code ( self ) :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2010-03-06 19:56:28 +03:00
return " /* FIXME: %s is currently ignored */ \n " % self . name
2010-04-13 16:25:52 +04:00
elif self . occurrence in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__SERIALIZE_LIST( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
elif self . type == " String " :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__SERIALIZE_VALUE(String, %s ) \n " \
% self . name
2010-03-06 19:56:28 +03:00
else :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__SERIALIZE( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_deserialize_code ( self ) :
2010-04-13 16:25:52 +04:00
if self . occurrence == OCCURRENCE__IGNORED :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE( %s ) /* FIXME */ \n " \
% self . name
2010-04-13 16:25:52 +04:00
elif self . occurrence in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
elif self . type == " String " :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, %s ) \n " \
% self . name
2010-03-06 19:56:28 +03:00
else :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE( %s , %s ) \n " \
% ( self . type , self . name )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2011-04-10 15:27:56 +04:00
def generate_lookup_code ( self ) :
if self . occurrence == OCCURRENCE__IGNORED :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE_IGNORE( %s ) /* FIXME */ \n " \
% self . name
2011-04-10 15:27:56 +04:00
elif self . occurrence in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__CAST_LIST_FROM_ANY_TYPE( %s , %s ) \n " \
% ( self . type , self . name )
2011-04-10 15:27:56 +04:00
elif self . type == " String " :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__CAST_VALUE_FROM_ANY_TYPE(String, %s ) \n " \
% self . name
2011-04-10 15:27:56 +04:00
else :
2011-05-01 23:57:42 +04:00
return " ESX_VI__TEMPLATE__PROPERTY__CAST_FROM_ANY_TYPE( %s , %s ) \n " \
% ( self . type , self . name )
2011-04-10 15:27:56 +04:00
2010-03-06 19:56:28 +03:00
def get_type_string ( self ) :
if self . type == " String " and \
2010-04-13 16:25:52 +04:00
self . occurrence not in [ OCCURRENCE__REQUIRED_LIST ,
OCCURRENCE__OPTIONAL_LIST ] :
2010-03-06 19:56:28 +03:00
return " char * "
elif self . is_enum ( ) :
return " esxVI_ %s " % self . type
else :
return " esxVI_ %s * " % self . type
2011-05-01 13:29:40 +04:00
class Type :
2011-04-10 15:26:47 +04:00
def __init__ ( self , kind , name ) :
self . kind = kind
self . name = name
def generate_typedef ( self ) :
2011-05-01 23:57:42 +04:00
return " typedef %s _esxVI_ %s esxVI_ %s ; \n " \
% ( self . kind , self . name , self . name )
2011-04-10 15:26:47 +04:00
def generate_typeenum ( self ) :
return " esxVI_Type_ %s , \n " % self . name
def generate_typetostring ( self ) :
string = " case esxVI_Type_ %s : \n " % self . name
string + = " return \" %s \" ; \n \n " % self . name
return string
def generate_typefromstring ( self ) :
string = " else if (STREQ(type, \" %s \" )) { \n " % self . name
string + = " return esxVI_Type_ %s ; \n " % self . name
string + = " } \n "
return string
2011-05-01 13:29:40 +04:00
class Object ( Type ) :
2010-03-06 19:56:28 +03:00
FEATURE__DYNAMIC_CAST = ( 1 << 1 )
FEATURE__LIST = ( 1 << 2 )
FEATURE__DEEP_COPY = ( 1 << 3 )
FEATURE__ANY_TYPE = ( 1 << 4 )
FEATURE__SERIALIZE = ( 1 << 5 )
FEATURE__DESERIALIZE = ( 1 << 6 )
2011-05-01 23:57:42 +04:00
def __init__ ( self , name , extends , properties , features = 0 , extended_by = None ) :
2011-05-01 13:29:40 +04:00
Type . __init__ ( self , " struct " , name )
2010-03-06 19:56:28 +03:00
self . extends = extends
2011-05-01 12:43:17 +04:00
self . features = features
2010-03-06 19:56:28 +03:00
self . properties = properties
self . extended_by = extended_by
2011-05-01 13:08:21 +04:00
self . candidate_for_dynamic_cast = False
2010-03-06 19:56:28 +03:00
2010-05-18 20:11:59 +04:00
if self . extended_by is not None :
2011-04-10 15:26:47 +04:00
self . extended_by . sort ( )
2010-05-18 20:11:59 +04:00
2010-03-06 19:56:28 +03:00
2011-04-10 15:26:47 +04:00
def generate_struct_members ( self , add_banner = False , struct_gap = False ) :
2010-03-06 19:56:28 +03:00
members = " "
2011-04-10 15:26:47 +04:00
if struct_gap :
2010-03-06 19:56:28 +03:00
members + = " \n "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
members + = objects_by_name [ self . extends ] \
. generate_struct_members ( add_banner = True ,
struct_gap = False ) + " \n "
2010-03-06 19:56:28 +03:00
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
2010-04-13 16:25:52 +04:00
2011-04-10 15:26:47 +04:00
def generate_free_code ( self , add_banner = False ) :
2010-03-06 19:56:28 +03:00
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ self . extends ] \
. generate_free_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
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
2010-04-13 16:25:52 +04:00
2011-04-10 15:26:47 +04:00
def generate_validate_code ( self , add_banner = False ) :
2010-03-06 19:56:28 +03:00
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ self . extends ] \
. generate_validate_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
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 ( )
if len ( string ) < 1 :
source + = " /* no required properties */ \n "
else :
source + = string
return source
2010-04-13 16:25:52 +04:00
2011-05-01 23:57:42 +04:00
def generate_dynamic_cast_code ( self , is_first = True ) :
2010-03-06 19:56:28 +03:00
source = " "
if self . extended_by is not None :
2010-07-06 19:27:05 +04:00
if not is_first :
source + = " \n "
2010-03-06 19:56:28 +03:00
source + = " /* %s */ \n " % self . name
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DYNAMIC_CAST__ACCEPT( %s ) \n " \
% extended_by
2010-03-06 19:56:28 +03:00
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ extended_by ] \
. generate_dynamic_cast_code ( False )
2010-03-06 19:56:28 +03:00
return source
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_deep_copy_code ( self , add_banner = False ) :
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ self . extends ] \
. generate_deep_copy_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
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_deep_copy_code ( )
if len ( string ) < 1 :
source + = " /* no properties to be deep copied */ \n "
else :
source + = string
return source
2010-04-13 16:25:52 +04:00
2011-05-01 23:57:42 +04:00
def generate_serialize_code ( self , add_banner = False ) :
2010-03-06 19:56:28 +03:00
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ self . extends ] \
. generate_serialize_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
if self . extends is not None or add_banner :
source + = " /* %s */ \n " % self . name
if len ( self . properties ) < 1 :
source + = " /* no properties */ \n "
else :
for property in self . properties :
source + = property . generate_serialize_code ( )
return source
2010-04-13 16:25:52 +04:00
2011-05-01 23:57:42 +04:00
def generate_deserialize_code ( self , add_banner = False ) :
2010-03-06 19:56:28 +03:00
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = objects_by_name [ self . extends ] \
. generate_deserialize_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
if self . extends is not None or add_banner :
source + = " /* %s */ \n " % self . name
if len ( self . properties ) < 1 :
source + = " /* no properties */ \n "
else :
for property in self . properties :
source + = property . generate_deserialize_code ( )
return source
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_header ( self ) :
2011-05-01 23:57:42 +04:00
header = separator
2011-04-10 15:27:56 +04:00
header + = " * VI Object: %s \n " % self . name
2010-03-06 19:56:28 +03:00
if self . extends is not None :
2011-04-10 15:27:56 +04:00
header + = " * extends %s \n " % self . extends
2010-03-06 19:56:28 +03:00
first = True
if self . extended_by is not None :
for extended_by in self . extended_by :
if first :
2011-04-10 15:27:56 +04:00
header + = " * extended by %s \n " % extended_by
2010-03-06 19:56:28 +03:00
first = False
else :
2011-04-10 15:27:56 +04:00
header + = " * %s \n " % extended_by
2010-03-06 19:56:28 +03:00
header + = " */ \n \n "
# struct
header + = " struct _esxVI_ %s { \n " % self . name
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = aligned ( " esxVI_ %s *_next; " % self . name ,
" /* optional */ \n " )
2010-03-06 19:56:28 +03:00
else :
2011-05-01 23:57:42 +04:00
header + = aligned ( " esxVI_ %s *_unused; " % self . name ,
" /* optional */ \n " )
2010-03-06 19:56:28 +03:00
2011-04-10 15:26:47 +04:00
header + = aligned ( " esxVI_Type _type; " , " /* required */ \n " )
header + = self . generate_struct_members ( struct_gap = True )
2010-03-06 19:56:28 +03:00
header + = " }; \n \n "
# functions
2011-05-01 23:57:42 +04:00
header + = " int esxVI_ %s _Alloc(esxVI_ %s **item); \n " \
% ( self . name , self . name )
header + = " void esxVI_ %s _Free(esxVI_ %s **item); \n " \
% ( self . name , self . name )
header + = " int esxVI_ %s _Validate(esxVI_ %s *item); \n " \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__DYNAMIC_CAST :
if self . extended_by is not None or self . extends is not None :
2011-05-01 23:57:42 +04:00
header + = " esxVI_ %s *esxVI_ %s _DynamicCast(void *item); \n " \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
else :
report_error ( " cannot add dynamic cast support for an untyped object " )
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = " int esxVI_ %s _AppendToList(esxVI_ %s **list, esxVI_ %s *item); \n " \
% ( self . name , self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__DEEP_COPY :
2011-05-01 23:57:42 +04:00
header + = " int esxVI_ %s _DeepCopy(esxVI_ %s **dst, esxVI_ %s *src); \n " \
% ( self . name , self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _DeepCopyList(esxVI_ %s **dstList, "
" esxVI_ %s *srcList); \n " ) \
% ( self . name , self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__ANY_TYPE :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _CastFromAnyType(esxVI_AnyType *anyType, "
" esxVI_ %s **item); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _CastListFromAnyType(esxVI_AnyType *anyType, "
" esxVI_ %s **list); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__SERIALIZE :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _Serialize(esxVI_ %s *item, "
" const char *element, "
" virBufferPtr output); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _SerializeList(esxVI_ %s *list, "
" const char *element, "
" virBufferPtr output); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__DESERIALIZE :
2011-05-01 23:57:42 +04:00
header + = " int esxVI_ %s _Deserialize(xmlNodePtr node, esxVI_ %s **item); \n " \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _DeserializeList(xmlNodePtr node, "
" esxVI_ %s **list); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
header + = " \n \n \n "
return header
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_source ( self ) :
2011-05-01 23:57:42 +04:00
source = separator
2011-04-10 15:27:56 +04:00
source + = " * VI Object: %s \n " % self . name
2010-03-06 19:56:28 +03:00
if self . extends is not None :
2011-04-10 15:27:56 +04:00
source + = " * extends %s \n " % self . extends
2010-03-06 19:56:28 +03:00
first = True
if self . extended_by is not None :
for extended_by in self . extended_by :
if first :
2011-04-10 15:27:56 +04:00
source + = " * extended by %s \n " % extended_by
2010-03-06 19:56:28 +03:00
first = False
else :
2011-04-10 15:27:56 +04:00
source + = " * %s \n " % extended_by
2010-03-06 19:56:28 +03:00
source + = " */ \n \n "
# functions
source + = " /* esxVI_ %s _Alloc */ \n " % self . name
source + = " ESX_VI__TEMPLATE__ALLOC( %s ) \n \n " % self . name
# free
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 :
2010-07-28 17:42:10 +04:00
if self . extends is not None :
2011-05-01 23:57:42 +04:00
# 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 )
2010-11-13 16:32:06 +03:00
source + = " esxVI_ %s _Free(&next); \n " % self . extends
source + = " item->_next = (esxVI_ %s *)next; \n \n " % self . name
2010-07-28 17:42:10 +04:00
else :
source + = " esxVI_ %s _Free(&item->_next); \n \n " % self . name
2010-03-06 19:56:28 +03:00
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 "
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DISPATCH__FREE( %s ) \n " \
% extended_by
2010-03-06 19:56:28 +03:00
source + = " }, \n "
source + = " { \n "
if self . features & Object . FEATURE__LIST :
2010-07-28 17:42:10 +04:00
if self . extends is not None :
2011-05-01 23:57:42 +04:00
# avoid "dereferencing type-punned pointer will brea
# strict-aliasing rules" warnings
source + = " esxVI_ %s *next = (esxVI_ %s *)item->_next; \n \n " \
% ( self . extends , self . extends )
2010-11-13 16:32:06 +03:00
source + = " esxVI_ %s _Free(&next); \n " % self . extends
source + = " item->_next = (esxVI_ %s *)next; \n \n " % self . name
2010-07-28 17:42:10 +04:00
else :
source + = " esxVI_ %s _Free(&item->_next); \n \n " % self . name
2010-03-06 19:56:28 +03:00
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
if self . features & Object . FEATURE__DYNAMIC_CAST :
if self . extended_by is not None or self . extends is not None :
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 " )
# append to list
if self . features & Object . FEATURE__LIST :
source + = " /* esxVI_ %s _AppendToList */ \n " % self . name
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__LIST :
source + = " /* esxVI_ %s _DeepCopyList */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__DEEP_COPY( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
else :
if self . features & Object . FEATURE__DEEP_COPY :
source + = " /* esxVI_ %s _DeepCopy */ \n " % self . name
2012-07-19 10:14:18 +04:00
source + = " ESX_VI__TEMPLATE__DYNAMIC_DEEP_COPY( %s , \n " % self . name
2010-03-06 19:56:28 +03:00
source + = " { \n "
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DISPATCH__DEEP_COPY( %s ) \n " \
% extended_by
2010-03-06 19:56:28 +03:00
source + = " }, \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
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__DEEP_COPY( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
# cast from any type
if self . features & Object . FEATURE__ANY_TYPE :
source + = " /* esxVI_ %s _CastFromAnyType */ \n " % self . name
2010-05-18 19:53:12 +04:00
if self . extended_by is None :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE( %s ) \n \n " \
% self . name
2010-05-18 19:53:12 +04:00
else :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DYNAMIC_CAST_FROM_ANY_TYPE( %s , \n " \
% self . name
2010-05-18 19:53:12 +04:00
source + = " { \n "
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DISPATCH__CAST_FROM_ANY_TYPE( %s ) \n " \
% extended_by
2010-05-18 19:53:12 +04:00
source + = " }) \n \n "
2010-03-06 19:56:28 +03:00
if self . features & Object . FEATURE__LIST :
source + = " /* esxVI_ %s _CastListFromAnyType */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__CAST_FROM_ANY_TYPE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
# 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__LIST :
source + = " /* esxVI_ %s _SerializeList */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__SERIALIZE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
else :
if self . features & Object . FEATURE__SERIALIZE :
source + = " /* esxVI_ %s _Serialize */ \n " % self . name
source + = " ESX_VI__TEMPLATE__DYNAMIC_SERIALIZE( %s , \n " % self . name
source + = " { \n "
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DISPATCH__SERIALIZE( %s ) \n " \
% extended_by
2010-03-06 19:56:28 +03:00
source + = " }, \n "
source + = " { \n "
source + = self . generate_serialize_code ( )
source + = " }) \n \n "
if self . features & Object . FEATURE__LIST :
source + = " /* esxVI_ %s _SerializeList */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__SERIALIZE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
2011-05-01 23:57:42 +04:00
# deserialize
2010-07-06 19:27:05 +04:00
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 "
2010-03-06 19:56:28 +03:00
2010-07-06 19:27:05 +04:00
source + = self . generate_deserialize_code ( )
2010-03-06 19:56:28 +03:00
2010-07-06 19:27:05 +04:00
source + = " }) \n \n "
2010-03-06 19:56:28 +03:00
2010-07-06 19:27:05 +04:00
if self . features & Object . FEATURE__LIST :
source + = " /* esxVI_ %s _DeserializeList */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__DESERIALIZE( %s ) \n \n " \
% self . name
2010-07-06 19:27:05 +04:00
else :
if self . features & Object . FEATURE__DESERIALIZE :
source + = " /* esxVI_ %s _Deserialize */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DYNAMIC_DESERIALIZE( %s , \n " \
% self . name
2010-07-06 19:27:05 +04:00
source + = " { \n "
for extended_by in self . extended_by :
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__DISPATCH__DESERIALIZE( %s ) \n " \
% extended_by
2010-07-06 19:27:05 +04:00
source + = " }, \n "
source + = " { \n "
source + = self . generate_deserialize_code ( )
source + = " }) \n \n "
if self . features & Object . FEATURE__LIST :
source + = " /* esxVI_ %s _DeserializeList */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__LIST__DESERIALIZE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
source + = " \n \n "
return source
2011-05-01 13:29:40 +04:00
class ManagedObject ( Type ) :
2011-04-10 15:27:56 +04:00
FEATURE__LIST = ( 1 << 2 )
def __init__ ( self , name , extends , properties , features = 0 , extended_by = None ) :
2011-05-01 13:29:40 +04:00
Type . __init__ ( self , " struct " , name )
2011-04-10 15:27:56 +04:00
self . extends = extends
self . features = features
self . properties = properties
self . extended_by = extended_by
if self . extended_by is not None :
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 :
2011-05-01 23:57:42 +04:00
members + = managed_objects_by_name [ self . extends ] \
. generate_struct_members ( add_banner = True ) + " \n "
2011-04-10 15:27:56 +04:00
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_free_code ( self , add_banner = False ) :
source = " "
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = managed_objects_by_name [ self . extends ] \
. generate_free_code ( add_banner = True ) + " \n "
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
if self . extends is not None or add_banner :
source + = " /* %s */ \n " % self . name
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
if len ( self . properties ) < 1 :
source + = " /* no properties */ \n "
else :
string = " "
2010-04-13 16:25:52 +04:00
2011-04-10 15:27:56 +04:00
for property in self . properties :
string + = property . generate_free_code ( )
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
if len ( string ) < 1 :
source + = " /* no properties to be freed */ \n "
else :
source + = string
2010-04-13 16:25:52 +04:00
2011-04-10 15:27:56 +04:00
return source
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2011-04-10 15:27:56 +04:00
def generate_validate_code ( self , add_banner = False ) :
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = managed_objects_by_name [ self . extends ] \
. generate_validate_code ( add_banner = True ) + " \n "
2011-04-10 15:27:56 +04:00
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 = " "
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
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 = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = managed_objects_by_name [ self . extends ] \
. generate_lookup_code1 ( add_banner = True ) + " \n "
2011-04-10 15:27:56 +04:00
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 + = " \" %s \\ 0 \" \n " % property . name
if len ( string ) < 1 :
source + = " /* no properties */ \n "
else :
source + = string
return source
def generate_lookup_code2 ( self , add_banner = False ) :
source = " "
if self . extends is not None :
2011-05-01 23:57:42 +04:00
source + = managed_objects_by_name [ self . extends ] \
. generate_lookup_code2 ( add_banner = True ) + " \n "
2011-04-10 15:27:56 +04:00
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_lookup_code ( )
if len ( string ) < 1 :
source + = " /* no properties */ \n "
else :
source + = string
return source
def generate_comment ( self ) :
2011-05-01 23:57:42 +04:00
comment = separator
2011-04-10 15:27:56 +04:00
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 :
2011-05-01 23:57:42 +04:00
comment + = " * extended by %s \n " \
% extended_by
2011-04-10 15:27:56 +04:00
first = False
else :
2011-05-01 23:57:42 +04:00
comment + = " * %s \n " \
% extended_by
2011-04-10 15:27:56 +04:00
comment + = " */ \n \n "
return comment
def generate_header ( self ) :
header = self . generate_comment ( )
# struct
header + = " struct _esxVI_ %s { \n " % self . name
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = aligned ( " esxVI_ %s *_next; " % self . name ,
" /* optional */ \n " )
2011-04-10 15:27:56 +04:00
else :
2011-05-01 23:57:42 +04:00
header + = aligned ( " esxVI_ %s *_unused; " % self . name ,
" /* optional */ \n " )
2011-04-10 15:27:56 +04:00
header + = aligned ( " esxVI_Type _type; " , " /* required */ \n " )
2011-05-01 23:57:42 +04:00
header + = aligned ( " esxVI_ManagedObjectReference *_reference; " ,
" /* required */ \n " )
2011-04-10 15:27:56 +04:00
header + = " \n "
header + = self . generate_struct_members ( )
header + = " }; \n \n "
# functions
header + = " int esxVI_ %s _Alloc(esxVI_ %s **item); \n " % ( self . name , self . name )
header + = " void esxVI_ %s _Free(esxVI_ %s **item); \n " % ( self . name , self . name )
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _Validate(esxVI_ %s *item, "
" esxVI_String *selectedPropertyNameList); \n " ) \
% ( self . name , self . name )
2011-04-10 15:27:56 +04:00
if self . features & Object . FEATURE__LIST :
2011-05-01 23:57:42 +04:00
header + = " int esxVI_ %s _AppendToList(esxVI_ %s **list, esxVI_ %s *item); \n " \
% ( self . name , self . name , self . name )
2011-04-10 15:27:56 +04:00
header + = " \n \n \n "
return header
def generate_helper_header ( self ) :
header = " "
# functions
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_Lookup %s (esxVI_Context *ctx, "
" const char *name, "
" esxVI_ManagedObjectReference *root, "
" esxVI_String *selectedPropertyNameList, "
" esxVI_ %s **item, "
" esxVI_Occurrence occurrence); \n " ) \
% ( self . name , self . name )
2011-04-10 15:27:56 +04:00
header + = " \n "
return header
def generate_source ( self ) :
source = self . generate_comment ( )
# functions
source + = " /* esxVI_ %s _Alloc */ \n " % self . name
source + = " ESX_VI__TEMPLATE__ALLOC( %s ) \n \n " % self . name
# free
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 :
2011-05-01 23:57:42 +04:00
# 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 )
2011-04-10 15:27:56 +04:00
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 "
for extended_by in self . extended_by :
source + = " ESX_VI__TEMPLATE__DISPATCH__FREE( %s ) \n " % extended_by
source + = " }, \n "
source + = " { \n "
if self . features & Object . FEATURE__LIST :
if self . extends is not None :
2011-05-01 23:57:42 +04:00
# 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 )
2011-04-10 15:27:56 +04:00
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 "
# validate
source + = " /* esxVI_ %s _Validate */ \n " % self . name
source + = " ESX_VI__TEMPLATE__MANAGED_VALIDATE( %s , \n " % self . name
source + = " { \n "
source + = self . generate_validate_code ( )
source + = " }) \n \n "
# append to list
if self . features & ManagedObject . FEATURE__LIST :
source + = " /* esxVI_ %s _AppendToList */ \n " % self . name
source + = " ESX_VI__TEMPLATE__LIST__APPEND( %s ) \n \n " % self . name
source + = " \n \n "
return source
def generate_helper_source ( self ) :
source = " "
# lookup
source + = " /* esxVI_Lookup %s */ \n " % self . name
source + = " ESX_VI__TEMPLATE__LOOKUP( %s , \n " % self . name
source + = " { \n "
source + = self . generate_lookup_code1 ( )
source + = " }, \n "
source + = " { \n "
source + = self . generate_lookup_code2 ( )
source + = " }) \n \n "
source + = " \n \n "
return source
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
2011-05-01 13:29:40 +04:00
class Enum ( Type ) :
2011-04-10 15:26:47 +04:00
FEATURE__ANY_TYPE = ( 1 << 1 )
FEATURE__SERIALIZE = ( 1 << 2 )
FEATURE__DESERIALIZE = ( 1 << 3 )
def __init__ ( self , name , values , features = 0 ) :
2011-05-01 13:29:40 +04:00
Type . __init__ ( self , " enum " , name )
2011-04-10 15:26:47 +04:00
self . values = values
2011-05-01 12:43:17 +04:00
self . features = features
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_header ( self ) :
2011-05-01 23:57:42 +04:00
header = separator
2010-03-06 19:56:28 +03:00
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
for value in self . values :
header + = " esxVI_ %s _ %s , \n " % ( self . name , capitalize_first ( value ) )
header + = " }; \n \n "
# functions
if self . features & Enum . FEATURE__ANY_TYPE :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _CastFromAnyType(esxVI_AnyType *anyType, "
" esxVI_ %s *item); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Enum . FEATURE__SERIALIZE :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _Serialize(esxVI_ %s item, const char *element, "
" virBufferPtr output); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
if self . features & Enum . FEATURE__DESERIALIZE :
2011-05-01 23:57:42 +04:00
header + = ( " int esxVI_ %s _Deserialize(xmlNodePtr node, "
" esxVI_ %s *item); \n " ) \
% ( self . name , self . name )
2010-03-06 19:56:28 +03:00
header + = " \n \n \n "
return header
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def generate_source ( self ) :
2011-05-01 23:57:42 +04:00
source = separator
2010-03-06 19:56:28 +03:00
source + = " * VI Enum: %s \n " % self . name
source + = " */ \n \n "
2011-05-01 23:57:42 +04:00
source + = " static const esxVI_Enumeration _esxVI_ %s _Enumeration = { \n " \
% self . name
2010-03-06 19:56:28 +03:00
source + = " esxVI_Type_ %s , { \n " % self . name
for value in self . values :
2011-05-01 23:57:42 +04:00
source + = " { \" %s \" , esxVI_ %s _ %s }, \n " \
% ( value , self . name , capitalize_first ( value ) )
2010-03-06 19:56:28 +03:00
source + = " { NULL, -1 }, \n "
source + = " }, \n "
source + = " }; \n \n "
# functions
if self . features & Enum . FEATURE__ANY_TYPE :
source + = " /* esxVI_ %s _CastFromAnyType */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__ENUMERATION__CAST_FROM_ANY_TYPE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
if self . features & Enum . FEATURE__SERIALIZE :
source + = " /* esxVI_ %s _Serialize */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__ENUMERATION__SERIALIZE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
if self . features & Enum . FEATURE__DESERIALIZE :
source + = " /* esxVI_ %s _Deserialize */ \n " % self . name
2011-05-01 23:57:42 +04:00
source + = " ESX_VI__TEMPLATE__ENUMERATION__DESERIALIZE( %s ) \n \n " \
% self . name
2010-03-06 19:56:28 +03:00
source + = " \n \n "
return source
def report_error ( message ) :
print " error: " + message
sys . exit ( 1 )
def capitalize_first ( string ) :
return string [ : 1 ] . upper ( ) + string [ 1 : ]
def parse_object ( block ) :
2011-04-10 15:27:56 +04:00
# expected format: [managed] object <name> [extends <name>]
2010-03-06 19:56:28 +03:00
header_items = block [ 0 ] [ 1 ] . split ( )
2011-04-10 15:27:56 +04:00
managed = False
if header_items [ 0 ] == " managed " :
managed = True
del header_items [ 0 ]
2010-03-06 19:56:28 +03:00
if len ( header_items ) < 2 :
report_error ( " line %d : invalid block header " % ( number ) )
assert header_items [ 0 ] == " object "
name = header_items [ 1 ]
extends = None
if len ( header_items ) > 2 :
if header_items [ 2 ] != " extends " :
report_error ( " line %d : invalid block header " % ( number ) )
else :
extends = header_items [ 3 ]
properties = [ ]
for line in block [ 1 : ] :
# expected format: <type> <name> <occurrence>
items = line [ 1 ] . split ( )
if len ( items ) != 3 :
report_error ( " line %d : invalid property " % line [ 0 ] )
2010-04-13 16:25:52 +04:00
if items [ 2 ] not in valid_occurrences :
2010-03-06 19:56:28 +03:00
report_error ( " line %d : invalid occurrence " % line [ 0 ] )
2011-04-10 15:26:47 +04:00
properties . append ( Property ( type = items [ 0 ] , name = items [ 1 ] ,
occurrence = items [ 2 ] ) )
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
if managed :
return ManagedObject ( name = name , extends = extends , properties = properties )
else :
return Object ( name = name , extends = extends , properties = properties )
2010-03-06 19:56:28 +03:00
def parse_enum ( block ) :
# expected format: enum <name>
header_items = block [ 0 ] [ 1 ] . split ( )
if len ( header_items ) < 2 :
report_error ( " line %d : invalid block header " % ( number ) )
assert header_items [ 0 ] == " enum "
name = header_items [ 1 ]
values = [ ]
for line in block [ 1 : ] :
# expected format: <value>
values . append ( line [ 1 ] )
2011-04-10 15:26:47 +04:00
return Enum ( name = name , values = values )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
def parse_method ( block ) :
# expected format: method <name> [returns <type> <occurrence>]
header_items = block [ 0 ] [ 1 ] . split ( )
if len ( header_items ) < 2 :
report_error ( " line %d : invalid block header " % ( number ) )
assert header_items [ 0 ] == " method "
name = header_items [ 1 ]
returns = None
if len ( header_items ) > 2 :
if header_items [ 2 ] != " returns " :
report_error ( " line %d : invalid block header " % ( number ) )
else :
2011-04-10 15:26:47 +04:00
returns = Parameter ( type = header_items [ 3 ] , name = " output " ,
occurrence = header_items [ 4 ] )
2010-04-13 16:25:52 +04:00
parameters = [ ]
for line in block [ 1 : ] :
# expected format: <type> <name> <occurrence>
items = line [ 1 ] . split ( )
if len ( items ) != 3 :
report_error ( " line %d : invalid property " % line [ 0 ] )
if items [ 2 ] not in valid_occurrences :
report_error ( " line %d : invalid occurrence " % line [ 0 ] )
2011-04-10 15:26:47 +04:00
parameters . append ( Parameter ( type = items [ 0 ] , name = items [ 1 ] ,
occurrence = items [ 2 ] ) )
2010-04-13 16:25:52 +04:00
2011-04-10 15:26:47 +04:00
return Method ( name = name , parameters = parameters , returns = returns )
2010-04-13 16:25:52 +04:00
2010-03-06 19:56:28 +03:00
def is_known_type ( type ) :
return type in predefined_objects or \
type in predefined_enums or \
type in objects_by_name or \
2011-04-10 15:27:56 +04:00
type in managed_objects_by_name or \
2010-03-06 19:56:28 +03:00
type in enums_by_name
def open_and_print ( filename ) :
if filename . startswith ( " ./ " ) :
print " GEN " + filename [ 2 : ]
else :
print " GEN " + filename
return open ( filename , " wb " )
predefined_enums = [ " Boolean " ]
predefined_objects = [ " AnyType " ,
2012-08-02 02:15:11 +04:00
" Byte " ,
2010-03-06 19:56:28 +03:00
" Int " ,
" Long " ,
" String " ,
" DateTime " ,
2010-12-06 15:53:36 +03:00
" MethodFault " ,
2010-03-06 19:56:28 +03:00
" ManagedObjectReference " ]
additional_enum_features = { " ManagedEntityStatus " : Enum . FEATURE__ANY_TYPE ,
" TaskInfoState " : Enum . FEATURE__ANY_TYPE ,
" VirtualMachinePowerState " : Enum . FEATURE__ANY_TYPE }
2010-12-30 03:36:31 +03:00
additional_object_features = { " AutoStartDefaults " : Object . FEATURE__ANY_TYPE ,
2011-05-01 13:31:55 +04:00
" AutoStartPowerInfo " : Object . FEATURE__ANY_TYPE ,
2011-05-01 23:57:42 +04:00
" DatastoreHostMount " : Object . FEATURE__DEEP_COPY |
Object . FEATURE__LIST |
Object . FEATURE__ANY_TYPE ,
" DatastoreInfo " : Object . FEATURE__ANY_TYPE |
Object . FEATURE__DYNAMIC_CAST ,
2010-12-30 03:36:31 +03:00
" HostConfigManager " : Object . FEATURE__ANY_TYPE ,
2011-05-01 23:57:42 +04:00
" HostCpuIdInfo " : Object . FEATURE__LIST |
Object . FEATURE__ANY_TYPE ,
" HostDatastoreBrowserSearchResults " : Object . FEATURE__LIST |
Object . FEATURE__ANY_TYPE ,
2010-03-06 19:56:28 +03:00
" ManagedObjectReference " : Object . FEATURE__ANY_TYPE ,
2011-05-01 13:31:55 +04:00
" ObjectContent " : Object . FEATURE__DEEP_COPY ,
2010-03-06 19:56:28 +03:00
" ResourcePoolResourceUsage " : Object . FEATURE__ANY_TYPE ,
2011-05-01 12:43:17 +04:00
" ServiceContent " : Object . FEATURE__DESERIALIZE ,
2010-03-06 19:56:28 +03:00
" SharesInfo " : Object . FEATURE__ANY_TYPE ,
2011-05-01 23:57:42 +04:00
" TaskInfo " : Object . FEATURE__LIST |
Object . FEATURE__ANY_TYPE ,
2010-03-06 19:56:28 +03:00
" UserSession " : Object . FEATURE__ANY_TYPE ,
2010-04-07 13:23:53 +04:00
" VirtualMachineQuestionInfo " : Object . FEATURE__ANY_TYPE ,
2011-05-01 23:57:42 +04:00
" VirtualMachineSnapshotTree " : Object . FEATURE__DEEP_COPY |
Object . FEATURE__ANY_TYPE ,
2011-05-01 12:43:17 +04:00
" VmEventArgument " : Object . FEATURE__DESERIALIZE }
2010-03-06 19:56:28 +03:00
2011-05-01 12:43:17 +04:00
removed_object_features = { }
2010-03-06 19:56:28 +03:00
if " srcdir " in os . environ :
input_filename = os . path . join ( os . environ [ " srcdir " ] , " esx/esx_vi_generator.input " )
output_dirname = os . path . join ( os . environ [ " srcdir " ] , " esx " )
else :
input_filename = os . path . join ( os . getcwd ( ) , " esx_vi_generator.input " )
output_dirname = os . getcwd ( )
2010-04-13 16:25:52 +04:00
types_typedef = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.typedef " ) )
types_typeenum = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.typeenum " ) )
types_typetostring = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.typetostring " ) )
types_typefromstring = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.typefromstring " ) )
types_header = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.h " ) )
types_source = open_and_print ( os . path . join ( output_dirname , " esx_vi_types.generated.c " ) )
methods_header = open_and_print ( os . path . join ( output_dirname , " esx_vi_methods.generated.h " ) )
methods_source = open_and_print ( os . path . join ( output_dirname , " esx_vi_methods.generated.c " ) )
2011-05-01 10:05:58 +04:00
methods_macro = open_and_print ( os . path . join ( output_dirname , " esx_vi_methods.generated.macro " ) )
2011-04-10 15:27:56 +04:00
helpers_header = open_and_print ( os . path . join ( output_dirname , " esx_vi.generated.h " ) )
helpers_source = open_and_print ( os . path . join ( output_dirname , " esx_vi.generated.c " ) )
2010-03-06 19:56:28 +03:00
number = 0
objects_by_name = { }
2011-04-10 15:27:56 +04:00
managed_objects_by_name = { }
2010-03-06 19:56:28 +03:00
enums_by_name = { }
2010-04-13 16:25:52 +04:00
methods_by_name = { }
2010-03-06 19:56:28 +03:00
block = None
2011-05-01 12:43:17 +04:00
# parse input file
2010-03-06 19:56:28 +03:00
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
2011-04-10 15:27:56 +04:00
if line . startswith ( " object " ) or line . startswith ( " managed object " ) or \
line . startswith ( " enum " ) or line . startswith ( " method " ) :
2010-03-06 19:56:28 +03:00
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 ( " object " ) :
obj = parse_object ( block )
objects_by_name [ obj . name ] = obj
2011-04-10 15:27:56 +04:00
elif block [ 0 ] [ 1 ] . startswith ( " managed object " ) :
obj = parse_object ( block )
managed_objects_by_name [ obj . name ] = obj
2010-04-13 16:25:52 +04:00
elif block [ 0 ] [ 1 ] . startswith ( " enum " ) :
2010-03-06 19:56:28 +03:00
enum = parse_enum ( block )
enums_by_name [ enum . name ] = enum
2010-04-13 16:25:52 +04:00
else :
method = parse_method ( block )
methods_by_name [ method . name ] = method
2010-03-06 19:56:28 +03:00
block = None
else :
block . append ( ( number , line ) )
2011-05-01 12:43:17 +04:00
for method in methods_by_name . values ( ) :
# method parameter types must be serializable
for parameter in method . parameters :
if not parameter . is_type_generated ( ) :
continue
if parameter . is_enum ( ) :
enums_by_name [ parameter . type ] . features | = Enum . FEATURE__SERIALIZE
else :
objects_by_name [ parameter . type ] . features | = Object . FEATURE__SERIALIZE
2011-05-01 13:08:21 +04:00
objects_by_name [ parameter . type ] . candidate_for_dynamic_cast = True
2011-05-01 12:43:17 +04:00
2011-05-01 13:31:55 +04:00
# detect list usage
if parameter . occurrence == OCCURRENCE__REQUIRED_LIST or \
parameter . occurrence == OCCURRENCE__OPTIONAL_LIST :
if parameter . is_enum ( ) :
report_error ( " unsupported usage of enum ' %s ' as list in ' %s ' "
% ( parameter . type , method . name ) )
else :
objects_by_name [ parameter . type ] . features | = Object . FEATURE__LIST
2011-05-01 12:43:17 +04:00
# method return types must be deserializable
if method . returns and method . returns . is_type_generated ( ) :
if method . returns . is_enum ( ) :
enums_by_name [ method . returns . type ] . features | = Enum . FEATURE__DESERIALIZE
else :
objects_by_name [ method . returns . type ] . features | = Object . FEATURE__DESERIALIZE
2011-05-01 13:08:21 +04:00
objects_by_name [ method . returns . type ] . candidate_for_dynamic_cast = True
2011-05-01 12:43:17 +04:00
2011-05-01 13:31:55 +04:00
# detect list usage
if method . returns . occurrence == OCCURRENCE__REQUIRED_LIST or \
method . returns . occurrence == OCCURRENCE__OPTIONAL_LIST :
if method . returns . is_enum ( ) :
report_error ( " unsupported usage of enum ' %s ' as list in ' %s ' "
% ( method . returns . type , method . name ) )
else :
objects_by_name [ method . returns . type ] . features | = Object . FEATURE__LIST
2011-05-01 12:43:17 +04:00
2010-03-06 19:56:28 +03:00
for enum in enums_by_name . values ( ) :
# apply additional features
if enum . name in additional_enum_features :
enum . features | = additional_enum_features [ enum . name ]
2011-05-01 12:43:17 +04:00
if additional_enum_features [ enum . name ] & Enum . FEATURE__ANY_TYPE :
enum . features | = Enum . FEATURE__DESERIALIZE
2010-03-06 19:56:28 +03:00
for obj in objects_by_name . values ( ) :
for property in obj . properties :
2010-04-13 16:25:52 +04:00
if property . occurrence != OCCURRENCE__IGNORED and \
2010-03-06 19:56:28 +03:00
not is_known_type ( property . type ) :
2011-05-01 23:57:42 +04:00
report_error ( " object ' %s ' contains unknown property type ' %s ' "
% ( obj . name , property . type ) )
2010-03-06 19:56:28 +03:00
if obj . extends is not None :
if not is_known_type ( obj . extends ) :
2011-05-01 23:57:42 +04:00
report_error ( " object ' %s ' extends unknown object ' %s ' "
% ( obj . name , obj . extends ) )
2010-03-06 19:56:28 +03:00
for property in obj . properties :
2011-05-01 13:31:55 +04:00
if not property . is_type_generated ( ) :
continue
2011-05-01 13:08:21 +04:00
if property . is_enum ( ) :
enums_by_name [ property . type ] . candidate_for_dynamic_cast = True
else :
objects_by_name [ property . type ] . candidate_for_dynamic_cast = True
# detect list usage
2011-05-01 13:31:55 +04:00
if property . occurrence == OCCURRENCE__REQUIRED_LIST or \
property . occurrence == OCCURRENCE__OPTIONAL_LIST :
if property . is_enum ( ) :
report_error ( " unsupported usage of enum ' %s ' as list in ' %s ' "
% ( property . type , obj . type ) )
else :
objects_by_name [ property . type ] . features | = Object . FEATURE__LIST
2010-03-06 19:56:28 +03:00
# apply/remove additional features
if obj . name in additional_object_features :
obj . features | = additional_object_features [ obj . name ]
2011-05-01 12:43:17 +04:00
if additional_object_features [ obj . name ] & Object . FEATURE__ANY_TYPE :
obj . features | = Object . FEATURE__DESERIALIZE
2010-03-06 19:56:28 +03:00
if obj . name in removed_object_features :
obj . features & = ~ removed_object_features [ obj . name ]
# detect extended_by relation
if obj . extends is not None :
extended_obj = objects_by_name [ obj . extends ]
if extended_obj . extended_by is None :
extended_obj . extended_by = [ obj . name ]
else :
extended_obj . extended_by . append ( obj . name )
2010-05-18 20:11:59 +04:00
extended_obj . extended_by . sort ( )
2010-03-06 19:56:28 +03:00
2011-05-01 13:08:21 +04:00
for obj in objects_by_name . values ( ) :
# if an object is a candidate (it is used directly as parameter or return
# type or is a member of another object) and it is extended by another
# object then this type needs the dynamic cast feature
if obj . candidate_for_dynamic_cast and obj . extended_by :
obj . features | = Object . FEATURE__DYNAMIC_CAST
2011-05-01 12:43:17 +04:00
def propagate_feature ( obj , feature ) :
global features_have_changed
if not ( obj . features & feature ) :
return
for property in obj . properties :
if property . occurrence == OCCURRENCE__IGNORED or \
not property . is_type_generated ( ) :
continue
if property . is_enum ( ) :
if feature == Object . FEATURE__SERIALIZE and \
not ( enums_by_name [ property . type ] . features & Enum . FEATURE__SERIALIZE ) :
enums_by_name [ property . type ] . features | = Enum . FEATURE__SERIALIZE
features_have_changed = True
elif feature == Object . FEATURE__DESERIALIZE and \
not ( enums_by_name [ property . type ] . features & Enum . FEATURE__DESERIALIZE ) :
enums_by_name [ property . type ] . features | = Enum . FEATURE__DESERIALIZE
features_have_changed = True
elif property . is_object ( ) :
if not ( objects_by_name [ property . type ] . features & feature ) :
objects_by_name [ property . type ] . features | = feature
features_have_changed = True
if obj . name != property . type :
propagate_feature ( objects_by_name [ property . type ] , feature )
def inherit_features ( obj ) :
global features_have_changed
if obj . extended_by is not None :
for extended_by in obj . extended_by :
previous = objects_by_name [ extended_by ] . features
objects_by_name [ extended_by ] . features | = obj . features
if objects_by_name [ extended_by ] . features != previous :
features_have_changed = True
if obj . extends is not None :
previous = objects_by_name [ obj . extends ] . features
objects_by_name [ obj . extends ] . features | = obj . features
if objects_by_name [ obj . extends ] . features != previous :
features_have_changed = True
if obj . extended_by is not None :
for extended_by in obj . extended_by :
inherit_features ( objects_by_name [ extended_by ] )
# there are two directions to spread features:
# 1) up and down the inheritance chain
# 2) from object types to their member property types
# spreading needs to be done alternating on both directions because they can
# affect each other
features_have_changed = True
while features_have_changed :
features_have_changed = False
for obj in objects_by_name . values ( ) :
propagate_feature ( obj , Object . FEATURE__DEEP_COPY )
propagate_feature ( obj , Object . FEATURE__SERIALIZE )
propagate_feature ( obj , Object . FEATURE__DESERIALIZE )
for obj in objects_by_name . values ( ) :
inherit_features ( obj )
2011-04-10 15:27:56 +04:00
for obj in managed_objects_by_name . values ( ) :
for property in obj . properties :
if property . occurrence != OCCURRENCE__IGNORED and \
not is_known_type ( property . type ) :
2011-05-01 23:57:42 +04:00
report_error ( " object ' %s ' contains unknown property type ' %s ' "
% ( obj . name , property . type ) )
2011-04-10 15:27:56 +04:00
if obj . extends is not None :
if not is_known_type ( obj . extends ) :
2011-05-01 23:57:42 +04:00
report_error ( " object ' %s ' extends unknown object ' %s ' "
% ( obj . name , obj . extends ) )
2011-04-10 15:27:56 +04:00
# detect extended_by relation
if obj . extends is not None :
extended_obj = managed_objects_by_name [ obj . extends ]
if extended_obj . extended_by is None :
extended_obj . extended_by = [ obj . name ]
else :
extended_obj . extended_by . append ( obj . name )
extended_obj . extended_by . sort ( )
2011-08-24 01:15:21 +04:00
notice = " /* Generated by esx_vi_generator.py */ \n \n \n \n "
types_typedef . write ( notice )
types_typeenum . write ( notice )
types_typetostring . write ( notice )
types_typefromstring . write ( notice )
types_header . write ( notice )
types_source . write ( notice )
methods_header . write ( notice )
methods_source . write ( notice )
methods_macro . write ( notice )
helpers_header . write ( notice )
helpers_source . write ( notice )
2010-03-06 19:56:28 +03:00
2011-05-01 10:05:58 +04:00
2010-04-13 16:25:52 +04:00
# output enums
2011-05-01 23:57:42 +04:00
types_typedef . write ( separator +
2010-04-13 16:25:52 +04:00
" * VI Enums \n " +
" */ \n \n " )
2010-03-06 19:56:28 +03:00
names = enums_by_name . keys ( )
names . sort ( )
for name in names :
2010-04-13 16:25:52 +04:00
types_typedef . write ( enums_by_name [ name ] . generate_typedef ( ) )
types_typeenum . write ( enums_by_name [ name ] . generate_typeenum ( ) )
types_typetostring . write ( enums_by_name [ name ] . generate_typetostring ( ) )
types_typefromstring . write ( enums_by_name [ name ] . generate_typefromstring ( ) )
types_header . write ( enums_by_name [ name ] . generate_header ( ) )
types_source . write ( enums_by_name [ name ] . generate_source ( ) )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
# output objects
types_typedef . write ( " \n \n \n " +
2011-05-01 23:57:42 +04:00
separator +
2011-04-10 15:27:56 +04:00
" * VI Objects \n " +
2010-04-13 16:25:52 +04:00
" */ \n \n " )
types_typeenum . write ( " \n " )
types_typetostring . write ( " \n " )
types_typefromstring . write ( " \n " )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
names = objects_by_name . keys ( )
names . sort ( )
2010-03-06 19:56:28 +03:00
2010-04-13 16:25:52 +04:00
for name in names :
types_typedef . write ( objects_by_name [ name ] . generate_typedef ( ) )
types_typeenum . write ( objects_by_name [ name ] . generate_typeenum ( ) )
types_typetostring . write ( objects_by_name [ name ] . generate_typetostring ( ) )
types_typefromstring . write ( objects_by_name [ name ] . generate_typefromstring ( ) )
types_header . write ( objects_by_name [ name ] . generate_header ( ) )
types_source . write ( objects_by_name [ name ] . generate_source ( ) )
2010-03-06 19:56:28 +03:00
2011-04-10 15:27:56 +04:00
# output managed objects
types_typedef . write ( " \n \n \n " +
2011-05-01 23:57:42 +04:00
separator +
2011-04-10 15:27:56 +04:00
" * VI Managed Objects \n " +
" */ \n \n " )
types_typeenum . write ( " \n " )
types_typetostring . write ( " \n " )
types_typefromstring . write ( " \n " )
names = managed_objects_by_name . keys ( )
names . sort ( )
for name in names :
types_typedef . write ( managed_objects_by_name [ name ] . generate_typedef ( ) )
types_typeenum . write ( managed_objects_by_name [ name ] . generate_typeenum ( ) )
types_typetostring . write ( managed_objects_by_name [ name ] . generate_typetostring ( ) )
types_typefromstring . write ( managed_objects_by_name [ name ] . generate_typefromstring ( ) )
types_header . write ( managed_objects_by_name [ name ] . generate_header ( ) )
types_source . write ( managed_objects_by_name [ name ] . generate_source ( ) )
2010-04-13 16:25:52 +04:00
# output methods
names = methods_by_name . keys ( )
names . sort ( )
2010-03-06 19:56:28 +03:00
for name in names :
2010-04-13 16:25:52 +04:00
methods_header . write ( methods_by_name [ name ] . generate_header ( ) )
methods_source . write ( methods_by_name [ name ] . generate_source ( ) )
2011-04-10 15:27:56 +04:00
2011-05-01 13:51:19 +04:00
names = list ( autobind_names )
names . sort ( )
2011-05-01 10:05:58 +04:00
2011-05-01 13:51:19 +04:00
for name in names :
2011-05-01 10:05:58 +04:00
string = aligned ( " #define ESX_VI__METHOD__PARAMETER__THIS__ %s " % name , " \\ \n " , 78 )
string + = " ESX_VI__METHOD__PARAMETER__THIS_FROM_SERVICE(ManagedObjectReference, \\ \n "
string + = aligned ( " " , " %s ) \n \n \n \n " % name , 49 )
methods_macro . write ( string )
2011-04-10 15:27:56 +04:00
# output helpers
names = managed_objects_by_name . keys ( )
names . sort ( )
for name in names :
helpers_header . write ( managed_objects_by_name [ name ] . generate_helper_header ( ) )
helpers_source . write ( managed_objects_by_name [ name ] . generate_helper_source ( ) )