32use fms_mod,
only: fms_c2f_string
42public :: missing_file_error_code
56integer,
parameter :: missing_file_error_code = 999
66integer,
parameter :: MISSING_FILE = -1
67integer,
parameter :: PARSER_INIT_ERROR = -2
68integer,
parameter :: INVALID_YAML = -3
69integer,
parameter :: SUCCESSFUL = 1
79 use iso_c_binding,
only: c_char, c_int, c_bool
80 character(kind=c_char),
intent(in) :: filename(*)
81 integer(kind=c_int),
intent(out) :: file_id
82 integer(kind=c_int) :: error_code
89 use iso_c_binding,
only: c_char, c_int, c_bool
90 integer(kind=c_int),
intent(in) :: file_id
91 logical(kind=c_bool) :: is_valid
98 use iso_c_binding,
only: c_char, c_int, c_bool
99 integer(kind=c_int),
intent(in) :: file_id
100 integer(kind=c_int),
intent(in) :: block_id
101 integer(kind=c_int) :: nkeys
106 use iso_c_binding,
only: c_char, c_int, c_bool
107 integer(kind=c_int),
intent(in) :: file_id
108 integer(kind=c_int),
intent(in) :: block_id
109 integer(kind=c_int),
intent(inout) :: key_ids(*)
116 use iso_c_binding,
only: c_char, c_int, c_bool
117 integer(kind=c_int),
intent(in) :: file_id
118 integer(kind=c_int),
intent(in) :: key_id
119 logical(kind=c_bool) :: is_valid
126 use iso_c_binding,
only: c_ptr, c_int, c_bool
127 integer(kind=c_int),
intent(in) :: file_id
128 integer(kind=c_int),
intent(in) :: key_id
129 type(c_ptr) :: key_name
136 use iso_c_binding,
only: c_ptr, c_int, c_bool
137 integer(kind=c_int),
intent(in) :: file_id
138 integer(kind=c_int),
intent(in) :: key_id
139 type(c_ptr) :: key_value
146 use iso_c_binding,
only: c_ptr, c_int, c_bool
147 integer(kind=c_int),
intent(in) :: file_id
148 integer(kind=c_int),
intent(in) :: block_id
150 type(c_ptr) :: block_name
158 use iso_c_binding,
only: c_ptr, c_char, c_int, c_bool
159 integer(kind=c_int),
intent(in) :: file_id
160 integer(kind=c_int),
intent(in) :: block_id
161 character(kind=c_char),
intent(in) :: key_name(*)
162 integer(kind=c_int),
intent(out) :: success
163 type(c_ptr) :: key_value2
171 use iso_c_binding,
only: c_char, c_int, c_bool
172 integer(kind=c_int),
intent(in) :: file_id
173 character(kind=c_char),
intent(in) :: block_name(*)
175 integer(kind=c_int) :: nblocks
183 use iso_c_binding,
only: c_char, c_int, c_bool
184 integer(kind=c_int),
intent(in) :: file_id
185 character(kind=c_char),
intent(in) :: block_name(*)
186 integer(kind=c_int) :: parent_block_id
188 integer(kind=c_int) :: nblocks
194 use iso_c_binding,
only: c_char, c_int, c_bool
195 integer(kind=c_int),
intent(in) :: file_id
196 character(kind=c_char),
intent(in) :: block_name(*)
197 integer(kind=c_int),
intent(inout) :: block_ids(*)
203 use iso_c_binding,
only: c_char, c_int, c_bool
204 integer(kind=c_int),
intent(in) :: file_id
205 character(kind=c_char),
intent(in) :: block_name(*)
206 integer(kind=c_int),
intent(inout) :: block_ids(*)
207 integer(kind=c_int) :: parent_block_id
214 use iso_c_binding,
only: c_char, c_int, c_bool
215 integer(kind=c_int),
intent(in) :: file_id
216 integer(kind=c_int),
intent(in) :: block_id
217 logical(kind=c_bool) :: is_valid
225 use iso_c_binding,
only: c_char, c_int, c_bool
226 integer(kind=c_int),
intent(in) :: file_id
227 integer(kind=c_int) :: parent_block_id
229 integer(kind=c_int) :: nblocks
235 use iso_c_binding,
only: c_char, c_int, c_bool, c_ptr
236 integer(kind=c_int),
intent(in) :: file_id
237 integer(kind=c_int),
intent(inout) :: block_ids(*)
238 integer(kind=c_int) :: parent_block_id
251 character(len=*),
intent(in) :: filename
252 integer :: error_code
253 logical :: yaml_exists
257 inquire(file=trim(filename), exist=yaml_exists)
258 if (.not. yaml_exists)
then
259 file_id = missing_file_error_code
260 call mpp_error(note,
"The yaml file:"//trim(filename)//
" does not exist, hopefully this is your intent!")
270 integer,
intent(in) :: error_code
271 character(len=*),
intent(in) :: filename
273 select case (error_code)
277 call mpp_error(fatal,
"Error opening the yaml file:"//trim(filename))
278 case (parser_init_error)
279 call mpp_error(fatal,
"Error initializing the parser for the file:"//trim(filename))
281 call mpp_error(fatal,
"Error parsing the file:"//trim(filename)//
". Check that your yaml file is valid")
287 integer,
intent(in) :: key_id
288 integer,
intent(in) :: file_id
289 character(len=*),
intent(out) :: key_name
292 &
"The file id in your get_key_name call is invalid! Check your call.")
294 &
"The key id in your get_key_name call is invalid! Check your call.")
302 integer,
intent(in) :: key_id
303 integer,
intent(in) :: file_id
304 character(len=*),
intent(out) :: key_value
307 &
"The file id in your get_key_value call is invalid! Check your call.")
309 &
"The key id in your get_key_value call is invalid! Check your call.")
317 integer,
intent(in) :: file_id
318 integer,
intent(in) :: block_id
319 character(len=*),
intent(in) :: key_name
320 class(*),
intent(inout):: key_value
321 logical,
intent(in),
optional :: is_optional
325 character(len=255) :: buffer
327 type(c_ptr) :: c_buffer
328 integer(kind=c_int) :: success
329 logical :: optional_flag
332 optional_flag = .false.
333 if (
present(is_optional)) optional_flag = is_optional
336 &
"The file id in your get_value_from_key call is invalid! Check your call.")
338 &
"The block id in your get_value_from_key call is invalid! Check your call.")
341 if (success == 1)
then
344 select type (key_value)
345 type is (
integer(kind=i4_kind))
346 read(buffer,*, iostat=err_unit) key_value
347 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
348 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
349 type is (
integer(kind=i8_kind))
350 read(buffer,*, iostat=err_unit) key_value
351 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
352 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
353 type is (real(kind=r4_kind))
354 read(buffer,*, iostat=err_unit) key_value
355 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
356 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
357 type is (real(kind=r8_kind))
358 read(buffer,*, iostat=err_unit) key_value
359 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
360 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
361 type is (
character(len=*))
364 if (lowercase(trim(buffer)) ==
"false")
then
366 elseif (lowercase(trim(buffer)) ==
"true")
then
369 call mpp_error(fatal,
"Key:"//trim(key_name)//
" Error converting '"//trim(buffer)//
"' to logical")
372 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
373 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
376 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
383 integer,
intent(in) :: file_id
384 integer,
intent(in) :: block_id
385 character(len=*),
intent(in) :: key_name
386 class(*),
intent(inout):: key_value(:)
387 logical,
intent(in),
optional :: is_optional
391 character(len=255) :: buffer
393 type(c_ptr) :: c_buffer
394 integer(kind=c_int) :: success
395 logical :: optional_flag
398 optional_flag=.false.
399 if (
present(is_optional)) optional_flag = is_optional
402 &
"The file id in your get_value_from_key call is invalid! Check your call.")
404 &
"The block id in your get_value_from_key call is invalid! Check your call.")
407 if (success == 1)
then
410 select type (key_value)
411 type is (
integer(kind=i4_kind))
412 read(buffer,*, iostat=err_unit) key_value
413 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
414 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
415 type is (
integer(kind=i8_kind))
416 read(buffer,*, iostat=err_unit) key_value
417 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
418 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
419 type is (real(kind=r4_kind))
420 read(buffer,*, iostat=err_unit) key_value
421 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
422 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
423 type is (real(kind=r8_kind))
424 read(buffer,*, iostat=err_unit) key_value
425 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
426 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
427 type is (
character(len=*))
428 call mpp_error(fatal,
"get_value_from_key 1d string variables are not supported. Contact developers")
430 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
431 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
434 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
444 integer,
intent(in) :: file_id
445 character(len=*),
intent(in) :: block_name
446 integer,
intent(in),
optional :: parent_block_id
450 &
"The file id in your get_num_blocks call is invalid! Check your call.")
452 if (.not.
present(parent_block_id))
then
456 &
"The parent_block id in your get_num_blocks call is invalid! Check your call.")
465 integer,
intent(in) :: file_id
466 character(len=*),
intent(in) :: block_name
467 integer,
intent(inout) :: block_ids(:)
468 integer,
intent(in),
optional :: parent_block_id
469 integer :: nblocks_id
473 &
"The file id in your get_block_ids call is invalid! Check your call.")
475 nblocks_id =
size(block_ids)
477 if (nblocks .ne. nblocks_id)
call mpp_error(fatal,
"The size of your block_ids array is not correct")
479 if (.not.
present(parent_block_id))
then
483 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
484 call get_block_ids_child(file_id, trim(block_name)//c_null_char, block_ids, parent_block_id)
492 integer,
intent(in) :: file_id
493 integer,
intent(in) :: block_id
497 &
"The file id in your get_nkeys call is invalid! Check your call.")
499 &
"The block id in your get_nkeys call is invalid! Check your call.")
506 integer,
intent(in) :: file_id
507 integer,
intent(in) :: block_id
508 integer,
intent(inout) :: key_ids(:)
514 &
"The file id in your get_key_ids call is invalid! Check your call.")
516 &
"The block id in your get_key_ids call is invalid! Check your call.")
518 nkey_ids =
size(key_ids)
521 if (nkeys .ne. nkey_ids)
call mpp_error(fatal,
"The size of your key_ids array is not correct.")
530 integer,
intent(in) :: file_id
531 integer,
intent(in),
optional :: parent_block_id
535 &
"The file id in your get_num_unique_blocks call is invalid! Check your call.")
537 if (.not.
present(parent_block_id))
then
541 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
548 integer,
intent(in) :: file_id
549 integer,
intent(inout) :: block_ids(:)
550 integer,
intent(in),
optional :: parent_block_id
553 &
"The file id in your get_num_unique_blocks_ids call is invalid! Check your call.")
555 if (.not.
present(parent_block_id))
then
559 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
566 integer,
intent(in) :: file_id
567 integer,
intent(in) :: block_id
568 character(len=*),
intent(out) :: block_name
573end module yaml_parser_mod
subroutine, public string_copy(dest, source, check_for_null)
Safely copy a string from one buffer to another.
integer function, public get_num_blocks(file_id, block_name, parent_block_id)
Determines the number of blocks with block_name in the yaml file If parent_block_id is present,...
subroutine, public get_unique_block_ids(file_id, block_ids, parent_block_id)
Gets the ids of the unique block ids.
subroutine, public get_block_name(file_id, block_id, block_name)
Gets the block name form the block id.
subroutine, public get_key_value(file_id, key_id, key_value)
Gets the value from a file id.
integer function, public get_nkeys(file_id, block_id)
Gets the number of key-value pairs in a block.
subroutine, public get_key_ids(file_id, block_id, key_ids)
Gets the ids of the key-value pairs in a block.
integer function, public get_num_unique_blocks(file_id, parent_block_id)
Gets the number of unique blocks.
integer function, public open_and_parse_file(filename)
Opens and parses a yaml file.
subroutine get_value_from_key_0d(file_id, block_id, key_name, key_value, is_optional)
Used to dermine the value of a key from a keyname.
subroutine get_value_from_key_1d(file_id, block_id, key_name, key_value, is_optional)
Used' to dermine the 1D value of a key from a keyname.
subroutine, public get_key_name(file_id, key_id, key_name)
Gets the key from a file id.
subroutine, public get_block_ids(file_id, block_name, block_ids, parent_block_id)
Gets the the ids of the blocks with block_name in the yaml file If parent_block_id is present,...
subroutine check_error_code(error_code, filename)
Checks the error code from a open_and_parse_file_wrap function call.
Dermine the value of a key from a keyname.
Converts a C string to a Fortran string.
Private c function that gets the the ids of the blocks with block_name in the yaml file (see yaml_par...
Private c function that gets the the ids of the blocks with block_name and that belong to a parent bl...
Private c function that get the block name from a block_id in a yaml file.
Private c function that gets the ids of the key-value pairs in a block (see yaml_parser_binding....
Private c function that get the key from a key_id in a yaml file.
Private c function that gets the number of key-value pairs in a block (see yaml_parser_binding....
Private c function that determines the number of blocks with block_name in the yaml file (see yaml_pa...
Private c function that determines the number of blocks with block_name that belong to a parent block...
Private c function that determines the number of unique blocks that belong to a parent block with par...
Private c function that gets the the ids of the unique blocks in the yaml file (see yaml_parser_bindi...
Private c function that determines the value of a key in yaml_file (see yaml_parser_binding....
Private c function that get the value from a key_id in a yaml file.
Private c function that checks if a block_id is valid (see yaml_parser_binding.c)
Private c function that checks if a file_id is valid (see yaml_parser_binding.c)
Private c function that checks if a key_id is valid (see yaml_parser_binding.c)