xref: /petsc/src/sys/objects/optionsyaml.c (revision ad781fe3223b515d45fb60062f8062326362e786)
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 
PetscYAMLGetComm(void)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 
PetscYAMLSetComm(MPI_Comm comm)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 
PetscParseLayerYAML(PetscOptions options,yaml_document_t * doc,yaml_node_t * node,PetscOptionSource source)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 
PetscOptionsInsertStringYAML_Private(PetscOptions options,const char in_str[],PetscOptionSource source)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 }
1775d83a8b1SBarry Smith 
1785d83a8b1SBarry Smith /*@
179811af0c4SBarry Smith   PetscOptionsInsertStringYAML - Inserts YAML-formatted options into the options database from a string
180f996e368SLisandro Dalcin 
181f996e368SLisandro Dalcin   Logically Collective
182f996e368SLisandro Dalcin 
183d8d19677SJose E. Roman   Input Parameters:
18421532e8aSBarry Smith + options - options database, use `NULL` for default global database
185f996e368SLisandro Dalcin - in_str  - YAML-formatted string options
186f996e368SLisandro Dalcin 
187f996e368SLisandro Dalcin   Level: intermediate
188f996e368SLisandro Dalcin 
189db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
190db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
191db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
192c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
193db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
194db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`, `PetscOptionsInsertFileYAML()`
195f996e368SLisandro Dalcin @*/
PetscOptionsInsertStringYAML(PetscOptions options,const char in_str[])196d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertStringYAML(PetscOptions options, const char in_str[])
197d71ae5a4SJacob Faibussowitsch {
198f996e368SLisandro Dalcin   PetscFunctionBegin;
1999355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertStringYAML_Private(options, in_str, PETSC_OPT_CODE));
2003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
201f996e368SLisandro Dalcin }
202f996e368SLisandro Dalcin 
2035d83a8b1SBarry Smith /*@
2047a30eb05SPatrick Sanan   PetscOptionsInsertFileYAML - Insert a YAML-formatted file in the options database
205f996e368SLisandro Dalcin 
206f996e368SLisandro Dalcin   Collective
207f996e368SLisandro Dalcin 
208d8d19677SJose E. Roman   Input Parameters:
209811af0c4SBarry Smith + comm    - the processes that will share the options (usually `PETSC_COMM_WORLD`)
21021532e8aSBarry Smith . options - options database, use `NULL` for default global database
211f996e368SLisandro Dalcin . file    - name of file
212811af0c4SBarry Smith - require - if `PETSC_TRUE` will generate an error if the file does not exist
213f996e368SLisandro Dalcin 
2141d27aa22SBarry Smith   Level: intermediate
2151d27aa22SBarry Smith 
216811af0c4SBarry Smith   Notes:
217f996e368SLisandro Dalcin   PETSc will generate an error condition that stops the program if a YAML error
218f996e368SLisandro Dalcin   is detected, hence the user should check that the YAML file is valid before
2191d27aa22SBarry Smith   supplying it, for instance at <http://www.yamllint.com> .
220f996e368SLisandro Dalcin 
221811af0c4SBarry Smith   Uses `PetscOptionsInsertStringYAML()`.
222f996e368SLisandro Dalcin 
223db781477SPatrick Sanan .seealso: `PetscOptionsSetValue()`, `PetscOptionsView()`, `PetscOptionsHasName()`, `PetscOptionsGetInt()`,
224db781477SPatrick Sanan           `PetscOptionsGetReal()`, `PetscOptionsGetString()`, `PetscOptionsGetIntArray()`, `PetscOptionsBool()`,
225db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
226c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
227db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
228db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`, `PetscOptionsInsertFile()`, `PetscOptionsInsertStringYAML()`
229f996e368SLisandro Dalcin @*/
PetscOptionsInsertFileYAML(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)230d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInsertFileYAML(MPI_Comm comm, PetscOptions options, const char file[], PetscBool require)
231d71ae5a4SJacob Faibussowitsch {
232f996e368SLisandro Dalcin   int         yamlLength = -1;
233f996e368SLisandro Dalcin   char       *yamlString = NULL;
234f996e368SLisandro Dalcin   MPI_Comm    prev;
235f996e368SLisandro Dalcin   PetscMPIInt rank;
236f996e368SLisandro Dalcin 
237f996e368SLisandro Dalcin   PetscFunctionBegin;
2389566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
239dd400576SPatrick Sanan   if (rank == 0) {
240f996e368SLisandro Dalcin     char   fpath[PETSC_MAX_PATH_LEN];
241f996e368SLisandro Dalcin     char   fname[PETSC_MAX_PATH_LEN];
242f996e368SLisandro Dalcin     FILE  *fd;
243f996e368SLisandro Dalcin     size_t rd;
244f996e368SLisandro Dalcin 
2459566063dSJacob Faibussowitsch     PetscCall(PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath)));
2469566063dSJacob Faibussowitsch     PetscCall(PetscFixFilename(fpath, fname));
247f996e368SLisandro Dalcin 
248f996e368SLisandro Dalcin     fd = fopen(fname, "r");
249f996e368SLisandro Dalcin     if (fd) {
250f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_END);
251f996e368SLisandro Dalcin       yamlLength = (int)ftell(fd);
252f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_SET);
25308401ef6SPierre Jolivet       PetscCheck(yamlLength >= 0, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to query size of YAML file: %s", fname);
2549566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(yamlLength + 1, &yamlString));
255f996e368SLisandro Dalcin       rd = fread(yamlString, 1, (size_t)yamlLength, fd);
256cc73adaaSBarry Smith       PetscCheck(rd == (size_t)yamlLength, PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Unable to read entire YAML file: %s", fname);
257f996e368SLisandro Dalcin       yamlString[yamlLength] = 0;
258f996e368SLisandro Dalcin       fclose(fd);
259f996e368SLisandro Dalcin     }
260f996e368SLisandro Dalcin   }
261f996e368SLisandro Dalcin 
2629566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(&yamlLength, 1, MPI_INT, 0, comm));
263cc73adaaSBarry Smith   PetscCheck(!require || yamlLength >= 0, comm, PETSC_ERR_FILE_OPEN, "Unable to open YAML option file: %s", file);
2643ba16761SJacob Faibussowitsch   if (yamlLength < 0) PetscFunctionReturn(PETSC_SUCCESS);
265f996e368SLisandro Dalcin 
2669566063dSJacob Faibussowitsch   if (rank) PetscCall(PetscMalloc1(yamlLength + 1, &yamlString));
2679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(yamlString, yamlLength + 1, MPI_CHAR, 0, comm));
268f996e368SLisandro Dalcin 
269f996e368SLisandro Dalcin   prev = PetscYAMLSetComm(comm);
2709355ec05SMatthew G. Knepley   PetscCall(PetscOptionsInsertStringYAML_Private(options, yamlString, PETSC_OPT_FILE));
271f996e368SLisandro Dalcin   (void)PetscYAMLSetComm(prev);
272f996e368SLisandro Dalcin 
2739566063dSJacob Faibussowitsch   PetscCall(PetscFree(yamlString));
2743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
275f996e368SLisandro Dalcin }
276951eb098SLisandro Dalcin 
277951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_YAML)
278951eb098SLisandro Dalcin 
279951eb098SLisandro Dalcin   /*
280951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_STRDUP)
281951eb098SLisandro Dalcin #define strdup(s) (char*)memcpy(malloc(strlen(s)+1),s,strlen(s)+1)
282951eb098SLisandro Dalcin #endif
283951eb098SLisandro Dalcin */
284951eb098SLisandro Dalcin 
285951eb098SLisandro Dalcin   /* Embed LibYAML in this compilation unit */
286951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/api.c>
287951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/loader.c>
288951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/parser.c>
289951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/reader.c>
2906d1d8577SJunchao Zhang 
2916d1d8577SJunchao Zhang /*
2926d1d8577SJunchao Zhang   Avoid compiler warnings like
2936d1d8577SJunchao Zhang     scanner.c, line 3181: warning: integer conversion resulted in a change of sign
2946d1d8577SJunchao Zhang                           *(string.pointer++) = '\xC2';
2956d1d8577SJunchao Zhang 
2966d1d8577SJunchao Zhang   Once yaml fixes them, we can remove the pragmas
2976d1d8577SJunchao Zhang */
298*1e98b048SBarry Smith   #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
2996d1d8577SJunchao Zhang     #pragma GCC diagnostic push
3006d1d8577SJunchao Zhang     #pragma GCC diagnostic ignored "-Wsign-conversion"
301*1e98b048SBarry Smith   #endif
302951eb098SLisandro Dalcin   #include <../src/sys/yaml/src/scanner.c>
303*1e98b048SBarry Smith   #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
3046d1d8577SJunchao Zhang     #pragma GCC diagnostic pop
305*1e98b048SBarry Smith   #endif
306951eb098SLisandro Dalcin 
307951eb098SLisandro Dalcin /* Silence a few unused-function warnings */
petsc_yaml_unused(void)308d71ae5a4SJacob Faibussowitsch static PETSC_UNUSED void petsc_yaml_unused(void)
309d71ae5a4SJacob Faibussowitsch {
310951eb098SLisandro Dalcin   (void)yaml_parser_scan;
311951eb098SLisandro Dalcin   (void)yaml_document_get_node;
312951eb098SLisandro Dalcin   (void)yaml_parser_set_encoding;
313951eb098SLisandro Dalcin   (void)yaml_parser_set_input;
314951eb098SLisandro Dalcin   (void)yaml_parser_set_input_file;
315951eb098SLisandro Dalcin }
316951eb098SLisandro Dalcin 
317951eb098SLisandro Dalcin #endif
318