コード例 #1
0
ファイル: generate_phpdoc.py プロジェクト: mstaack/php-vips
def generate_operation(operation_name):
    intro = Introspect.get(operation_name)

    result = ' * @method '
    if intro.member_x is None:
        result += 'static '
    if len(intro.required_output) == 0:
        result += 'void '
    elif len(intro.required_output) == 1:
        arg = intro.required_output[0]
        details = intro.details[arg]
        result += '{0} '.format(gtype_to_php(details['type'], True))
    else:
        # we generate a Returns: block for this case, see below
        result += 'array '

    result += '{0}('.format(operation_name)
    for name in intro.method_args:
        details = intro.details[name]
        result += '{0} ${1}, '.format(gtype_to_php(details['type']), name)

    result += 'array $options = []) '

    description = intro.description
    result += description[0].upper() + description[1:] + '.\n'

    # find any Enums we've referenced and output @see lines for them
    for name in intro.required_output + intro.method_args:
        details = intro.details[name]
        fundamental = gobject_lib.g_type_fundamental(details['type'])

        if fundamental != GValue.genum_type:
            continue

        result += ' *     @see {0} for possible values for ${1}\n'.format(
            remove_prefix(type_name(details['type'])), name)

    if len(intro.required_output) > 1:
        result += ' *     Return array with: [\n'
        for name in intro.required_output:
            details = intro.details[name]
            result += ' *         \'{0}\' => @type {1} {2}\n'.format(
                name, gtype_to_php(details['type']),
                details['blurb'][0].upper() + details['blurb'][1:])
        result += ' *     ];\n'

    result += ' *     @throws Exception\n'

    return result
コード例 #2
0
    def add_nickname(gtype, a, b):
        nickname = nickname_find(gtype)
        try:
            # can fail for abstract types
            intro = Introspect.get(nickname)

            # we are only interested in non-deprecated operations
            if (intro.flags & _OPERATION_DEPRECATED) == 0:
                all_nicknames.append(nickname)
        except Error:
            pass

        type_map(gtype, add_nickname)

        return ffi.NULL
コード例 #3
0
def gen_function(operation_name, overloads):
    intro = Introspect.get(operation_name)

    c_operations = 'vips_{}()'.format(operation_name)

    if overloads:
        c_operations += ', ' + (', '.join('vips_{}()'.format(n) for n in overloads))

    result = '<row>\n'
    result += '  <entry>{}</entry>\n'.format(operation_name)
    result += '  <entry>{}</entry>\n'.format(intro.description.capitalize())
    result += '  <entry>{}</entry>\n'.format(c_operations)
    result += '</row>'

    return result
コード例 #4
0
def generate_type_declarations(filename):
    all_nicknames = []

    def add_nickname(gtype, a, b):
        nickname = nickname_find(gtype)
        try:
            # can fail for abstract types
            intro = Introspect.get(nickname)

            # we are only interested in non-deprecated operations
            if (intro.flags & _OPERATION_DEPRECATED) == 0:
                all_nicknames.append(nickname)
        except Error:
            pass

        type_map(gtype, add_nickname)

        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(key=lambda x: (bool(Introspect.get(x).member_x), x))

    # filter functions we document by hand
    filter = [
        'composite', 'find_trim', 'profile', 'project', 'bandjoin_const',
        'boolean_const', 'math2_const', 'relational_const', 'remainder_const'
    ]
    all_nicknames = [name for name in all_nicknames if name not in filter]

    with open(filename, 'a') as f:
        f.write('    class ImageAutoGen {\n')
        f.write(
            '        // THIS IS A GENERATED CLASS. DO NOT EDIT DIRECTLY.\n')

        for nickname in all_nicknames:
            f.write(generate_operation(nickname) + '\n')

        f.write('    }\n')
        f.write('}')
コード例 #5
0
def generate_functions(file):
    all_nicknames = []

    def add_nickname(gtype, a, b):
        nickname = nickname_find(gtype)
        try:
            # can fail for abstract types
            intro = Introspect.get(nickname)

            # we are only interested in non-deprecated operations
            if (intro.flags & _OPERATION_DEPRECATED) == 0:
                all_nicknames.append(nickname)
        except Error:
            pass

        type_map(gtype, add_nickname)

        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(key=lambda x: (bool(Introspect.get(x).member_x), x))

    # enum, _const and multiple output functions are wrapped by hand
    filter = [
        'add', 'bandbool', 'bandjoin_const', 'boolean', 'boolean_const',
        'complex', 'complexget', 'composite', 'divide', 'find_trim', 'flip',
        'linear', 'math', 'math2', 'math2_const', 'morph', 'multiply',
        'profile', 'project', 'relational', 'relational_const', 'remainder',
        'remainder_const', 'rot', 'round', 'subtract'
    ]
    all_nicknames = [name for name in all_nicknames if name not in filter]

    print(f'Generating {file}...')

    with open(file, 'w') as f:
        f.write('        // Auto-generated (class-)functions\n')

        for nickname in all_nicknames:
            f.write(generate_operation(nickname) + '\n')
