Пример #1
0
def constrExternFuncDecl(func_el):

    extern_decl = ''

    return_type_dict = utils.findType( gb.id_dict[func_el.get('returns')] )
    return_type = return_type_dict['name'] + '*'*return_type_dict['pointerness'] + '&'*return_type_dict['is_reference']

    func_name = getFunctionNameDict(func_el)

    namespaces = utils.getNamespaces(func_el)
    n_indents = len(namespaces)

    extern_decl += utils.constrNamespace(namespaces, 'open')
    extern_decl += ' '*cfg.indent*n_indents + 'extern ' + return_type + ' ' + func_name['short_templ_args'] + ';\n'
    extern_decl += utils.constrNamespace(namespaces, 'close')

    return extern_decl
Пример #2
0
def addWrapperTypedefs(class_name, namespaces):

    short_wrapper_class_name = classutils.toWrapperType(class_name['short'])

    indent = ' ' * cfg.indent * len(namespaces)

    wrapper_typedef_code = ''
    wrapper_typedef_code += utils.constrNamespace(namespaces, 'open')

    temp_namespace_list = [gb.gambit_backend_namespace] + namespaces
    wrapper_typedef_code += indent + 'typedef ' + '::'.join(
        temp_namespace_list
    ) + '::' + class_name['short'] + ' ' + short_wrapper_class_name + ';\n'

    wrapper_typedef_code += utils.constrNamespace(namespaces, 'close')
    wrapper_typedef_code += '\n'

    frw_decl_include_statement = '#include "' + os.path.join(
        gb.backend_types_basedir, gb.gambit_backend_name_full,
        gb.frwd_decls_wrp_fname + cfg.header_extension) + '"\n'
    identification_include_statement = '#include "' + os.path.join(
        gb.backend_types_basedir, gb.gambit_backend_name_full,
        'identification.hpp') + '"\n\n'
    undef_include_statement = '#include "' + os.path.join(
        gb.gambit_backend_incl_dir, 'backend_undefs.hpp') + '"\n'

    wrapper_typedefs_path = os.path.join(
        gb.boss_output_dir, gb.wrapper_typedefs_fname + cfg.header_extension)

    if wrapper_typedefs_path not in gb.new_code.keys():
        gb.new_code[wrapper_typedefs_path] = {
            'code_tuples': [],
            'add_include_guard': False
        }

        gb.new_code[wrapper_typedefs_path]['code_tuples'].append(
            (0, frw_decl_include_statement))
        gb.new_code[wrapper_typedefs_path]['code_tuples'].append(
            (len(frw_decl_include_statement),
             identification_include_statement))
        gb.new_code[wrapper_typedefs_path]['code_tuples'].append(
            (-1, undef_include_statement))

    gb.new_code[wrapper_typedefs_path]['code_tuples'].append(
        (-len(undef_include_statement), wrapper_typedef_code))
Пример #3
0
def addAbstractTypedefs(abstr_class_name, namespaces):

    indent = ' ' * cfg.indent * len(namespaces)
    abstr_typedef_code = ''
    abstr_typedef_code += utils.constrNamespace(namespaces,
                                                'open',
                                                indent=cfg.indent)

    temp_namespace_list = [gb.gambit_backend_namespace] + namespaces
    abstr_typedef_code += indent + 'typedef ' + '::'.join(
        temp_namespace_list) + '::' + abstr_class_name[
            'short'] + ' ' + abstr_class_name['short'] + ';\n'

    abstr_typedef_code += utils.constrNamespace(namespaces,
                                                'close',
                                                indent=cfg.indent)
    abstr_typedef_code += '\n'

    frw_decl_include_statement = '#include "' + os.path.join(
        gb.backend_types_basedir, gb.gambit_backend_name_full,
        gb.frwd_decls_abs_fname + cfg.header_extension) + '"\n'
    identification_include_statement = '#include "' + os.path.join(
        gb.backend_types_basedir, gb.gambit_backend_name_full,
        'identification.hpp') + '"\n\n'
    undef_include_statement = '#include "' + os.path.join(
        gb.gambit_backend_incl_dir, 'backend_undefs.hpp') + '"\n'

    abstracts_typedefs_header_path = os.path.join(
        gb.boss_output_dir, gb.abstract_typedefs_fname + cfg.header_extension)
    if abstracts_typedefs_header_path not in gb.new_code.keys():
        gb.new_code[abstracts_typedefs_header_path] = {
            'code_tuples': [],
            'add_include_guard': False
        }

        gb.new_code[abstracts_typedefs_header_path]['code_tuples'].append(
            (0, frw_decl_include_statement))
        gb.new_code[abstracts_typedefs_header_path]['code_tuples'].append(
            (len(frw_decl_include_statement),
             identification_include_statement))
        gb.new_code[abstracts_typedefs_header_path]['code_tuples'].append(
            (-1, undef_include_statement))

    gb.new_code[abstracts_typedefs_header_path]['code_tuples'].append(
        (-len(undef_include_statement), abstr_typedef_code))
