29 module yaml_parser_mod
32 use fms_mod,
only: fms_c2f_string
63 integer,
parameter :: MISSING_FILE = -1
64 integer,
parameter :: PARSER_INIT_ERROR = -2
65 integer,
parameter :: INVALID_YAML = -3
66 integer,
parameter :: SUCCESSFUL = 1
76 use iso_c_binding,
only: c_char, c_int, c_bool
77 character(kind=c_char),
intent(in) :: filename(*)
78 integer(kind=c_int),
intent(out) :: file_id
79 logical(kind=c_int) :: error_code
86 use iso_c_binding,
only: c_char, c_int, c_bool
87 integer(kind=c_int),
intent(in) :: file_id
88 logical(kind=c_bool) :: is_valid
95 use iso_c_binding,
only: c_char, c_int, c_bool
96 integer(kind=c_int),
intent(in) :: file_id
97 integer(kind=c_int),
intent(in) :: block_id
98 integer(kind=c_int) :: nkeys
103 use iso_c_binding,
only: c_char, c_int, c_bool
104 integer(kind=c_int),
intent(in) :: file_id
105 integer(kind=c_int),
intent(in) :: block_id
106 integer(kind=c_int),
intent(inout) :: key_ids(*)
113 use iso_c_binding,
only: c_char, c_int, c_bool
114 integer(kind=c_int),
intent(in) :: file_id
115 integer(kind=c_int),
intent(in) :: key_id
116 logical(kind=c_bool) :: is_valid
123 use iso_c_binding,
only: c_ptr, c_int, c_bool
124 integer(kind=c_int),
intent(in) :: file_id
125 integer(kind=c_int),
intent(in) :: key_id
126 type(c_ptr) :: key_name
133 use iso_c_binding,
only: c_ptr, c_int, c_bool
134 integer(kind=c_int),
intent(in) :: file_id
135 integer(kind=c_int),
intent(in) :: key_id
136 type(c_ptr) :: key_value
143 use iso_c_binding,
only: c_ptr, c_int, c_bool
144 integer(kind=c_int),
intent(in) :: file_id
145 integer(kind=c_int),
intent(in) :: block_id
147 type(c_ptr) :: block_name
155 use iso_c_binding,
only: c_ptr, c_char, c_int, c_bool
156 integer(kind=c_int),
intent(in) :: file_id
157 integer(kind=c_int),
intent(in) :: block_id
158 character(kind=c_char),
intent(in) :: key_name(*)
159 integer(kind=c_int),
intent(out) :: success
160 type(c_ptr) :: key_value2
168 use iso_c_binding,
only: c_char, c_int, c_bool
169 integer(kind=c_int),
intent(in) :: file_id
170 character(kind=c_char),
intent(in) :: block_name(*)
172 integer(kind=c_int) :: nblocks
180 use iso_c_binding,
only: c_char, c_int, c_bool
181 integer(kind=c_int),
intent(in) :: file_id
182 character(kind=c_char),
intent(in) :: block_name(*)
183 integer(kind=c_int) :: parent_block_id
185 integer(kind=c_int) :: nblocks
191 use iso_c_binding,
only: c_char, c_int, c_bool
192 integer(kind=c_int),
intent(in) :: file_id
193 character(kind=c_char),
intent(in) :: block_name(*)
194 integer(kind=c_int),
intent(inout) :: block_ids(*)
200 use iso_c_binding,
only: c_char, c_int, c_bool
201 integer(kind=c_int),
intent(in) :: file_id
202 character(kind=c_char),
intent(in) :: block_name(*)
203 integer(kind=c_int),
intent(inout) :: block_ids(*)
204 integer(kind=c_int) :: parent_block_id
211 use iso_c_binding,
only: c_char, c_int, c_bool
212 integer(kind=c_int),
intent(in) :: file_id
213 integer(kind=c_int),
intent(in) :: block_id
214 logical(kind=c_bool) :: is_valid
222 use iso_c_binding,
only: c_char, c_int, c_bool
223 integer(kind=c_int),
intent(in) :: file_id
224 integer(kind=c_int) :: parent_block_id
226 integer(kind=c_int) :: nblocks
232 use iso_c_binding,
only: c_char, c_int, c_bool, c_ptr
233 integer(kind=c_int),
intent(in) :: file_id
234 integer(kind=c_int),
intent(inout) :: block_ids(*)
235 integer(kind=c_int) :: parent_block_id
248 character(len=*),
intent(in) :: filename
249 integer :: error_code
250 logical :: yaml_exists
254 inquire(file=trim(filename), exist=yaml_exists)
255 if (.not. yaml_exists)
then
257 call mpp_error(note,
"The yaml file:"//trim(filename)//
" does not exist, hopefully this is your intent!")
267 integer,
intent(in) :: error_code
268 character(len=*),
intent(in) :: filename
270 select case (error_code)
274 call mpp_error(fatal,
"Error opening the yaml file:"//trim(filename))
275 case (parser_init_error)
276 call mpp_error(fatal,
"Error initializing the parser for the file:"//trim(filename))
278 call mpp_error(fatal,
"Error parsing the file:"//trim(filename)//
". Check that your yaml file is valid")
284 integer,
intent(in) :: key_id
285 integer,
intent(in) :: file_id
286 character(len=*),
intent(out) :: key_name
289 &
"The file id in your get_key_name call is invalid! Check your call.")
291 &
"The key id in your get_key_name call is invalid! Check your call.")
299 integer,
intent(in) :: key_id
300 integer,
intent(in) :: file_id
301 character(len=*),
intent(out) :: key_value
304 &
"The file id in your get_key_value call is invalid! Check your call.")
306 &
"The key id in your get_key_value call is invalid! Check your call.")
314 integer,
intent(in) :: file_id
315 integer,
intent(in) :: block_id
316 character(len=*),
intent(in) :: key_name
317 class(*),
intent(inout):: key_value
318 logical,
intent(in),
optional :: is_optional
322 character(len=255) :: buffer
324 type(c_ptr) :: c_buffer
325 integer(kind=c_int) :: success
326 logical :: optional_flag
329 optional_flag = .false.
330 if (
present(is_optional)) optional_flag = is_optional
333 &
"The file id in your get_value_from_key call is invalid! Check your call.")
335 &
"The block id in your get_value_from_key call is invalid! Check your call.")
338 if (success == 1)
then
341 select type (key_value)
342 type is (
integer(kind=i4_kind))
343 read(buffer,*, iostat=err_unit) key_value
344 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
345 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
346 type is (
integer(kind=i8_kind))
347 read(buffer,*, iostat=err_unit) key_value
348 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
349 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
350 type is (real(kind=r4_kind))
351 read(buffer,*, iostat=err_unit) key_value
352 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
353 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
354 type is (real(kind=r8_kind))
355 read(buffer,*, iostat=err_unit) key_value
356 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
357 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
358 type is (
character(len=*))
361 if (lowercase(trim(buffer)) ==
"false")
then
363 elseif (lowercase(trim(buffer)) ==
"true")
then
366 call mpp_error(fatal,
"Key:"//trim(key_name)//
" Error converting '"//trim(buffer)//
"' to logical")
369 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
370 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
373 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
380 integer,
intent(in) :: file_id
381 integer,
intent(in) :: block_id
382 character(len=*),
intent(in) :: key_name
383 class(*),
intent(inout):: key_value(:)
384 logical,
intent(in),
optional :: is_optional
388 character(len=255) :: buffer
390 type(c_ptr) :: c_buffer
391 integer(kind=c_int) :: success
392 logical :: optional_flag
395 optional_flag=.false.
396 if (
present(is_optional)) optional_flag = is_optional
399 &
"The file id in your get_value_from_key call is invalid! Check your call.")
401 &
"The block id in your get_value_from_key call is invalid! Check your call.")
404 if (success == 1)
then
407 select type (key_value)
408 type is (
integer(kind=i4_kind))
409 read(buffer,*, iostat=err_unit) key_value
410 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
411 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
412 type is (
integer(kind=i8_kind))
413 read(buffer,*, iostat=err_unit) key_value
414 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
415 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
416 type is (real(kind=r4_kind))
417 read(buffer,*, iostat=err_unit) key_value
418 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
419 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
420 type is (real(kind=r8_kind))
421 read(buffer,*, iostat=err_unit) key_value
422 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
423 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
424 type is (
character(len=*))
425 call mpp_error(fatal,
"get_value_from_key 1d string variables are not supported. Contact developers")
427 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
428 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
431 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
441 integer,
intent(in) :: file_id
442 character(len=*),
intent(in) :: block_name
443 integer,
intent(in),
optional :: parent_block_id
447 &
"The file id in your get_num_blocks call is invalid! Check your call.")
449 if (.not.
present(parent_block_id))
then
453 &
"The parent_block id in your get_num_blocks call is invalid! Check your call.")
462 integer,
intent(in) :: file_id
463 character(len=*),
intent(in) :: block_name
464 integer,
intent(inout) :: block_ids(:)
465 integer,
intent(in),
optional :: parent_block_id
466 integer :: nblocks_id
470 &
"The file id in your get_block_ids call is invalid! Check your call.")
472 nblocks_id =
size(block_ids)
474 if (nblocks .ne. nblocks_id)
call mpp_error(fatal,
"The size of your block_ids array is not correct")
476 if (.not.
present(parent_block_id))
then
480 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
481 call get_block_ids_child(file_id, trim(block_name)//c_null_char, block_ids, parent_block_id)
489 integer,
intent(in) :: file_id
490 integer,
intent(in) :: block_id
494 &
"The file id in your get_nkeys call is invalid! Check your call.")
496 &
"The block id in your get_nkeys call is invalid! Check your call.")
503 integer,
intent(in) :: file_id
504 integer,
intent(in) :: block_id
505 integer,
intent(inout) :: key_ids(:)
511 &
"The file id in your get_key_ids call is invalid! Check your call.")
513 &
"The block id in your get_key_ids call is invalid! Check your call.")
515 nkey_ids =
size(key_ids)
518 if (nkeys .ne. nkey_ids)
call mpp_error(fatal,
"The size of your key_ids array is not correct.")
527 integer,
intent(in) :: file_id
528 integer,
intent(in),
optional :: parent_block_id
532 &
"The file id in your get_num_unique_blocks call is invalid! Check your call.")
534 if (.not.
present(parent_block_id))
then
538 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
545 integer,
intent(in) :: file_id
546 integer,
intent(inout) :: block_ids(:)
547 integer,
intent(in),
optional :: parent_block_id
550 &
"The file id in your get_num_unique_blocks_ids call is invalid! Check your call.")
552 if (.not.
present(parent_block_id))
then
556 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
563 integer,
intent(in) :: file_id
564 integer,
intent(in) :: block_id
565 character(len=*),
intent(out) :: block_name
570 end module yaml_parser_mod
Converts a C string to a Fortran string.
subroutine, public string_copy(dest, source, check_for_null)
Safely copy a string from one buffer to another.
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.
integer function, public get_nkeys(file_id, block_id)
Gets the number of key-value pairs in a block.
subroutine, public get_key_name(file_id, key_id, key_name)
Gets the key from a file id.
integer function, public open_and_parse_file(filename)
Opens and parses a yaml file.
subroutine check_error_code(error_code, filename)
Checks the error code from a open_and_parse_file_wrap function call.
subroutine, public get_key_ids(file_id, block_id, key_ids)
Gets the ids of the key-value pairs in a block.
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_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,...
integer function, public get_num_unique_blocks(file_id, parent_block_id)
Gets the number of unique blocks.
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.
Dermine the value of a key from a keyname.
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)