!> `bem_app_config_parser` の文字列パース補助手続きを実装する submodule。 submodule(bem_app_config_parser) bem_app_config_parser_parse_utils implicit none contains !> `key = value` 形式の行を分割してキーと値を返す。 module procedure split_key_value integer :: p p = index(line, '=') if (p <= 0) then key = '' value = '' return end if key = lower_ascii(trim(adjustl(line(:p - 1)))) value = trim(adjustl(line(p + 1:))) end procedure split_key_value !> 値文字列を倍精度実数へ変換する。 module procedure parse_real read (text, *) out end procedure parse_real !> 値文字列を `integer(i32)` へ変換する。 module procedure parse_int read (text, *) out end procedure parse_int !> 値文字列を論理値へ変換する。 module procedure parse_logical character(len=32) :: t t = lower_ascii(trim(adjustl(text))) select case (t) case ('true', '.true.') out = .true. case ('false', '.false.') out = .false. case default error stop 'Logical value must be true/false (or .true./.false.).' end select end procedure parse_logical !> 値文字列を引用符除去済みの文字列へ変換する。 module procedure parse_string character(len=:), allocatable :: tmp tmp = trim(adjustl(text)) if (len(tmp) >= 2 .and. tmp(1:1) == '"' .and. tmp(len(tmp):len(tmp)) == '"') then tmp = tmp(2:len(tmp) - 1) end if out = trim(tmp) end procedure parse_string !> `[x, y, z]` 形式の値文字列を3成分実数配列へ変換する。 module procedure parse_real3 character(len=256) :: t t = trim(adjustl(text)) if (t(1:1) == '[') t = t(2:) if (t(len_trim(t):len_trim(t)) == ']') t = t(:len_trim(t) - 1) read (t, *) out(1), out(2), out(3) end procedure parse_real3 !> 境界条件モード文字列を内部定数へ変換する。 module procedure parse_boundary_mode character(len=64) :: mode call parse_string(text, mode) select case (trim(lower_ascii(mode))) case ('open', 'outflow', 'escape') out = bc_open case ('reflect', 'reflection') out = bc_reflect case ('periodic') out = bc_periodic case default error stop 'Unknown boundary condition mode in [sim].' end select end procedure parse_boundary_mode !> 行内コメント (`#` 以降) を除去した文字列を返す。 module procedure strip_comment integer :: p p = index(line, '#') if (p > 0) then out = trim(line(:p - 1)) else out = trim(line) end if end procedure strip_comment !> 文字列が指定した接尾辞で終わるかを判定する。 module procedure ends_with integer :: ls, lf ls = len_trim(s) lf = len_trim(suffix) if (lf > ls) then ends_it = .false. else ends_it = (s(ls - lf + 1:ls) == suffix(1:lf)) end if end procedure ends_with end submodule bem_app_config_parser_parse_utils