FMS  2025.04
Flexible Modeling System
fms_yaml_output.F90
1 !***********************************************************************
2 !* Apache License 2.0
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* Licensed under the Apache License, Version 2.0 (the "License");
7 !* you may not use this file except in compliance with the License.
8 !* You may obtain a copy of the License at
9 !*
10 !* http://www.apache.org/licenses/LICENSE-2.0
11 !*
12 !* FMS is distributed in the hope that it will be useful, but WITHOUT
13 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
14 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 !* PARTICULAR PURPOSE. See the License for the specific language
16 !* governing permissions and limitations under the License.
17 !***********************************************************************
18 !> @defgroup fms_yaml_output_mod fms_yaml_output_mod
19 !> @ingroup parser
20 !> @author Tom Robinson
21 !> @description Writes a 3 tiered yaml where the first and second tier can have 1 key that has an
22 !! array of values. This is usefule for writing a diag_output.yaml Here is an example:
23 !! \verbatim
24 !! ---
25 !! basedate: 0 0 0 0 0 0 0
26 !! experiment: c192L65_exp
27 !! files:
28 !! - name: atmos_daily
29 !! freq: days
30 !! vars:
31 !! - name: temp
32 !! units: K
33 !! - name: P
34 !! longname: pressure
35 !! - name: wind
36 !! units: m/s
37 !! longname: wind velocity magnitude
38 !! - name: atmos_monthly
39 !! freq: months
40 !! vars:
41 !! - name: temp
42 !! units: K
43 !! ...
44 !! \endverbatim
45 !! In this example, basedate, experiment, and files are the level 1 (top level) keys. files is the
46 !! level2key in the keys struct. The array of structs for the files with name, freq has a size of 2, and
47 !! vars is the level2key. The key3 and var3 arrays should have a size of 4, and a3each=(\3,1\‍)
48 !! corresponding to the number of elements in each array within the yaml.
49 
50 !> @file
51 !> @brief File for @ref fms_yaml_output_mod
52 
53 !> @addtogroup fms_yaml_output_mod
54 !> @{
55 module fms_yaml_output_mod
56 #ifdef use_yaml
57 
58 use iso_c_binding
59 use fms_string_utils_mod, only: fms_f2c_string
60 implicit none
61 
62 private
63 
66 public :: yaml_out_add_level2key
67 public :: string_len_parameter
69 
70 integer, parameter :: string_len_parameter = 255 !< Max number of characters in the key and value strings.
71  !! Must match whats in yaml_output_functions.c
72 integer, parameter :: lvl2_key_parameter = 8 !< Max number of strings to be stored in lvl2keys
73  !! Must match whats in yaml_output_functions.c
74 !> Keys for the output yaml on a given level corresponding to the struct in yaml_output_functions.c
75 !! Should be set using the fms_f2c_string routine to get properly formatted c style strings
76 !! level2keys should be set with add_level2key()
77 type, bind(c) :: fmsYamlOutKeys_type
78  character (c_char) :: key1 (string_len_parameter)
79  character (c_char) :: key2 (string_len_parameter)
80  character (c_char) :: key3 (string_len_parameter)
81  character (c_char) :: key4 (string_len_parameter)
82  character (c_char) :: key5 (string_len_parameter)
83  character (c_char) :: key6 (string_len_parameter)
84  character (c_char) :: key7 (string_len_parameter)
85  character (c_char) :: key8 (string_len_parameter)
86  character (c_char) :: key9 (string_len_parameter)
87  character (c_char) :: key10 (string_len_parameter)
88  character (c_char) :: key11 (string_len_parameter)
89  character (c_char) :: key12 (string_len_parameter)
90  character (c_char) :: key13 (string_len_parameter)
91  character (c_char) :: key14 (string_len_parameter)
92  character (c_char) :: key15 (string_len_parameter)
93  character (c_char) :: key16 (string_len_parameter)
94  character (c_char) :: level2key (string_len_parameter * lvl2_key_parameter)
95  integer(c_int) :: level2key_offset
96 end type fmsyamloutkeys_type
97 !> Values for the output yaml on a given level corresponding to the struct in yaml_output_functions.c
98 type, bind(c) :: fmsYamlOutValues_type
99  character (c_char) :: val1 (string_len_parameter)
100  character (c_char) :: val2 (string_len_parameter)
101  character (c_char) :: val3 (string_len_parameter)
102  character (c_char) :: val4 (string_len_parameter)
103  character (c_char) :: val5 (string_len_parameter)
104  character (c_char) :: val6 (string_len_parameter)
105  character (c_char) :: val7 (string_len_parameter)
106  character (c_char) :: val8 (string_len_parameter)
107  character (c_char) :: val9 (string_len_parameter)
108  character (c_char) :: val10 (string_len_parameter)
109  character (c_char) :: val11 (string_len_parameter)
110  character (c_char) :: val12 (string_len_parameter)
111  character (c_char) :: val13 (string_len_parameter)
112  character (c_char) :: val14 (string_len_parameter)
113  character (c_char) :: val15 (string_len_parameter)
114  character (c_char) :: val16 (string_len_parameter)
115 end type fmsyamloutvalues_type
116 
117 
118 interface
119 subroutine write_yaml_from_struct_3 (yamlname, a1size, keys, vals, a2size, key2, val2, a3size, a3each,&
120  key3, val3, lvl2keyeach) bind(C, name="write_yaml_from_struct_3")
121 use iso_c_binding
123 character (c_char) :: yamlname !< The output yaml file name
124 integer (c_int), value :: a1size !< The size of the first yaml array
125 type (fmsYamlOutKeys_type) :: keys(a1size) !< Top level yaml keys
126 type (fmsYamlOutValues_type) :: vals(a1size) !< Values corresponding to keys
127 integer (c_int), value :: a2size !< The size of the second yaml array
128 type (fmsYamlOutKeys_type) :: key2(a2size) !< Second level keys
129 type (fmsYamlOutValues_type) :: val2(a2size) !< Values corresponding to key2
130 integer (c_int), value :: a3size !< The size of the third yaml array
131 integer (c_int) :: a3each (a2size) !< Array that has the number of elements for each level 2 key's
132  !! third level elements. If using multiple lvl2keys, a value must be
133  !! present for each key.
134 type (fmsYamlOutKeys_type) :: key3(a3size) !< Third level keys
135 type (fmsYamlOutValues_type) :: val3(a3size) !< Values corresponding to keys2
136 integer (c_int) :: lvl2keyeach(lvl2_key_parameter) !< amount of key2 'blocks' to print per level2key in keys
137 end subroutine write_yaml_from_struct_3
138 !> Adds a level 2 key (key that starts new tabbed section) to the list.
139 !! @ref yaml_out_add_level2key (wrapper routine) should be used instead.
140 subroutine yaml_out_add_level2key_c(key_length, key_name, keytype) bind(C, name="add_level2key")
141  use iso_c_binding
142  import fmsyamloutkeys_type
143  character(c_char), intent(in) :: key_name !< name of level 2 key (starts a new tabbed section) to add to list
144  integer(c_int), value :: key_length !< length of key_name
145  type(fmsyamloutkeys_type), intent(inout) :: keytype !< struct of keys to output
146 end subroutine
147 end interface
148 
149 contains
150 
151 !> Adds a level 2 key (key that starts new tabbed section) to the list.
152 !! Will print level 2 keys in the order added. See write_yaml_from_struct_3 for more details.
153 !! This routine is a wrapper for @ref yaml_out_add_level2key_c .
154 subroutine yaml_out_add_level2key(key_name, keytype)
155  character(len=*) :: key_name
156  type(fmsyamloutkeys_type), intent(inout) :: keytype
157  call yaml_out_add_level2key_c(len_trim(key_name), key_name, keytype )
158 end subroutine
159 
160 !! Initialize one instance of the fmsYamlOutKeys_type structure.
161 subroutine initialize_key_struct( yk )
162  type (fmsyamloutkeys_type), intent(inout) :: yk !< Instance of the stucture
163  call fms_f2c_string (yk%key1,"")
164  call fms_f2c_string (yk%key2,"")
165  call fms_f2c_string (yk%key3,"")
166  call fms_f2c_string (yk%key4,"")
167  call fms_f2c_string (yk%key5,"")
168  call fms_f2c_string (yk%key6,"")
169  call fms_f2c_string (yk%key7,"")
170  call fms_f2c_string (yk%key8,"")
171  call fms_f2c_string (yk%key9,"")
172  call fms_f2c_string (yk%key10,"")
173  call fms_f2c_string (yk%key11,"")
174  call fms_f2c_string (yk%key12,"")
175  call fms_f2c_string (yk%key13,"")
176  call fms_f2c_string (yk%key14,"")
177  call fms_f2c_string (yk%key15,"")
178  call fms_f2c_string (yk%key16,"")
179  call fms_f2c_string(yk%level2key,"")
180  yk%level2key_offset = -1
181 end subroutine initialize_key_struct
182 
183 !! Initialize one instance of the fmsYamlOutValues_type structure.
184 subroutine initialize_val_struct( yv)
185  type (fmsyamloutvalues_type), intent(inout):: yv !< Instance of the stucture
186  call fms_f2c_string (yv%val1,"")
187  call fms_f2c_string (yv%val2,"")
188  call fms_f2c_string (yv%val3,"")
189  call fms_f2c_string (yv%val4,"")
190  call fms_f2c_string (yv%val5,"")
191  call fms_f2c_string (yv%val6,"")
192  call fms_f2c_string (yv%val7,"")
193  call fms_f2c_string (yv%val8,"")
194  call fms_f2c_string (yv%val9,"")
195  call fms_f2c_string (yv%val10,"")
196  call fms_f2c_string (yv%val11,"")
197  call fms_f2c_string (yv%val12,"")
198  call fms_f2c_string (yv%val13,"")
199  call fms_f2c_string (yv%val14,"")
200  call fms_f2c_string (yv%val15,"")
201  call fms_f2c_string (yv%val16,"")
202 end subroutine initialize_val_struct
203 
204 #endif
205 end module fms_yaml_output_mod
206 !> @}
207 ! close documentation grouping
subroutine, public fms_f2c_string(dest, str_in)
Copies a Fortran string into a C string and puts c_null_char in any trailing spaces.
subroutine, public initialize_val_struct(yv)
integer, parameter lvl2_key_parameter
Max number of strings to be stored in lvl2keys Must match whats in yaml_output_functions....
subroutine, public initialize_key_struct(yk)
Keys for the output yaml on a given level corresponding to the struct in yaml_output_functions....
Values for the output yaml on a given level corresponding to the struct in yaml_output_functions....
Adds a level 2 key (key that starts new tabbed section) to the list. yaml_out_add_level2key (wrapper ...