(src: Path, srcdir: Path, dirname: Path, tdeps, compiler)
return mod_files
scan a Fortran file for dependencies. Needs to be distinct from target
    to allow for recursion induced by `include` statements.er

    It makes a number of assumptions, including

    * `use`, `module`, `submodule` name is not on a continuation line

    Regex
    -----

    * `incre` works for `#include "foo.f90"` and `include "foo.f90"`
    * `usere` works for legacy and Fortran 2003 `use` statements
    * `submodre` is for Fortran >= 2008 `submodule`
scan a Fortran file for dependencies. Needs to be distinct from target
    to allow for recursion induced by `include` statements.er
scan a Fortran file for dependencies . Needs to be distinct from target to allow for recursion induced by include statements . er
def _scan_fortran_file_deps(src: Path, srcdir: Path, dirname: Path, tdeps, compiler) -> T.List[str]:
    """
    scan a Fortran file for dependencies. Needs to be distinct from target
    to allow for recursion induced by `include` statements.er

    It makes a number of assumptions, including

    * `use`, `module`, `submodule` name is not on a continuation line

    Regex
    -----

    * `incre` works for `#include "foo.f90"` and `include "foo.f90"`
    * `usere` works for legacy and Fortran 2003 `use` statements
    * `submodre` is for Fortran >= 2008 `submodule`
    """

    incre = re.compile(FORTRAN_INCLUDE_PAT, re.IGNORECASE)
    usere = re.compile(FORTRAN_USE_PAT, re.IGNORECASE)
    submodre = re.compile(FORTRAN_SUBMOD_PAT, re.IGNORECASE)

    mod_files = []
    src = Path(src)
    with src.open(encoding='ascii', errors='ignore') as f:
        for line in f:
            # included files
            incmatch = incre.match(line)
            if incmatch is not None:
                incfile = src.parent / incmatch.group(1)
                # NOTE: src.parent is most general, in particular for CMake subproject with Fortran file
                # having an `include 'foo.f'` statement.
                if incfile.suffix.lower()[1:] in compiler.file_suffixes:
                    mod_files.extend(_scan_fortran_file_deps(incfile, srcdir, dirname, tdeps, compiler))
            # modules
            usematch = usere.match(line)
            if usematch is not None:
                usename = usematch.group(1).lower()
                if usename == 'intrinsic':  # this keeps the regex simpler
                    continue
                if usename not in tdeps:
                    # The module is not provided by any source file. This
                    # is due to:
                    #   a) missing file/typo/etc
                    #   b) using a module provided by the compiler, such as
                    #      OpenMP
                    # There's no easy way to tell which is which (that I
                    # know of) so just ignore this and go on. Ideally we
                    # would print a warning message to the user but this is
                    # a common occurrence, which would lead to lots of
                    # distracting noise.
                    continue
                srcfile = srcdir / tdeps[usename].fname  # type: Path
                if not srcfile.is_file():
                    if srcfile.name != src.name:  # generated source file
                        pass
                    else:  # subproject
                        continue
                elif srcfile.samefile(src):  # self-reference
                    continue

                mod_name = compiler.module_name_to_filename(usename)
                mod_files.append(str(dirname / mod_name))
            else:  # submodules
                submodmatch = submodre.match(line)
                if submodmatch is not None:
                    parents = submodmatch.group(1).lower().split(':')
                    assert len(parents) in (1, 2), (
                        'submodule ancestry must be specified as'
                        f' ancestor:parent but Meson found {parents}')

                    ancestor_child = '_'.join(parents)
                    if ancestor_child not in tdeps:
                        raise MesonException("submodule {} relies on ancestor module {} that was not found.".format(submodmatch.group(2).lower(), ancestor_child.split('_')[0]))
                    submodsrcfile = srcdir / tdeps[ancestor_child].fname  # type: Path
                    if not submodsrcfile.is_file():
                        if submodsrcfile.name != src.name:  # generated source file
                            pass
                        else:  # subproject
                            continue
                    elif submodsrcfile.samefile(src):  # self-reference
                        continue
                    mod_name = compiler.module_name_to_filename(ancestor_child)
                    mod_files.append(str(dirname / mod_name))
    return mod_files
def _scan_fortran_file_deps ( src : Path , srcdir : Path , dirname : Path , tdeps , compiler ) -> T . List [ str ] : incre = re . compile ( FORTRAN_INCLUDE_PAT , re . IGNORECASE ) usere = re . compile ( FORTRAN_USE_PAT , re . IGNORECASE ) submodre = re . compile ( FORTRAN_SUBMOD_PAT , re . IGNORECASE ) mod_files = [ ] src = Path ( src ) with src . open ( encoding = 'ascii' , errors = 'ignore' ) as f : for line in f : # included files incmatch = incre . match ( line ) if incmatch is not None : incfile = src . parent / incmatch . group ( 1 ) # NOTE: src.parent is most general, in particular for CMake subproject with Fortran file # having an `include 'foo.f'` statement. if incfile . suffix . lower ( ) [ 1 : ] in compiler . file_suffixes : mod_files . extend ( _scan_fortran_file_deps ( incfile , srcdir , dirname , tdeps , compiler ) ) # modules usematch = usere . match ( line ) if usematch is not None : usename = usematch . group ( 1 ) . lower ( ) if usename == 'intrinsic' : # this keeps the regex simpler continue if usename not in tdeps : # The module is not provided by any source file. This # is due to: #   a) missing file/typo/etc #   b) using a module provided by the compiler, such as #      OpenMP # There's no easy way to tell which is which (that I # know of) so just ignore this and go on. Ideally we # would print a warning message to the user but this is # a common occurrence, which would lead to lots of # distracting noise. continue srcfile = srcdir / tdeps [ usename ] . fname # type: Path if not srcfile . is_file ( ) : if srcfile . name != src . name : # generated source file pass else : # subproject continue elif srcfile . samefile ( src ) : # self-reference continue mod_name = compiler . module_name_to_filename ( usename ) mod_files . append ( str ( dirname / mod_name ) ) else : # submodules submodmatch = submodre . match ( line ) if submodmatch is not None : parents = submodmatch . group ( 1 ) . lower ( ) . split ( ':' ) assert len ( parents ) in ( 1 , 2 ) , ( 'submodule ancestry must be specified as' f' ancestor:parent but Meson found {parents}' ) ancestor_child = '_' . join ( parents ) if ancestor_child not in tdeps : raise MesonException ( "submodule {} relies on ancestor module {} that was not found." . format ( submodmatch . group ( 2 ) . lower ( ) , ancestor_child . split ( '_' ) [ 0 ] ) ) submodsrcfile = srcdir / tdeps [ ancestor_child ] . fname # type: Path if not submodsrcfile . is_file ( ) : if submodsrcfile . name != src . name : # generated source file pass else : # subproject continue elif submodsrcfile . samefile ( src ) : # self-reference continue mod_name = compiler . module_name_to_filename ( ancestor_child ) mod_files . append ( str ( dirname / mod_name ) ) return mod_files