! -*- coding: utf-8; mode: f90 -*-
!==   sysdep.f90 - module providing interface for system dependent procedures
!
! Authors::   Youhei SASAKI, Eizi TOYODA, Yasuhiro MORIKAWA
! Copyright:: Copyright (C) GFD Dennou Club, 2000-2017. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
! This file provides sysdep
!

module sysdep
  !
  != module providing interface for system dependent procedures
  !
  ! ã“ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯ã‚·ã‚¹ãƒ†ãƒ ã«ä¾å˜ã™ã‚‹æ‰‹ç¶šãã«é–¢ã™ã‚‹
  ! ã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹ã‚’æä¾›ã—ã¾ã™ã€‚
  ! è¨€ã„æ›ãˆã‚‹ã¨ã€ã“ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã§ã¯ã‚·ã‚¹ãƒ†ãƒ ã«ä¾å˜ã™ã‚‹ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³ã¨é–¢æ•°ã®
  ! ã‚¤ãƒ³ã‚¿ãƒ•ã‚§ãƒ¼ã‚¹å®£è¨€ãŒãªã•ã‚Œã¦ã„ã¾ã™ã€‚
  ! ã“ã‚Œã‚‰ã®æ‰‹ç¶šãã¯å¯¾å¿œã™ã‚‹åå‰ãŒã¤ã„ãŸãƒ•ã‚¡ã‚¤ãƒ«å†…ã«ãŠã„ã¦å®Ÿè£…ã•ã‚Œã¦ã„ã¾ã™
  ! (ã™ãªã‚ã¡ <tt>sysdep</tt> ã§å§‹ã¾ã‚‹åå‰ã®ãƒ•ã‚¡ã‚¤ãƒ«ç¾¤ã«ãŠã„ã¦ã€ã§ã™)ã€‚
  !
  ! å¾“ã£ã¦ã€ã‚ã‚‹åå‰ã®æ‰‹ç¶šããŒã‚ã£ãŸã¨ã—ã¦ã€ãã®æ‰‹ç¶šãã®å®Ÿè£…ã¯å®Ÿéš›ã«ã¯
  ! è¤‡æ•°ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ãŠã„ã¦è¡Œã‚ã‚Œã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ã®ã§æ°—ã‚’ã¤ã‘ã¦ãã ã•ã„ã€‚
  !
  ! ã“ã® sysdep ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯ä»–ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã«ä¾å˜ã—ã¾ã›ã‚“ã€‚
  !
  !
  ! It provides interface for system dependent procedures.
  ! In other words, there is interface declaration of a function and
  ! subroutines whose feature is regarded as system dependent.
  ! Implementation of these procedures are given in files with
  ! corresponding name (i.e. that begins with <tt>sysdep</tt>-).
  !
  ! Note that a procedure with one name may have several implementations.
  !
  ! The sysdep has no dependence to other modules.
  !
  use, intrinsic :: ISO_C_BINDING
  implicit none
  private
  public :: AbortProgram
  public :: SysdepArgGet
  public :: SysdepArgCount
  public :: SysdepEnvGet

  interface
    subroutine dc_f_abort() &
      ! bind(C, name="dc_c_abort")
      bind(C, name="abort")
      import
    end subroutine dc_f_abort
  end interface

contains

  subroutine AbortProgram(message)
    use dc_types, only: STDERR
    implicit none
    character(len=*), intent(in), optional :: message
    continue
    if (present(message)) write(STDERR, *) trim(message)
    call dc_f_abort()
  end subroutine AbortProgram

  integer function SysdepArgCount()
    implicit none
    SysdepArgCount = COMMAND_ARGUMENT_COUNT()
  end function SysdepArgCount

  subroutine SysdepArgGet(index, val)
    implicit none
    integer,            intent(in)  :: index
    character(len = *), intent(out) :: val
    !
    integer:: idx
    integer:: argc
    continue
    argc = SysdepArgCount()
    if (index < 0) then
      idx = argc + 1 + index
    else
      idx = index
    endif
    if (idx > argc) then
      val = ''
    else
      call GET_COMMAND_ARGUMENT(index, val)
    end if
  end subroutine SysdepArgGet

  subroutine SysdepEnvGet(env, str)
    character(len = *), intent(in)  :: env
    character(len = *), intent(out) :: str
    call GET_ENVIRONMENT_VARIABLE(trim(adjustl(env)), str)
  end subroutine SysdepEnvGet

end module sysdep