コード例 #6
0
def generate_operators(declarations_only=False):
    all_nicknames = []

    def add_nickname(gtype, a, b):
        nickname = nickname_find(gtype)
        try:
            # can fail for abstract types
            intro = Introspect.get(nickname)

            # we are only interested in non-deprecated operations
            if (intro.flags & _OPERATION_DEPRECATED) == 0:
                all_nicknames.append(nickname)
        except Error:
            pass

        type_map(gtype, add_nickname)

        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(key=lambda x: (bool(Introspect.get(x).member_x), x))

    # some functions are wrapped by hand
    filter = [
        'add', 'bandjoin_const', 'boolean', 'composite', 'divide',
        'ifthenelse', 'math2', 'multiply', 'relational', 'remainder',
        'subtract'
    ]
    all_nicknames = [name for name in all_nicknames if name not in filter]

    print(preamble)

    for nickname in all_nicknames:
        print(generate_operation(nickname, declarations_only))
コード例 #7
0
def generate_operation(operation_name, indent='        '):
    intro = Introspect.get(operation_name)

    required_output = [
        name for name in intro.required_output if name != intro.member_x
    ]

    has_input = len(intro.method_args) >= 1
    has_output = len(required_output) >= 1
    has_optional_options = len(intro.doc_optional_input) + len(
        intro.doc_optional_output) >= 1

    # Add a comment block with some additional markings (@param, @return)
    result = f'\n{indent}/**'
    result += f'\n{indent} * {intro.description.capitalize()}.'

    for name in intro.method_args:
        result += f"\n{indent} * @param {js_name(name)} {intro.details[name]['blurb']}."

    if has_optional_options:
        result += f'\n{indent} * @param options Optional options.'

    if has_output:
        result += f"\n{indent} * @return {intro.details[required_output[0]]['blurb']}."

    result += f'\n{indent} */\n'

    if intro.member_x is None:
        result += f'{indent}static '
    else:
        result += indent

    js_operation = to_camel_case(operation_name)

    result += f'{js_operation}('
    result += ', '.join([
        f"{js_name(x)}: {get_js_type(intro.details[x]['type'], True)}"
        for x in intro.method_args
    ])

    if has_optional_options:
        if has_input:
            result += ', '
        result += 'options?: {'
        for name in intro.doc_optional_input:
            result += f'\n{indent}    /**'
            result += f"\n{indent}     * {intro.details[name]['blurb'].capitalize()}."
            result += f'\n{indent}     */'
            result += f"\n{indent}    {js_name(name)}?: {get_js_type(intro.details[name]['type'], True)}"
        for name in intro.doc_optional_output:
            result += f'\n{indent}    /**'
            result += f"\n{indent}     * {intro.details[name]['blurb'].capitalize()} (output)."
            result += f'\n{indent}     */'
            result += f"\n{indent}    {js_name(name)}?: {get_js_type(intro.details[name]['type'], False)} | undefined"
        result += f'\n{indent}}}'

    result += '): '

    # the first output arg will be used as the result
    if has_output:
        js_type = get_js_type(intro.details[required_output[0]]['type'], False)
        result += f'{js_type};'
    else:
        result += 'void;'

    return result
