def test_labels(): source_str = '''\ subroutine foo real a ! Valid code: 100 a = 3 l: do end do l 200 &! haa a=4 300 l1: do end do l1 end subroutine foo ''' tree = parse(source_str, isfree=True, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' !BEGINSOURCE <cStringIO.StringI object at 0x2952e70> mode=free90 SUBROUTINE foo() REAL a ! Valid code: 100 a = 3 l: DO END DO l 200 a = 4 ! haa 300 l1: DO END DO l1 END SUBROUTINE foo '''.strip().split('\n')[1:] source_str = '''\ subroutine foo real a ! Valid code: 100 a = 3 l: do end do l 200 ! haa &a=4 300 l1: do end do l1 end subroutine foo ''' tree = parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' ! BEGINSOURCE <cStringIO.StringI object at 0x1d3b390> mode=fix90 SUBROUTINE foo() REAL a ! Valid code: 100 a = 3 l: DO END DO l 200 a = 4 ! haa 300 l1: DO END DO l1 END SUBROUTINE foo '''.strip().split('\n')[1:]
def generate_ast(fsrcs): ast = [] for src in fsrcs: block = api.parse(src, analyze=True) tree = block.content for proc in tree: if not is_proc(proc): raise RuntimeError( "unsupported Fortran construct %r." % proc) args = _get_args(proc) params = _get_params(proc) if proc.blocktype == 'subroutine': ast.append(pyf.Subroutine( name=proc.name, args=args, params=params)) elif proc.blocktype == 'function': ast.append(pyf.Function( name=proc.name, args=args, params=params, return_arg=_get_ret_arg(proc))) return ast
def test_reproduce_issue(): source_str = '''\ subroutine gwinput_v2x(ifi,konf,ncore) integer :: ifi, !File handle. Write & konf(0:lmxamx,nclass),! Principle ! For examp ! Core orbi ! 1, 2,.. ! 2, 3,.. ! 3, 4,.. ! & ncore(nclass) ! ncore = \sum_l ! Number of diffe end ''' tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' ! BEGINSOURCE <cStringIO.StringI object at 0x1e52ea0> mode=fix90 SUBROUTINE gwinput_v2x(ifi, konf, ncore) INTEGER ifi, konf(0:lmxamx,nclass), ncore(nclass) !File handle. Write ! Principle ! For examp ! Core orbi ! 1, 2,.. ! 2, 3,.. ! 3, 4,.. ! ! ncore = \sum_l ! Number of diffe END SUBROUTINE gwinput_v2x '''.strip().split('\n')[1:]
def test_reproduce_issue(): source_str = """\ module m_rdctrl contains subroutine readctrl(prgn,vstrn,vn) end subroutine readctrl end module """ tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert ( str(tree).strip().split("\n")[1:] == """ ! BEGINSOURCE <cStringIO.StringI object at 0x2405ea0> mode=fix90 MODULE m_rdctrl CONTAINS SUBROUTINE readctrl(prgn, vstrn, vn) END SUBROUTINE readctrl END MODULE m_rdctrl """.strip().split( "\n" )[ 1: ] )
def parse_fortran(source, filename="<floopy code>", free_form=True, strict=True, auto_dependencies=True, target=None): """ :returns: a list of :class:`loopy.LoopKernel` objects """ import logging console = logging.StreamHandler() console.setLevel(logging.INFO) formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') console.setFormatter(formatter) logging.getLogger('fparser').addHandler(console) from fparser import api tree = api.parse(source, isfree=free_form, isstrict=strict, analyze=False, ignore_comments=False) if tree is None: raise LoopyError("Fortran parser was unhappy with source code " "and returned invalid data (Sorry!)") from loopy.frontend.fortran.translator import F2LoopyTranslator f2loopy = F2LoopyTranslator(filename, auto_dependencies=auto_dependencies, target=target) f2loopy(tree) return f2loopy.make_kernels()
def generate_ast(fsrcs): ast = [] for src in fsrcs: block = api.parse(src, analyze=True) tree = block.content for proc in tree: if not is_proc(proc): # we ignore non-top-level procedures until modules are supported. continue args = _get_args(proc) params = _get_params(proc) if proc.blocktype == 'subroutine': ast.append(pyf.Subroutine( name=proc.name, args=args, params=params)) elif proc.blocktype == 'function': ast.append(pyf.Function( name=proc.name, args=args, params=params, return_arg=_get_ret_arg(proc))) return ast
def test_reproduce_issue(): source_str = ''' subroutine foo implicit none character a*8 real*4 r character*2 b*4 end subroutine foo ''' tree = api.parse(source_str, isfree=True, isstrict=False) foo = tree.content[0] a = foo.get_variable('a') b = foo.get_variable('b') r = foo.get_variable('r') assert a.typedecl.__class__.__name__=='Character' assert a.length == '8',repr(a.length) assert a.name =='a' assert a.typedecl.selector==('','') assert r.typedecl.__class__.__name__=='Real' assert r.typedecl.selector==('4','') assert b.typedecl.__class__.__name__=='Character' assert b.length == '4',repr(a.length) assert b.name =='b' assert b.typedecl.selector==('2','')
def parse_master_files(filename_modules, **kwargs): master_objs = [] for master_fn, mod_name in filename_modules.items(): master_tree = fapi.parse(master_fn, isfree=True, isstrict=False) mod_obj = master_tree.a.module[mod_name] master_class_obj = MasterClass(mod_obj, **kwargs) master_objs.append(master_class_obj) return master_objs
def test_recursive(): source_str = ''' recursive subroutine foo end subroutine foo ''' tree = api.parse(source_str, isfree=True, isstrict=False) foo = tree.content[0] assert foo.is_recursive()
def test_reproduce_issue_private(): source_str = ''' module m contains subroutine a end subroutine a end module m ''' tree = api.parse(source_str, isfree=True, isstrict=False)
def test_mdata_invalid_property(): ''' Check that we raise the expected error if an unrecognised mesh property is requested. ''' code = MESH_PROPS_MDATA.replace("adjacent_face", "not_a_property") ast = fpapi.parse(code, ignore_comments=False) name = "testkern_mesh_type" with pytest.raises(ParseError) as err: DynKernMetadata(ast, name=name) assert ("property: 'not_a_property'. Supported values are: " "['ADJACENT_FACE'" in str(err.value))
def test_mdata_wrong_name(): ''' Check that we raise the expected error if the array holding properties of the mesh is given the wrong name. ''' code = MESH_PROPS_MDATA.replace("meta_mesh =", "meta_meshes =") ast = fpapi.parse(code, ignore_comments=False) name = "testkern_mesh_type" with pytest.raises(ParseError) as err: DynKernMetadata(ast, name=name) assert ("No variable named 'meta_mesh' found in the metadata for" in str(err.value))
def test_fs_desc_replicated_fs_type(): ''' Tests that an error is raised when a function space name is replicated. ''' code = CODE.replace("w3, gh_basis", "w1, gh_basis", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert 'function spaces specified in meta_funcs must be unique' \ in str(excinfo.value)
def test_fs_desc_invalid_op_type(): ''' Tests that an error is raised when an invalid function space operator name is provided as an argument. ''' code = CODE.replace("w2, gh_diff_basis", "w2, gh_dif_basis", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert '2nd argument and all subsequent arguments of a meta_func ' + \ 'entry should be one of' in str(excinfo.value)
def test_fsdesc_fs_not_in_argdesc(): ''' Tests that an error is raised when a function space name is provided that has not been used in the arg descriptor. ''' code = CODE.replace("w3, gh_basis", "w0, gh_basis", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert 'function spaces specified in meta_funcs must exist in ' + \ 'meta_args' in str(excinfo)
def test_invalid_mesh_specifier(): ''' Check that we raise an error if "mesh_arg" is mis-spelt ''' fparser.logging.disable(fparser.logging.CRITICAL) code = RESTRICT_MDATA.replace("mesh_arg=GH_COARSE", "mesh_ar=GH_COARSE", 1) ast = fpapi.parse(code, ignore_comments=False) name = "restrict_kernel_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("mesh_ar=gh_coarse is not a valid mesh identifier" in str(excinfo.value))
def test_get_kernel_metadata_match_case_insensitive(get_code_fragment): '''Test that searching for a kernel is not dependent upon the case of the name. ''' module_parse_tree = parse(get_code_fragment) kernel_type_name = "TeSt_TyPe" meta = get_kernel_metadata(kernel_type_name, module_parse_tree) # Make sure we found it. assert meta is not None
def test_ad_op_type_too_many_args(): ''' Tests that an error is raised when the operator descriptor metadata has more than 4 args. ''' code = CODE.replace("arg_type(gh_operator,gh_read, w2, w2)", "arg_type(gh_operator,gh_read, w2, w2, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert 'meta_arg entry must have 4 arguments' in str(excinfo.value)
def test_get_kernel_interface_double_interface(): ''' Tests that parse error occurs when the parse tree contains two interfaces.''' module_parse_tree = parse(CODE_DOUBLE_INTERFACE) kernel_type_name = "double_interface_kernel" with pytest.raises(ParseError) as excinfo: _, _ = get_kernel_interface(kernel_type_name, module_parse_tree) assert "Module containing kernel double_interface_kernel has more than "\ "one interface, this is forbidden in the LFRic API."\ in str(excinfo.value)
def test_fs_descriptor_wrong_type(): ''' Tests that an error is raised when the function space descriptor metadata is not of type func_type. ''' code = CODE.replace("func_type(w2", "funced_up_type(w2", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert "each meta_func entry must be of type 'func_type'" in \ str(excinfo.value)
def test_get_kernel_interface_match_correct(): ''' Tests that the get_kernel_interface has correct return when searching for an interface that defines more than one module procedure. ''' module_parse_tree = parse(CODE_DOUBLE_PROCEDURE) kernel_type_name = "interface_procedures" meta1, meta2 = get_kernel_interface(kernel_type_name, module_parse_tree) assert meta1 == "test_code" assert meta2[0] == "sub_code" assert meta2[1] == "more_code" assert len(meta2) == 2
def test_ad_op_type_wrong_access(): ''' Test that an error is raised if an operator has gh_inc access. ''' code = CODE.replace("arg_type(gh_operator,gh_read, w2, w2)", "arg_type(gh_operator,gh_inc, w2, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("In the dynamo0.3 API operators cannot have a 'gh_inc' access" in str(excinfo.value))
def test_mdata_parse(): ''' Check that we get the correct list of mesh properties. ''' from psyclone.dynamo0p3 import MeshPropertiesMetaData fparser.logging.disable(fparser.logging.CRITICAL) code = MESH_PROPS_MDATA ast = fpapi.parse(code, ignore_comments=False) name = "testkern_mesh_type" dkm = DynKernMetadata(ast, name=name) assert dkm.mesh.properties == \ [MeshPropertiesMetaData.Property.ADJACENT_FACE]
def test_kernel_binding_missing(): ''' Check that we raise the correct error when the Kernel meta-data is missing the type-bound procedure giving the name of the subroutine. ''' mdata = MDATA.replace( "contains\n procedure, nopass :: code => testkern_eval_code\n", "") ast = fpapi.parse(mdata) with pytest.raises(RuntimeError) as err: _ = KernelType(ast) assert ("Kernel type testkern_eval_type does not bind a specific " "procedure" in str(err))
def test_fs_desc_invalid_fs_type(): ''' Tests that an error is raised when an invalid function space name is provided as the first argument. ''' code = CODE.replace("w3, gh_basis", "w4, gh_basis", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert '1st argument of a meta_func entry should be a valid function ' + \ 'space name' in str(excinfo.value)
def test_mdata_invalid_property(property_name): ''' Check that we raise the expected error if an unrecognised mesh property is requested. Also test with a value that *is* a valid mesh property but is not supported in kernel metadata. ''' code = MESH_PROPS_MDATA.replace("adjacent_face", property_name) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_mesh_type" with pytest.raises(ParseError) as err: DynKernMetadata(ast, name=name) assert ("in metadata: '{0}'. Supported values are: " "['ADJACENT_FACE'".format(property_name) in str(err.value))
def test_invalid_vector_operator(): ''' Tests that an error is raised when a field vector does not use "*" as its operator. ''' fparser.logging.disable(fparser.logging.CRITICAL) code = FIELD_CODE.replace("(gh_field, gh_real, gh_inc, w1)", "(gh_field+3, gh_real, gh_inc, w1)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_field_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert "must use '*' as the separator" in str(excinfo.value)
def test_kerneltype_both_operates_on_iterates_over(): ''' Check that KernelType raises the expected error if the kernel metadata specifies *both* operates_on and iterates_over. ''' code = ITERATES_OVER_CODE.replace( " contains\n", " integer :: operates_on = cell_column\n" " contains\n") parse_tree = parse(code) with pytest.raises(ParseError) as err: KernelType(parse_tree) assert ("kernel 'test_type' contains both 'operates_on' and " "'iterates_over'" in str(err.value))
def test_fs_desc_replicated_op_type(): ''' Tests that an error is raised when a function space operator name is replicated as an argument. ''' code = CODE.replace("w3, gh_basis, gh_diff_basis", "w3, gh_basis, gh_basis", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert 'error to specify an operator name more than once' \ in str(excinfo.value)
def test_ad_op_type_wrong_3rd_arg(): ''' Tests that an error is raised when the 3rd entry in the operator descriptor metadata is invalid. ''' code = CODE.replace("arg_type(gh_operator, gh_read, w2, w2)", "arg_type(gh_operator, gh_read, woops, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("LFRic API the 3rd argument of a 'meta_arg' operator entry " "must be a valid function space name" in str(excinfo.value))
def test_invalid_mesh_type(): ''' Check that we raise an error if an unrecognised name is supplied for the mesh associated with a field argument ''' fparser.logging.disable(fparser.logging.CRITICAL) code = RESTRICT_MDATA.replace("GH_COARSE", "GH_RUBBISH", 1) ast = fpapi.parse(code, ignore_comments=False) name = "restrict_kernel_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("mesh_arg must be one of [\\'gh_coarse\\', " "\\'gh_fine\\'] but got gh_rubbish" in str(excinfo.value))
def test_get_kernel_metadata_no_match(): '''Test that we get a ParseError when searching for a kernel that does not exist in the parse tree. ''' module_parse_tree = parse(CODE) kernel_type_name = "no_matching_kernel" with pytest.raises(ParseError) as excinfo: get_kernel_metadata( kernel_type_name, module_parse_tree) assert 'Kernel type no_matching_kernel does not exist' in str(excinfo)
def test_ad_op_type_1st_arg_not_space(): ''' Tests that an error is raised when the operator descriptor metadata contains something that is not a valid space. ''' code = CODE.replace("arg_type(gh_operator, gh_read, w2, w2)", "arg_type(gh_operator, gh_read, wbroke, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("'meta_arg' operator entry must be a valid function space" in str(excinfo.value))
def test_get_int_array_not_array(): ''' Test that get_integer_array returns the expected error if the requested variable is not an array. ''' ast = fpapi.parse(MDATA, ignore_comments=False) ktype = KernelType(ast) # Erroneously call get_integer_array with the name of a scalar meta-data # entry with pytest.raises(ParseError) as err: _ = ktype.get_integer_array("iterates_over") assert ("RHS of assignment is not an array constructor: 'iterates_over = " "cells'" in str(err))
def test_reproduce_issue_1(): source_str = '''\ subroutine bndfp(ax,i) logical:: ax if(ax) i=1 end ''' tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) ifstmt = tree.content[0].content[1] assert str(ifstmt).strip()==''' IF (ax) i = 1'''.strip()
def test_kerneltype_typename(): '''Test that an exception is raised if the metadata type name is not what was expected. ''' my_code = CODE.replace("meta_args", "invalid_name") parse_tree = parse(my_code) with pytest.raises(ParseError) as excinfo: _ = KernelType(parse_tree) assert "No kernel metadata with type name 'meta_args' found." \ in str(excinfo.value)
def test_reproduce_issue(): source_str = '''\ subroutine bndfp() include "events.ins" end ''' tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) print(tree) return assert str(tree).strip().split('\n')[1:]==''' '''.strip().split('\n')[1:]
def test_ad_op_type_wrong_access(): ''' Test that an error is raised if an operator has 'gh_inc' access. ''' code = CODE.replace("arg_type(gh_operator, gh_real, gh_read, w2, w2)", "arg_type(gh_operator, gh_real, gh_inc, w2, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("In the LFRic API, allowed accesses for operators are " "['gh_read', 'gh_write', 'gh_readwrite'] because they behave " "as discontinuous quantities, but found 'gh_inc'" in str(excinfo.value))
def test_kerneltype_dimensions(): '''Test that an exception is raised if the metadata variable is a multi-dimensional array. ''' my_code = CODE.replace("dimension(1)", "dimension(1,1)") parse_tree = parse(my_code) with pytest.raises(ParseError) as excinfo: _ = KernelType(parse_tree) assert ("In kernel metadata 'test_type': 'meta_args' variable must be a " "1 dimensional array") in str(excinfo.value)
def test_use_module(): ''' Test that we parse a function that uses a module when we supply the latter via the `source_only` argument. ''' cwd = dirname(__file__) sources = [join(cwd, 'modfile.f95'), join(cwd, 'funcfile.f95')] file_to_parse = sources[1] _ = api.parse(file_to_parse, isfree=True, isstrict=False, source_only=sources)
def test_no_vector_operator(): ''' Test that we raise an error when kernel metadata erroneously specifies a vector operator argument. ''' code = CODE.replace( "arg_type(gh_operator, gh_real, gh_read, w2, w2)", "arg_type(gh_operator*3, gh_real, gh_read, w2, w2)", 1) ast = fpapi.parse(code, ignore_comments=False) name = "testkern_qr_type" with pytest.raises(ParseError) as excinfo: _ = DynKernMetadata(ast, name=name) assert ("vector notation is only supported for ['gh_field'] " "argument types but found 'gh_operator * 3'" in str(excinfo.value))
def test_reproduce_issue(): source_str = '''\ subroutine foobar() !#here's a f90 comment starting at 0 end ''' tree = api.parse(source_str, isfree=False, isstrict=True, analyze=False) assert str(tree).strip().split('\n')[1:] == ''' ! BEGINSOURCE <cStringIO.StringI object at 0x3721710> mode=f77 SUBROUTINE foobar() END SUBROUTINE foobar '''.strip().split('\n')[1:]
def test_walk(): source_str = '''\ ! before foo subroutine foo integer i, r do i = 1,100 r = r + 1 end do ! after end do end subroutine foo ''' tree = api.parse(source_str, isfree=True, isstrict=False, ignore_comments=False) for stmt, depth in api.walk(tree, 1): print depth, stmt.item
def test_default_private(): src = '''\ module mod1 private integer :: i contains subroutine s1 end subroutine end module mod1 ''' mod1 = api.parse(src, isfree=True, isstrict=False).content[0] assert mod1.get_provides() == {}, `mod1.get_provides()` assert mod1.a.variables.keys() == ['i'] assert mod1.a.module_subprogram.keys() == ['s1']
def test_comment_4(): source_str = """ subroutine m_struc_def() !abc test end """ tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==""" ! BEGINSOURCE <cStringIO.StringI object at 0x121aa80> mode=fix90 SUBROUTINE m_struc_def() !abc test END SUBROUTINE m_struc_def """.strip().split('\n')[1:]
def test_Issue_r25_1(): source_str = ''' subroutine bndfp() logical:: mlog c test abb c #1232 ! c cabi real(8):: abc,a(5), & abcx !hhhh1 abc=3 !hhhh2 do i=1,5 a(i)=i enddo ! ! end ''' tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' ! BEGINSOURCE <cStringIO.StringI object at 0xb52b40> mode=fix90 SUBROUTINE bndfp() LOGICAL mlog ! test abb ! !1232 ! ! !abi REAL(KIND=8) abc, a(5), abcx !hhhh1 abc = 3 !hhhh2 DO i=1,5 a(i) = i END DO ! ! END SUBROUTINE bndfp '''.strip().split('\n')[1:]
def test_reproduce_issue(): source_str = '''\ subroutine foo do 10 10 continue end subroutine ''' tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' ! BEGINSOURCE <cStringIO.StringI object at 0x1733ea0> mode=fix90 SUBROUTINE foo() DO 10 10 CONTINUE END SUBROUTINE foo '''.strip().split('\n')[1:]
def f2cl( source, free_form=False, strict=True, addr_space_hints={}, force_casts={}, do_arg_analysis=True, use_restrict_pointers=False, try_compile=False, ): from fparser import api tree = api.parse(source, isfree=free_form, isstrict=strict, analyze=False, ignore_comments=False) arg_info = ArgumentAnalayzer() if do_arg_analysis: arg_info(tree) source = F2CLTranslator(addr_space_hints, force_casts, arg_info, use_restrict_pointers=use_restrict_pointers)(tree) func_decls = [] for entry in source: if isinstance(entry, cgen.FunctionBody): func_decls.append(entry.fdecl) mod = cgen.Module(func_decls + [cgen.Line()] + source) # open("pre-cnd.cl", "w").write(str(mod)) from cnd import transform_cl str_mod = transform_cl(str(mod)) if try_compile: import pyopencl as cl ctx = cl.create_some_context() cl.Program( ctx, """ #if __OPENCL_VERSION__ <= CL_VERSION_1_1 #pragma OPENCL EXTENSION cl_khr_fp64: enable #endif #include <pyopencl-complex.h> """, ).build() return str_mod
def test_reproduce_issue(): source_str = """\ MODULE testa CONTAINS SUBROUTINE f(arga) INTEGER :: arga CONTAINS SUBROUTINE subf(argx) INTEGER :: argx END SUBROUTINE subf END SUBROUTINE f END MODULE testa """ tree = api.parse(source_str, isfree=True, isstrict=False, ignore_comments=False) r = str(tree).strip() assert ( r.split("\n")[1:] == """ ...!BEGINSOURCE <cStringIO.StringI object at 0x139f8a0> mode=free MODULE testa CONTAINS SUBROUTINE f(arga) INTEGER arga CONTAINS SUBROUTINE subf(argx) INTEGER argx END SUBROUTINE subf END SUBROUTINE f END MODULE testa """.strip().split( "\n" )[ 1: ] ), ` r `
def test_reproduce_issue_len(): source_str = ''' subroutine foo(a) character(lenmax) a character(lenmax, kind=4) b character(len=lenmax, kind=4) c character(kind=4, len=lenmax) d character(lenmax, 4) e end subroutine foo ''' tree = api.parse(source_str, isfree=True, isstrict=False) a, b, c, d, e=tree.content[0].content[:5] assert a.selector==('lenmax','') assert b.selector==('lenmax','4') assert c.selector==('lenmax','4') assert d.selector==('lenmax','4') assert e.selector==('lenmax','4')
def test_access_spec(): src = '''\ module mod1 private integer, public :: i integer :: j, k public :: j, s1 contains subroutine s1 end subroutine subroutine s2 end subroutine end module mod1 ''' mod1 = api.parse(src, isfree=True, isstrict=False).content[0] assert sorted(mod1.get_provides().keys()) == sorted(['i', 'j', 's1']) assert sorted(mod1.a.variables.keys()) == sorted(['i', 'j', 'k']) assert sorted(mod1.a.module_subprogram.keys()) == sorted(['s2', 's1'])
def test_reproduce_issue(): source_str = '''\ MODULE testa TYPE t INTEGER :: x END TYPE CONTAINS SUBROUTINE f(arga) INTEGER :: arga TYPE(t), DIMENSION(2) :: v v(1)%x = 23 v (2) % x = 42 END SUBROUTINE f END MODULE testa ''' tree = api.parse(source_str, isfree=True, isstrict=False, ignore_comments=False) r = str(tree).strip() assert r.split('\n')[1:]==''' !BEGINSOURCE <cStringIO.StringI object at 0x2a1ee70> mode=free MODULE testa TYPE t INTEGER x END TYPE t CONTAINS SUBROUTINE f(arga) INTEGER arga TYPE(t), dimension(2) :: v v(1)%x = 23 v(2)%x = 42 END SUBROUTINE f END MODULE testa '''.strip().split('\n')[1:],repr(r)
def test_dimension_attr(): source_str = ''' subroutine foo integer, dimension( -10 : 10, - 2147483648 : 2147483648) :: a( -2 : 2, 1000000 : 1000001 ) real, dimension(-20:20, 100:113, - 512 : 713) :: b end ''' tree = api.parse(source_str, isfree=True, isstrict=False) subr = tree.a.external_subprogram['foo'] avar = subr.a.variables['a'] assert avar.dimension == [('-10', '10'), ('- 2147483648', '2147483648')] assert avar.bounds == [('-2', '2'), ('1000000', '1000001')] assert avar.shape == ['4', '1'] bvar = subr.a.variables['b'] assert bvar.dimension == [('-20', '20'), ('100', '113'), ('- 512', '713')] assert bvar.shape == ['40', '13', '1225']
def test_reproduce_issue(): source_str = '''\ subroutine bl(a, &b, &c) integer a, b, c a = b + c end subroutine bl subroutine blc(a, c here's an annoying comment line &b, &c, c another annoying comment &d, c a third annoying comment &e) a = b + c + d + e end subroutine blc ''' tree = api.parse(source_str, isfree=False, isstrict=True, analyze=False) print tree assert str(tree).strip().split('\n')[1:] == ''' ! BEGINSOURCE <cStringIO.StringI object at 0x3723710> mode=f77 SUBROUTINE bl(a, b, c) INTEGER a, b, c a = b + c END SUBROUTINE bl SUBROUTINE blc(a, b, c, d, e) a = b + c + d + e END SUBROUTINE blc '''.strip().split('\n')[1:]
def test_comment_lines(): source_str = '''\ !comment line 1 !comment line 2 module foo !comment line 3 subroutine f !comment line 4 end subroutine f !comment line 5 end module foo ''' tree = parse(source_str, isfree=True, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==''' !BEGINSOURCE <cStringIO.StringI object at 0x1518de0> mode=free90 !comment line 1 !comment line 2 MODULE foo !comment line 3 SUBROUTINE f() !comment line 4 END SUBROUTINE f !comment line 5 END MODULE foo '''.strip().split('\n')[1:] assert tree.asfix().strip().split('\n')[1:]==''' C BEGINSOURCE <cStringIO.StringI object at 0x1630de0> mode=free90 C comment line 1 C comment line 2 MODULE foo C comment line 3 SUBROUTINE f() C comment line 4 END SUBROUTINE f C comment line 5 END MODULE foo '''.strip().split('\n')[1:]
def test_private_type(): source_str = ''' module m private public b type :: a end type a type :: b end type b type public :: c end type c end module m ''' tree = api.parse(source_str, isfree=True, isstrict=False) a,b,c = tree.content[0].content[2:5] assert a.is_private() assert not a.is_public() assert not b.is_private() assert b.is_public() assert not c.is_private() assert c.is_public()
def test_private_subroutine(): source_str = ''' module m public private a contains subroutine a end subroutine a subroutine b end subroutine b end module m ''' tree = api.parse(source_str, isfree=True, isstrict=False) a = tree.content[0].content[3] b = tree.content[0].content[4] assert not a.is_public() assert a.is_private() assert b.is_public() assert not b.is_private()
def test_Issue_r25_1(): source_str = """ subroutine rsedit() print 311 311 format(/ . t4,'read [fn]',t15, . t14,' Third argument = flip: exchange n+, n- ') end """ tree = api.parse(source_str, isfree=False, isstrict=False, ignore_comments=False) assert str(tree).strip().split('\n')[1:]==""" ! BEGINSOURCE <cStringIO.StringI object at 0x121bab0> mode=fix90 SUBROUTINE rsedit() PRINT 311 311 FORMAT (/ t4, 'read [fn]', t15, t14, ' Third argument = flip: exchange n+, n- ') END SUBROUTINE rsedit """.strip().split('\n')[1:]
def test_reproduce_issue(): source_str = '''\ module foo interface assignment(=) module procedure baa end interface assignment(=) end module foo ''' tree = api.parse(source_str, isfree=True, isstrict=False, ignore_comments=False) r = str(tree).strip() assert r.split('\n')[1:]==''' ...!BEGINSOURCE <cStringIO.StringI object at 0x302c1e0> mode=free MODULE foo INTERFACE assignment(=) MODULE PROCEDURE baa END INTERFACE assignment(=) END MODULE foo '''.strip().split('\n')[1:],repr(r)
def use_pars_var(var_name): # Do include certain pars variabls if not type(var_name) is str: return False elif re.match("fmt_", var_name): return False else: return True # Use this for where else for fparse to search for information source_only_list = [os.path.join(LIDORT_DEFS_DIR, fn) for fn in USE_SOURCES] # Parse PARS file pars_tree = fapi.parse(os.path.join(LIDORT_DEFS_DIR, PARS_FILENAME), isfree=True, isstrict=False, source_only=source_only_list) pars_module = pars_tree.a.module[LIDORT_PARS_NAME] pars_var_names = filter(use_pars_var, pars_module.a.variable_names) pars_wrapper = TypeClass(pars_module, variable_names=pars_var_names, c_store_var_name="{name}", ignore_variables=PARS_IGNORE_VARIABLES) # Parse definition files def_type_vars = [] for def_fn in DEF_FILENAMES: def_tree = fapi.parse(def_fn, isfree=True, isstrict=False, source_only=source_only_list) for mod_name, mod_obj in def_tree.a.module.items():