! -*- mode: f90; coding: utf-8 -*-
!-----------------------------------------------------------------------
! Copyright (c) 2000-2017 Gtool Development Group. All rights reserved.
!-----------------------------------------------------------------------
!>
!> @author    Youhei SASAKI, Yasuhiro MORIKAWA, Eizi TOYODA
!> @copyright Copyright (C) GFD Dennou Club, 2000-2017. All rights reserved. <br/>
!>            License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
!
! This file is generated from dc_string.erb by ERB included Ruby 2.3.3.
! Please do not edit this file directly.
!>
!> @en
!> @brief Handling character types
!> @details
!> This module provides subrouteins handle character type variables.
!> @enden
!> @ja
!> @brief æ–‡å—åž‹å¤‰æ•°ã®æ“ä½œ.
!> @details
!> æœ¬ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã¯æ–‡å—åˆ—ã‚’æ“ä½œã™ã‚‹ãŸã‚ã®ã‚µãƒ–ãƒ«ãƒ¼ãƒãƒ³ç¾¤ã‚’æä¾›ã—ã¾ã™.
!> @endja
!
module dc_string
  use dc_types, only: TOKEN, STRING, DP
  implicit none
  private

  public :: StoI
  public :: StoD
  public :: get_array
  public :: Str_to_Logical
  public :: toChar
  public :: RoundNum
  public :: JoinChar
  public :: Concat
  public :: StoA
  public :: Split
  public :: Index_Ofs
  public :: Replace
  public :: toUpper
  public :: toLower
  public :: UChar
  public :: LChar
  public :: StriEq
  public :: StrHead
  public :: StrInclude
  ! public :: GTStringQuoteForDcl
  public :: CPrintf
  public :: Printf
  public :: PutLine

  interface StoI
    module procedure atoi_scalar
  end interface StoI

  interface StoD
    module procedure atod_scalar
  end interface StoD

  interface get_array
    module procedure str2ip
    module procedure str2rp
    module procedure str2dp
  end interface get_array

  interface Str_to_Logical
    module procedure str2bool
  end interface Str_to_Logical

  !-------------------------------------
  !  æ•°å€¤ã‹ã‚‰æ–‡å—ã¸ã®å¤‰æ›
  interface toChar
    module procedure itoa_scalar
    module procedure itoa_array
    module procedure rtoa_scalar
    module procedure rtoa_array
    module procedure dtoa_scalar
    module procedure dtoa_array
    module procedure ltoa_scalar
    module procedure ltoa_array
  end interface toChar

  !-------------------------------------
  !  æ•°å€¤è¡¨è¨˜ã®æ–‡å—åˆ—ã®ç«¯æ•°é™¤åŽ»
  interface RoundNum
    module procedure RoundNum
  end interface RoundNum

  !-------------------------------------
  !  æ–‡å—åž‹é…åˆ—ã®é€£çµ

  !-------------------------------------
  !  æ–‡å—åž‹é…åˆ—ã®æœ«å°¾ã«æ–‡å—ã‚’é€£çµ
  interface Concat
    module procedure concat_tail
  end interface Concat

  !-------------------------------------
  !  é•·ã•ã®ç•°ãªã‚‹æ–‡å—ç¾¤ã®é…åˆ—åŒ–
  interface StoA
    module procedure Str_to_Array1
    module procedure Str_to_Array2
    module procedure Str_to_Array3
    module procedure Str_to_Array4
    module procedure Str_to_Array5
    module procedure Str_to_Array6
    module procedure Str_to_Array7
    module procedure Str_to_Array8
    module procedure Str_to_Array9
    module procedure Str_to_Array10
    module procedure Str_to_Array11
    module procedure Str_to_Array12
  end interface StoA

  !-------------------------------------
  !  æ–‡å—åˆ—ã®åˆ†è§£
  interface Split
    module procedure Split_CC
  end interface Split

  !-------------------------------------
  !  æ–‡å—åˆ—ã®è§£æž
  interface Index_Ofs
    module procedure Index_Ofs
  end interface Index_Ofs

  interface Replace
    module procedure Replace
  end interface Replace

  !-------------------------------------
  !  å¤§æ–‡å—ãƒ»å°æ–‡å—ã‚’ç„¡è¦–ã—ãŸå‡¦ç†
  interface toUpper
    module procedure cupper
  end interface toUpper

  interface toLower
    module procedure clower
  end interface toLower

  interface UChar
    module procedure UChar
  end interface UChar

  interface LChar
    module procedure LChar
  end interface LChar

  interface StriEq
    module procedure StriEq_cc
  end interface StriEq

  interface StrHead
    module procedure strhead_cc
  end interface StrHead

  interface StrInclude
    module procedure str_include_ac
  end interface StrInclude

  !-------------------------------------
  !  å°å—ã®ãŸã‚ã®æ–‡å—å‡¦ç†
  ! interface
  !   function GTStringQuoteForDcl(string) result(result)
  !     use dc_types, only: STRLEN => STRING
  !     character(*), intent(in):: string
  !     character(STRLEN):: result
  !   end function GTStringQuoteForDcl
  ! end interface

  interface CPrintf
    function DCStringCPrintf(fmt, i, r, d, L, n, c1, c2, c3, ca) result(result)
      use dc_types, only: STRING, DP
      character(len = STRING):: result
      character(*), intent(in):: fmt
      integer, intent(in), optional:: i(:), n(:)
      real, intent(in), optional:: r(:)
      real(DP), intent(in), optional:: d(:)
      logical, intent(in), optional:: L(:)
      character(*), intent(in), optional:: c1, c2, c3
      character(*), intent(in), optional:: ca(:)
    end function DCStringCPrintf
  end interface CPrintf

  interface Printf
    subroutine DCStringSPrintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
      use dc_types, only: DP
      character(*), intent(out):: unit
      character(*), intent(in):: fmt
      integer, intent(in), optional:: i(:), n(:)
      real, intent(in), optional:: r(:)
      real(DP), intent(in), optional:: d(:)
      logical, intent(in), optional:: L(:)
      character(*), intent(in), optional:: c1, c2, c3
      character(*), intent(in), optional:: ca(:)
    end subroutine DCStringSPrintf

    subroutine DCStringFPrintf(unit, fmt, i, r, d, L, n, c1, c2, c3, ca)
      use dc_types, only: DP
      integer, intent(in), optional:: unit
      character(*), intent(in):: fmt
      integer, intent(in), optional:: i(:), n(:)
      real, intent(in), optional:: r(:)
      real(DP), intent(in), optional:: d(:)
      logical, intent(in), optional:: L(:)
      character(*), intent(in), optional:: c1, c2, c3
      character(*), intent(in), optional:: ca(:)
    end subroutine DCStringFPrintf

  end interface Printf

  !-------------------------------------
  !  æ•°å€¤åž‹é…åˆ—ã®è¦ç´„å°å—
  interface PutLine
    subroutine PutLineInt1( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:)
        integer, intent(in), optional:: lbounds(1)
        integer, intent(in), optional:: ubounds(1)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt1
    subroutine PutLineInt2( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:)
        integer, intent(in), optional:: lbounds(2)
        integer, intent(in), optional:: ubounds(2)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt2
    subroutine PutLineInt3( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:,:)
        integer, intent(in), optional:: lbounds(3)
        integer, intent(in), optional:: ubounds(3)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt3
    subroutine PutLineInt4( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:,:,:)
        integer, intent(in), optional:: lbounds(4)
        integer, intent(in), optional:: ubounds(4)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt4
    subroutine PutLineInt5( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:,:,:,:)
        integer, intent(in), optional:: lbounds(5)
        integer, intent(in), optional:: ubounds(5)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt5
    subroutine PutLineInt6( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(6)
        integer, intent(in), optional:: ubounds(6)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt6
    subroutine PutLineInt7( array, lbounds, ubounds, unit, indent, sd  )
        integer, intent(in):: array(:,:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(7)
        integer, intent(in), optional:: ubounds(7)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineInt7
    subroutine PutLineReal1( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:)
        integer, intent(in), optional:: lbounds(1)
        integer, intent(in), optional:: ubounds(1)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal1
    subroutine PutLineReal2( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:)
        integer, intent(in), optional:: lbounds(2)
        integer, intent(in), optional:: ubounds(2)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal2
    subroutine PutLineReal3( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:,:)
        integer, intent(in), optional:: lbounds(3)
        integer, intent(in), optional:: ubounds(3)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal3
    subroutine PutLineReal4( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:,:,:)
        integer, intent(in), optional:: lbounds(4)
        integer, intent(in), optional:: ubounds(4)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal4
    subroutine PutLineReal5( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:,:,:,:)
        integer, intent(in), optional:: lbounds(5)
        integer, intent(in), optional:: ubounds(5)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal5
    subroutine PutLineReal6( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(6)
        integer, intent(in), optional:: ubounds(6)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal6
    subroutine PutLineReal7( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: SP
        real(SP), intent(in):: array(:,:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(7)
        integer, intent(in), optional:: ubounds(7)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineReal7
    subroutine PutLineDouble1( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:)
        integer, intent(in), optional:: lbounds(1)
        integer, intent(in), optional:: ubounds(1)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble1
    subroutine PutLineDouble2( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:)
        integer, intent(in), optional:: lbounds(2)
        integer, intent(in), optional:: ubounds(2)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble2
    subroutine PutLineDouble3( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:,:)
        integer, intent(in), optional:: lbounds(3)
        integer, intent(in), optional:: ubounds(3)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble3
    subroutine PutLineDouble4( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:,:,:)
        integer, intent(in), optional:: lbounds(4)
        integer, intent(in), optional:: ubounds(4)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble4
    subroutine PutLineDouble5( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:,:,:,:)
        integer, intent(in), optional:: lbounds(5)
        integer, intent(in), optional:: ubounds(5)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble5
    subroutine PutLineDouble6( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(6)
        integer, intent(in), optional:: ubounds(6)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble6
    subroutine PutLineDouble7( array, lbounds, ubounds, unit, indent, sd  )
        use dc_types, only: DP
        real(DP), intent(in):: array(:,:,:,:,:,:,:)
        integer, intent(in), optional:: lbounds(7)
        integer, intent(in), optional:: ubounds(7)
        integer, intent(in), optional:: unit
        character(*), intent(in), optional:: indent
        logical, intent(in), optional:: sd
    end subroutine PutLineDouble7
  end interface PutLine

contains
  logical function strhead_cc(whole, head) result(result)
    !
    ! æ–‡å—åˆ— head ã¨æ–‡å—åˆ— whole ã®å…ˆé éƒ¨åˆ† (head ã¨åŒã˜æ–‡å—åˆ—é•·)
    ! ã¨ã‚’æ¯”è¼ƒã—ã€åŒã˜ã‚‚ã®ãªã‚‰ã° .true. ã‚’ã€ç•°ãªã‚‹å ´åˆã«ã¯ .false.
    ! ã‚’è¿”ã—ã¾ã™ã€‚ whole ã®æ–‡å—åˆ—é•·ãŒ head ã®æ–‡å—åˆ—é•·ã‚ˆã‚Šã‚‚çŸã„å ´åˆã«ã¯
    ! .false. ã‚’è¿”ã—ã¾ã™ã€‚
    !
    character(len = *), intent(in):: whole
    character(len = *), intent(in):: head

    continue

    result = (len(whole) >= len(head))
    if (.not. result) return
    result = (whole(1:len(head)) == head)

  end function strhead_cc

  logical function StriEq_cc(string_a, string_b) result(result)
    !
    ! å¤§æ–‡å—ãƒ»å°æ–‡å—ã‚’ç„¡è¦–ã—ã¦æ–‡å—åˆ—ã®æ¯”è¼ƒã‚’è¡Œã„ã¾ã™ã€‚
    ! æ–‡å—åˆ— string_a ã¨æ–‡å—åˆ— string_b ã‚’æ¯”è¼ƒã—ã€åŒã˜ã‚‚ã®ãªã‚‰ã°
    ! .true. ã‚’ã€ç•°ãªã‚‹å ´åˆã«ã¯ .false. ã‚’è¿”ã—ã¾ã™ã€‚
    !
    !--
    ! â€» æ³¨æ„æ›¸ã â€»
    !
    ! ã‚³ãƒ³ãƒ‘ã‚¤ãƒ©ã«ã‚ˆã£ã¦ã¯ character(len = len(string_a)):: abuf
    ! ãŒé€šã‚‰ãªã„ãŸã‚, æ–‡å—æ•°ã‚’ dc_types ã§æä¾›ã•ã‚Œã‚‹ç¨®åˆ¥åž‹
    ! ãƒ‘ãƒ©ãƒ¡ã‚¿ STRING ã§åˆ¶é™
    !++
    !
    character(len = *), intent(in):: string_a
    character(len = *), intent(in):: string_b
    character(len = STRING):: abuf
    character(len = STRING):: bbuf
    abuf = string_a
    bbuf = string_b
    call toUpper(abuf)
    call toUpper(bbuf)
    result = (abuf == bbuf)
  end function StriEq_cc

  logical function str_include_ac( &
    & carray, string, ignore_space, ignore_case ) result(result)
    !
    ! æ–‡å—åž‹é…åˆ—å¼•æ•° *carray* ãŒæ–‡å—åž‹å¼•æ•° *string* ã¨ç‰ã—ã„è¦ç´ ã‚’æŒã¤å ´åˆã«
    ! .true. ã‚’è¿”ã—ã¾ã™.
    !
    ! æ–‡å—åˆ—ã®å‰å¾Œã®ç©ºç™½ã¯ç„¡è¦–ã•ã‚Œã¾ã™.
    ! ã‚ªãƒ—ã‚·ãƒ§ãƒŠãƒ«å¼•æ•° *ignore_space* ã« .false. ã‚’
    ! ä¸ŽãˆãŸå ´åˆã«ã¯æ–‡å—åˆ—å…ˆé ã®ç©ºç™½ã‚’ç„¡è¦–ã—ã¾ã›ã‚“.
    !
    ! ã‚ªãƒ—ã‚·ãƒ§ãƒŠãƒ«å¼•æ•° *ignore_case* ã« .true. ã‚’ä¸ŽãˆãŸå ´åˆã«ã¯
    ! å¤§æ–‡å—, å°æ–‡å—ã®é•ã„ã‚’ç„¡è¦–ã—ã¦æ¯”è¼ƒã—ã¾ã™.
    !
    ! If an character array argument *carray* has the same
    ! as character argument *string*, ".true." is returned.
    !
    ! And beginning and trailing spaces are ignored.
    ! If ".false." is given to an optional argument *ignore_space*,
    ! beginning spaces are not ignored.
    !
    ! If ".true." is given to an optional argument *ignore_case*,
    ! this function ignores case.
    !
    character(*), intent(in):: carray(:)
    character(*), intent(in):: string
    logical, intent(in), optional:: ignore_space
    logical, intent(in), optional:: ignore_case
    integer:: array_size, i
    logical:: ignore_space_work, ignore_case_work

    continue

    ignore_space_work = .true.
    if ( present(ignore_space) ) then
      if ( .not. ignore_space ) then
        ignore_space_work = .false.
      end if
    end if

    ignore_case_work = .false.
    if ( present(ignore_case) ) then
      if ( ignore_case ) then
        ignore_case_work = .true.
      end if
    end if

    array_size = size(carray)
    do i = 1, array_size
      if ( ignore_space_work ) then
        if ( ignore_case_work ) then
          result = &
            & StriEq_cc( trim( adjustl( carray(i) ) ), &
            &            trim( adjustl( string    ) ) )
        else
          result = &
            & ( trim( adjustl( carray(i) ) ) == trim( adjustl( string ) ) )
        end if

      else
        if ( ignore_case_work ) then
          result = &
            & StriEq_cc( trim( carray(i) ), trim( string ) )
        else
          result = ( trim(carray(i)) == trim(string) )
        end if
      end if
      if (result) return
    end do
  end function str_include_ac

  logical function str2bool(string) result(result)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’è«–ç†åž‹ã«ã—ã¦è¿”ã—ã¾ã™ã€‚ string
    ! ãŒç©ºã€ ã¾ãŸã¯ 0ã€ 0.0ã€ 0.0D0ã€ 0.0d0ã€ .false.ã€ .FALSE.ã€ fã€
    ! Fã€ falseã€ FALSE ã®å ´åˆã«ã¯ <tt>.false.</tt> ãŒè¿”ã‚Šã¾ã™ã€‚
    ! ãã‚Œä»¥å¤–ã®å ´åˆã«ã¯ <tt>.true.</tt> ãŒè¿”ã‚Šã¾ã™ã€‚
    !
    character(len = *), intent(in):: string

    continue

    select case(string)
    case ("", "0", "0.0", "0.0D0", "0.0d0", ".false.", ".FALSE.", &
            & "f", "F", "false", "FALSE")
      result = .false.
    case default
      result = .true.
    end select
  end function str2bool

  integer function atoi_scalar(string, default) result(result)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’ã€æ•´æ•°åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! ã‚‚ã—ã‚‚ string ãŒæ•°å€¤ã«å¤‰æ›ã§ããªã„å ´åˆã€default ãŒè¿”ã‚Šã¾ã™ã€‚
    ! default ã‚’æŒ‡å®šã—ãªã„å ´åˆã¯ 0 ãŒè¿”ã‚Šã¾ã™ã€‚
    !
    character(len = *), intent(in):: string
    integer, intent(in), optional:: default
    integer:: ios

    continue

    read(unit=string, fmt="(i80)", iostat=ios) result
    if (ios /= 0) then
      if (present(default)) then
        result = default
      else
        result = 0
      endif
    endif
  end function atoi_scalar

  real(DP) function atod_scalar(string_in) result(result)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’ã€å€ç²¾åº¦å®Ÿæ•°åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! ã‚‚ã—ã‚‚ string ãŒæ•°å€¤ã«å¤‰æ›ã§ããªã„å ´åˆã€0.0 ãŒè¿”ã‚Šã¾ã™ã€‚
    !
    use dc_types, only: STRING
    character(len = *), intent(in):: string_in
    integer:: ios
    character(len = STRING):: buffer
    integer:: ipoint, iexp
    intrinsic scan

    continue

    buffer = string_in
    ! ã‚‚ã—æ•´å®šæ•°ã‚’ã„ã‚Œã¦ã—ã¾ã£ãŸå ´åˆã¯å°æ•°ç‚¹ã‚’é™„åŠ
    if (index(buffer, '.') == 0) then
      iexp = scan(buffer, "eEdD")
      if (iexp /= 0) then
        buffer(iexp+1: len(buffer)) = buffer(iexp: len(buffer)-1)
        ipoint = iexp
      else
        ipoint = len_trim(buffer) + 1
      endif
      buffer(ipoint: ipoint) = '.'
    endif
    read(unit=buffer, fmt="(g80.10)", iostat=ios) result
    if (ios /= 0) result = 0.0
  end function atod_scalar

  subroutine str2ip(int_ptr, string_in)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’ã‚«ãƒ³ãƒžã€Œ,ã€ã§åŒºåˆ‡ã‚Šã€
    ! æ•´æ•°åž‹é…åˆ—ãƒã‚¤ãƒ³ã‚¿ int_ptr(:) ã«ã—ã¦è¿”ã—ã¾ã™ã€‚ int_ptr(:)
    ! ã®é…åˆ—ã‚µã‚¤ã‚ºã¯ string ã®å†…å®¹ã«å¿œã˜ã¦è‡ªå‹•çš„ã«æ±ºã¾ã‚Šã¾ã™ã€‚
    !
    ! ãŸã ã—ã€int_ptr(:) ã¯å¿…ãšç©ºçŠ¶æ…‹ã¾ãŸã¯ä¸å®šçŠ¶æ…‹ã§ä¸Žãˆã¦ãã ã•ã„ã€‚
    ! æ—¢ã«å‰²ã‚Šä»˜ã‘ã‚‰ã‚Œã¦ã„ã‚‹å ´åˆã€ãƒ¡ãƒ¢ãƒªãƒªãƒ¼ã‚¯ã‚’èµ·ã“ã—ã¾ã™ã€‚
    !
    integer, pointer:: int_ptr(:) !(out)
    character(len = *), intent(in):: string_in
    integer:: i, j, idx, nvalues
  continue
    nvalues = 1
    i = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) exit
      i = i + idx - 1 + 1
      nvalues = nvalues + 1
    enddo
    allocate(int_ptr(nvalues))
    i = 1
    j = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) then
        int_ptr(j) = stoi(string_in(i: ))
        exit
      endif
      int_ptr(j) = stod(string_in(i: i+idx-2))
      i = i + idx - 1 + 1
      j = j + 1
    enddo
  end subroutine str2ip

  subroutine str2rp(real_ptr, string_in)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’ã‚«ãƒ³ãƒžã€Œ,ã€ã§åŒºåˆ‡ã‚Šã€
    ! å˜ç²¾åº¦å®Ÿæ•°åž‹é…åˆ—ãƒã‚¤ãƒ³ã‚¿ real_ptr(:) ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! real_ptr(:) ã®é…åˆ—ã‚µã‚¤ã‚ºã¯ string ã®å†…å®¹ã«å¿œã˜ã¦è‡ªå‹•çš„ã«æ±ºã¾ã‚Šã¾ã™ã€‚
    !
    ! ãŸã ã—ã€real_ptr(:) ã¯å¿…ãšç©ºçŠ¶æ…‹ã¾ãŸã¯ä¸å®šçŠ¶æ…‹ã§ä¸Žãˆã¦ãã ã•ã„ã€‚
    ! æ—¢ã«å‰²ã‚Šä»˜ã‘ã‚‰ã‚Œã¦ã„ã‚‹å ´åˆã€ãƒ¡ãƒ¢ãƒªãƒªãƒ¼ã‚¯ã‚’èµ·ã“ã—ã¾ã™ã€‚
    !
    real, pointer:: real_ptr(:) !(out)
    character(len = *), intent(in):: string_in
    integer:: i, j, idx, nvalues
  continue
    nvalues = 1
    i = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) exit
      i = i + idx - 1 + 1
      nvalues = nvalues + 1
    enddo
    allocate(real_ptr(nvalues))
    i = 1
    j = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) then
        real_ptr(j) = stod(string_in(i: ))
        exit
      endif
      real_ptr(j) = stod(string_in(i: i+idx-2))
      i = i + idx - 1 + 1
      j = j + 1
    enddo
  end subroutine str2rp

  subroutine str2dp(real_ptr, string_in)
    !
    ! string ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ–‡å—åž‹å¤‰æ•°ã‚’ã‚«ãƒ³ãƒžã€Œ,ã€ã§åŒºåˆ‡ã‚Šã€
    ! å€ç²¾åº¦å®Ÿæ•°åž‹é…åˆ—ãƒã‚¤ãƒ³ã‚¿ real_ptr(:) ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! real_ptr(:) ã®é…åˆ—ã‚µã‚¤ã‚ºã¯ string ã®å†…å®¹ã«å¿œã˜ã¦è‡ªå‹•çš„ã«æ±ºã¾ã‚Šã¾ã™ã€‚
    !
    ! ãŸã ã—ã€real_ptr(:) ã¯å¿…ãšç©ºçŠ¶æ…‹ã¾ãŸã¯ä¸å®šçŠ¶æ…‹ã§ä¸Žãˆã¦ãã ã•ã„ã€‚
    ! æ—¢ã«å‰²ã‚Šä»˜ã‘ã‚‰ã‚Œã¦ã„ã‚‹å ´åˆã€ãƒ¡ãƒ¢ãƒªãƒªãƒ¼ã‚¯ã‚’èµ·ã“ã—ã¾ã™ã€‚
    !
    real(DP), pointer:: real_ptr(:) !(out)
    character(len = *), intent(in):: string_in
    integer:: i, j, idx, nvalues
  continue
    nvalues = 1
    i = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) exit
      i = i + idx - 1 + 1
      nvalues = nvalues + 1
    enddo
    allocate(real_ptr(nvalues))
    i = 1
    j = 1
    do
      idx = index(string_in(i: ), ',')
      if (idx == 0) then
        real_ptr(j) = stod(string_in(i: ))
        exit
      endif
      real_ptr(j) = stod(string_in(i: i+idx-2))
      i = i + idx - 1 + 1
      j = j + 1
    enddo
  end subroutine str2dp

  !== æ•°å€¤åž‹ã€è«–ç†åž‹ã‹ã‚‰æ–‡å—åž‹ã¸ã®å¤‰æ›
  !
  ! ç·ç§°åç§° toChar ã¨ã—ã¦å‘¼ã³å‡ºã•ã‚Œã‚‹é–¢æ•°ç¾¤
  !
  character(TOKEN) function itoa_scalar(i) result(result)
    !
    ! æ•´æ•°åž‹å¤‰æ•° i ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    integer, intent(in):: i
    character(len = 32):: buffer
  continue
    write(unit=buffer, fmt="(i20)") i
    result = adjustl(buffer)
  end function itoa_scalar

  character(STRING) function itoa_array(ibuf) result(result)
    !
    ! æ•´æ•°åž‹é…åˆ—å¤‰æ•° ibuf(:) ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    integer, intent(in):: ibuf(:)
    integer:: i
  continue
    if (size(ibuf) <= 0) then
      result = ""
      return
    endif
    result = toChar(ibuf(1))
    do, i = 2, size(ibuf)
      result = trim(result) // ", " // trim(toChar(ibuf(i)))
    enddo
  end function itoa_array

  character(TOKEN) function rtoa_scalar(x) result(result)
    !
    ! å˜ç²¾åº¦å®Ÿæ•°åž‹å¤‰æ•° x ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    real, intent(in):: x
    character(len = 16):: buffer, expbuf
    integer:: ptr, eptr
  continue
    write(unit=buffer, fmt="(g16.8)") x
    eptr = scan(buffer, "eE", back=.true.)
    expbuf = ''
    if (eptr > 1) then
      expbuf = buffer(eptr: )
      buffer(eptr: ) = " "
    end if

    ptr = verify(buffer, " 0", back=.true.)
    if (ptr > 0) buffer(ptr+1: ) = " "

    if (eptr > 1) then
      buffer = buffer(1:len_trim(buffer)) // expbuf
    end if
    result = adjustl(buffer)
  end function rtoa_scalar

  character(STRING) function rtoa_array(rbuf) result(result)
    !
    ! å˜ç²¾åº¦å®Ÿæ•°åž‹é…åˆ— rbuf(:)ã€ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    real, intent(in):: rbuf(:)
    integer:: i
  continue
    if (size(rbuf) <= 0) then
      result = ""
      return
    endif
    result = toChar(rbuf(1))
    do, i = 2, size(rbuf)
      result = trim(result) // ", " // trim(toChar(rbuf(i)))
    enddo
  end function rtoa_array

  character(TOKEN) function dtoa_scalar(d) result(result)
    !
    ! å€ç²¾åº¦å®Ÿæ•°åž‹å¤‰æ•° d ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    real(DP), intent(in):: d
    character(len = 32):: buffer, expbuf
    integer:: ptr, eptr
  continue
    write(unit=buffer, fmt="(g32.24)") d
    eptr = scan(buffer, "eE", back=.true.)
    expbuf = ''
    if (eptr > 1) then
      expbuf = buffer(eptr: )
      buffer(eptr: ) = " "
    end if

    ptr = verify(buffer, " 0", back=.true.)
    if (ptr > 0) buffer(ptr+1: ) = " "

    if (eptr > 1) then
      buffer = buffer(1:len_trim(buffer)) // expbuf
    end if
    result = adjustl(buffer)
  end function dtoa_scalar

  character(STRING) function dtoa_array(dbuf) result(result)
    !
    ! å€ç²¾åº¦å®Ÿæ•°åž‹é…åˆ— dbuf(:) ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    real(DP), intent(in):: dbuf(:)
    integer:: i
  continue
    if (size(dbuf) <= 0) then
      result = ""
      return
    endif
    result = toChar(dbuf(1))
    do, i = 2, size(dbuf)
      result = trim(result) // ", " // trim(toChar(dbuf(i)))
    enddo
  end function dtoa_array

  character(TOKEN) function ltoa_scalar(l) result(result)
    !
    ! è«–ç†åž‹å¤‰æ•° l ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    logical, intent(in):: l
  continue
    if (l) then
      result = ".true."
    else
      result = ".false."
    end if
  end function ltoa_scalar

  character(STRING) function ltoa_array(lbuf) result(result)
    !
    ! è«–ç†åž‹é…åˆ— lbuf(:) ã§ä¸Žãˆã‚‰ã‚Œã‚‹æ•°å€¤ã‚’æ–‡å—åž‹å¤‰æ•°ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! é…åˆ—ãŒä¸Žãˆã‚‰ã‚Œã‚‹å ´åˆã€å„è¦ç´ ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½ã€Œ<tt>, </tt>ã€
    ! ã§åŒºåˆ‡ã£ã¦è¿”ã—ã¾ã™ã€‚
    !
    logical, intent(in):: lbuf(:)
    integer:: i
  continue
    if (size(lbuf) <= 0) then
      result = ""
      return
    endif
    result = toChar(lbuf(1))
    do, i = 2, size(lbuf)
      result = trim(result) // ", " // trim(toChar(lbuf(i)))
    enddo
  end function ltoa_array

  !-------------------------------------------------------------------
  !  æ–‡å—é…åˆ—ã®é€£çµ
  !-------------------------------------------------------------------

  character(STRING) function JoinChar(carray, expr) result(result)
    !
    ! æ–‡å—åž‹é…åˆ— carray ã«ä¸ŽãˆãŸè¤‡æ•°ã®æ–‡å—åˆ—ã‚’ã‚«ãƒ³ãƒžã¨ç©ºç™½
    ! ã€Œ<tt>, </tt>ã€ ã§åŒºåˆ‡ã£ãŸ1ã¤ã®æ–‡å—åˆ—ã«ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! expr ã«æ–‡å—åˆ—ã‚’ä¸Žãˆã‚‹ã¨ã€ãã®æ–‡å—åˆ—ã‚’åŒºåˆ‡ã‚Šæ–‡å—ã¨ã—ã¦ç”¨ã„ã¾ã™ã€‚
    !
    implicit none
    character(*)     , intent(in)           :: carray(:)
    character(*)     , intent(in), optional :: expr

    character(2)     ,parameter :: default = ', '
    character(STRING)           :: delimiter
    integer                     :: dellen, i
  continue
    if ( present(expr) ) then
      delimiter = expr
      dellen = len(expr)
    else
      delimiter = default
      dellen = len(default)
    endif
    if (size(carray) <= 0) then
      result = ""
      return
    endif
    result = trim(carray(1))
    do, i = 2, size(carray)
      result = trim(result) // delimiter(1:dellen) // trim(carray(i))
    enddo
  end function JoinChar

  subroutine concat_tail(carray, str, result)
    !
    ! æ–‡å—åž‹é…åˆ— *carray* ã®å„æˆåˆ†ã®æœ«å°¾ã« *str* ã‚’è¿½åŠ ã—ã¦
    ! *result* ã«è¿”ã—ã¾ã™ã€‚*carray* ã®å„æˆåˆ†ã®æœ«å°¾ã®ç©ºç™½ã¯ç„¡è¦–ã•ã‚Œã¾ã™ã€‚
    !
    ! result(:) ã®é…åˆ—ã‚µã‚¤ã‚ºã¯ carray ã®ã‚µã‚¤ã‚ºã«å¿œã˜ã¦è‡ªå‹•çš„ã«æ±ºã¾ã‚Šã¾ã™ã€‚
    ! ãŸã ã—ã€result(:) ã¯å¿…ãšç©ºçŠ¶æ…‹ã¾ãŸã¯ä¸å®šçŠ¶æ…‹ã§ä¸Žãˆã¦ãã ã•ã„ã€‚
    ! æ—¢ã«å‰²ã‚Šä»˜ã‘ã‚‰ã‚Œã¦ã„ã‚‹å ´åˆã€ãƒ¡ãƒ¢ãƒªãƒªãƒ¼ã‚¯ã‚’èµ·ã“ã—ã¾ã™ã€‚
    !
    implicit none
    character(*), intent(in)  :: carray(:)
    character(*), intent(in)  :: str
    character(STRING), pointer:: result(:) ! (out)
    integer                     :: i, size_carray
  continue
    size_carray = size(carray)
    allocate(result(size_carray))

    do i = 1, size_carray
      result(i) = trim(carray(i)) // str
    end do

  end subroutine concat_tail

  function Str_to_Array1(c1) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 1 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1
    character(STRING) :: result(1)

  continue
    result(1) = c1
  end function Str_to_Array1

  function Str_to_Array2(c1,c2) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 2 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2
    character(STRING) :: result(2)

  continue
    result(1) = c1
    result(2) = c2
  end function Str_to_Array2

  function Str_to_Array3(c1,c2,c3) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 3 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3
    character(STRING) :: result(3)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
  end function Str_to_Array3

  function Str_to_Array4(c1,c2,c3,c4) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 4 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4
    character(STRING) :: result(4)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
  end function Str_to_Array4

  function Str_to_Array5(c1,c2,c3,c4,c5) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 5 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5
    character(STRING) :: result(5)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
  end function Str_to_Array5

  function Str_to_Array6(c1,c2,c3,c4,c5,c6) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 6 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6
    character(STRING) :: result(6)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
  end function Str_to_Array6

  function Str_to_Array7(c1,c2,c3,c4,c5,c6,c7) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 7 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7
    character(STRING) :: result(7)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
  end function Str_to_Array7

  function Str_to_Array8(c1,c2,c3,c4,c5,c6,c7,c8) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 8 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8
    character(STRING) :: result(8)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
    result(8) = c8
  end function Str_to_Array8

  function Str_to_Array9(c1,c2,c3,c4,c5,c6,c7,c8,c9) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 9 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9
    character(STRING) :: result(9)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
    result(8) = c8
    result(9) = c9
  end function Str_to_Array9

  function Str_to_Array10(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 10 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10
    character(STRING) :: result(10)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
    result(8) = c8
    result(9) = c9
    result(10) = c10
  end function Str_to_Array10

  function Str_to_Array11(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 11 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11
    character(STRING) :: result(11)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
    result(8) = c8
    result(9) = c9
    result(10) = c10
    result(11) = c11
  end function Str_to_Array11

  function Str_to_Array12(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12) result(result)
    !
    ! ç•°ãªã‚‹é•·ã•ã®è¤‡æ•°ã®æ–‡å—åž‹å¤‰æ•°ã‚’ 1 ã¤ã®æ–‡å—åž‹é…åˆ—ã«å¤‰æ›ã—ã¾ã™ã€‚
    !
    ! 1 ã‹ã‚‰ 12 å€‹ã¾ã§ã®å¼•æ•°ã‚’ä¸Žãˆã‚‹ã“ã¨ãŒå¯èƒ½ã§ã™ã€‚
    !
    character(*), intent(in) :: c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12
    character(STRING) :: result(12)

  continue
    result(1) = c1
    result(2) = c2
    result(3) = c3
    result(4) = c4
    result(5) = c5
    result(6) = c6
    result(7) = c7
    result(8) = c8
    result(9) = c9
    result(10) = c10
    result(11) = c11
    result(12) = c12
  end function Str_to_Array12

  !-------------------------------------------------------------------
  !  æ–‡å—åˆ—ã®åˆ†è§£
  !-------------------------------------------------------------------

  subroutine Split_CC(str, carray, sep, limit)
    !
    ! *str* ã§ä¸Žãˆã‚‰ã‚ŒãŸæ–‡å—åˆ—ã‚’ æ–‡å—åˆ— *sep* ã§åˆ†è§£ã—,
    ! ãƒã‚¤ãƒ³ã‚¿é…åˆ— *carray* ã«è¿”ã—ã¾ã™.
    ! *carray* ã¯å¿…ãšç©ºçŠ¶æ…‹ã«ã—ã¦ä¸Žãˆã¦ãã ã•ã„. å‰²ã‚Šä»˜ã‘çŠ¶æ…‹ã®
    ! å ´åˆã«ã¯ã‚¨ãƒ©ãƒ¼ã‚’è¿”ã—ã¾ã™.
    !
    ! *limit* ã«æ£ã®æ•°ã‚’ä¸ŽãˆãŸå ´åˆ, æœ€å¤§ *limit* å€‹ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«åˆ†å‰²
    ! ã—ã¾ã™.  è² ã®æ•°ã‚„ 0 ã®å ´åˆã¯çœç•¥ã—ãŸå ´åˆã¨åŒã˜ã«ãªã‚Šã¾ã™.  *str*
    ! ã®æœ«å°¾ã®ç©ºç™½ã¯é™¤åŽ»ã•ã‚Œã¾ã™.  *sep* ã«ç©ºæ–‡å—ã‚’ä»£å…¥ã™ã‚‹å ´åˆ, ç©ºç™½
    ! æ–‡å—ã§åˆ†å‰²ã•ã‚Œã¾ã™.
    !
    use dc_types, only: STRING
    implicit none
    character(*), intent(in):: str
    character(*), pointer:: carray(:) !(out)
    character(*), intent(in):: sep
    integer, intent(in), optional:: limit
    integer :: num, cur, i, limitnum
    character(STRING) :: substr
    logical :: end_flag
  continue
    if (present(limit)) then
      if (limit > 0) then
        limitnum = limit
      else
        limitnum = 0
      end if
    else
      limitnum = 0
    end if

    if (len(trim(sep)) == 0) then
      num = 1
      substr = str
      ! é‡è¤‡ã—ã¦ç„¡é§„ã ãŒ carray ã‚’ allocate ã™ã‚‹ãŸã‚, ä½•åˆ†å‰²ã™ã‚‹ã‹
      ! èª¿ã¹, num ã«æ ¼ç´ã™ã‚‹.
      do
        cur = index(trim(substr), ' ')
        if (cur == 0) exit
        num = num + 1
        substr = adjustl(substr(cur + len(sep) :len(substr)))
      end do

      if (limitnum /= 0 .and. num > limitnum) num = limitnum
      allocate(carray(num))

      substr = str
      end_flag = .false.
      do i = 1, num
        cur = index(trim(substr), ' ')
        if (cur == 0 .or. i == num) end_flag = .true.
        if (end_flag) then
          carray(i) = substr
          exit
        else
          carray(i) = substr(1:cur - 1)
        end if
        substr = adjustl(substr(cur + len(sep) :len(substr)))
      end do

    else
      num = 1
      substr = str
      ! é‡è¤‡ã—ã¦ç„¡é§„ã ãŒ carray ã‚’ allocate ã™ã‚‹ãŸã‚, ä½•åˆ†å‰²ã™ã‚‹ã‹
      ! èª¿ã¹, num ã«æ ¼ç´ã™ã‚‹.
      do
        cur = index(substr, trim(sep))
        if (cur == 0) exit
        num = num + 1
        substr = substr(cur + len(sep) :len(substr))
      end do

      if (limitnum /= 0 .and. num > limitnum) num = limitnum
      allocate(carray(num))

      substr = str
      end_flag = .false.
      do i = 1, num
        cur = index(substr, trim(sep))
        if (cur == 0 .or. i == num) end_flag = .true.
        if (end_flag) then
          carray(i) = substr
          exit
        else
          carray(i) = substr(1:cur - 1)
        end if
        substr = substr(cur + len(sep) :len(substr))
      end do
    end if

    return

  end subroutine Split_CC

  !-------------------------------------------------------------------
  !  æ–‡å—åˆ—ã®è§£æž
  !-------------------------------------------------------------------

  integer function Index_Ofs(string, start, substr) result(result)
    !
    ! æ–‡å—åˆ— string ã® start æ–‡å—ç›®ä»¥é™ã®æ–‡å—åˆ—ã®ä¸ã« substr
    ! ã®æ–‡å—åˆ—ãŒå«ã¾ã‚Œã¦ã„ã‚‹æ™‚ã€ãã®é–‹å§‹æ–‡å—ä½ç½®ã‚’è¿”ã—ã¾ã™ã€‚
    ! å«ã¾ã‚Œãªã„å ´åˆã¯ 0 ã‚’è¿”ã—ã¾ã™ã€‚
    ! è¿”ã•ã‚Œã‚‹é–‹å§‹æ–‡å—ä½ç½®ã¯æ–‡å—åˆ— string ã®å…ˆé ã‹ã‚‰æ•°ãˆã¾ã™ã€‚
    !
    character(len = *), intent(in):: string
    integer, intent(in):: start
    character(len = *), intent(in):: substr
    intrinsic index
    if (start < 1) then
      result = 0
      return
    endif
    result = index(string(start: ), substr)
    if (result == 0) return
    result = start + result - 1
  end function Index_Ofs

  recursive function Replace( &
    & string, from, to, recursive, start_pos ) result(result)
    !
    ! æ–‡å—åˆ— *string* ã«æ–‡å—åˆ— *from* ãŒå«ã¾ã‚Œã‚‹å ´åˆ, ãã®éƒ¨åˆ†ã‚’æ–‡å—åˆ— *to*
    ! ã«ç½®æ›ã—ã¦è¿”ã—ã¾ã™. æ–‡å—åˆ— *from* ãŒå«ã¾ã‚Œãªã„å ´åˆã¯ *string*
    ! ã‚’ãã®ã¾ã¾è¿”ã—ã¾ã™. *from* ãŒè¤‡æ•°å«ã¾ã‚Œã‚‹å ´åˆ, å…ˆé ã® *from*
    ! ã®ã¿ãŒç½®æ›ã•ã‚Œã¾ã™.
    !
    ! å…¨ã¦ã® *from* ã‚’ *to* ã¸å¤‰æ›ã—ãŸã„å ´åˆã«ã¯,
    ! ã‚ªãƒ—ã‚·ãƒ§ãƒŠãƒ«å¼•æ•° *recursive* ã« .true. ã‚’ä¸Žãˆã¦ãã ã•ã„.
    !
    ! ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã¯, æ–‡å—åˆ—ã®æœ€åˆã‹ã‚‰æ¤œç´¢ã‚’è¡Œã„ã¾ã™.
    ! ã‚ªãƒ—ã‚·ãƒ§ãƒŠãƒ«å¼•æ•° *start_pos* ã‚’ä¸Žãˆã‚‹å ´åˆ,
    ! *start_pos* æ–‡å—ç›®ã‹ã‚‰æ¤œç´¢ã‚’è¡Œã„ã¾ã™.
    !
    ! If a string *from* is included in *string*, the string is
    ! replace to *to*, and the replaced string is returned.
    ! If a string *from* is not included, *string* is returned
    ! without change.
    ! When multiple *from* are included, only first *from* is replaced.
    !
    ! In order to replace all *from* to *to*, give ".true." to
    ! optional argument *recursive*.
    !
    ! By default, the string is searched from the top.
    ! If optional argument *start_pos* is given,
    ! the search is started from *start_pos*.
    !
    use dc_types, only: STRLEN => STRING
    implicit none
    character(STRLEN):: result
    character(*), intent(in):: string, from, to
    logical, intent(in), optional:: recursive
    integer, intent(in), optional:: start_pos
    integer:: sp
    integer:: i, isa, isb, iea, ieb
    integer:: ir
  continue
    if ( present(start_pos) ) then
      sp = start_pos
    else
      sp = 1
    end if
    if ( sp < 1 ) then
      sp = 1
    end if

    result = string
    i = index(result(sp:), from)
    if (i == 0) return
    i = i + sp - 1
    isa = i + len(from)
    isb = i + len(to)
    if (len(to) < len(from)) then
      iea = len(result)
      ieb = len(result) + len(to) - len(from)
    else
      iea = len(result) + len(from) - len(to)
      ieb = len(result)
    endif
    if (len(to) /= len(from)) result(isb:ieb) = result(isa:iea)
    result(i:i+len(to)-1) = to

    !-----------------------------------
    !  å†å¸°çš„å‡¦ç†
    !  Recursive process
    ir = index(result(i+len(to):), from)
    if ( len_trim(from) == 0 ) then
      ir = index(trim(result(i+len(to):)), from)
    end if
    if (ir /= 0) then
      if ( present(recursive) ) then
        if ( recursive ) then
          result = Replace( string = result, &
            &               from = from, to = to, &
            &               recursive = recursive, &
            &               start_pos = i+len(to) )
        end if
      end if
    end if

  end function Replace

  !-------------------------------------------------------------------
  !  å¤§æ–‡å—ãƒ»å°æ–‡å—ã‚’ç„¡è¦–ã—ãŸå‡¦ç†
  !-------------------------------------------------------------------

  subroutine cupper(ch)
    !
    ! æ–‡å—åˆ— ch ã«è‹±å—ãŒå«ã¾ã‚Œã‚‹å ´åˆã€ãã®è‹±å—ã‚’å¤§æ–‡å—ã«å¤‰æ›ã—ã¦ ch
    ! ã«è¿”ã—ã¾ã™ã€‚ è‹±å—ã§ãªã„æ–‡å—ã‚„æ—¢ã«å¤§æ–‡å—ã«ãªã£ã¦ã„ã‚‹æ–‡å—ã¯
    ! ãã®ã¾ã¾è¿”ã—ã¾ã™ã€‚
    !
    character(len = *), intent(inout):: ch
    integer:: i, lch, idx
  continue
    lch = len(ch)
    do, i = 1, lch
      idx = ichar(ch(i:i))
      if (97 <= idx .and. idx <= 122) then
        ch(i:i)=char(idx - 32)
      end if
    end do
  end subroutine cupper

  subroutine clower(ch)
    !
    ! æ–‡å—åˆ— ch ã«è‹±å—ãŒå«ã¾ã‚Œã‚‹å ´åˆã€ãã®è‹±å—ã‚’å°æ–‡å—ã«å¤‰æ›ã—ã¦ ch
    ! ã«è¿”ã—ã¾ã™ã€‚ è‹±å—ã§ãªã„æ–‡å—ã‚„æ—¢ã«å°æ–‡å—ã«ãªã£ã¦ã„ã‚‹æ–‡å—ã¯
    ! ãã®ã¾ã¾è¿”ã—ã¾ã™ã€‚
    !
    character(len = *), intent(inout):: ch
    integer:: i, lch, idx
  continue
    lch = len(ch)
    do, i = 1, lch
      idx = ichar(ch(i:i))
      if (65 <= idx .and. idx <= 90) then
        ch(i:i)=char(idx + 32)
      end if
    end do
  end subroutine clower

  character(STRING) function UChar(ch) result(result)
    !
    ! æ–‡å—åˆ— ch ã«è‹±å—ãŒå«ã¾ã‚Œã‚‹å ´åˆã€ãã®è‹±å—ã‚’å¤§æ–‡å—ã«å¤‰æ›ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! è‹±å—ã§ãªã„æ–‡å—ã‚„æ—¢ã«å¤§æ–‡å—ã«ãªã£ã¦ã„ã‚‹æ–‡å—ã¯ãã®ã¾ã¾è¿”ã—ã¾ã™ã€‚
    !
    character(len = *), intent(in):: ch
  continue
    result = ch
    call toUpper(result)
  end function UChar

  character(STRING) function LChar(ch) result(result)
    !
    ! æ–‡å—åˆ— ch ã«è‹±å—ãŒå«ã¾ã‚Œã‚‹å ´åˆã€ãã®è‹±å—ã‚’å°æ–‡å—ã«å¤‰æ›ã—ã¦è¿”ã—ã¾ã™ã€‚
    ! è‹±å—ã§ãªã„æ–‡å—ã‚„æ—¢ã«å°æ–‡å—ã«ãªã£ã¦ã„ã‚‹æ–‡å—ã¯ãã®ã¾ã¾è¿”ã—ã¾ã™ã€‚
    !
    character(len = *), intent(in):: ch
  continue
    result = ch
    call toLower(result)
  end function LChar

  character(STRING) function RoundNum(num) result(result)
    !
    ! '0.30000001' ã‚„ '12.999998' ãªã©ã®ä¸¸ã‚èª¤å·®ã«ã‚ˆã£ã¦ç«¯æ•°ãŒæ®‹ã£ã¦
    ! ã—ã¾ã£ã¦ã„ã‚‹æ•°å€¤è¡¨è¨˜ã‚’ '0.3' ã‚„ '13.' ãªã©ã«æ•´å½¢ã—ã¦è¿”ã—ã¾ã™.
    !
    character(*), intent(in):: num
    character(STRING):: nrv, enrv
    integer:: i, moving_up, nrvi, dig, zero_stream
  continue
    !
    ! å®Ÿæ•°ã§ãªã„ã‚‚ã®ã«ã¤ã„ã¦ã¯ãã®ã¾ã¾è¿”ã™.
    !
    if ( scan('.', trim(num) ) == 0  ) then
      result = num
      return
    end if
    nrv = num

    !
    ! æŒ‡æ•°éƒ¨ã‚’é¿ã‘ã¦ãŠã.
    !
    enrv = ''
    i = scan(nrv, "eE", back=.true.)
    if ( i > 1  ) then
      enrv = nrv(i:)
      nrv(i:) = " "
    elseif ( i == 1 ) then
      result = nrv
      return
    end if

    !
    ! 0.30000001 ãªã©ã®æœ«å°¾ã® 1 ã®ã‚ˆã†ãª, ã‚´ãƒŸã®æ¡ã®æ•°å€¤ã‚’æŽƒé™¤ã—,
    ! 0.3000000 ãªã©ã«æ•´å½¢.
    !
    if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
      do while ( index('567890.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
        if ( len_trim(nrv) < 2 ) exit
        nrv = nrv(1:len_trim(nrv)-1)
      end do
    end if

    !
    ! 0.30000001986 ãªã©ã®æœ«å°¾ã® 1 ä»¥é™ã®ã‚´ãƒŸã®æ¡ã®æ•°å€¤ã‚’æŽƒé™¤ã—,
    ! 0.3000000 ãªã©ã«æ•´å½¢.
    !
    if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
      dig = index( trim( nrv ), '.') + 1
      zero_stream = 0
      do while ( dig < len_trim( nrv ) )
        if ( nrv(dig:dig) == "0" ) then
          zero_stream = zero_stream + 1
        else
          zero_stream = 0
        end if
        if ( zero_stream > 7 ) then
          nrv(dig:len_trim(nrv)) = '0'
          exit
        end if
        dig = dig + 1
      end do
    end if

    !
    ! 0.3000000 ãªã©ã®æœ«å°¾ã® 0 ã‚’æŽƒé™¤ã—,
    ! 0.3 ãªã©ã«æ•´å½¢.
    !
    if ( index( trim( nrv ), '.') /= 0 ) then
      do while ( index('123456789.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
        if ( len_trim(nrv) < 2 ) exit
        nrv = nrv(1:len_trim(nrv)-1)
      end do
    end if

    !
    ! 0.89999998 ãªã©ã®æœ«å°¾ã® 8 ã®ã‚ˆã†ãª, ã‚´ãƒŸã®æ¡ã®æ•°å€¤ã‚’æŽƒé™¤ã—,
    ! 0.8999999 ãªã©ã«æ•´å½¢.
    !
    moving_up = 0
    if ( index( trim( nrv ), '.') - len_trim( nrv ) < -7 ) then
      do while ( index('12345690.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
        if ( len_trim(nrv) < 2 ) exit
        nrv = nrv(1:len_trim(nrv)-1)
      end do
      moving_up = 1
    end if

    !
    ! 0.8999999 ãªã©ã®æœ«å°¾ã® 9 ã‚’æŽƒé™¤ã—, ç¹°ã‚Šä¸Šã’ã¦
    ! 0.9 ãªã©ã«æ•´å½¢.
    !
    if ( moving_up > 0 ) then
      do while ( index('012345678.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
        if ( len_trim(nrv) < 2 ) exit
        nrv = nrv(1:len_trim(nrv)-1)
      end do
    end if

    i = len_trim(nrv)
    do while ( moving_up > 0 .and. i > 0 )
      if ( index('.', nrv(i:i)) /= 0 ) then
        i = i - 1
        cycle
      end if
      nrvi = StoI( nrv(i:i) ) + moving_up

      if ( nrvi < 10 ) then
        nrv(i:i) = trim( toChar( nrvi ) )
        exit
      else
        nrv(i:i) = '0'
        if ( i < 2 ) then
          nrv = '10'
          exit
        else
          i = i - 1
          cycle
        end if
      end if
      if ( len_trim(nrv) < 2 ) exit
      nrv = nrv(1:len_trim(nrv)-1)
    end do

    !
    ! 0.3000000 ãªã©ã®æœ«å°¾ã® 0 ã‚’æŽƒé™¤ã—,
    ! 0.3 ãªã©ã«æ•´å½¢.
    !
    if ( index( trim( nrv ), '.') /= 0 ) then
      do while ( index('123456789.', nrv(len_trim(nrv):len_trim(nrv)) ) == 0 )
        if ( len_trim(nrv) < 2 ) exit
        nrv = nrv(1:len_trim(nrv)-1)
      end do
    end if

    !
    ! æŒ‡æ•°éƒ¨ã‚’å¾©å¸°ã™ã‚‹
    !
    if ( len_trim(enrv) > 0 ) then
      nrv = trim(nrv) // enrv
    end if

    result = nrv
  end function RoundNum

  !> @namespace dc_string
end module