コード例 #8
0
def generate_operation(operation_name, declaration_only=False):
    intro = Introspect.get(operation_name)

    required_output = [
        name for name in intro.required_output if name != intro.member_x
    ]

    has_output = len(required_output) >= 1

    # Add a C++ style comment block with some additional markings (@param,
    # @return)
    if declaration_only:
        result = f'\n/**\n * {intro.description.capitalize()}.'

        if len(intro.optional_input) > 0:
            result += '\n *\n * **Optional parameters**'
            for name in intro.optional_input:
                details = intro.details[name]
                result += f'\n *   - **{cppize(name)}** -- '
                result += f'{details["blurb"]}, '
                result += f'{get_cpp_type(details["type"])}.'
            result += '\n *'

        for name in intro.method_args:
            details = intro.details[name]
            result += f'\n * @param {cppize(name)} {details["blurb"]}.'

        if has_output:
            # skip the first element
            for name in required_output[1:]:
                details = intro.details[name]
                result += f'\n * @param {cppize(name)} {details["blurb"]}.'

        result += '\n * @param options Set of options.'

        if has_output:
            details = intro.details[required_output[0]]
            result += f'\n * @return {details["blurb"]}.'

        result += '\n */\n'
    else:
        result = '\n'

    if intro.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(intro.details[required_output[0]]['type'])
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'{cpp_type}{spacing}'
    else:
        result += 'void '

    if not declaration_only:
        result += 'VImage::'

    cplusplus_operation = operation_name
    if operation_name in cplusplus_keywords:
        cplusplus_operation += '_image'

    result += f'{cplusplus_operation}( '
    for name in intro.method_args:
        details = intro.details[name]
        gtype = details['type']
        cpp_type = get_cpp_type(gtype)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'{cpp_type}{spacing}{cppize(name)}, '

    # output params are passed by reference
    if has_output:
        # skip the first element
        for name in required_output[1:]:
            details = intro.details[name]
            gtype = details['type']
            cpp_type = get_cpp_type(gtype)
            spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
            result += f'{cpp_type}{spacing}*{cppize(name)}, '

    result += f'VOption *options {"= 0 " if declaration_only else ""})'

    # if no 'this' available, it's a class method and they are all const
    if intro.member_x is not None:
        result += ' const'

    if declaration_only:
        result += ';'

        return result

    result += '\n{\n'

    if has_output:
        # the first output arg will be used as the result
        name = required_output[0]
        cpp_type = get_cpp_type(intro.details[name]['type'])
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'    {cpp_type}{spacing}{cppize(name)};\n\n'

    result += f'    call( "{operation_name}",\n'
    result += f'        (options ? options : VImage::option())'
    if intro.member_x is not None:
        result += f'->\n'
        result += f'            set( "{intro.member_x}", *this )'

    all_required = intro.method_args

    if has_output:
        # first element needs to be passed by reference
        arg = cppize(required_output[0])
        result += f'->\n'
        result += f'            set( "{required_output[0]}", &{arg} )'

        # append the remaining list
        all_required += required_output[1:]

    for name in all_required:
        arg = cppize(name)
        result += f'->\n'
        result += f'            set( "{name}", {arg} )'

    result += ' );\n'

    if has_output:
        result += f'\n'
        result += f'    return( {required_output[0]} );\n'

    result += '}'

    return result
コード例 #9
0
def generate_operation(operation_name):
    intro = Introspect.get(operation_name)

    required_output = [
        name for name in intro.required_output if name != intro.member_x
    ]

    is_void = len(required_output) == 0
    has_input = len(intro.method_args) >= 1
    has_multiple_output = len(required_output) > 1
    has_optional_options = len(intro.optional_input) + len(
        intro.optional_output) >= 1

    function_type = 'function' if intro.member_x else 'class_function'

    result = ''

    cplusplus_operation = operation_name
    if operation_name in cplusplus_keywords:
        cplusplus_operation += '_image'

    padding = ' ' * 9 if intro.member_x else ' ' * 15

    result += f'        .{function_type}("{to_camel_case(operation_name)}", &Image::{cplusplus_operation}'

    if has_multiple_output:
        result += ', allow_raw_pointers())\n'
    else:
        result += ')'

    if not has_optional_options:
        return result

    # need to overload the function without optional options
    result += f'\n        .{function_type}("{to_camel_case(operation_name)}", optional_override([]('

    if intro.member_x is not None:
        result += 'const Image &image'
        if has_input or len(required_output) > 1:
            result += ', '

    for i, name in enumerate(intro.method_args):
        details = intro.details[name]
        gtype = details['type']
        cpp_type = get_cpp_type(gtype)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'{cpp_type}{spacing}{cppize(name)}'
        if i != len(intro.method_args) - 1:
            result += ', '

    # output params are passed by reference
    if has_multiple_output:
        # skip the first element
        for i, name in enumerate(required_output[1:]):
            details = intro.details[name]
            gtype = details['type']
            cpp_type = get_cpp_type(gtype)
            spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
            result += f'{cpp_type}{spacing}*{cppize(name)}'
            if i != len(required_output) - 2:
                result += ', '

    result += ') {\n'
    result += f'{padding}             '
    result += f"{'' if is_void else 'return '}"
    result += f"{'Image::' if intro.member_x is None else 'image.'}{cplusplus_operation}("

    for i, name in enumerate(intro.method_args):
        result += cppize(name)
        if i != len(intro.method_args) - 1:
            result += ', '

    if has_multiple_output:
        # skip the first element
        for i, name in enumerate(required_output[1:]):
            result += cppize(name)
            if i != len(required_output) - 2:
                result += ', '

    result += ');\n'
    result += f'         {padding}}})'

    if has_multiple_output:
        result += ', allow_raw_pointers())'
    else:
        result += ')'

    return result