Пример #4
0
def run():

    #
    # Loop over all functions
    #

    for func_name_full, func_el in gb.func_dict.items():

        # Clear all info messages
        infomsg.clearInfoMessages()

        # Number of functions done
        func_i = len(gb.functions_done)

        # Generate dict with different variations of the function name
        func_name = funcutils.getFunctionNameDict(func_el)

        # Print current function
        print
        print '  ' + utils.modifyText(
            'Function:', 'underline') + ' ' + func_name['long_templ_args']

        # Check if this function is accepted
        if funcutils.ignoreFunction(func_el):
            continue

        # Function namespace
        namespaces = utils.getNamespaces(func_el)
        has_namespace = bool(len(namespaces))

        # Check if this is a template function
        is_template = utils.isTemplateFunction(func_el)

        # If template function, figure out template variables
        if is_template == True:
            template_bracket, template_types = utils.getTemplateBracket(
                func_el)
            spec_template_types = utils.getSpecTemplateTypes(func_el)
            print 'TEMPLATE: ', template_bracket, template_types, spec_template_types

        #
        # Generate extra source file with overloaded and wrapper class versions
        #

        # Construct a wrapper function name, eg "someFunction__BOSS_7"
        wr_func_name = func_el.get('name') + gb.code_suffix + '_' + str(
            gb.symbol_name_counter)
        gb.symbol_name_counter += 1

        # New source file name
        new_source_file_name = gb.function_files_prefix + func_el.get(
            'name') + cfg.source_extension
        new_source_file_path = os.path.join(gb.boss_output_dir,
                                            new_source_file_name)

        # Get include statements
        include_statements = []

        # - Generate include statements based on the types used in the function
        include_statements += utils.getIncludeStatements(
            func_el, convert_loaded_to='none', input_element='function')
        include_statements += utils.getIncludeStatements(
            func_el,
            convert_loaded_to='wrapper',
            input_element='function',
            use_full_path=True)
        include_statements.append('#include "' + os.path.join(
            gb.gambit_backend_incl_dir, gb.abstract_typedefs_fname +
            cfg.header_extension) + '"')
        include_statements.append('#include "' + os.path.join(
            gb.gambit_backend_incl_dir, gb.wrapper_typedefs_fname +
            cfg.header_extension) + '"')

        # - Then check if we have a header file for the function in question.
        #   If not, declare the original function as 'extern'
        file_el = gb.id_dict[func_el.get('file')]
        has_function_header = utils.isHeader(file_el)
        if has_function_header:
            header_full_path = file_el.get('name')
            use_path = utils.shortenHeaderPath(header_full_path)
            include_statements.append('#include "' + use_path + '"')

        # Add include statement for gambit/Backends/function_return_utils.hpp
        include_statements.append('#include "' + os.path.join(
            gb.gambit_backend_incl_dir, 'function_return_utils.hpp') + '"')

        include_statements = list(OrderedDict.fromkeys(include_statements))
        include_statements_code = '\n'.join(include_statements) + 2 * '\n'

        # If no header file is found for the original function, generate 'extern' declaration
        extern_declaration = ''
        if not has_function_header:
            extern_declaration += funcutils.constrExternFuncDecl(func_el)
            extern_declaration += '\n'

        # If we have access to the function header, we can implement one overloaded versions
        # to account for default value arguments.
        if has_function_header:
            n_overloads = funcutils.numberOfDefaultArgs(func_el)
        else:
            n_overloads = 0

        #
        # Generate code for wrapper class version
        #

        # # Register the wrapper name
        # func_name['wr_name'] = wr_func_name

        # Construct wrapper function code
        wrapper_code = generateFunctionWrapperClassVersion(
            func_el, wr_func_name, namespaces, n_overloads)
        wrapper_code = utils.addIndentation(wrapper_code,
                                            len(namespaces) * cfg.indent)
        wrapper_code += '\n'

        # Prepare element in gb.new_code
        if new_source_file_path not in gb.new_code.keys():
            gb.new_code[new_source_file_path] = {
                'code_tuples': [],
                'add_include_guard': False
            }

        # Define code string
        n_indents = len(namespaces)
        new_code = 2 * '\n'

        # - Add include statements
        new_code += include_statements_code

        # - Add extern function declaration
        new_code += extern_declaration

        # - Construct the beginning of the namespaces
        new_code += utils.constrNamespace(namespaces, 'open')

        # - Add code for 'wrapper' version
        new_code += wrapper_code

        # - Construct the closing of the namespaces
        new_code += utils.constrNamespace(namespaces, 'close')

        new_code += '\n'

        # Register new code in return_code_dict
        insert_pos = -1  # end of file
        # return_code_dict[new_source_file_path]['code_tuples'].append( (insert_pos, new_code) )
        gb.new_code[new_source_file_path]['code_tuples'].append(
            (insert_pos, new_code))

        # Register that this function has a source file
        gb.function_file_dict[
            func_name['long_templ_args']] = new_source_file_path

        #
        # Keep track of functions done
        #
        gb.functions_done.append(func_name)
        gb.wr_func_names.append(wr_func_name)

        print
