Merge pull request #1220 from kleisauke/generate-cpp-pyvips
Use pyvips to generate the C++ binding
This commit is contained in:
commit
96cc19b5e9
@ -25,8 +25,7 @@ vips-operators.cpp:
|
|||||||
echo -n "// " >> vips-operators.cpp; \
|
echo -n "// " >> vips-operators.cpp; \
|
||||||
date >> vips-operators.cpp; \
|
date >> vips-operators.cpp; \
|
||||||
echo "// this file is generated automatically, do not edit!" >> vips-operators.cpp; \
|
echo "// this file is generated automatically, do not edit!" >> vips-operators.cpp; \
|
||||||
echo "" >> vips-operators.cpp; \
|
./gen-operators.py -g cpp >> vips-operators.cpp
|
||||||
./gen-operators.py >> vips-operators.cpp
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
README \
|
README \
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# walk vips and generate member definitions for all operators
|
# This file generates the member definitions and declarations for all vips operators.
|
||||||
|
# It's in Python, since we use the whole of FFI.
|
||||||
|
|
||||||
# sample member definition:
|
# Regenerate the files with something like:
|
||||||
|
#
|
||||||
|
# cd cplusplus
|
||||||
|
# python gen-operators.py
|
||||||
|
|
||||||
# VImage VImage::invert( VOption *options )
|
# this needs pyvips
|
||||||
|
#
|
||||||
|
# pip install --user pyvips
|
||||||
|
|
||||||
|
# Sample member declaration:
|
||||||
|
# VImage invert(VOption *options = 0) const;
|
||||||
|
|
||||||
|
# Sample member definition:
|
||||||
|
# VImage VImage::invert( VOption *options ) const
|
||||||
# {
|
# {
|
||||||
# VImage out;
|
# VImage out;
|
||||||
#
|
#
|
||||||
@ -16,197 +28,236 @@
|
|||||||
# return( out );
|
# return( out );
|
||||||
# }
|
# }
|
||||||
|
|
||||||
import sys
|
import argparse
|
||||||
import re
|
|
||||||
|
|
||||||
import logging
|
from pyvips import Image, Operation, GValue, Error, \
|
||||||
#logging.basicConfig(level = logging.DEBUG)
|
ffi, gobject_lib, type_map, type_from_name, nickname_find, type_name
|
||||||
|
|
||||||
import gi
|
|
||||||
gi.require_version('Vips', '8.0')
|
|
||||||
from gi.repository import Vips, GObject
|
|
||||||
|
|
||||||
vips_type_image = GObject.GType.from_name("VipsImage")
|
|
||||||
vips_type_operation = GObject.GType.from_name("VipsOperation")
|
|
||||||
param_enum = GObject.GType.from_name("GParamEnum")
|
|
||||||
|
|
||||||
# turn a GType into a C++ type
|
# turn a GType into a C++ type
|
||||||
gtype_to_cpp = {
|
gtype_to_cpp = {
|
||||||
"VipsImage" : "VImage",
|
GValue.gbool_type: 'bool',
|
||||||
"gint" : "int",
|
GValue.gint_type: 'int',
|
||||||
"gdouble" : "double",
|
GValue.gdouble_type: 'double',
|
||||||
"gboolean" : "bool",
|
GValue.gstr_type: 'char *',
|
||||||
"gchararray" : "char *",
|
GValue.refstr_type: 'char *',
|
||||||
"VipsArrayInt" : "std::vector<int>",
|
GValue.gflags_type: 'int',
|
||||||
"VipsArrayDouble" : "std::vector<double>",
|
GValue.image_type: 'VImage',
|
||||||
"VipsArrayImage" : "std::vector<VImage>",
|
GValue.array_int_type: 'std::vector<int>',
|
||||||
"VipsBlob" : "VipsBlob *"
|
GValue.array_double_type: 'std::vector<double>',
|
||||||
|
GValue.array_image_type: 'std::vector<VImage>',
|
||||||
|
GValue.blob_type: 'VipsBlob *'
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_ctype(prop):
|
# values for VipsArgumentFlags
|
||||||
|
_REQUIRED = 1
|
||||||
|
_INPUT = 16
|
||||||
|
_OUTPUT = 32
|
||||||
|
_DEPRECATED = 64
|
||||||
|
_MODIFY = 128
|
||||||
|
|
||||||
|
# for VipsOperationFlags
|
||||||
|
_OPERATION_DEPRECATED = 8
|
||||||
|
|
||||||
|
|
||||||
|
def get_cpp_type(gtype):
|
||||||
|
"""Map a gtype to C++ type name we use to represent it.
|
||||||
|
"""
|
||||||
|
if gtype in gtype_to_cpp:
|
||||||
|
return gtype_to_cpp[gtype]
|
||||||
|
|
||||||
|
fundamental = gobject_lib.g_type_fundamental(gtype)
|
||||||
|
|
||||||
# enum params use the C name as their name
|
# enum params use the C name as their name
|
||||||
if GObject.type_is_a(param_enum, prop):
|
if fundamental == GValue.genum_type:
|
||||||
return prop.value_type.name
|
return type_name(gtype)
|
||||||
|
|
||||||
return gtype_to_cpp[prop.value_type.name]
|
if fundamental in gtype_to_cpp:
|
||||||
|
return gtype_to_cpp[fundamental]
|
||||||
|
|
||||||
def find_required(op):
|
return '<unknown type>'
|
||||||
required = []
|
|
||||||
for prop in op.props:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.REQUIRED:
|
|
||||||
continue
|
|
||||||
if flags & Vips.ArgumentFlags.DEPRECATED:
|
|
||||||
continue
|
|
||||||
|
|
||||||
required.append(prop)
|
|
||||||
|
|
||||||
def priority_sort(a, b):
|
# swap any '-' for '_'
|
||||||
pa = op.get_argument_priority(a.name)
|
|
||||||
pb = op.get_argument_priority(b.name)
|
|
||||||
|
|
||||||
return pa - pb
|
|
||||||
|
|
||||||
required.sort(priority_sort)
|
|
||||||
|
|
||||||
return required
|
|
||||||
|
|
||||||
# find the first input image ... this will be used as "this"
|
|
||||||
def find_first_input_image(op, required):
|
|
||||||
found = False
|
|
||||||
for prop in required:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.INPUT:
|
|
||||||
continue
|
|
||||||
if GObject.type_is_a(vips_type_image, prop.value_type):
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return prop
|
|
||||||
|
|
||||||
# find the first output arg ... this will be used as the result
|
|
||||||
def find_first_output(op, required):
|
|
||||||
found = False
|
|
||||||
for prop in required:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.OUTPUT:
|
|
||||||
continue
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return prop
|
|
||||||
|
|
||||||
# swap any "-" for "_"
|
|
||||||
def cppize(name):
|
def cppize(name):
|
||||||
return re.sub('-', '_', name)
|
return name.replace('-', '_')
|
||||||
|
|
||||||
def gen_arg_list(op, required):
|
|
||||||
first = True
|
def generate_operation(operation_name, declaration_only=False):
|
||||||
for prop in required:
|
op = Operation.new_from_name(operation_name)
|
||||||
if not first:
|
|
||||||
print ',',
|
# we are only interested in non-deprecated args
|
||||||
|
args = [[name, flags] for name, flags in op.get_args()
|
||||||
|
if not flags & _DEPRECATED]
|
||||||
|
|
||||||
|
# find the first required input image arg, if any ... that will be self
|
||||||
|
member_x = None
|
||||||
|
for name, flags in args:
|
||||||
|
if ((flags & _INPUT) != 0 and
|
||||||
|
(flags & _REQUIRED) != 0 and
|
||||||
|
op.get_typeof(name) == GValue.image_type):
|
||||||
|
member_x = name
|
||||||
|
break
|
||||||
|
|
||||||
|
required_input = [name for name, flags in args
|
||||||
|
if (flags & _INPUT) != 0 and
|
||||||
|
(flags & _REQUIRED) != 0 and
|
||||||
|
name != member_x]
|
||||||
|
|
||||||
|
required_output = [name for name, flags in args
|
||||||
|
if ((flags & _OUTPUT) != 0 and
|
||||||
|
(flags & _REQUIRED) != 0) or
|
||||||
|
((flags & _INPUT) != 0 and
|
||||||
|
(flags & _REQUIRED) != 0 and
|
||||||
|
(flags & _MODIFY) != 0) and
|
||||||
|
name != member_x]
|
||||||
|
|
||||||
|
has_output = len(required_output) >= 1
|
||||||
|
|
||||||
|
# Add a C++ style comment block with some additional markings (@param, @return)
|
||||||
|
if declaration_only:
|
||||||
|
description = op.get_description()
|
||||||
|
|
||||||
|
result = '\n/**\n'
|
||||||
|
result += ' * ' + description[0].upper() + description[1:] + '.'
|
||||||
|
|
||||||
|
for name in required_input:
|
||||||
|
result += '\n * @param ' + cppize(name) + ' ' + op.get_blurb(name) + '.'
|
||||||
|
|
||||||
|
if has_output:
|
||||||
|
# skip the first element
|
||||||
|
for name in required_output[1:]:
|
||||||
|
result += '\n * @param ' + cppize(name) + ' ' + op.get_blurb(name) + '.'
|
||||||
|
|
||||||
|
result += '\n * @param options Optional options.'
|
||||||
|
|
||||||
|
if has_output:
|
||||||
|
result += '\n * @return ' + op.get_blurb(required_output[0]) + '.'
|
||||||
|
|
||||||
|
result += '\n */\n'
|
||||||
else:
|
else:
|
||||||
first = False
|
result = '\n'
|
||||||
|
|
||||||
print get_ctype(prop),
|
if member_x is None and declaration_only:
|
||||||
|
result += 'static '
|
||||||
|
if has_output:
|
||||||
|
# the first output arg will be used as the result
|
||||||
|
cpp_type = get_cpp_type(op.get_typeof(required_output[0]))
|
||||||
|
spacing = '' if cpp_type.endswith('*') else ' '
|
||||||
|
result += '{0}{1}'.format(cpp_type, spacing)
|
||||||
|
else:
|
||||||
|
result += 'void '
|
||||||
|
|
||||||
|
if not declaration_only:
|
||||||
|
result += 'VImage::'
|
||||||
|
|
||||||
|
result += '{0}( '.format(operation_name)
|
||||||
|
for name in required_input:
|
||||||
|
gtype = op.get_typeof(name)
|
||||||
|
cpp_type = get_cpp_type(gtype)
|
||||||
|
spacing = '' if cpp_type.endswith('*') else ' '
|
||||||
|
result += '{0}{1}{2}, '.format(cpp_type, spacing, cppize(name))
|
||||||
|
|
||||||
# output params are passed by reference
|
# output params are passed by reference
|
||||||
flags = op.get_argument_flags(prop.name)
|
if has_output:
|
||||||
if flags & Vips.ArgumentFlags.OUTPUT:
|
# skip the first element
|
||||||
print '*',
|
for name in required_output[1:]:
|
||||||
|
gtype = op.get_typeof(name)
|
||||||
|
cpp_type = get_cpp_type(gtype)
|
||||||
|
spacing = '' if cpp_type.endswith('*') else ' '
|
||||||
|
result += '{0}{1}*{2}, '.format(cpp_type, spacing, cppize(name))
|
||||||
|
|
||||||
print cppize(prop.name),
|
result += 'VOption *options {0})'.format('= 0 ' if declaration_only else '')
|
||||||
|
|
||||||
if not first:
|
# if no 'this' available, it's a class method and they are all const
|
||||||
print ',',
|
if member_x is not None:
|
||||||
print 'VOption *options',
|
result += ' const'
|
||||||
|
|
||||||
def gen_operation(cls):
|
if declaration_only:
|
||||||
op = Vips.Operation.new(cls.name)
|
result += ';'
|
||||||
gtype = Vips.type_find("VipsOperation", cls.name)
|
|
||||||
nickname = Vips.nickname_find(gtype)
|
|
||||||
all_required = find_required(op)
|
|
||||||
|
|
||||||
result = find_first_output(op, all_required)
|
return result
|
||||||
this = find_first_input_image(op, all_required)
|
|
||||||
|
|
||||||
# shallow copy
|
result += '\n{\n'
|
||||||
required = all_required[:]
|
|
||||||
if result != None:
|
|
||||||
required.remove(result)
|
|
||||||
if this != None:
|
|
||||||
required.remove(this)
|
|
||||||
|
|
||||||
if result == None:
|
if has_output:
|
||||||
print 'void',
|
# the first output arg will be used as the result
|
||||||
else:
|
name = required_output[0]
|
||||||
print '%s' % gtype_to_cpp[result.value_type.name],
|
cpp_type = get_cpp_type(op.get_typeof(name))
|
||||||
|
spacing = '' if cpp_type.endswith('*') else ' '
|
||||||
|
result += ' {0}{1}{2};\n\n'.format(cpp_type, spacing, cppize(name))
|
||||||
|
|
||||||
print 'VImage::%s(' % nickname,
|
result += ' call( "{0}",\n'.format(operation_name)
|
||||||
|
result += ' (options ? options : VImage::option())'
|
||||||
|
if member_x is not None:
|
||||||
|
result += '->\n'
|
||||||
|
result += ' set( "{0}", *this )'.format(member_x)
|
||||||
|
|
||||||
gen_arg_list(op, required)
|
all_required = required_input
|
||||||
|
|
||||||
print ')',
|
if has_output:
|
||||||
if this != None:
|
# first element needs to be passed by reference
|
||||||
print 'const',
|
arg = cppize(required_output[0])
|
||||||
print
|
result += '->\n'
|
||||||
|
result += ' set( "{0}", &{1} )'.format(required_output[0], arg)
|
||||||
|
|
||||||
print '{'
|
# append the remaining list
|
||||||
if result != None:
|
all_required += required_output[1:]
|
||||||
print ' %s %s;' % (get_ctype(result), cppize(result.name))
|
|
||||||
print ''
|
|
||||||
|
|
||||||
print ' call( "%s"' % nickname,
|
for name in all_required:
|
||||||
|
arg = cppize(name)
|
||||||
|
result += '->\n'
|
||||||
|
result += ' set( "{0}", {1} )'.format(name, arg)
|
||||||
|
|
||||||
first = True
|
result += ' );\n'
|
||||||
for prop in all_required:
|
|
||||||
if first:
|
|
||||||
print ','
|
|
||||||
print ' (options ? options : VImage::option())',
|
|
||||||
first = False
|
|
||||||
|
|
||||||
print '->'
|
if has_output:
|
||||||
print ' ',
|
result += '\n'
|
||||||
if prop == this:
|
result += ' return( {0} );\n'.format(required_output[0])
|
||||||
print 'set( "%s", *this )' % prop.name,
|
|
||||||
else:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
arg = cppize(prop.name)
|
|
||||||
if flags & Vips.ArgumentFlags.OUTPUT and prop == result:
|
|
||||||
arg = '&' + arg
|
|
||||||
|
|
||||||
print 'set( "%s", %s )' % (prop.name, arg),
|
result += '}'
|
||||||
|
|
||||||
print ');'
|
return result
|
||||||
|
|
||||||
if result != None:
|
|
||||||
print ''
|
|
||||||
print ' return( %s );' % cppize(result.name)
|
|
||||||
|
|
||||||
print '}'
|
def generate_operators(declarations_only=False):
|
||||||
print ''
|
all_nicknames = []
|
||||||
|
|
||||||
# we have a few synonyms ... don't generate twice
|
def add_nickname(gtype, a, b):
|
||||||
generated = {}
|
nickname = nickname_find(gtype)
|
||||||
|
try:
|
||||||
|
# can fail for abstract types
|
||||||
|
op = Operation.new_from_name(nickname)
|
||||||
|
|
||||||
def find_class_methods(cls):
|
# we are only interested in non-deprecated operations
|
||||||
if not cls.is_abstract():
|
if (op.get_flags() & _OPERATION_DEPRECATED) == 0:
|
||||||
gtype = Vips.type_find("VipsOperation", cls.name)
|
all_nicknames.append(nickname)
|
||||||
nickname = Vips.nickname_find(gtype)
|
except Error:
|
||||||
if not nickname in generated:
|
pass
|
||||||
gen_operation(cls)
|
|
||||||
generated[nickname] = True
|
|
||||||
|
|
||||||
if len(cls.children) > 0:
|
type_map(gtype, add_nickname)
|
||||||
for child in cls.children:
|
|
||||||
find_class_methods(child)
|
return ffi.NULL
|
||||||
|
|
||||||
|
type_map(type_from_name('VipsOperation'), add_nickname)
|
||||||
|
|
||||||
|
# add 'missing' synonyms by hand
|
||||||
|
all_nicknames.append('crop')
|
||||||
|
|
||||||
|
# make list unique and sort
|
||||||
|
all_nicknames = list(set(all_nicknames))
|
||||||
|
all_nicknames.sort()
|
||||||
|
|
||||||
|
for nickname in all_nicknames:
|
||||||
|
print(generate_operation(nickname, declarations_only))
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='C++ binding generator')
|
||||||
|
parser.add_argument('--gen', '-g',
|
||||||
|
default='cpp',
|
||||||
|
choices=['h', 'cpp'],
|
||||||
|
help='File to generate: h (headers) or cpp (implementations) (default: %(default)s)')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
find_class_methods(vips_type_operation)
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
generate_operators(args.gen == 'h')
|
||||||
|
@ -10,8 +10,7 @@ vips-operators.h:
|
|||||||
echo -n "// " >> vips-operators.h; \
|
echo -n "// " >> vips-operators.h; \
|
||||||
date >> vips-operators.h; \
|
date >> vips-operators.h; \
|
||||||
echo "// this file is generated automatically, do not edit!" >> vips-operators.h; \
|
echo "// this file is generated automatically, do not edit!" >> vips-operators.h; \
|
||||||
echo "" >> vips-operators.h; \
|
./../../gen-operators.py -g h >> vips-operators.h
|
||||||
./gen-operators-h.py >> vips-operators.h
|
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
gen-operators-h.py
|
gen-operators-h.py
|
||||||
|
@ -1,174 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
# walk vips and generate headers for all operators
|
|
||||||
|
|
||||||
# sample member declaration :
|
|
||||||
|
|
||||||
# VImage invert( VOption *options = 0 )
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
|
|
||||||
import logging
|
|
||||||
#logging.basicConfig(level = logging.DEBUG)
|
|
||||||
|
|
||||||
import gi
|
|
||||||
gi.require_version('Vips', '8.0')
|
|
||||||
from gi.repository import Vips, GObject
|
|
||||||
|
|
||||||
vips_type_image = GObject.GType.from_name("VipsImage")
|
|
||||||
vips_type_operation = GObject.GType.from_name("VipsOperation")
|
|
||||||
param_enum = GObject.GType.from_name("GParamEnum")
|
|
||||||
|
|
||||||
# turn a GType into a C++ type
|
|
||||||
gtype_to_cpp = {
|
|
||||||
"VipsImage" : "VImage",
|
|
||||||
"gint" : "int",
|
|
||||||
"gdouble" : "double",
|
|
||||||
"gboolean" : "bool",
|
|
||||||
"gchararray" : "char *",
|
|
||||||
"VipsArrayInt" : "std::vector<int>",
|
|
||||||
"VipsArrayDouble" : "std::vector<double>",
|
|
||||||
"VipsArrayImage" : "std::vector<VImage>",
|
|
||||||
"VipsBlob" : "VipsBlob *"
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_ctype(prop):
|
|
||||||
# enum params use the C name as their name
|
|
||||||
if GObject.type_is_a(param_enum, prop):
|
|
||||||
return prop.value_type.name
|
|
||||||
|
|
||||||
return gtype_to_cpp[prop.value_type.name]
|
|
||||||
|
|
||||||
def find_required(op):
|
|
||||||
required = []
|
|
||||||
for prop in op.props:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.REQUIRED:
|
|
||||||
continue
|
|
||||||
if flags & Vips.ArgumentFlags.DEPRECATED:
|
|
||||||
continue
|
|
||||||
|
|
||||||
required.append(prop)
|
|
||||||
|
|
||||||
def priority_sort(a, b):
|
|
||||||
pa = op.get_argument_priority(a.name)
|
|
||||||
pb = op.get_argument_priority(b.name)
|
|
||||||
|
|
||||||
return pa - pb
|
|
||||||
|
|
||||||
required.sort(priority_sort)
|
|
||||||
|
|
||||||
return required
|
|
||||||
|
|
||||||
# find the first input image ... this will be used as "this"
|
|
||||||
def find_first_input_image(op, required):
|
|
||||||
found = False
|
|
||||||
for prop in required:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.INPUT:
|
|
||||||
continue
|
|
||||||
if GObject.type_is_a(vips_type_image, prop.value_type):
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return prop
|
|
||||||
|
|
||||||
# find the first output arg ... this will be used as the result
|
|
||||||
def find_first_output(op, required):
|
|
||||||
found = False
|
|
||||||
for prop in required:
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if not flags & Vips.ArgumentFlags.OUTPUT:
|
|
||||||
continue
|
|
||||||
found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return prop
|
|
||||||
|
|
||||||
# swap any "-" for "_"
|
|
||||||
def cppize(name):
|
|
||||||
return re.sub('-', '_', name)
|
|
||||||
|
|
||||||
def gen_arg_list(op, required):
|
|
||||||
first = True
|
|
||||||
for prop in required:
|
|
||||||
if not first:
|
|
||||||
print ',',
|
|
||||||
else:
|
|
||||||
first = False
|
|
||||||
|
|
||||||
print get_ctype(prop),
|
|
||||||
|
|
||||||
# output params are passed by reference
|
|
||||||
flags = op.get_argument_flags(prop.name)
|
|
||||||
if flags & Vips.ArgumentFlags.OUTPUT:
|
|
||||||
print '*',
|
|
||||||
|
|
||||||
print cppize(prop.name),
|
|
||||||
|
|
||||||
if not first:
|
|
||||||
print ',',
|
|
||||||
print 'VOption *options = 0',
|
|
||||||
|
|
||||||
def gen_operation(cls):
|
|
||||||
op = Vips.Operation.new(cls.name)
|
|
||||||
gtype = Vips.type_find("VipsOperation", cls.name)
|
|
||||||
nickname = Vips.nickname_find(gtype)
|
|
||||||
all_required = find_required(op)
|
|
||||||
|
|
||||||
result = find_first_output(op, all_required)
|
|
||||||
this = find_first_input_image(op, all_required)
|
|
||||||
|
|
||||||
# shallow copy
|
|
||||||
required = all_required[:]
|
|
||||||
if result != None:
|
|
||||||
required.remove(result)
|
|
||||||
if this != None:
|
|
||||||
required.remove(this)
|
|
||||||
|
|
||||||
# no "this" available, it's a class method
|
|
||||||
if this == None:
|
|
||||||
print 'static',
|
|
||||||
|
|
||||||
if result == None:
|
|
||||||
print 'void',
|
|
||||||
else:
|
|
||||||
print '%s' % gtype_to_cpp[result.value_type.name],
|
|
||||||
|
|
||||||
print '%s(' % nickname,
|
|
||||||
|
|
||||||
gen_arg_list(op, required)
|
|
||||||
|
|
||||||
print ')',
|
|
||||||
|
|
||||||
# if no "this" available, it's a class method and they are all const
|
|
||||||
if this != None:
|
|
||||||
print ' const',
|
|
||||||
|
|
||||||
print ';'
|
|
||||||
|
|
||||||
# we have a few synonyms ... don't generate twice
|
|
||||||
generated = {}
|
|
||||||
|
|
||||||
def find_class_methods(cls):
|
|
||||||
if not cls.is_abstract():
|
|
||||||
gtype = Vips.type_find("VipsOperation", cls.name)
|
|
||||||
nickname = Vips.nickname_find(gtype)
|
|
||||||
if not nickname in generated:
|
|
||||||
gen_operation(cls)
|
|
||||||
generated[nickname] = True
|
|
||||||
|
|
||||||
if len(cls.children) > 0:
|
|
||||||
for child in cls.children:
|
|
||||||
find_class_methods(child)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
find_class_methods(vips_type_operation)
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user