コード例 #10
0
ファイル: gen-operators.py プロジェクト: helloESA/lordz-bot
def generate_operation(operation_name, declaration_only=False):
    intro = Introspect.get(operation_name)

    required_output = [
        name for name in intro.required_output if name != intro.member_x
    ]

    has_output = len(required_output) >= 1

    # Add a C++ style comment block with some additional markings (@param,
    # @return)
    if declaration_only:
        result = '\n/**\n * {}.'.format(intro.description.capitalize())

        for name in intro.method_args:
            result += '\n * @param {} {}.' \
                      .format(cppize(name), intro.details[name]['blurb'])

        if has_output:
            # skip the first element
            for name in required_output[1:]:
                result += '\n * @param {} {}.' \
                          .format(cppize(name), intro.details[name]['blurb'])

        result += '\n * @param options Optional options.'

        if has_output:
            result += '\n * @return {}.' \
                      .format(intro.details[required_output[0]]['blurb'])

        result += '\n */\n'
    else:
        result = '\n'

    if intro.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(intro.details[required_output[0]]['type'])
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += '{0}{1}'.format(cpp_type, spacing)
    else:
        result += 'void '

    if not declaration_only:
        result += 'VImage::'

    cplusplus_operation = operation_name
    if operation_name in cplusplus_keywords:
        cplusplus_operation += '_image'

    result += '{0}( '.format(cplusplus_operation)
    for name in intro.method_args:
        details = intro.details[name]
        gtype = details['type']
        cpp_type = get_cpp_type(gtype)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += '{0}{1}{2}, '.format(cpp_type, spacing, cppize(name))

    # output params are passed by reference
    if has_output:
        # skip the first element
        for name in required_output[1:]:
            details = intro.details[name]
            gtype = details['type']
            cpp_type = get_cpp_type(gtype)
            spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
            result += '{0}{1}*{2}, '.format(cpp_type, spacing, cppize(name))

    result += 'VOption *options {0})'.format(
        '= 0 ' if declaration_only else '')

    # if no 'this' available, it's a class method and they are all const
    if intro.member_x is not None:
        result += ' const'

    if declaration_only:
        result += ';'

        return result

    result += '\n{\n'

    if has_output:
        # the first output arg will be used as the result
        name = required_output[0]
        cpp_type = get_cpp_type(intro.details[name]['type'])
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += '    {0}{1}{2};\n\n'.format(cpp_type, spacing, cppize(name))

    result += '    call( "{0}",\n'.format(operation_name)
    result += '        (options ? options : VImage::option())'
    if intro.member_x is not None:
        result += '->\n'
        result += '            set( "{0}", *this )'.format(intro.member_x)

    all_required = intro.method_args

    if has_output:
        # first element needs to be passed by reference
        arg = cppize(required_output[0])
        result += '->\n'
        result += '            set( "{0}", &{1} )' \
                  .format(required_output[0], arg)

        # append the remaining list
        all_required += required_output[1:]

    for name in all_required:
        arg = cppize(name)
        result += '->\n'
        result += '            set( "{0}", {1} )'.format(name, arg)

    result += ' );\n'

    if has_output:
        result += '\n'
        result += '    return( {0} );\n'.format(required_output[0])

    result += '}'

    return result