Пример #5
0
def createFrontendHeader(function_xml_files_dict):

    # Read all xml files
    utils.xmlFilesToDicts(function_xml_files_dict.values())

    #
    # Generate typedefs for loaded classes, from ::BACKENDNAME_SAFE_VERSION::class_name
    # to ::Gambit::Backends::BACKENDNAME_SAFE_VERSION::class_name
    #

    outer_namespace_list = ['Gambit', 'Backends', gb.gambit_backend_name_full]

    typedef_code = ''
    typedef_code += utils.constrNamespace(outer_namespace_list,
                                          'open',
                                          indent=cfg.indent)

    # Loop over all classes
    for class_name in gb.classes_done:

        if not class_name['long'] in gb.factory_info.keys():
            continue
        else:

            class_typedef_code = ''

            class_namespace, class_name_short = utils.removeNamespace(
                class_name['long'], return_namespace=True)

            if class_namespace == '':
                class_typedef_code += 'typedef ::' + gb.gambit_backend_name_full + '::' + class_name[
                    'long'] + ' ' + class_name['short'] + ';\n'
            else:
                class_namespace_list = class_namespace.split('::')

                class_typedef_code += utils.constrNamespace(
                    class_namespace_list, 'open', indent=cfg.indent)
                class_typedef_code += ' ' * cfg.indent * len(
                    class_namespace_list
                ) + 'typedef ::' + gb.gambit_backend_name_full + '::' + class_name[
                    'long'] + ' ' + class_name['short'] + ';\n'
                class_typedef_code += utils.constrNamespace(
                    class_namespace_list, 'close', indent=cfg.indent)

            class_typedef_code = utils.addIndentation(class_typedef_code,
                                                      3 * cfg.indent)
            typedef_code += class_typedef_code

    typedef_code += utils.constrNamespace(outer_namespace_list,
                                          'close',
                                          indent=cfg.indent)

    #
    # Generate code for all the BE_FUNCTION macros
    #

    be_function_macro_code = ''

    for i, func_name in enumerate(gb.functions_done):

        # Set useful variables
        xml_file = function_xml_files_dict[func_name['long_templ_args']]

        # If new xml file, initialise global dicts
        if xml_file != gb.xml_file_name:
            gb.xml_file_name = xml_file
            utils.initGlobalXMLdicts(xml_file, id_and_name_only=True)

        # Get wrapper function element
        tree = ET.parse(xml_file)
        root = tree.getroot()
        wr_func_el = None

        for el in root.findall('Function'):

            if el.get('name') == gb.wr_func_names[i]:
                wr_func_el = el

        if wr_func_el is None:
            continue

        # Get information about the return type.
        return_type_dict = utils.findType(wr_func_el)
        return_el = return_type_dict['el']
        pointerness = return_type_dict['pointerness']
        is_ref = return_type_dict['is_reference']
        return_kw = return_type_dict['cv_qualifiers']

        return_kw_str = ' '.join(return_kw) + ' ' * bool(len(return_kw))

        return_type = return_type_dict[
            'name'] + '*' * pointerness + '&' * is_ref

        # Construct argument bracket
        args = funcutils.getArgs(wr_func_el)
        args_bracket = funcutils.constrArgsBracket(args,
                                                   include_arg_name=False,
                                                   include_arg_type=True,
                                                   include_namespace=True)

        # Get mangled symbol
        # symbol = wr_func_el.get('mangled')
        symbol = wr_func_el.get('name')

        be_function_macro_code += 'BE_FUNCTION('
        be_function_macro_code += func_name['short'] + ', '
        be_function_macro_code += return_type + ', '
        be_function_macro_code += args_bracket + ', '
        be_function_macro_code += '"' + symbol + '"' + ', '
        be_function_macro_code += '"' + func_name['short'] + '"' + ')\n'

    #
    # Generate code for the frontend header
    #

    frontend_content = ''

    # - Comment at beginning
    backend_name_and_version = cfg.gambit_backend_name + ' ' + cfg.gambit_backend_version
    frontend_content += '//\n'
    frontend_content += '// Frontend header generated by BOSS for GAMBIT backend %s.\n' % (
        backend_name_and_version)
    frontend_content += '//\n'

    # - Include statement for the identification header
    frontend_content += '\n'
    frontend_content += '#include "' + os.path.join(
        gb.gambit_backend_incl_dir, gb.backend_types_basedir,
        gb.gambit_backend_name_full, 'identification.hpp') + '"\n'

    # - LOAD_LIBRARY macro
    frontend_content += '\n'
    frontend_content += 'LOAD_LIBRARY\n'

    # - Class typedefs
    frontend_content += '\n'
    frontend_content += typedef_code

    # - BE_FUNCTION macros
    frontend_content += '\n'
    frontend_content += '// Functions\n'
    frontend_content += be_function_macro_code

    # - Descriptions of different things that can go into a frontend header
    frontend_content += '// Variables\n'
    frontend_content += '\n'
    frontend_content += '// Initialisation function (dependencies)\n'
    frontend_content += '\n'
    frontend_content += '// Convenience functions (registration)\n'
    frontend_content += '\n'
    frontend_content += '// Initialisation function (definition)\n'
    frontend_content += 'BE_INI_FUNCTION{} END_BE_INI_FUNCTION\n'
    frontend_content += '\n'
    frontend_content += '// Convenience functions (definitions)\n'

    # - Include statement for backend_undefs.hpp
    frontend_content += '\n'
    frontend_content += '// End\n'
    frontend_content += '#include "' + os.path.join(
        gb.gambit_backend_incl_dir, 'backend_undefs.hpp') + '"\n'

    # Write to file
    f = open(gb.frontend_path, 'w')
    f.write(frontend_content)
    f.close()