xref: /petsc/src/sys/objects/optionsyaml.c (revision 1d27aa22b2f6148b2c4e3f06a75e0638d6493e09)
1951eb098SLisandro Dalcin #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for strdup() */
2f996e368SLisandro Dalcin #include <petsc/private/petscimpl.h>     /*I  "petscsys.h"  I*/
3951eb098SLisandro Dalcin 
4f996e368SLisandro Dalcin #if defined(PETSC_HAVE_YAML)
5951eb098SLisandro Dalcin   #include <yaml.h> /* use external LibYAML */
6951eb098SLisandro Dalcin #else
7951eb098SLisandro Dalcin   #include <../src/sys/yaml/include/yaml.h>
8f996e368SLisandro Dalcin #endif
9f996e368SLisandro Dalcin 
109355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsSetValue_Private(PetscOptions, const char[], const char[], int *, PetscOptionSource);
119355ec05SMatthew G. Knepley PETSC_INTERN PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions, const char[], PetscOptionSource);
129355ec05SMatthew G. Knepley 
13f996e368SLisandro Dalcin static MPI_Comm petsc_yaml_comm = MPI_COMM_NULL; /* only used for parallel error handling */
14f996e368SLisandro Dalcin 
15d71ae5a4SJacob Faibussowitsch static inline MPI_Comm PetscYAMLGetComm(void)
16d71ae5a4SJacob Faibussowitsch {
17f996e368SLisandro Dalcin   return PetscLikely(petsc_yaml_comm != MPI_COMM_NULL) ? petsc_yaml_comm : (petsc_yaml_comm = PETSC_COMM_SELF);
18f996e368SLisandro Dalcin }
19f996e368SLisandro Dalcin 
20d71ae5a4SJacob Faibussowitsch static inline MPI_Comm PetscYAMLSetComm(MPI_Comm comm)
21d71ae5a4SJacob Faibussowitsch {
229371c9d4SSatish Balay   MPI_Comm prev   = PetscYAMLGetComm();
239371c9d4SSatish Balay   petsc_yaml_comm = comm;
249371c9d4SSatish Balay   return prev;
25f996e368SLisandro Dalcin }
26f996e368SLisandro Dalcin 
27f996e368SLisandro Dalcin #define TAG(node) ((const char *)((node)->tag))
28f996e368SLisandro Dalcin #define STR(node) ((const char *)((node)->data.scalar.value))
29f996e368SLisandro Dalcin #define SEQ(node) ((node)->data.sequence.items)
30f996e368SLisandro Dalcin #define MAP(node) ((node)->data.mapping.pairs)
31f996e368SLisandro Dalcin 
329355ec05SMatthew G. Knepley static PetscErrorCode PetscParseLayerYAML(PetscOptions options, yaml_document_t *doc, yaml_node_t *node, PetscOptionSource source)
33d71ae5a4SJacob Faibussowitsch {
34f996e368SLisandro Dalcin   MPI_Comm comm                        = PetscYAMLGetComm();
35f996e368SLisandro Dalcin   char     name[PETSC_MAX_OPTION_NAME] = "", prefix[PETSC_MAX_OPTION_NAME] = "";
36f996e368SLisandro Dalcin 
37f996e368SLisandro Dalcin   PetscFunctionBegin;
383ba16761SJacob Faibussowitsch   if (node->type == YAML_SCALAR_NODE && !STR(node)[0]) PetscFunctionReturn(PETSC_SUCCESS); /* empty */
3908401ef6SPierre Jolivet   PetscCheck(node->type == YAML_MAPPING_NODE, comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping");
40f996e368SLisandro Dalcin   for (yaml_node_pair_t *pair = MAP(node).start; pair < MAP(node).top; pair++) {
41f996e368SLisandro Dalcin     yaml_node_t *keynode = yaml_document_get_node(doc, pair->key);
42f996e368SLisandro Dalcin     yaml_node_t *valnode = yaml_document_get_node(doc, pair->value);
43f996e368SLisandro Dalcin     PetscBool    isMergeKey, isDummyKey, isIncludeTag;
44f996e368SLisandro Dalcin 
4528b400f6SJacob Faibussowitsch     PetscCheck(keynode, comm, PETSC_ERR_LIB, "Corrupt YAML document");
4628b400f6SJacob Faibussowitsch     PetscCheck(valnode, comm, PETSC_ERR_LIB, "Corrupt YAML document");
4708401ef6SPierre Jolivet     PetscCheck(keynode->type == YAML_SCALAR_NODE, comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar");
48f996e368SLisandro Dalcin 
49f996e368SLisandro Dalcin     /* "<<" is the merge key: don't increment the prefix */
509566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(STR(keynode), "<<", &isMergeKey));
51f996e368SLisandro Dalcin     if (isMergeKey) {
52f996e368SLisandro Dalcin       if (valnode->type == YAML_SEQUENCE_NODE) {
53f996e368SLisandro Dalcin         for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) {
54f996e368SLisandro Dalcin           yaml_node_t *itemnode = yaml_document_get_node(doc, *item);
5528b400f6SJacob Faibussowitsch           PetscCheck(itemnode, comm, PETSC_ERR_LIB, "Corrupt YAML document");
5608401ef6SPierre Jolivet           PetscCheck(itemnode->type == YAML_MAPPING_NODE, comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping");
579355ec05SMatthew G. Knepley           PetscCall(PetscParseLayerYAML(options, doc, itemnode, source));
58f996e368SLisandro Dalcin         }
59f996e368SLisandro Dalcin       } else if (valnode->type == YAML_MAPPING_NODE) {
609355ec05SMatthew G. Knepley         PetscCall(PetscParseLayerYAML(options, doc, valnode, source));
61f996e368SLisandro Dalcin       } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected sequence or mapping");
62f996e368SLisandro Dalcin       continue; /* to next pair */
63f996e368SLisandro Dalcin     }
64f996e368SLisandro Dalcin 
65f996e368SLisandro Dalcin     /* "$$*" are treated as dummy keys, we use them for !include tags and to define anchors */
669566063dSJacob Faibussowitsch     PetscCall(PetscStrbeginswith(STR(keynode), "$$", &isDummyKey));
67f996e368SLisandro Dalcin     if (isDummyKey) {
689566063dSJacob Faibussowitsch       PetscCall(PetscStrendswith(TAG(valnode), "!include", &isIncludeTag));
69f996e368SLisandro Dalcin       if (isIncludeTag) { /* TODO: add proper support relative paths */
709566063dSJacob Faibussowitsch         PetscCall(PetscOptionsInsertFileYAML(comm, options, STR(valnode), PETSC_TRUE));
71f996e368SLisandro Dalcin       }
72f996e368SLisandro Dalcin       continue; /* to next pair */
73f996e368SLisandro Dalcin     }
74f996e368SLisandro Dalcin 
75f996e368SLisandro Dalcin     if (valnode->type == YAML_SCALAR_NODE) {
769566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode)));
779355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, name, STR(valnode), NULL, source));
78f996e368SLisandro Dalcin 
79f996e368SLisandro Dalcin     } else if (valnode->type == YAML_SEQUENCE_NODE) {
80f996e368SLisandro Dalcin       PetscSegBuffer seg;
81f996e368SLisandro Dalcin       char          *buf, *strlist;
82f996e368SLisandro Dalcin       PetscBool      addSep = PETSC_FALSE;
83f996e368SLisandro Dalcin 
849566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferCreate(sizeof(char), PETSC_MAX_PATH_LEN, &seg));
85f996e368SLisandro Dalcin       for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) {
86f996e368SLisandro Dalcin         yaml_node_t *itemnode = yaml_document_get_node(doc, *item);
87f996e368SLisandro Dalcin         const char  *itemstr  = NULL;
88f996e368SLisandro Dalcin         size_t       itemlen;
89f996e368SLisandro Dalcin 
9028b400f6SJacob Faibussowitsch         PetscCheck(itemnode, comm, PETSC_ERR_LIB, "Corrupt YAML document");
91f996e368SLisandro Dalcin 
92f996e368SLisandro Dalcin         if (itemnode->type == YAML_SCALAR_NODE) {
93f996e368SLisandro Dalcin           itemstr = STR(itemnode);
94f996e368SLisandro Dalcin 
95f996e368SLisandro Dalcin         } else if (itemnode->type == YAML_MAPPING_NODE) {
96f996e368SLisandro Dalcin           yaml_node_pair_t *kvn = itemnode->data.mapping.pairs.start;
97f996e368SLisandro Dalcin           yaml_node_pair_t *top = itemnode->data.mapping.pairs.top;
98f996e368SLisandro Dalcin 
99cc73adaaSBarry Smith           PetscCheck(top - kvn <= 1, comm, PETSC_ERR_SUP, "Unsupported YAML node value: expected a single key:value pair");
100f996e368SLisandro Dalcin           if (top - kvn > 0) {
101f996e368SLisandro Dalcin             yaml_node_t *kn = yaml_document_get_node(doc, kvn->key);
102f996e368SLisandro Dalcin             yaml_node_t *vn = yaml_document_get_node(doc, kvn->value);
103f996e368SLisandro Dalcin 
10428b400f6SJacob Faibussowitsch             PetscCheck(kn, comm, PETSC_ERR_LIB, "Corrupt YAML document");
10528b400f6SJacob Faibussowitsch             PetscCheck(vn, comm, PETSC_ERR_LIB, "Corrupt YAML document");
10608401ef6SPierre Jolivet             PetscCheck(kn->type == YAML_SCALAR_NODE, comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar");
107f996e368SLisandro Dalcin 
1089566063dSJacob Faibussowitsch             PetscCall(PetscStrcmp(STR(kn), "<<", &isMergeKey));
10928b400f6SJacob Faibussowitsch             PetscCheck(!isMergeKey, comm, PETSC_ERR_SUP, "Unsupported YAML node value: merge key '<<' not supported here");
110f996e368SLisandro Dalcin 
1119566063dSJacob Faibussowitsch             PetscCall(PetscStrbeginswith(STR(kn), "$$", &isDummyKey));
112f996e368SLisandro Dalcin             if (isDummyKey) continue;
113f996e368SLisandro Dalcin             itemstr = STR(kn);
114f996e368SLisandro Dalcin           }
115f996e368SLisandro Dalcin 
1169566063dSJacob Faibussowitsch           PetscCall(PetscSNPrintf(prefix, sizeof(prefix), "%s_", STR(keynode)));
1179566063dSJacob Faibussowitsch           PetscCall(PetscOptionsPrefixPush(options, prefix));
1189355ec05SMatthew G. Knepley           PetscCall(PetscParseLayerYAML(options, doc, itemnode, source));
1199566063dSJacob Faibussowitsch           PetscCall(PetscOptionsPrefixPop(options));
120f996e368SLisandro Dalcin 
121f996e368SLisandro Dalcin         } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar or mapping");
122f996e368SLisandro Dalcin 
1239566063dSJacob Faibussowitsch         PetscCall(PetscStrlen(itemstr, &itemlen));
124f996e368SLisandro Dalcin         if (itemlen) {
125f996e368SLisandro Dalcin           if (addSep) {
1269566063dSJacob Faibussowitsch             PetscCall(PetscSegBufferGet(seg, 1, &buf));
1279566063dSJacob Faibussowitsch             PetscCall(PetscArraycpy(buf, ",", 1));
128f996e368SLisandro Dalcin           }
1299566063dSJacob Faibussowitsch           PetscCall(PetscSegBufferGet(seg, itemlen, &buf));
1309566063dSJacob Faibussowitsch           PetscCall(PetscArraycpy(buf, itemstr, itemlen));
131f996e368SLisandro Dalcin           addSep = PETSC_TRUE;
132f996e368SLisandro Dalcin         }
133f996e368SLisandro Dalcin       }
1349566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferGet(seg, 1, &buf));
1359566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(buf, 1));
1369566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferExtractAlloc(seg, &strlist));
1379566063dSJacob Faibussowitsch       PetscCall(PetscSegBufferDestroy(&seg));
138f996e368SLisandro Dalcin 
1399566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode)));
1409355ec05SMatthew G. Knepley       PetscCall(PetscOptionsSetValue_Private(options, name, strlist, NULL, source));
1419566063dSJacob Faibussowitsch       PetscCall(PetscFree(strlist));
142f996e368SLisandro Dalcin 
143f996e368SLisandro Dalcin     } else if (valnode->type == YAML_MAPPING_NODE) {
1449566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(prefix, sizeof(prefix), "%s_", STR(keynode)));
1459566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPush(options, prefix));
1469355ec05SMatthew G. Knepley       PetscCall(PetscParseLayerYAML(options, doc, valnode, source));
1479566063dSJacob Faibussowitsch       PetscCall(PetscOptionsPrefixPop(options));
148f996e368SLisandro Dalcin 
149f996e368SLisandro Dalcin     } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar, sequence or mapping");
150f996e368SLisandro Dalcin   }
1513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
152f996e368SLisandro Dalcin }
153f996e368SLisandro Dalcin 
1549355ec05SMatthew G. Knepley PetscErrorCode PetscOptionsInsertStringYAML_Private(PetscOptions options, const char in_str[], PetscOptionSource source)
1559355ec05SMatthew G. Knepley {
1569355ec05SMatthew G. Knepley   MPI_Comm        comm = PetscYAMLGetComm();
1579355ec05SMatthew G. Knepley   yaml_parser_t   parser;
1589355ec05SMatthew G. Knepley   yaml_document_t doc;
1599355ec05SMatthew G. Knepley   yaml_node_t    *root;
1609355ec05SMatthew G. Knepley   int             err;
1619355ec05SMatthew G. Knepley 
1629355ec05SMatthew G. Knepley   PetscFunctionBegin;
1639355ec05SMatthew G. Knepley   if (!in_str) in_str = "";
1649355ec05SMatthew G. Knepley   err = !yaml_parser_initialize(&parser);
1659355ec05SMatthew G. Knepley   PetscCheck(!err, comm, PETSC_ERR_LIB, "YAML parser initialization error");
1669355ec05SMatthew G. Knepley   yaml_parser_set_input_string(&parser, (const unsigned char *)in_str, strlen(in_str));
1679355ec05SMatthew G. Knepley   do {
1689355ec05SMatthew G. Knepley     err = !yaml_parser_load(&parser, &doc);
1699355ec05SMatthew G. Knepley     PetscCheck(!err, comm, PETSC_ERR_LIB, "YAML parser loading error");
1709355ec05SMatthew G. Knepley     root = yaml_document_get_root_node(&doc);
1719355ec05SMatthew G. Knepley     if (root) PetscCall(PetscParseLayerYAML(options, &doc, root, source));
1729355ec05SMatthew G. Knepley     yaml_document_delete(&doc);
1739355ec05SMatthew G. Knepley   } while (root);
1749355ec05SMatthew G. Knepley   yaml_parser_delete(&parser);
1753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1769355ec05SMatthew G. Knepley }
177f996e368SLisandro Dalcin /*@C
178811af0c4SBarry Smith   PetscOptionsInsertStringYAML - Inserts YAML-formatted options into the options database from a string
179f996e368SLisandro Dalcin 
180f996e368SLisandro Dalcin   Logically Collective
181f996e368SLisandro Dalcin 
182d8d19677SJose E. Roman   Input Parameters:
18321532e8aSBarry Smith + options - options database, use `NULL` for default global database
184f996e368SLisandro Dalcin - in_str  - YAML-formatted string options
185f996e368SLisandro Dalcin 
186f996e368SLisandro Dalcin   Level: intermediate
187f996e368SLisandro Dalcin 
188db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
189db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
190db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
191c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
192db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
193db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`, `PetscOptionsInsertFileYAML()`
194f996e368SLisandro Dalcin @*/
195d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertStringYAML(PetscOptions options, const char in_str[])
196d71ae5a4SJacob Faibussowitsch {
197f996e368SLisandro Dalcin   PetscFunctionBegin;
1989355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertStringYAML_Private(options, in_str, PETSC_OPT_CODE));
1993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
200f996e368SLisandro Dalcin }
201f996e368SLisandro Dalcin 
202f996e368SLisandro Dalcin /*@C
2037a30eb05SPatrick Sanan   PetscOptionsInsertFileYAML - Insert a YAML-formatted file in the options database
204f996e368SLisandro Dalcin 
205f996e368SLisandro Dalcin   Collective
206f996e368SLisandro Dalcin 
207d8d19677SJose E. Roman   Input Parameters:
208811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
20921532e8aSBarry Smith . options - options database, use `NULL` for default global database
210f996e368SLisandro Dalcin . file    - name of file
211811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
212f996e368SLisandro Dalcin 
213*1d27aa22SBarry Smith   Level: intermediate
214*1d27aa22SBarry Smith 
215811af0c4SBarry Smith   Notes:
216f996e368SLisandro Dalcin   PETSc will generate an error condition that stops the program if a YAML error
217f996e368SLisandro Dalcin   is detected, hence the user should check that the YAML file is valid before
218*1d27aa22SBarry Smith   supplying it, for instance at <http://www.yamllint.com> .
219f996e368SLisandro Dalcin 
220811af0c4SBarry Smith   Uses `PetscOptionsInsertStringYAML()`.
221f996e368SLisandro Dalcin 
222db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
223db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
224db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
225c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
226db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
227db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`, `PetscOptionsInsertStringYAML()`
228f996e368SLisandro Dalcin @*/
229d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFileYAML(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
230d71ae5a4SJacob Faibussowitsch {
231f996e368SLisandro Dalcin   int         yamlLength = -1;
232f996e368SLisandro Dalcin   char       *yamlString = NULL;
233f996e368SLisandro Dalcin   MPI_Comm    prev;
234f996e368SLisandro Dalcin   PetscMPIInt rank;
235f996e368SLisandro Dalcin 
236f996e368SLisandro Dalcin   PetscFunctionBegin;
2379566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
238dd400576SPatrick Sanan   if (rank == 0) {
239f996e368SLisandro Dalcin     char   fpath[PETSC_MAX_PATH_LEN];
240f996e368SLisandro Dalcin     char   fname[PETSC_MAX_PATH_LEN];
241f996e368SLisandro Dalcin     FILE  *fd;
242f996e368SLisandro Dalcin     size_t rd;
243f996e368SLisandro Dalcin 
2449566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
2459566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
246f996e368SLisandro Dalcin 
247f996e368SLisandro Dalcin     fd = fopen(fname, "r");
248f996e368SLisandro Dalcin     if (fd) {
249f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_END);
250f996e368SLisandro Dalcin       yamlLength = (int)ftell(fd);
251f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_SET);
25208401ef6SPierre Jolivet       PetscCheck(yamlLength >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to query size of YAML file: %s", fname);
2539566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(yamlLength + 1, &yamlString));
254f996e368SLisandro Dalcin       rd = fread(yamlString, 1, (size_t)yamlLength, fd);
255cc73adaaSBarry Smith       PetscCheck(rd == (size_t)yamlLength, PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Unable to read entire YAML file: %s", fname);
256f996e368SLisandro Dalcin       yamlString[yamlLength] = 0;
257f996e368SLisandro Dalcin       fclose(fd);
258f996e368SLisandro Dalcin     }
259f996e368SLisandro Dalcin   }
260f996e368SLisandro Dalcin 
2619566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&yamlLength, 1, MPI_INT, 0, comm));
262cc73adaaSBarry Smith   PetscCheck(!require || yamlLength >= 0, comm, PETSC_ERR_FILE_OPEN, "Unable to open YAML option file: %s", file);
2633ba16761SJacob Faibussowitsch   if (yamlLength < 0) PetscFunctionReturn(PETSC_SUCCESS);
264f996e368SLisandro Dalcin 
2659566063dSJacob Faibussowitsch   if (rank) PetscCall(PetscMalloc1(yamlLength + 1, &yamlString));
2669566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(yamlString, yamlLength + 1, MPI_CHAR, 0, comm));
267f996e368SLisandro Dalcin 
268f996e368SLisandro Dalcin   prev = PetscYAMLSetComm(comm);
2699355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertStringYAML_Private(options, yamlString, PETSC_OPT_FILE));
270f996e368SLisandro Dalcin   (void)PetscYAMLSetComm(prev);
271f996e368SLisandro Dalcin 
2729566063dSJacob Faibussowitsch   PetscCall(PetscFree(yamlString));
2733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
274f996e368SLisandro Dalcin }
275951eb098SLisandro Dalcin 
276951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_YAML)
277951eb098SLisandro Dalcin 
278951eb098SLisandro Dalcin   /*
279951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_STRDUP)
280951eb098SLisandro Dalcin #define strdup(s) (char*)memcpy(malloc(strlen(s)+1),s,strlen(s)+1)
281951eb098SLisandro Dalcin #endif
282951eb098SLisandro Dalcin */
283951eb098SLisandro Dalcin 
284951eb098SLisandro Dalcin   /* Embed LibYAML in this compilation unit */
285951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/api.c>
286951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/loader.c>
287951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/parser.c>
288951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/reader.c>
2896d1d8577SJunchao Zhang 
2906d1d8577SJunchao Zhang   /*
2916d1d8577SJunchao Zhang   Avoid compiler warnings like
2926d1d8577SJunchao Zhang     scanner.c, line 3181: warning: integer conversion resulted in a change of sign
2936d1d8577SJunchao Zhang                           *(string.pointer++) = '\xC2';
2946d1d8577SJunchao Zhang 
2956d1d8577SJunchao Zhang   Once yaml fixes them, we can remove the pragmas
2966d1d8577SJunchao Zhang */
2976d1d8577SJunchao Zhang   #pragma GCC diagnostic push
2986d1d8577SJunchao Zhang   #pragma GCC diagnostic ignored "-Wsign-conversion"
299951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/scanner.c>
3006d1d8577SJunchao Zhang   #pragma GCC diagnostic pop
301951eb098SLisandro Dalcin 
302951eb098SLisandro Dalcin /* Silence a few unused-function warnings */
303d71ae5a4SJacob Faibussowitsch static PETSC_UNUSED void petsc_yaml_unused(void)
304d71ae5a4SJacob Faibussowitsch {
305951eb098SLisandro Dalcin   (void)yaml_parser_scan;
306951eb098SLisandro Dalcin   (void)yaml_document_get_node;
307951eb098SLisandro Dalcin   (void)yaml_parser_set_encoding;
308951eb098SLisandro Dalcin   (void)yaml_parser_set_input;
309951eb098SLisandro Dalcin   (void)yaml_parser_set_input_file;
310951eb098SLisandro Dalcin }
311951eb098SLisandro Dalcin 
312951eb098SLisandro Dalcin #endif
313