def generate(fort_ast,name,project_path): r"""Given a fortran abstract syntax tree ast, generate wrapper files :Input: - *fort_ast* - (`fparser.ProgramBlock`) Abstract syntax tree from parser - *name* - (string) Name of the library module - *out_dir* - (string) Path to build directory, defaults to './' Raises `Exception.IOError` if writing the generated code fails. """ # Generate wrapping abstract syntax trees logger.info("Generating abstract syntax tress for c and cython.") c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) # Generate files and write them out generators = ( (generate_type_specs,(c_ast,name)), (generate_fc_f,(c_ast,name)), (generate_fc_h,(c_ast,name)), (generate_fc_pxd,(c_ast,name)), (generate_cy_pxd,(cython_ast,name)), (generate_cy_pyx,(cython_ast,name)) ) for (generator,args) in generators: file_name, buf = generator(*args) write_to_project_dir(project_path, file_name, buf)
def test_generate_fc_f(self): fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = main.generate_fc_f(c_ast, self.name) fc = '''\ subroutine empty_func_c(fw_ret_arg, fw_iserr__, fw_errstr__) bind(c, name="em& &pty_func_c") use fwrap_ktp_mod implicit none integer(kind=fwi_integer_t), intent(out) :: fw_ret_arg integer(kind=fwi_integer_t), intent(out) :: fw_iserr__ character(kind=fw_character_t, len=1), dimension(fw_errstr_len) :: fw_err& &str__ interface function empty_func() use fwrap_ktp_mod implicit none integer(kind=fwi_integer_t) :: empty_func end function empty_func end interface fw_iserr__ = FW_INIT_ERR__ fw_ret_arg = empty_func() fw_iserr__ = FW_NO_ERR__ end subroutine empty_func_c ''' compare(fc, buf.getvalue())
def test_generate_fc_f(self): fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = fwrapper.generate_fc_f(c_ast, self.name) fc = '''\ subroutine empty_func_c(fw_ret_arg, fw_iserr__, fw_errstr__) bind(c, name="em& &pty_func_c") use fwrap_ktp_mod implicit none integer(kind=fwi_integer_t), intent(out) :: fw_ret_arg integer(kind=fwi_integer_t), intent(out) :: fw_iserr__ character(kind=fw_character_t, len=1), dimension(fw_errstr_len) :: fw_err& &str__ interface function empty_func() use fwrap_ktp_mod implicit none integer(kind=fwi_integer_t) :: empty_func end function empty_func end interface fw_iserr__ = FW_INIT_ERR__ fw_ret_arg = empty_func() fw_iserr__ = FW_NO_ERR__ end subroutine empty_func_c ''' compare(fc, buf.getvalue())
def generate(fort_ast, name): r"""Given a fortran abstract syntax tree ast, generate wrapper files :Input: - *fort_ast* - (`fparser.ProgramBlock`) Abstract syntax tree from parser - *name* - (string) Name of the library module Raises `Exception.IOError` if writing the generated code fails. """ # Generate wrapping abstract syntax trees # logger.info("Generating abstract syntax tress for c and cython.") c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) # Generate files and write them out generators = ((generate_type_specs, (c_ast, name)), (generate_fc_f, (c_ast, name)), (generate_fc_h, (c_ast, name)), (generate_fc_pxd, (c_ast, name)), (generate_cy_pxd, (cython_ast, name)), (generate_cy_pyx, (cython_ast, name))) for (generator, args) in generators: file_name, buf = generator(*args) write_to_dir(os.getcwd(), file_name, buf)
def test_generate_fc_h(self): fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = main.generate_fc_h(c_ast, self.name) header = '''\ #include "fwrap_ktp_header.h" void empty_func_c(fwi_integer_t *, fwi_integer_t *, fw_character_t *); ''' compare(buf.getvalue(), header) eq_(fname, constants.FC_HDR_TMPL % self.name)
def test_generate_type_specs(self): from cPickle import loads fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = main.generate_type_specs(fort_ast, self.name) ctps = loads(buf.getvalue()) for ctp in ctps: ok_(isinstance(ctp, dict)) eq_(sorted(ctp.keys()), ['basetype', 'fwrap_name', 'lang', 'npy_enum', 'odecl'])
def test_generate_fc_pxd(self): fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = main.generate_fc_pxd(c_ast, self.name) header = '''\ from fwrap_ktp cimport * cdef extern from "test_fc.h": void empty_func_c(fwi_integer_t *, fwi_integer_t *, fw_character_t *) ''' compare(header, buf.getvalue())
def test_generate_fc_pxd(self): fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = fwrapper.generate_fc_pxd(c_ast, self.name) header = '''\ from fwrap_ktp cimport * cdef extern from "test_fc.h": void empty_func_c(fwi_integer_t *, fwi_integer_t *, fw_character_t *) ''' compare(header, buf.getvalue())
def test_generate_fc_h(self): fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) fname, buf = fwrapper.generate_fc_h(c_ast, self.name) header = '''\ #include "fwrap_ktp_header.h" void empty_func_c(fwi_integer_t *, fwi_integer_t *, fw_character_t *); ''' compare(buf.getvalue(), header) eq_(fname, constants.FC_HDR_TMPL % self.name)
def test_generate_type_specs(self): from cPickle import loads fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = fwrapper.generate_type_specs(fort_ast, self.name) ctps = loads(buf.getvalue()) for ctp in ctps: ok_(isinstance(ctp, dict)) eq_(sorted(ctp.keys()), ['basetype', 'fwrap_name', 'lang', 'npy_enum', 'odecl'])
def test_generate_cy_pxd(self): fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = main.generate_cy_pxd(cython_ast, self.name) pxd = '''\ cimport numpy as np from test_fc cimport * cpdef api object empty_func() ''' compare(pxd, buf.getvalue())
def test_generate_cy_pxd(self): fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = fwrapper.generate_cy_pxd(cython_ast, self.name) pxd = '''\ cimport numpy as np from test_fc cimport * cpdef api object empty_func() ''' compare(pxd, buf.getvalue())
def test_generate_cy_pyx(self): from fwrap.version import get_version fort_ast = main.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = main.generate_cy_pyx(cython_ast, self.name) test_str = '''\ """ The test module was generated with Fwrap v%s. Below is a listing of functions and data types. For usage information see the function docstrings. Functions --------- empty_func(...) Data Types ---------- fw_character fwi_integer """ np.import_array() include 'fwrap_ktp.pxi' cdef extern from "string.h": void *memcpy(void *dest, void *src, size_t n) cpdef api object empty_func(): """ empty_func() -> fw_ret_arg Parameters ---------- None Returns ------- fw_ret_arg : fwi_integer, intent out """ cdef fwi_integer_t fw_ret_arg cdef fwi_integer_t fw_iserr__ cdef fw_character_t fw_errstr__[fw_errstr_len] empty_func_c(&fw_ret_arg, &fw_iserr__, fw_errstr__) if fw_iserr__ != FW_NO_ERR__: raise RuntimeError("an error was encountered when calling the 'empty_func' wrapper.") return fw_ret_arg ''' % get_version() compare(test_str, buf.getvalue())
def test_generate_cy_pyx(self): from fwrap.version import get_version fort_ast = fwrapper.parse(self.source_file_lst) c_ast = fc_wrap.wrap_pyf_iface(fort_ast) cython_ast = cy_wrap.wrap_fc(c_ast) fname, buf = fwrapper.generate_cy_pyx(cython_ast, self.name) test_str = '''\ """ The test module was generated with Fwrap v%s. Below is a listing of functions and data types. For usage information see the function docstrings. Functions --------- empty_func(...) Data Types ---------- fw_character fwi_integer """ np.import_array() include 'fwrap_ktp.pxi' cdef extern from "string.h": void *memcpy(void *dest, void *src, size_t n) cpdef api object empty_func(): """ empty_func() -> fw_ret_arg Parameters ---------- None Returns ------- fw_ret_arg : fwi_integer, intent out """ cdef fwi_integer_t fw_ret_arg cdef fwi_integer_t fw_iserr__ cdef fw_character_t fw_errstr__[fw_errstr_len] empty_func_c(&fw_ret_arg, &fw_iserr__, fw_errstr__) if fw_iserr__ != FW_NO_ERR__: raise RuntimeError("an error was encountered when calling the 'empty_func' wrapper.") return fw_ret_arg ''' % get_version() compare(test_str, buf.getvalue())