!fpx3_header(0.13_3a)
!
!dependencies
!   dir: ~/devel/gyre-4/src/utils 
!   sources: -
!   includes: ../extern/core/core.inc
!   uses: ISO_FORTRAN_ENV core_kinds
!   provides: core_system
!end dependencies
!
!end fpx3_header
! Module   : core_system
! Purpose  : operating system support

! Incfile  : core
! Purpose  : fpx3 macros

!****

!****

!****

!****

!****

!****

!****

!****

!****

module core_system

  ! Uses

  use core_kinds

  use ISO_FORTRAN_ENV

  ! No implicit typing

  implicit none

  ! Interfaces

  interface get_arg
     module procedure get_arg_i_i4_
     module procedure get_arg_i_i8_
     module procedure get_arg_r_sp_
     module procedure get_arg_r_dp_
     module procedure get_arg_c_sp_
     module procedure get_arg_c_dp_
     module procedure get_arg_a_
     module procedure get_arg_l_
  end interface get_arg

  interface get_env
     module procedure get_env_i_i4_
     module procedure get_env_i_i8_
     module procedure get_env_r_sp_
     module procedure get_env_r_dp_
     module procedure get_env_c_sp_
     module procedure get_env_c_dp_
     module procedure get_env_a_
     module procedure get_env_l_
  end interface get_env

  ! Access specifiers

  private

  public :: n_arg
  public :: get_arg
  public :: get_env

contains

  function n_arg ()

    integer :: n_arg

    ! Get the number of arguments

    n_arg = COMMAND_ARGUMENT_COUNT()

    ! Finish

    return

  end function n_arg

!****

  subroutine get_arg_i_i4_ (number, value)

    integer, intent(in)      :: number
    integer(I4), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_i_i4_

  subroutine get_arg_i_i8_ (number, value)

    integer, intent(in)      :: number
    integer(I8), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_i_i8_

  subroutine get_arg_r_sp_ (number, value)

    integer, intent(in)      :: number
    real(SP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_r_sp_

  subroutine get_arg_r_dp_ (number, value)

    integer, intent(in)      :: number
    real(DP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_r_dp_

  subroutine get_arg_c_sp_ (number, value)

    integer, intent(in)      :: number
    complex(SP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_c_sp_

  subroutine get_arg_c_dp_ (number, value)

    integer, intent(in)      :: number
    complex(DP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_c_dp_

  subroutine get_arg_a_ (number, value)

    integer, intent(in)      :: number
    character(*), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_a_

  subroutine get_arg_l_ (number, value)

    integer, intent(in)      :: number
    logical, intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the argument into a character buffer

    call GET_COMMAND_ARGUMENT(number, LENGTH=buffer_len)

    allocate(character(buffer_len)::buffer)

    call GET_COMMAND_ARGUMENT(number, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_arg_l_

!****

  subroutine get_env_i_i4_ (name, value)

    character(*), intent(in) :: name
    integer(I4), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 147 <core_system:get_env_i_i4_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_i_i4_

  subroutine get_env_i_i8_ (name, value)

    character(*), intent(in) :: name
    integer(I8), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 148 <core_system:get_env_i_i8_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_i_i8_

  subroutine get_env_r_sp_ (name, value)

    character(*), intent(in) :: name
    real(SP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 149 <core_system:get_env_r_sp_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_r_sp_

  subroutine get_env_r_dp_ (name, value)

    character(*), intent(in) :: name
    real(DP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 150 <core_system:get_env_r_dp_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_r_dp_

  subroutine get_env_c_sp_ (name, value)

    character(*), intent(in) :: name
    complex(SP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 151 <core_system:get_env_c_sp_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_c_sp_

  subroutine get_env_c_dp_ (name, value)

    character(*), intent(in) :: name
    complex(DP), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 152 <core_system:get_env_c_dp_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_c_dp_

  subroutine get_env_a_ (name, value)

    character(*), intent(in) :: name
    character(*), intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 153 <core_system:get_env_a_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_a_

  subroutine get_env_l_ (name, value)

    character(*), intent(in) :: name
    logical, intent(out) :: value

    integer                   :: buffer_len
    character(:), allocatable :: buffer

    ! Read the environment variable into a character buffer

    call GET_ENVIRONMENT_VARIABLE(name, LENGTH=buffer_len)

    if(.NOT. (buffer_len > 0)) then
      write(UNIT=ERROR_UNIT, FMT=*) 'ASSERT ''buffer_len > 0'' failed at line 154 <core_system:get_env_l_>:'
      write(UNIT=ERROR_UNIT, FMT=*) 'Invalid environment variable'
      stop
    endif

    allocate(character(buffer_len)::buffer)

    call GET_ENVIRONMENT_VARIABLE(name, buffer)

    ! Extract the value from the buffer

    read(buffer, *) value

    ! Finish

    return

  end subroutine get_env_l_

end module core_system