コード例 #11
0
def generate_operation(operation_name, declaration_only=False):
    intro = Introspect.get(operation_name)

    required_output = [
        name for name in intro.required_output if name != intro.member_x
    ]

    has_input = len(intro.method_args) >= 1
    has_output = len(required_output) >= 1
    has_optional_options = len(intro.optional_input) + len(
        intro.optional_output) >= 1

    # Add a C++ style comment block with some additional markings (@param,
    # @return)
    if declaration_only:
        result = f'\n/**\n * {intro.description.capitalize()}.'

        for name in intro.method_args:
            result += f"\n * @param {cppize(name)} {intro.details[name]['blurb']}."

        if has_output:
            # skip the first element
            for name in required_output[1:]:
                result += f"\n * @param {cppize(name)} {intro.details[name]['blurb']}."

        if has_optional_options:
            result += '\n * @param js_options Optional options.'

        if has_output:
            result += f"\n * @return {intro.details[required_output[0]]['blurb']}."

        result += '\n */\n'
    else:
        result = '\n'

    if intro.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(intro.details[required_output[0]]['type'],
                                False)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'{cpp_type}{spacing}'
    else:
        result += 'void '

    if not declaration_only:
        result += 'Image::'

    cplusplus_operation = operation_name
    if operation_name in cplusplus_keywords:
        cplusplus_operation += '_image'

    result += f'{cplusplus_operation}('
    for i, name in enumerate(intro.method_args):
        details = intro.details[name]
        gtype = details['type']
        cpp_type = get_cpp_type(gtype, True)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'{cpp_type}{spacing}{cppize(name)}'
        if i != len(intro.method_args) - 1:
            result += ', '

    # output params are passed by reference
    if has_output:
        # skip the first element
        for i, name in enumerate(required_output[1:]):
            details = intro.details[name]
            gtype = details['type']
            cpp_type = get_cpp_type(gtype, False)
            spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
            result += f'{cpp_type}{spacing}*{cppize(name)}'
            if i != len(required_output) - 2:
                result += ', '

    if has_optional_options:
        if has_input or len(required_output) > 1:
            result += ', '
        result += f"emscripten::val js_options{' = emscripten::val::null()' if declaration_only else ''}"

    result += ')'

    # if no 'this' available, it's a class method and they are all const
    if intro.member_x is not None:
        result += ' const'

    if declaration_only:
        result += ';'

        return result

    result += '\n{\n'

    if has_output:
        # the first output arg will be used as the result
        name = required_output[0]
        gtype = intro.details[name]['type']
        cpp_type = 'VipsBlob *' if (
            gtype == GValue.blob_type) else get_cpp_type(gtype, False)
        spacing = '' if cpp_type.endswith(cplusplus_suffixes) else ' '
        result += f'    {cpp_type}{spacing}{ cppize(name)};\n\n'

    separate_blob = False

    for name in intro.method_args:
        if intro.details[name]['type'] == GValue.blob_type:
            #  We must take a copy of the data.
            result += f'    VipsBlob *blob = vips_blob_copy({name}.c_str(), {name}.size());\n'
            separate_blob = True
            break

    if not separate_blob:
        result += f"    {'Image::' if intro.member_x is None else 'this->'}"
        result += f'call("{operation_name}",'
        result += f"{' nullptr,' if intro.member_x is None else ''}\n"

    padding = ' ' * 16 if intro.member_x is None else ' ' * 15

    if separate_blob:
        padding += ' ' * 6
        result += '    Option *options = (new Option)'
    else:
        result += f'{padding}(new Option)'

    if intro.member_x is not None:
        result += f'\n    {padding}->set("{intro.member_x}", *this)'

    all_required = intro.method_args

    if has_output:
        # first element needs to be passed by reference
        arg = cppize(required_output[0])
        result += f'\n    {padding}->set("{required_output[0]}", &{arg})'

        # append the remaining list
        all_required += required_output[1:]

    for name in all_required:
        gtype = intro.details[name]['type']

        if gtype == GValue.blob_type:
            arg = 'blob'
        elif name not in required_output and get_cpp_type(
                gtype, True) == 'emscripten::val':
            type = to_snake_case(remove_prefix(type_name(gtype))).upper()
            arg = f'VIPS_TYPE_{type}, {cppize(name)}'
            # a match image is needed for image types
            if intro.member_x is not None \
                and (gtype == GValue.image_type or
                     gtype == GValue.array_image_type):
                arg += ', this'
        else:
            arg = cppize(name)

        result += f'\n    {padding}->set("{name}", {arg})'

    if separate_blob:
        result += ';\n'
        result += '    vips_area_unref(VIPS_AREA(blob));\n\n'
        result += f"    {'Image::' if intro.member_x is None else 'this->'}"
        result += f'call("{operation_name}",'
        result += f"{' nullptr,' if intro.member_x is None else ''} options, js_options);\n"
    else:
        result += f',\n{padding}js_options);\n' if has_optional_options else ');\n'

    if has_output:
        gtype = intro.details[required_output[0]]['type']

        result += '\n'
        if gtype == GValue.blob_type:
            result += '    emscripten::val result = emscripten::val(emscripten::typed_memory_view(\n'
            result += f'        VIPS_AREA({required_output[0]})->length,\n'
            result += f'        reinterpret_cast<uint8_t *>(VIPS_AREA({required_output[0]})->data)));\n'
            result += f'    VIPS_AREA({required_output[0]})->free_fn = nullptr;\n'
            result += f'    vips_area_unref(VIPS_AREA({required_output[0]}));\n\n'
            result += '    return result;\n'
        else:
            result += f'    return {required_output[0]};\n'

    result += '}'

    return result