fix: mosaic2 tests with strict debug flags (#1597)
[FMS.git] / parser / yaml_output_functions.c
blobe748a827295f0251586ccd462fea59bc2cf3d47c
1 /***********************************************************************
2 * GNU Lesser General Public License
4 * This file is part of the GFDL Flexible Modeling System (FMS).
6 * FMS is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or (at
9 * your option) any later version.
11 * FMS is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
19 #ifdef use_yaml
21 #include <stdio.h>
22 #include <yaml.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <ctype.h>
28 // Should always match values of string_len_parameter and lvl2_key_parameter in fms_yaml_output_mod
29 #define LVL2KEY_NUM 8
30 #define KEY_STR_LEN 255
31 #define LVL2KEY_SIZE LVL2KEY_NUM*KEY_STR_LEN
33 #define DEBUG 0
35 struct fmsyamloutkeys {
36 char key1 [KEY_STR_LEN];
37 char key2 [KEY_STR_LEN];
38 char key3 [KEY_STR_LEN];
39 char key4 [KEY_STR_LEN];
40 char key5 [KEY_STR_LEN];
41 char key6 [KEY_STR_LEN];
42 char key7 [KEY_STR_LEN];
43 char key8 [KEY_STR_LEN];
44 char key9 [KEY_STR_LEN];
45 char key10 [KEY_STR_LEN];
46 char key11 [KEY_STR_LEN];
47 char key12 [KEY_STR_LEN];
48 char key13 [KEY_STR_LEN];
49 char key14 [KEY_STR_LEN];
50 char key15 [KEY_STR_LEN];
51 char key16 [KEY_STR_LEN];
52 int level2key_offset;
53 char level2key [LVL2KEY_SIZE];
55 struct fmsyamloutvalues {
56 char val1 [KEY_STR_LEN];
57 char val2 [KEY_STR_LEN];
58 char val3 [KEY_STR_LEN];
59 char val4 [KEY_STR_LEN];
60 char val5 [KEY_STR_LEN];
61 char val6 [KEY_STR_LEN];
62 char val7 [KEY_STR_LEN];
63 char val8 [KEY_STR_LEN];
64 char val9 [KEY_STR_LEN];
65 char val10 [KEY_STR_LEN];
66 char val11 [KEY_STR_LEN];
67 char val12 [KEY_STR_LEN];
68 char val13 [KEY_STR_LEN];
69 char val14 [KEY_STR_LEN];
70 char val15 [KEY_STR_LEN];
71 char val16 [KEY_STR_LEN];
74 /* \breif Prints a warning message that the yaml was not written correctly
75 * \param emitter The libyaml emitter for this file
76 * \param event The libyaml eent pointer
77 * \param yamlname The name of the yaml file
78 * \param keys yamlout The file pointer for the yaml file
80 void error(char * yamlname ,yaml_event_t * event, yaml_emitter_t * emitter, FILE * yamlout){
81 /* Write a warning to stderr and srdout */
82 fprintf(stderr, "WARNING: YAML_OUTPUT: No output %s written. Failed to emit event %d: %s\n", yamlname, event->type, emitter->problem);
83 fprintf(stdout, "WARNING: YAML_OUTPUT: No output %s written. Failed to emit event %d: %s\n", yamlname, event->type, emitter->problem);
84 yaml_emitter_delete(emitter);
85 fclose(yamlout);
87 void keyerror(yaml_event_t * event, yaml_emitter_t * emitter){
88 /* Write a warning to stderr and srdout */
89 fprintf(stderr, "WARNING: YAML_OUTPUT: Failed to emit event %d: %s\n", event->type, emitter->problem);
90 fprintf(stdout, "WARNING: YAML_OUTPUT: Failed to emit event %d: %s\n", event->type, emitter->problem);
92 /* \breif Writes the key/value pairs of the fmsyamloutkeys and fmsyamloutvalues structs
93 * \param emitter The libyaml emitter for this file
94 * \param event The libyaml eent pointer
95 * \param aindex The index of keys and vals that are being written currently
96 * \param keys The keys to be written
97 * \param vals The values correcponding to keys
99 void write_keys_vals_yaml (yaml_emitter_t * emitter, yaml_event_t * event , int aindex, struct fmsyamloutkeys *keys, struct fmsyamloutvalues *vals){
100 /* Check if a key exists */
101 if (keys[aindex].key1[0] !='\0') {
102 /* Write the key */
103 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
104 (yaml_char_t *)keys[aindex].key1, strlen(keys[aindex].key1), 1, 0, YAML_PLAIN_SCALAR_STYLE);
105 /* Check for errors */
106 if (!yaml_emitter_emit(emitter, event)){
107 keyerror(event, emitter);
108 return;
110 /* Write the value */
111 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
112 (yaml_char_t *)vals[aindex].val1, strlen(vals[aindex].val1), 1, 0, YAML_PLAIN_SCALAR_STYLE);
113 /* check for errors */
114 if (!yaml_emitter_emit(emitter, event)){
115 keyerror(event, emitter);
116 return;
119 /* Repeat for all possible keys */
120 if (keys[aindex].key2[0] !='\0') {
121 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
122 (yaml_char_t *)keys[aindex].key2, strlen(keys[aindex].key2), 1, 0, YAML_PLAIN_SCALAR_STYLE);
123 if (!yaml_emitter_emit(emitter, event)){
124 keyerror(event, emitter);
125 return;
127 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
128 (yaml_char_t *)vals[aindex].val2, strlen(vals[aindex].val2), 1, 0, YAML_PLAIN_SCALAR_STYLE);
129 if (!yaml_emitter_emit(emitter, event)){
130 keyerror(event, emitter);
131 return;
134 if (keys[aindex].key3[0] !='\0') {
135 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
136 (yaml_char_t *)keys[aindex].key3, strlen(keys[aindex].key3), 1, 0, YAML_PLAIN_SCALAR_STYLE);
137 if (!yaml_emitter_emit(emitter, event)){
138 keyerror(event, emitter);
139 return;
141 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
142 (yaml_char_t *)vals[aindex].val3, strlen(vals[aindex].val3), 1, 0, YAML_PLAIN_SCALAR_STYLE);
143 if (!yaml_emitter_emit(emitter, event)){
144 keyerror(event, emitter);
145 return;
148 if (keys[aindex].key4[0] !='\0') {
149 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
150 (yaml_char_t *)keys[aindex].key4, strlen(keys[aindex].key4), 1, 0, YAML_PLAIN_SCALAR_STYLE);
151 if (!yaml_emitter_emit(emitter, event)){
152 keyerror(event, emitter);
153 return;
155 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
156 (yaml_char_t *)vals[aindex].val4, strlen(vals[aindex].val4), 1, 0, YAML_PLAIN_SCALAR_STYLE);
157 if (!yaml_emitter_emit(emitter, event)){
158 keyerror(event, emitter);
159 return;
162 if (keys[aindex].key5[0] !='\0') {
163 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
164 (yaml_char_t *)keys[aindex].key5, strlen(keys[aindex].key5), 1, 0, YAML_PLAIN_SCALAR_STYLE);
165 if (!yaml_emitter_emit(emitter, event)){
166 keyerror(event, emitter);
167 return;
169 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
170 (yaml_char_t *)vals[aindex].val5, strlen(vals[aindex].val5), 1, 0, YAML_PLAIN_SCALAR_STYLE);
171 if (!yaml_emitter_emit(emitter, event)){
172 keyerror(event, emitter);
173 return;
176 if (keys[aindex].key6[0] !='\0') {
177 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
178 (yaml_char_t *)keys[aindex].key6, strlen(keys[aindex].key6), 1, 0, YAML_PLAIN_SCALAR_STYLE);
179 if (!yaml_emitter_emit(emitter, event)){
180 keyerror(event, emitter);
181 return;
183 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
184 (yaml_char_t *)vals[aindex].val6, strlen(vals[aindex].val6), 1, 0, YAML_PLAIN_SCALAR_STYLE);
185 if (!yaml_emitter_emit(emitter, event)){
186 keyerror(event, emitter);
187 return;
190 if (keys[aindex].key7[0] !='\0') {
191 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
192 (yaml_char_t *)keys[aindex].key7, strlen(keys[aindex].key7), 1, 0, YAML_PLAIN_SCALAR_STYLE);
193 if (!yaml_emitter_emit(emitter, event)){
194 keyerror(event, emitter);
195 return;
197 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
198 (yaml_char_t *)vals[aindex].val7, strlen(vals[aindex].val7), 1, 0, YAML_PLAIN_SCALAR_STYLE);
199 if (!yaml_emitter_emit(emitter, event)){
200 keyerror(event, emitter);
201 return;
204 if (keys[aindex].key8[0] !='\0') {
205 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
206 (yaml_char_t *)keys[aindex].key8, strlen(keys[aindex].key8), 1, 0, YAML_PLAIN_SCALAR_STYLE);
207 if (!yaml_emitter_emit(emitter, event)){
208 keyerror(event, emitter);
209 return;
211 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
212 (yaml_char_t *)vals[aindex].val8, strlen(vals[aindex].val8), 1, 0, YAML_PLAIN_SCALAR_STYLE);
213 if (!yaml_emitter_emit(emitter, event)){
214 keyerror(event, emitter);
215 return;
218 if (keys[aindex].key9[0] !='\0') {
219 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
220 (yaml_char_t *)keys[aindex].key9, strlen(keys[aindex].key9), 1, 0, YAML_PLAIN_SCALAR_STYLE);
221 if (!yaml_emitter_emit(emitter, event)){
222 keyerror(event, emitter);
223 return;
225 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
226 (yaml_char_t *)vals[aindex].val9, strlen(vals[aindex].val9), 1, 0, YAML_PLAIN_SCALAR_STYLE);
227 if (!yaml_emitter_emit(emitter, event)){
228 keyerror(event, emitter);
229 return;
232 if (keys[aindex].key10[0] !='\0') {
233 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
234 (yaml_char_t *)keys[aindex].key10, strlen(keys[aindex].key10), 1, 0, YAML_PLAIN_SCALAR_STYLE);
235 if (!yaml_emitter_emit(emitter, event)){
236 keyerror(event, emitter);
237 return;
239 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
240 (yaml_char_t *)vals[aindex].val10, strlen(vals[aindex].val10), 1, 0, YAML_PLAIN_SCALAR_STYLE);
241 if (!yaml_emitter_emit(emitter, event)){
242 keyerror(event, emitter);
243 return;
246 if (keys[aindex].key11[0] !='\0') {
247 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
248 (yaml_char_t *)keys[aindex].key11, strlen(keys[aindex].key11), 1, 0, YAML_PLAIN_SCALAR_STYLE);
249 if (!yaml_emitter_emit(emitter, event)){
250 keyerror(event, emitter);
251 return;
253 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
254 (yaml_char_t *)vals[aindex].val11, strlen(vals[aindex].val11), 1, 0, YAML_PLAIN_SCALAR_STYLE);
255 if (!yaml_emitter_emit(emitter, event)){
256 keyerror(event, emitter);
257 return;
260 if (keys[aindex].key12[0] !='\0') {
261 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
262 (yaml_char_t *)keys[aindex].key12, strlen(keys[aindex].key12), 1, 0, YAML_PLAIN_SCALAR_STYLE);
263 if (!yaml_emitter_emit(emitter, event)){
264 keyerror(event, emitter);
265 return;
267 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
268 (yaml_char_t *)vals[aindex].val12, strlen(vals[aindex].val12), 1, 0, YAML_PLAIN_SCALAR_STYLE);
269 if (!yaml_emitter_emit(emitter, event)){
270 keyerror(event, emitter);
271 return;
274 if (keys[aindex].key13[0] !='\0') {
275 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
276 (yaml_char_t *)keys[aindex].key13, strlen(keys[aindex].key13), 1, 0, YAML_PLAIN_SCALAR_STYLE);
277 if (!yaml_emitter_emit(emitter, event)){
278 keyerror(event, emitter);
279 return;
281 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
282 (yaml_char_t *)vals[aindex].val13, strlen(vals[aindex].val13), 1, 0, YAML_PLAIN_SCALAR_STYLE);
283 if (!yaml_emitter_emit(emitter, event)){
284 keyerror(event, emitter);
285 return;
288 if (keys[aindex].key14[0] !='\0') {
289 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
290 (yaml_char_t *)keys[aindex].key14, strlen(keys[aindex].key14), 1, 0, YAML_PLAIN_SCALAR_STYLE);
291 if (!yaml_emitter_emit(emitter, event)){
292 keyerror(event, emitter);
293 return;
295 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
296 (yaml_char_t *)vals[aindex].val14, strlen(vals[aindex].val14), 1, 0, YAML_PLAIN_SCALAR_STYLE);
297 if (!yaml_emitter_emit(emitter, event)){
298 keyerror(event, emitter);
299 return;
302 if (keys[aindex].key15[0] !='\0') {
303 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
304 (yaml_char_t *)keys[aindex].key15, strlen(keys[aindex].key15), 1, 0, YAML_PLAIN_SCALAR_STYLE);
305 if (!yaml_emitter_emit(emitter, event)){
306 keyerror(event, emitter);
307 return;
309 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
310 (yaml_char_t *)vals[aindex].val15, strlen(vals[aindex].val15), 1, 0, YAML_PLAIN_SCALAR_STYLE);
311 if (!yaml_emitter_emit(emitter, event)){
312 keyerror(event, emitter);
313 return;
316 if (keys[aindex].key16[0] !='\0') {
317 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
318 (yaml_char_t *)keys[aindex].key16, strlen(keys[aindex].key16), 1, 0, YAML_PLAIN_SCALAR_STYLE);
319 if (!yaml_emitter_emit(emitter, event)){
320 keyerror(event, emitter);
321 return;
323 yaml_scalar_event_initialize(event, NULL, (yaml_char_t *)YAML_STR_TAG,
324 (yaml_char_t *)vals[aindex].val16, strlen(vals[aindex].val16), 1, 0, YAML_PLAIN_SCALAR_STYLE);
325 if (!yaml_emitter_emit(emitter, event)){
326 keyerror(event, emitter);
327 return;
331 return ;
333 /* \description Writes a YAML.
334 * In this function, the YAML can have one key per "level" that has an array of keys.
335 * If a struct has a level2key, then that key is written as a sequence. If level2key is empty, no second level is written.
336 * If a key is null, then the kay/value pair is not written.
337 * Users must pass in the size of each struct array for level 2 or 3.
338 * L3 arrays are essentially 2D arrays in 1D and the number of elements can change between each instance, so the user must pass
339 * the array `neach` which has the number of elements per instance.
340 * The top level size must be 1 (for now).
341 * \param yamlname The name of the output yaml file
342 * \param asize The size of the top level array (must be 1)
343 * \param topkeys The Keys for the top level of the yaml
344 * \param topvals The values corresponding to the topkeys
345 * \param a2size The size of the second level arrays and n3each
346 * \param l2keys The keys for the second level of the yaml
347 * \param l2vals The values corresponding to l2keys
348 * \param a3size The full size of the l3 arrays
349 * \param n3each Array that has the number of elements for each l2 array's third level elements
350 * \param l3keys The keys for the third level of the yaml, any lvl2 keys will not be printed
351 * \param l3vals The values corresponding to l3keys
352 * \param lvl2keyeach array to indicate how many structs to print per level2key for the top level keys, should be the size of LVL2KEY_NUM
354 void write_yaml_from_struct_3 (char *yamlname, int asize, struct fmsyamloutkeys *topkeys, struct fmsyamloutvalues *topvals, int a2size, struct fmsyamloutkeys *l2keys,
355 struct fmsyamloutvalues *l2vals, int a3size, int * n3each, struct fmsyamloutkeys *l3keys, struct fmsyamloutvalues *l3vals,
356 int* lvl2keyeach){
357 yaml_emitter_t emitter; /* libyaml emitter */
358 yaml_event_t event; /* libyaml event for the output yaml */
359 int s2count = 0; /* A counter to keep track of the number of level 2 arrays output */
360 int s3count = 0; /* A counter to keep track of the number of level 3 arrays output */
361 FILE * yamlout; /* The file for the YAML output. */
362 int i_n3 = 0;/* index for the n3each argument*/
364 // trim any trailing whitespace
365 int ws_ind = strlen(yamlname)-1;
366 while(*(yamlname+ws_ind) == ' ') ws_ind--;
367 if( ws_ind != strlen(yamlname)-1) yamlname[ws_ind+1] = '\0';
369 /* open the yaml output file. Only 1 core should do this */
370 yamlout = fopen(yamlname,"w");
371 /* Start the emmitter */
372 yaml_emitter_initialize(&emitter);
373 yaml_emitter_set_output_file(&emitter, yamlout);
374 yaml_stream_start_event_initialize(&event, YAML_UTF8_ENCODING);
375 if (!yaml_emitter_emit(&emitter, &event)){
376 error(yamlname, &event, &emitter, yamlout);
377 return;
380 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
381 if (!yaml_emitter_emit(&emitter, &event)){
382 error(yamlname, &event, &emitter, yamlout);
383 return;
385 /* start the event (top level) */
386 yaml_mapping_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_MAP_TAG,
387 1, YAML_ANY_MAPPING_STYLE);
388 if (!yaml_emitter_emit(&emitter, &event)){
389 error(yamlname, &event, &emitter, yamlout);
390 return;
393 /* write the top level */
394 write_keys_vals_yaml (&emitter, &event , 0, topkeys, topvals);
395 char* curr_topkey = topkeys->level2key;
397 /* loop through the top level 2 keys */
398 int top_ind;
399 for (top_ind=0; top_ind < topkeys->level2key_offset; top_ind++) {
400 /* Start the secodn level event */
401 yaml_scalar_event_initialize(&event, NULL, (yaml_char_t *)YAML_STR_TAG,
402 (yaml_char_t *)curr_topkey, strlen(curr_topkey), 1, 0,
403 YAML_PLAIN_SCALAR_STYLE);
404 if (!yaml_emitter_emit(&emitter, &event)){
405 error(yamlname, &event, &emitter, yamlout);
406 return;
408 /* Start the sequencing */
409 yaml_sequence_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_SEQ_TAG,
410 1, YAML_ANY_SEQUENCE_STYLE);
411 if (!yaml_emitter_emit(&emitter, &event)){
412 error(yamlname, &event, &emitter, yamlout);
413 return;
415 /* loop through the structs for this key*/
416 int s2;
417 for (s2 = 0 ; s2 < lvl2keyeach[top_ind]; s2++){
418 yaml_mapping_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_MAP_TAG,
419 1, YAML_ANY_MAPPING_STYLE);
420 if (!yaml_emitter_emit(&emitter, &event)){
421 error(yamlname, &event, &emitter, yamlout);
422 return;
424 /* call the write function */
425 write_keys_vals_yaml (&emitter, &event , s2count, l2keys, l2vals);
427 /* Next level keys */
428 char * curr_l2key = (&l2keys[s2count])->level2key;
429 int l2_ind;
430 for (l2_ind = 0; l2_ind < (&l2keys[s2count])->level2key_offset; l2_ind++) {
431 /* Start the third level event */
432 yaml_scalar_event_initialize(&event, NULL, (yaml_char_t *)YAML_STR_TAG,
433 (yaml_char_t *)curr_l2key, strlen(curr_l2key), 1, 0,
434 YAML_PLAIN_SCALAR_STYLE);
435 if (!yaml_emitter_emit(&emitter, &event)){
436 error(yamlname, &event, &emitter, yamlout);
437 return;
439 /* Start the sequencing */
440 yaml_sequence_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_SEQ_TAG,
441 1, YAML_ANY_SEQUENCE_STYLE);
442 if (!yaml_emitter_emit(&emitter, &event)){
443 error(yamlname, &event, &emitter, yamlout);
444 return;
446 /* loop through the structs */
447 int s3start = s3count;
448 int s3end = s3start + n3each[i_n3];
449 i_n3++;
450 int s3;
451 for (s3 = s3start ; s3 < s3end ; s3++){
452 yaml_mapping_start_event_initialize(&event, NULL, (yaml_char_t *)YAML_MAP_TAG,
453 1, YAML_ANY_MAPPING_STYLE);
454 if (!yaml_emitter_emit(&emitter, &event)){
455 error(yamlname, &event, &emitter, yamlout);
456 return;
458 /* call the write function */
459 write_keys_vals_yaml (&emitter, &event , s3, l3keys, l3vals);
460 yaml_mapping_end_event_initialize(&event);
461 if(!yaml_emitter_emit(&emitter, &event)){
462 error(yamlname, &event, &emitter, yamlout);
463 return;
465 s3count ++;
466 } // for s3
467 yaml_sequence_end_event_initialize(&event);
468 if (!yaml_emitter_emit(&emitter, &event)){
469 error(yamlname, &event, &emitter, yamlout);
470 return;
472 curr_l2key = (&l2keys[s2count])->level2key + ((l2_ind+1) * KEY_STR_LEN);
473 } /* for l2_ind */
474 yaml_mapping_end_event_initialize(&event);
475 if (!yaml_emitter_emit(&emitter, &event)){
476 error(yamlname, &event, &emitter, yamlout);
477 return;
480 s2count++;
481 }/* for s2 loop */
483 yaml_sequence_end_event_initialize(&event);
484 if (!yaml_emitter_emit(&emitter, &event)){
485 error(yamlname, &event, &emitter, yamlout);
486 return;
488 curr_topkey = topkeys->level2key + ((top_ind+1) * KEY_STR_LEN);
489 }/* for top_ind */
491 /* end the emitter */
492 yaml_mapping_end_event_initialize(&event);
493 if (!yaml_emitter_emit(&emitter, &event)){
494 error(yamlname, &event, &emitter, yamlout);
495 return;
498 yaml_document_end_event_initialize(&event, 0);
499 if (!yaml_emitter_emit(&emitter, &event)){
500 error(yamlname, &event, &emitter, yamlout);
501 return;
503 yaml_stream_end_event_initialize(&event);
504 if (!yaml_emitter_emit(&emitter, &event)){
505 error(yamlname, &event, &emitter, yamlout);
506 return;
508 yaml_emitter_delete(&emitter);
509 fclose(yamlout);
510 return;
512 /// @brief Adds a key to the level2key character array in the struct.
513 /// Uses an offset to store multiple keys, size(amount of strings) is set by LVL2KEY_NUM (avoids c to fortran 2d array issues)
514 /// @param key_name name of level 2 key to add
515 /// @param key_length string length of key_name
516 /// @param keys key struct to add level 2 key to
517 void add_level2key(int key_length, char* key_name, struct fmsyamloutkeys* keys){
519 // local fixed length copy to try to mitigate any fortran to c string weirdness
520 char kname_loc[key_length + 1];
521 //memset(kname_loc, '\0', sizeof(kname_loc));
522 strncpy(kname_loc, key_name, key_length);
523 kname_loc[key_length] = '\0';
524 // error checking
525 if ( strlen(kname_loc) > KEY_STR_LEN){
526 fprintf(stderr, "WARNING: YAML_OUTPUT: invalid level two key passed to add_level2key. Max string size is %d, passed in string: %s", KEY_STR_LEN, key_name);
527 fprintf(stdout, "WARNING: YAML_OUTPUT: invalid level two key passed to add_level2key. Max string size is %d, passed in string: %s", KEY_STR_LEN, key_name);
529 if( keys->level2key_offset >= LVL2KEY_NUM ){
530 fprintf(stderr, "WARNING: YAML_OUTPUT: max amount of level 2 keys (%d) has been exceeded", LVL2KEY_NUM);
531 fprintf(stdout, "WARNING: YAML_OUTPUT: max amount of level 2 keys (%d) has been exceeded", LVL2KEY_NUM);
533 // check if string is set to initialize offset count
534 if ( keys->level2key[0] == '\0'){
535 keys->level2key_offset = 0;
537 // calculate offset and copy into the level2key array
538 int offset = keys->level2key_offset * KEY_STR_LEN;
539 char* curr_key;
540 curr_key = keys->level2key + offset;
541 strcpy(curr_key, kname_loc);
543 keys->level2key_offset++;
545 if (DEBUG) {
546 printf("key length: %d \n key_name:", key_length);
547 printf(key_name);
548 printf("\n");
549 printf("offset: %d \n", offset);
550 printf("kname_loc:");
551 printf(kname_loc);
552 printf("\n*l2key:");
553 printf(keys->level2key);
554 printf("\nl2key+offset:");
555 printf(keys->level2key + offset);
556 printf("\n");
560 #endif