28 module yaml_parser_mod
31 use fms_mod,
only: fms_c2f_string
41 public :: missing_file_error_code
55 integer,
parameter :: missing_file_error_code = 999
65 integer,
parameter :: MISSING_FILE = -1
66 integer,
parameter :: PARSER_INIT_ERROR = -2
67 integer,
parameter :: INVALID_YAML = -3
68 integer,
parameter :: INVALID_ALIAS = -4
69 integer,
parameter :: MAX_LEVELS_REACH = -5
70 integer,
parameter :: SUCCESSFUL = 1
80 use iso_c_binding,
only: c_char, c_int, c_bool
81 character(kind=c_char),
intent(in) :: filename(*)
82 integer(kind=c_int),
intent(out) :: file_id
83 integer(kind=c_int) :: error_code
90 use iso_c_binding,
only: c_char, c_int, c_bool
91 integer(kind=c_int),
intent(in) :: file_id
92 logical(kind=c_bool) :: is_valid
99 use iso_c_binding,
only: c_char, c_int, c_bool
100 integer(kind=c_int),
intent(in) :: file_id
101 integer(kind=c_int),
intent(in) :: block_id
102 integer(kind=c_int) :: nkeys
107 use iso_c_binding,
only: c_char, c_int, c_bool
108 integer(kind=c_int),
intent(in) :: file_id
109 integer(kind=c_int),
intent(in) :: block_id
110 integer(kind=c_int),
intent(inout) :: key_ids(*)
117 use iso_c_binding,
only: c_char, c_int, c_bool
118 integer(kind=c_int),
intent(in) :: file_id
119 integer(kind=c_int),
intent(in) :: key_id
120 logical(kind=c_bool) :: is_valid
127 use iso_c_binding,
only: c_ptr, c_int, c_bool
128 integer(kind=c_int),
intent(in) :: file_id
129 integer(kind=c_int),
intent(in) :: key_id
130 type(c_ptr) :: key_name
137 use iso_c_binding,
only: c_ptr, c_int, c_bool
138 integer(kind=c_int),
intent(in) :: file_id
139 integer(kind=c_int),
intent(in) :: key_id
140 type(c_ptr) :: key_value
147 use iso_c_binding,
only: c_ptr, c_int, c_bool
148 integer(kind=c_int),
intent(in) :: file_id
149 integer(kind=c_int),
intent(in) :: block_id
151 type(c_ptr) :: block_name
159 use iso_c_binding,
only: c_ptr, c_char, c_int, c_bool
160 integer(kind=c_int),
intent(in) :: file_id
161 integer(kind=c_int),
intent(in) :: block_id
162 character(kind=c_char),
intent(in) :: key_name(*)
163 integer(kind=c_int),
intent(out) :: success
164 type(c_ptr) :: key_value2
172 use iso_c_binding,
only: c_char, c_int, c_bool
173 integer(kind=c_int),
intent(in) :: file_id
174 character(kind=c_char),
intent(in) :: block_name(*)
176 integer(kind=c_int) :: nblocks
184 use iso_c_binding,
only: c_char, c_int, c_bool
185 integer(kind=c_int),
intent(in) :: file_id
186 character(kind=c_char),
intent(in) :: block_name(*)
187 integer(kind=c_int) :: parent_block_id
189 integer(kind=c_int) :: nblocks
195 use iso_c_binding,
only: c_char, c_int, c_bool
196 integer(kind=c_int),
intent(in) :: file_id
197 character(kind=c_char),
intent(in) :: block_name(*)
198 integer(kind=c_int),
intent(inout) :: block_ids(*)
204 use iso_c_binding,
only: c_char, c_int, c_bool
205 integer(kind=c_int),
intent(in) :: file_id
206 character(kind=c_char),
intent(in) :: block_name(*)
207 integer(kind=c_int),
intent(inout) :: block_ids(*)
208 integer(kind=c_int) :: parent_block_id
215 use iso_c_binding,
only: c_char, c_int, c_bool
216 integer(kind=c_int),
intent(in) :: file_id
217 integer(kind=c_int),
intent(in) :: block_id
218 logical(kind=c_bool) :: is_valid
226 use iso_c_binding,
only: c_char, c_int, c_bool
227 integer(kind=c_int),
intent(in) :: file_id
228 integer(kind=c_int) :: parent_block_id
230 integer(kind=c_int) :: nblocks
236 use iso_c_binding,
only: c_char, c_int, c_bool, c_ptr
237 integer(kind=c_int),
intent(in) :: file_id
238 integer(kind=c_int),
intent(inout) :: block_ids(*)
239 integer(kind=c_int) :: parent_block_id
252 character(len=*),
intent(in) :: filename
253 integer :: error_code
254 logical :: yaml_exists
258 inquire(file=trim(filename), exist=yaml_exists)
259 if (.not. yaml_exists)
then
260 file_id = missing_file_error_code
261 call mpp_error(note,
"The yaml file:"//trim(filename)//
" does not exist, hopefully this is your intent!")
271 integer,
intent(in) :: error_code
272 character(len=*),
intent(in) :: filename
274 select case (error_code)
278 call mpp_error(fatal,
"Error opening the yaml file:"//trim(filename))
279 case (parser_init_error)
280 call mpp_error(fatal,
"Error initializing the parser for the file:"//trim(filename))
282 call mpp_error(fatal,
"Error parsing the file:"//trim(filename)//
". Check that your yaml file is valid")
284 call mpp_error(fatal,
"An alias (*alias_name) in your file:"//trim(filename)//
" is invalid."//&
285 "Make sure that all aliases correspond to an anchor (&anchor_name)!")
286 case (max_levels_reach)
287 call mpp_error(fatal,
"The file:"//trim(filename)//
" has reached the maximum number of level!"//&
288 "Try setting -DMAX_LEVELS to a number greater than the current limit and recompile")
294 integer,
intent(in) :: key_id
295 integer,
intent(in) :: file_id
296 character(len=*),
intent(out) :: key_name
299 &
"The file id in your get_key_name call is invalid! Check your call.")
301 &
"The key id in your get_key_name call is invalid! Check your call.")
309 integer,
intent(in) :: key_id
310 integer,
intent(in) :: file_id
311 character(len=*),
intent(out) :: key_value
314 &
"The file id in your get_key_value call is invalid! Check your call.")
316 &
"The key id in your get_key_value call is invalid! Check your call.")
324 integer,
intent(in) :: file_id
325 integer,
intent(in) :: block_id
326 character(len=*),
intent(in) :: key_name
327 class(*),
intent(inout):: key_value
328 logical,
intent(in),
optional :: is_optional
332 character(len=255) :: buffer
334 type(c_ptr) :: c_buffer
335 integer(kind=c_int) :: success
336 logical :: optional_flag
339 optional_flag = .false.
340 if (
present(is_optional)) optional_flag = is_optional
343 &
"The file id in your get_value_from_key call is invalid! Check your call.")
345 &
"The block id in your get_value_from_key call is invalid! Check your call.")
348 if (success == 1)
then
351 select type (key_value)
352 type is (
integer(kind=i4_kind))
353 read(buffer,*, iostat=err_unit) key_value
354 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
355 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
356 type is (
integer(kind=i8_kind))
357 read(buffer,*, iostat=err_unit) key_value
358 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
359 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
360 type is (real(kind=r4_kind))
361 read(buffer,*, iostat=err_unit) key_value
362 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
363 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
364 type is (real(kind=r8_kind))
365 read(buffer,*, iostat=err_unit) key_value
366 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
367 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
368 type is (
character(len=*))
371 if (lowercase(trim(buffer)) ==
"false")
then
373 elseif (lowercase(trim(buffer)) ==
"true")
then
376 call mpp_error(fatal,
"Key:"//trim(key_name)//
" Error converting '"//trim(buffer)//
"' to logical")
379 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
380 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
383 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
390 integer,
intent(in) :: file_id
391 integer,
intent(in) :: block_id
392 character(len=*),
intent(in) :: key_name
393 class(*),
intent(inout):: key_value(:)
394 logical,
intent(in),
optional :: is_optional
398 character(len=255) :: buffer
400 type(c_ptr) :: c_buffer
401 integer(kind=c_int) :: success
402 logical :: optional_flag
405 optional_flag=.false.
406 if (
present(is_optional)) optional_flag = is_optional
409 &
"The file id in your get_value_from_key call is invalid! Check your call.")
411 &
"The block id in your get_value_from_key call is invalid! Check your call.")
414 if (success == 1)
then
417 select type (key_value)
418 type is (
integer(kind=i4_kind))
419 read(buffer,*, iostat=err_unit) key_value
420 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
421 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i4")
422 type is (
integer(kind=i8_kind))
423 read(buffer,*, iostat=err_unit) key_value
424 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
425 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to i8")
426 type is (real(kind=r4_kind))
427 read(buffer,*, iostat=err_unit) key_value
428 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
429 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r4")
430 type is (real(kind=r8_kind))
431 read(buffer,*, iostat=err_unit) key_value
432 if (err_unit .ne. 0)
call mpp_error(fatal,
"Key:"// &
433 & trim(key_name)//
" Error converting '"//trim(buffer)//
"' to r8")
434 type is (
character(len=*))
435 call mpp_error(fatal,
"get_value_from_key 1d string variables are not supported. Contact developers")
437 call mpp_error(fatal,
"The type of your buffer in your get_value_from_key call for key "//trim(key_name)//&
438 &
" is not supported. Only i4, i8, r4, r8 and strings are supported.")
441 if(.not. optional_flag)
call mpp_error(fatal,
"Error getting the value for key:"//trim(key_name))
451 integer,
intent(in) :: file_id
452 character(len=*),
intent(in) :: block_name
453 integer,
intent(in),
optional :: parent_block_id
457 &
"The file id in your get_num_blocks call is invalid! Check your call.")
459 if (.not.
present(parent_block_id))
then
463 &
"The parent_block id in your get_num_blocks call is invalid! Check your call.")
472 integer,
intent(in) :: file_id
473 character(len=*),
intent(in) :: block_name
474 integer,
intent(inout) :: block_ids(:)
475 integer,
intent(in),
optional :: parent_block_id
476 integer :: nblocks_id
480 &
"The file id in your get_block_ids call is invalid! Check your call.")
482 nblocks_id =
size(block_ids)
484 if (nblocks .ne. nblocks_id)
call mpp_error(fatal,
"The size of your block_ids array is not correct")
486 if (.not.
present(parent_block_id))
then
490 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
491 call get_block_ids_child(file_id, trim(block_name)//c_null_char, block_ids, parent_block_id)
499 integer,
intent(in) :: file_id
500 integer,
intent(in) :: block_id
504 &
"The file id in your get_nkeys call is invalid! Check your call.")
506 &
"The block id in your get_nkeys call is invalid! Check your call.")
513 integer,
intent(in) :: file_id
514 integer,
intent(in) :: block_id
515 integer,
intent(inout) :: key_ids(:)
521 &
"The file id in your get_key_ids call is invalid! Check your call.")
523 &
"The block id in your get_key_ids call is invalid! Check your call.")
525 nkey_ids =
size(key_ids)
528 if (nkeys .ne. nkey_ids)
call mpp_error(fatal,
"The size of your key_ids array is not correct.")
537 integer,
intent(in) :: file_id
538 integer,
intent(in),
optional :: parent_block_id
542 &
"The file id in your get_num_unique_blocks call is invalid! Check your call.")
544 if (.not.
present(parent_block_id))
then
548 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
555 integer,
intent(in) :: file_id
556 integer,
intent(inout) :: block_ids(:)
557 integer,
intent(in),
optional :: parent_block_id
560 &
"The file id in your get_num_unique_blocks_ids call is invalid! Check your call.")
562 if (.not.
present(parent_block_id))
then
566 &
"The parent_block id in your get_block_ids call is invalid! Check your call.")
573 integer,
intent(in) :: file_id
574 integer,
intent(in) :: block_id
575 character(len=*),
intent(out) :: block_name
580 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 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 ids of the blocks with block_name in the yaml file (see yaml_parser_...
Private c function that gets the ids of the blocks with block_name and that belong to a parent block ...
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 ids of the unique blocks in the yaml file (see yaml_parser_binding....
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)