add_sources_from_dir Subroutine

public subroutine add_sources_from_dir(sources, directory, scope, with_executables, recurse, error)

Add to sources by looking for source files in directory


Type IntentOptional AttributesName
type(srcfile_t), intent(inout), allocatable, target:: sources(:)

List of srcfile_t objects to append to. Allocated if not allocated

character(len=*), intent(in) :: directory

Directory in which to search for source files

integer, intent(in) :: scope

Scope to apply to the discovered sources, see fpm_model for enumeration

logical, intent(in), optional :: with_executables

Executable sources (fortran programs) are ignored unless with_executables=.true.

logical, intent(in), optional :: recurse

Whether to recursively search subdirectories, default is .true.

type(error_t), intent(out), allocatable:: error

Error handling


Source Code


TypeVisibility AttributesNameInitial
type(srcfile_t), public, allocatable:: dir_sources(:)
logical, public, allocatable:: exclude_source(:)
type(string_t), public, allocatable:: existing_src_files(:)
type(string_t), public, allocatable:: file_names(:)
integer, public :: i
logical, public, allocatable:: is_source(:)
type(string_t), public, allocatable:: src_file_names(:)

Source Code

subroutine add_sources_from_dir(sources,directory,scope,with_executables,recurse,error)
    !> List of `[[srcfile_t]]` objects to append to. Allocated if not allocated
    type(srcfile_t), allocatable, intent(inout), target :: sources(:)
    !> Directory in which to search for source files
    character(*), intent(in) :: directory
    !> Scope to apply to the discovered sources, see [[fpm_model]] for enumeration
    integer, intent(in) :: scope
    !> Executable sources (fortran `program`s) are ignored unless `with_executables=.true.`
    logical, intent(in), optional :: with_executables
    !> Whether to recursively search subdirectories, default is `.true.`
    logical, intent(in), optional :: recurse
    !> Error handling
    type(error_t), allocatable, intent(out) :: error

    integer :: i
    logical, allocatable :: is_source(:), exclude_source(:)
    type(string_t), allocatable :: file_names(:)
    type(string_t), allocatable :: src_file_names(:)
    type(string_t), allocatable :: existing_src_files(:)
    type(srcfile_t), allocatable :: dir_sources(:)

    ! Scan directory for sources
    call list_files(directory, file_names,recurse=merge(recurse,.true.,present(recurse)))

    if (allocated(sources)) then
        do i=1,size(sources)
            existing_src_files(i)%s = canon_path(sources(i)%file_name)
        end do
    end if

    is_source = [(.not.(canon_path(file_names(i)%s) .in. existing_src_files) .and. &
                  (str_ends_with(lower(file_names(i)%s), fortran_suffixes) .or. &
                   str_ends_with(lower(file_names(i)%s),[".c",".h"]) ),i=1,size(file_names))]
    src_file_names = pack(file_names,is_source)


    do i = 1, size(src_file_names)

        dir_sources(i) = parse_source(src_file_names(i)%s,error)
        if (allocated(error)) return

        dir_sources(i)%unit_scope = scope

        ! Exclude executables unless specified otherwise
        exclude_source(i) = (dir_sources(i)%unit_type == FPM_UNIT_PROGRAM)
        if (dir_sources(i)%unit_type == FPM_UNIT_PROGRAM .and. &
            & present(with_executables)) then
            if (with_executables) then

                exclude_source(i) = .false.

            end if
        end if

    end do

    if (.not.allocated(sources)) then
        sources = pack(dir_sources,.not.exclude_source)
        sources = [sources, pack(dir_sources,.not.exclude_source)]
    end if

end subroutine add_sources_from_dir