diff --git a/examples/Makefile b/examples/Makefile index 3963561a..71c5e874 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -40,6 +40,7 @@ EXAMPLES = \ issue306_allocatable_realloc \ issue307_logical_array \ issue32 \ + issue353_selected_kind \ issue41_abstract_classes \ keep_single_interface \ keyword_renaming_issue160 \ diff --git a/examples/issue353_selected_kind/Makefile b/examples/issue353_selected_kind/Makefile new file mode 100644 index 00000000..a6aa39a2 --- /dev/null +++ b/examples/issue353_selected_kind/Makefile @@ -0,0 +1,13 @@ +include ../make.inc + +.PHONY: all test clean + +all: + f90wrap test_selected_kind.f90 -v + +test: all + $(PYTHON) run.py + +clean: + rm -f f90wrap*.f90 .f2py_f2cmap mod.py + rm -rf __pycache__/ build/ _build_dir/ diff --git a/examples/issue353_selected_kind/Makefile.meson b/examples/issue353_selected_kind/Makefile.meson new file mode 100644 index 00000000..888dad8b --- /dev/null +++ b/examples/issue353_selected_kind/Makefile.meson @@ -0,0 +1,7 @@ +include ../make.meson.inc + +NAME := test_selected_kind +LIBSRC_WRAP_FPP_FILES := test_selected_kind.f90 + +test: extension + $(PYTHON) run.py diff --git a/examples/issue353_selected_kind/run.py b/examples/issue353_selected_kind/run.py new file mode 100644 index 00000000..9133d615 --- /dev/null +++ b/examples/issue353_selected_kind/run.py @@ -0,0 +1,25 @@ +from pathlib import Path +import glob + +wrapper_files = glob.glob("f90wrap_*.f90") +if not wrapper_files: + raise SystemExit("No f90wrap_*.f90 files found") + +wrapper = "" +for f in wrapper_files: + wrapper += Path(f).read_text(encoding="utf-8") + +expected = [ + "integer(selected_int_kind(9)), intent(out) :: i", + "real(selected_real_kind(13,300)), intent(out) :: a", +] + +missing = [line for line in expected if line not in wrapper] +if missing: + raise SystemExit( + "Missing expected wrapper lines:\n" + + "\n".join(missing) + + "\n\nGenerated wrapper:\n" + + wrapper + ) + diff --git a/examples/issue353_selected_kind/test_selected_kind.f90 b/examples/issue353_selected_kind/test_selected_kind.f90 new file mode 100644 index 00000000..ed4d6dd5 --- /dev/null +++ b/examples/issue353_selected_kind/test_selected_kind.f90 @@ -0,0 +1,6 @@ +subroutine test_selected_kind(i, a) + implicit none + integer(kind=selected_int_kind(9)), intent(out) :: i + real(kind=selected_real_kind(13,300)), intent(out) :: a +end subroutine test_selected_kind + diff --git a/f90wrap/parser.py b/f90wrap/parser.py index e64302e2..97c0c51c 100644 --- a/f90wrap/parser.py +++ b/f90wrap/parser.py @@ -1481,7 +1481,17 @@ def check_decl(cl, file): filename = file.filename lineno = file.lineno - tp = re.match(types_re, cl).group() + tp_match = re.match(types_re, cl) + tp = tp_match.group() + tp_end = tp_match.end() + while tp.count('(') > tp.count(')') and tp_end < len(cl): + while tp_end < len(cl) and cl[tp_end].isspace(): + tp_end += 1 + if tp_end < len(cl) and cl[tp_end] == ')': + tp += ')' + tp_end += 1 + else: + break atr = re.search(attr_re, cl) if atr != None: atrl = s_attrib_re.findall(atr.group()) @@ -1493,7 +1503,7 @@ def check_decl(cl, file): if m is not None: names = cl[m.end():] else: - names = types_re.sub('', cl) + names = cl[tp_end:] # old line - doesn't handle array constants # nl=re.split(r'\s*,\s*',names) @@ -1575,15 +1585,24 @@ def check_arg(cl, file): filename = file.filename lineno = file.lineno - tp = re.match(types_re, cl).group() + tp_match = re.match(types_re, cl) + tp = tp_match.group() + tp_end = tp_match.end() + while tp.count('(') > tp.count(')') and tp_end < len(cl): + while tp_end < len(cl) and cl[tp_end].isspace(): + tp_end += 1 + if tp_end < len(cl) and cl[tp_end] == ')': + tp += ')' + tp_end += 1 + else: + break m = re.search(d_colon, cl) if m is not None: - atr_temp = cl[re.match(types_re, cl).end():m.start()] + atr_temp = cl[tp_end:m.start()] names = cl[m.end():] else: atr_temp = '' - # Need to remove ONLY THE FIRST type string (the name may have the type in it) - names = types_re.sub('', cl, 1) + names = cl[tp_end:] atrl = split_attribs(atr_temp)