xref: /petsc/src/sys/objects/optionsyaml.c (revision 9fbee5477fd88ea4536ebb185f3c80da15fb55c0)
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 
10f996e368SLisandro Dalcin static MPI_Comm petsc_yaml_comm = MPI_COMM_NULL; /* only used for parallel error handling */
11f996e368SLisandro Dalcin 
12*9fbee547SJacob Faibussowitsch static inline MPI_Comm PetscYAMLGetComm(void)
13f996e368SLisandro Dalcin {
14f996e368SLisandro Dalcin   return PetscLikely(petsc_yaml_comm != MPI_COMM_NULL) ? petsc_yaml_comm : (petsc_yaml_comm = PETSC_COMM_SELF);
15f996e368SLisandro Dalcin }
16f996e368SLisandro Dalcin 
17*9fbee547SJacob Faibussowitsch static inline MPI_Comm PetscYAMLSetComm(MPI_Comm comm)
18f996e368SLisandro Dalcin {
19f996e368SLisandro Dalcin   MPI_Comm prev = PetscYAMLGetComm(); petsc_yaml_comm = comm; return prev;
20f996e368SLisandro Dalcin }
21f996e368SLisandro Dalcin 
22f996e368SLisandro Dalcin #define TAG(node) ((const char *)((node)->tag))
23f996e368SLisandro Dalcin #define STR(node) ((const char *)((node)->data.scalar.value))
24f996e368SLisandro Dalcin #define SEQ(node) ((node)->data.sequence.items)
25f996e368SLisandro Dalcin #define MAP(node) ((node)->data.mapping.pairs)
26f996e368SLisandro Dalcin 
27f996e368SLisandro Dalcin static PetscErrorCode PetscParseLayerYAML(PetscOptions options, yaml_document_t *doc, yaml_node_t *node)
28f996e368SLisandro Dalcin {
29f996e368SLisandro Dalcin   MPI_Comm         comm = PetscYAMLGetComm();
30f996e368SLisandro Dalcin   char             name[PETSC_MAX_OPTION_NAME] = "", prefix[PETSC_MAX_OPTION_NAME] = "";
31f996e368SLisandro Dalcin   PetscErrorCode   ierr;
32f996e368SLisandro Dalcin 
33f996e368SLisandro Dalcin   PetscFunctionBegin;
342b8ac955SLisandro Dalcin   if (node->type == YAML_SCALAR_NODE && !STR(node)[0]) PetscFunctionReturn(0); /* empty */
359ace16cdSJacob Faibussowitsch   PetscAssertFalse(node->type != YAML_MAPPING_NODE,comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping");
36f996e368SLisandro Dalcin   for (yaml_node_pair_t *pair = MAP(node).start; pair < MAP(node).top; pair++) {
37f996e368SLisandro Dalcin     yaml_node_t *keynode = yaml_document_get_node(doc, pair->key);
38f996e368SLisandro Dalcin     yaml_node_t *valnode = yaml_document_get_node(doc, pair->value);
39f996e368SLisandro Dalcin     PetscBool   isMergeKey,isDummyKey,isIncludeTag;
40f996e368SLisandro Dalcin 
419ace16cdSJacob Faibussowitsch     PetscAssertFalse(!keynode,comm, PETSC_ERR_LIB, "Corrupt YAML document");
429ace16cdSJacob Faibussowitsch     PetscAssertFalse(!valnode,comm, PETSC_ERR_LIB, "Corrupt YAML document");
439ace16cdSJacob Faibussowitsch     PetscAssertFalse(keynode->type != YAML_SCALAR_NODE,comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar");
44f996e368SLisandro Dalcin 
45f996e368SLisandro Dalcin     /* "<<" is the merge key: don't increment the prefix */
46f996e368SLisandro Dalcin     ierr = PetscStrcmp(STR(keynode), "<<", &isMergeKey);CHKERRQ(ierr);
47f996e368SLisandro Dalcin     if (isMergeKey) {
48f996e368SLisandro Dalcin       if (valnode->type == YAML_SEQUENCE_NODE) {
49f996e368SLisandro Dalcin         for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) {
50f996e368SLisandro Dalcin           yaml_node_t *itemnode = yaml_document_get_node(doc, *item);
519ace16cdSJacob Faibussowitsch           PetscAssertFalse(!itemnode,comm, PETSC_ERR_LIB, "Corrupt YAML document");
529ace16cdSJacob Faibussowitsch           PetscAssertFalse(itemnode->type != YAML_MAPPING_NODE,comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping");
53f996e368SLisandro Dalcin           ierr = PetscParseLayerYAML(options, doc, itemnode);CHKERRQ(ierr);
54f996e368SLisandro Dalcin         }
55f996e368SLisandro Dalcin       } else if (valnode->type == YAML_MAPPING_NODE) {
56f996e368SLisandro Dalcin         ierr = PetscParseLayerYAML(options, doc, valnode);CHKERRQ(ierr);
57f996e368SLisandro Dalcin       } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected sequence or mapping");
58f996e368SLisandro Dalcin       continue; /* to next pair */
59f996e368SLisandro Dalcin     }
60f996e368SLisandro Dalcin 
61f996e368SLisandro Dalcin     /* "$$*" are treated as dummy keys, we use them for !include tags and to define anchors */
62f996e368SLisandro Dalcin     ierr = PetscStrbeginswith(STR(keynode), "$$", &isDummyKey);CHKERRQ(ierr);
63f996e368SLisandro Dalcin     if (isDummyKey) {
64f996e368SLisandro Dalcin       ierr = PetscStrendswith(TAG(valnode), "!include", &isIncludeTag);CHKERRQ(ierr);CHKERRQ(ierr);
65f996e368SLisandro Dalcin       if (isIncludeTag) { /* TODO: add proper support relative paths */
66f996e368SLisandro Dalcin         ierr = PetscOptionsInsertFileYAML(comm, options, STR(valnode), PETSC_TRUE);CHKERRQ(ierr);
67f996e368SLisandro Dalcin       }
68f996e368SLisandro Dalcin       continue; /* to next pair */
69f996e368SLisandro Dalcin     }
70f996e368SLisandro Dalcin 
71f996e368SLisandro Dalcin     if (valnode->type == YAML_SCALAR_NODE) {
72f996e368SLisandro Dalcin       ierr = PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode));CHKERRQ(ierr);
73f996e368SLisandro Dalcin       ierr = PetscOptionsSetValue(options, name, STR(valnode));CHKERRQ(ierr);
74f996e368SLisandro Dalcin 
75f996e368SLisandro Dalcin     } else if (valnode->type == YAML_SEQUENCE_NODE) {
76f996e368SLisandro Dalcin       PetscSegBuffer seg;
77f996e368SLisandro Dalcin       char           *buf, *strlist;
78f996e368SLisandro Dalcin       PetscBool      addSep = PETSC_FALSE;
79f996e368SLisandro Dalcin 
80f996e368SLisandro Dalcin       ierr = PetscSegBufferCreate(sizeof(char), PETSC_MAX_PATH_LEN, &seg);CHKERRQ(ierr);
81f996e368SLisandro Dalcin       for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) {
82f996e368SLisandro Dalcin         yaml_node_t *itemnode = yaml_document_get_node(doc, *item);
83f996e368SLisandro Dalcin         const char  *itemstr = NULL;
84f996e368SLisandro Dalcin         size_t       itemlen;
85f996e368SLisandro Dalcin 
869ace16cdSJacob Faibussowitsch         PetscAssertFalse(!itemnode,comm, PETSC_ERR_LIB, "Corrupt YAML document");
87f996e368SLisandro Dalcin 
88f996e368SLisandro Dalcin         if (itemnode->type == YAML_SCALAR_NODE) {
89f996e368SLisandro Dalcin           itemstr = STR(itemnode);
90f996e368SLisandro Dalcin 
91f996e368SLisandro Dalcin         } else if (itemnode->type == YAML_MAPPING_NODE) {
92f996e368SLisandro Dalcin           yaml_node_pair_t *kvn = itemnode->data.mapping.pairs.start;
93f996e368SLisandro Dalcin           yaml_node_pair_t *top = itemnode->data.mapping.pairs.top;
94f996e368SLisandro Dalcin 
959ace16cdSJacob Faibussowitsch           PetscAssertFalse(top - kvn > 1,comm, PETSC_ERR_SUP, "Unsupported YAML node value: expected a single key:value pair");
96f996e368SLisandro Dalcin           if (top - kvn > 0) {
97f996e368SLisandro Dalcin             yaml_node_t *kn = yaml_document_get_node(doc, kvn->key);
98f996e368SLisandro Dalcin             yaml_node_t *vn = yaml_document_get_node(doc, kvn->value);
99f996e368SLisandro Dalcin 
1009ace16cdSJacob Faibussowitsch             PetscAssertFalse(!kn,comm, PETSC_ERR_LIB, "Corrupt YAML document");
1019ace16cdSJacob Faibussowitsch             PetscAssertFalse(!vn,comm, PETSC_ERR_LIB, "Corrupt YAML document");
1029ace16cdSJacob Faibussowitsch             PetscAssertFalse(kn->type != YAML_SCALAR_NODE,comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar");
103f996e368SLisandro Dalcin 
104f996e368SLisandro Dalcin             ierr = PetscStrcmp(STR(kn), "<<", &isMergeKey);CHKERRQ(ierr);
1059ace16cdSJacob Faibussowitsch             PetscAssertFalse(isMergeKey,comm, PETSC_ERR_SUP, "Unsupported YAML node value: merge key '<<' not supported here");
106f996e368SLisandro Dalcin 
107f996e368SLisandro Dalcin             ierr = PetscStrbeginswith(STR(kn), "$$", &isDummyKey);CHKERRQ(ierr);
108f996e368SLisandro Dalcin             if (isDummyKey) continue;
109f996e368SLisandro Dalcin             itemstr = STR(kn);
110f996e368SLisandro Dalcin           }
111f996e368SLisandro Dalcin 
112f996e368SLisandro Dalcin           ierr = PetscSNPrintf(prefix,sizeof(prefix), "%s_", STR(keynode));CHKERRQ(ierr);
113f996e368SLisandro Dalcin           ierr = PetscOptionsPrefixPush(options, prefix);CHKERRQ(ierr);
114f996e368SLisandro Dalcin           ierr = PetscParseLayerYAML(options, doc, itemnode);CHKERRQ(ierr);
115f996e368SLisandro Dalcin           ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr);
116f996e368SLisandro Dalcin 
117f996e368SLisandro Dalcin         } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar or mapping");
118f996e368SLisandro Dalcin 
119f996e368SLisandro Dalcin         ierr = PetscStrlen(itemstr, &itemlen);CHKERRQ(ierr);
120f996e368SLisandro Dalcin         if (itemlen) {
121f996e368SLisandro Dalcin           if (addSep) {
122f996e368SLisandro Dalcin             ierr = PetscSegBufferGet(seg, 1, &buf);CHKERRQ(ierr);
123f996e368SLisandro Dalcin             ierr = PetscArraycpy(buf, ",", 1);CHKERRQ(ierr);
124f996e368SLisandro Dalcin           }
125f996e368SLisandro Dalcin           ierr = PetscSegBufferGet(seg, itemlen, &buf);CHKERRQ(ierr);
126f996e368SLisandro Dalcin           ierr = PetscArraycpy(buf, itemstr, itemlen);CHKERRQ(ierr);
127f996e368SLisandro Dalcin           addSep = PETSC_TRUE;
128f996e368SLisandro Dalcin         }
129f996e368SLisandro Dalcin       }
130f996e368SLisandro Dalcin       ierr = PetscSegBufferGet(seg, 1, &buf);CHKERRQ(ierr);
131f996e368SLisandro Dalcin       ierr = PetscArrayzero(buf, 1);CHKERRQ(ierr);
132f996e368SLisandro Dalcin       ierr = PetscSegBufferExtractAlloc(seg, &strlist);CHKERRQ(ierr);
133f996e368SLisandro Dalcin       ierr = PetscSegBufferDestroy(&seg);CHKERRQ(ierr);
134f996e368SLisandro Dalcin 
135f996e368SLisandro Dalcin       ierr = PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode));CHKERRQ(ierr);
136f996e368SLisandro Dalcin       ierr = PetscOptionsSetValue(options, name, strlist);CHKERRQ(ierr);
137f996e368SLisandro Dalcin       ierr = PetscFree(strlist);CHKERRQ(ierr);
138f996e368SLisandro Dalcin 
139f996e368SLisandro Dalcin     } else if (valnode->type == YAML_MAPPING_NODE) {
140f996e368SLisandro Dalcin       ierr = PetscSNPrintf(prefix,sizeof(prefix), "%s_", STR(keynode));CHKERRQ(ierr);
141f996e368SLisandro Dalcin       ierr = PetscOptionsPrefixPush(options, prefix);CHKERRQ(ierr);
142f996e368SLisandro Dalcin       ierr = PetscParseLayerYAML(options, doc, valnode);CHKERRQ(ierr);
143f996e368SLisandro Dalcin       ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr);
144f996e368SLisandro Dalcin 
145f996e368SLisandro Dalcin     } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar, sequence or mapping");
146f996e368SLisandro Dalcin   }
147f996e368SLisandro Dalcin   PetscFunctionReturn(0);
148f996e368SLisandro Dalcin }
149f996e368SLisandro Dalcin 
150f996e368SLisandro Dalcin /*@C
151f996e368SLisandro Dalcin    PetscOptionsInsertStringYAML - Inserts YAML-formatted options into the database from a string
152f996e368SLisandro Dalcin 
153f996e368SLisandro Dalcin    Logically Collective
154f996e368SLisandro Dalcin 
155d8d19677SJose E. Roman    Input Parameters:
156f996e368SLisandro Dalcin +  options - options database, use NULL for default global database
157f996e368SLisandro Dalcin -  in_str - YAML-formatted string options
158f996e368SLisandro Dalcin 
159f996e368SLisandro Dalcin    Level: intermediate
160f996e368SLisandro Dalcin 
161f996e368SLisandro Dalcin .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
162f996e368SLisandro Dalcin           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
163f996e368SLisandro Dalcin           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
164f996e368SLisandro Dalcin           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
165f996e368SLisandro Dalcin           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
166f996e368SLisandro Dalcin           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile(), PetscOptionsInsertFileYAML()
167f996e368SLisandro Dalcin @*/
168f996e368SLisandro Dalcin PetscErrorCode PetscOptionsInsertStringYAML(PetscOptions options,const char in_str[])
169f996e368SLisandro Dalcin {
170f996e368SLisandro Dalcin   MPI_Comm        comm = PetscYAMLGetComm();
171f996e368SLisandro Dalcin   yaml_parser_t   parser;
172f996e368SLisandro Dalcin   yaml_document_t doc;
173f996e368SLisandro Dalcin   yaml_node_t     *root;
174f996e368SLisandro Dalcin   PetscErrorCode  ierr;
175f996e368SLisandro Dalcin 
176f996e368SLisandro Dalcin   PetscFunctionBegin;
177f996e368SLisandro Dalcin   if (!in_str) in_str = "";
1789ace16cdSJacob Faibussowitsch   ierr = !yaml_parser_initialize(&parser); PetscAssertFalse(ierr,comm, PETSC_ERR_LIB, "YAML parser initialization error");
179f996e368SLisandro Dalcin   yaml_parser_set_input_string(&parser, (const unsigned char *)in_str, strlen(in_str));
180f996e368SLisandro Dalcin   do {
1819ace16cdSJacob Faibussowitsch     ierr = !yaml_parser_load(&parser, &doc); PetscAssertFalse(ierr,comm, PETSC_ERR_LIB, "YAML parser loading error");
182f996e368SLisandro Dalcin     root = yaml_document_get_root_node(&doc);
183f996e368SLisandro Dalcin     if (root) {
184f996e368SLisandro Dalcin       ierr = PetscParseLayerYAML(options, &doc, root);CHKERRQ(ierr);
185f996e368SLisandro Dalcin     }
186f996e368SLisandro Dalcin     yaml_document_delete(&doc);
187f996e368SLisandro Dalcin   } while (root);
188f996e368SLisandro Dalcin   yaml_parser_delete(&parser);
189f996e368SLisandro Dalcin   PetscFunctionReturn(0);
190f996e368SLisandro Dalcin }
191f996e368SLisandro Dalcin 
192f996e368SLisandro Dalcin /*@C
1937a30eb05SPatrick Sanan   PetscOptionsInsertFileYAML - Insert a YAML-formatted file in the options database
194f996e368SLisandro Dalcin 
195f996e368SLisandro Dalcin   Collective
196f996e368SLisandro Dalcin 
197d8d19677SJose E. Roman   Input Parameters:
198f996e368SLisandro Dalcin +   comm - the processes that will share the options (usually PETSC_COMM_WORLD)
199f996e368SLisandro Dalcin .   options - options database, use NULL for default global database
200f996e368SLisandro Dalcin .   file - name of file
201f996e368SLisandro Dalcin -   require - if PETSC_TRUE will generate an error if the file does not exist
202f996e368SLisandro Dalcin 
203f996e368SLisandro Dalcin   PETSc will generate an error condition that stops the program if a YAML error
204f996e368SLisandro Dalcin   is detected, hence the user should check that the YAML file is valid before
205f996e368SLisandro Dalcin   supplying it, for instance at http://www.yamllint.com/ .
206f996e368SLisandro Dalcin 
2077a30eb05SPatrick Sanan   Uses PetscOptionsInsertStringYAML().
208f996e368SLisandro Dalcin 
209f996e368SLisandro Dalcin   Level: intermediate
210f996e368SLisandro Dalcin 
211f996e368SLisandro Dalcin .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(),
212f996e368SLisandro Dalcin           PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(),
213f996e368SLisandro Dalcin           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
214f996e368SLisandro Dalcin           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
215f996e368SLisandro Dalcin           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
216f996e368SLisandro Dalcin           PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile(), PetscOptionsInsertStringYAML()
217f996e368SLisandro Dalcin @*/
218f996e368SLisandro Dalcin PetscErrorCode PetscOptionsInsertFileYAML(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require)
219f996e368SLisandro Dalcin {
220f996e368SLisandro Dalcin   int            yamlLength = -1;
221f996e368SLisandro Dalcin   char          *yamlString = NULL;
222f996e368SLisandro Dalcin   MPI_Comm       prev;
223f996e368SLisandro Dalcin   PetscMPIInt    rank;
224f996e368SLisandro Dalcin   PetscErrorCode ierr;
225f996e368SLisandro Dalcin 
226f996e368SLisandro Dalcin   PetscFunctionBegin;
227f996e368SLisandro Dalcin   ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr);
228dd400576SPatrick Sanan   if (rank == 0) {
229f996e368SLisandro Dalcin     char   fpath[PETSC_MAX_PATH_LEN];
230f996e368SLisandro Dalcin     char   fname[PETSC_MAX_PATH_LEN];
231f996e368SLisandro Dalcin     FILE  *fd;
232f996e368SLisandro Dalcin     size_t rd;
233f996e368SLisandro Dalcin 
234f996e368SLisandro Dalcin     ierr = PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath));CHKERRQ(ierr);
235f996e368SLisandro Dalcin     ierr = PetscFixFilename(fpath, fname);CHKERRQ(ierr);
236f996e368SLisandro Dalcin 
237f996e368SLisandro Dalcin     fd = fopen(fname, "r");
238f996e368SLisandro Dalcin     if (fd) {
239f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_END);
240f996e368SLisandro Dalcin       yamlLength = (int)ftell(fd);
241f996e368SLisandro Dalcin       fseek(fd, 0, SEEK_SET);
2429ace16cdSJacob Faibussowitsch       PetscAssertFalse(yamlLength < 0,PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to query size of YAML file: %s", fname);
243f996e368SLisandro Dalcin       ierr = PetscMalloc1(yamlLength+1, &yamlString);CHKERRQ(ierr);
244f996e368SLisandro Dalcin       rd = fread(yamlString, 1, (size_t)yamlLength, fd);
2459ace16cdSJacob Faibussowitsch       PetscAssertFalse(rd != (size_t)yamlLength,PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Unable to read entire YAML file: %s", fname);
246f996e368SLisandro Dalcin       yamlString[yamlLength] = 0;
247f996e368SLisandro Dalcin       fclose(fd);
248f996e368SLisandro Dalcin     }
249f996e368SLisandro Dalcin   }
250f996e368SLisandro Dalcin 
251f996e368SLisandro Dalcin   ierr = MPI_Bcast(&yamlLength, 1, MPI_INT, 0, comm);CHKERRMPI(ierr);
2529ace16cdSJacob Faibussowitsch   PetscAssertFalse(require && yamlLength < 0,comm, PETSC_ERR_FILE_OPEN, "Unable to open YAML option file: %s", file);
253f996e368SLisandro Dalcin   if (yamlLength < 0) PetscFunctionReturn(0);
254f996e368SLisandro Dalcin 
255f996e368SLisandro Dalcin   if (rank) {ierr = PetscMalloc1(yamlLength+1, &yamlString);CHKERRQ(ierr);}
256f996e368SLisandro Dalcin   ierr = MPI_Bcast(yamlString, yamlLength+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr);
257f996e368SLisandro Dalcin 
258f996e368SLisandro Dalcin   prev = PetscYAMLSetComm(comm);
259f996e368SLisandro Dalcin   ierr = PetscOptionsInsertStringYAML(options, yamlString);CHKERRQ(ierr);
260f996e368SLisandro Dalcin   (void) PetscYAMLSetComm(prev);
261f996e368SLisandro Dalcin 
262f996e368SLisandro Dalcin   ierr = PetscFree(yamlString);CHKERRQ(ierr);
263f996e368SLisandro Dalcin   PetscFunctionReturn(0);
264f996e368SLisandro Dalcin }
265951eb098SLisandro Dalcin 
266951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_YAML)
267951eb098SLisandro Dalcin 
268951eb098SLisandro Dalcin /*
269951eb098SLisandro Dalcin #if !defined(PETSC_HAVE_STRDUP)
270951eb098SLisandro Dalcin #define strdup(s) (char*)memcpy(malloc(strlen(s)+1),s,strlen(s)+1)
271951eb098SLisandro Dalcin #endif
272951eb098SLisandro Dalcin */
273951eb098SLisandro Dalcin 
274951eb098SLisandro Dalcin /* Embed LibYAML in this compilation unit */
275951eb098SLisandro Dalcin #include <../src/sys/yaml/src/api.c>
276951eb098SLisandro Dalcin #include <../src/sys/yaml/src/loader.c>
277951eb098SLisandro Dalcin #include <../src/sys/yaml/src/parser.c>
278951eb098SLisandro Dalcin #include <../src/sys/yaml/src/reader.c>
2796d1d8577SJunchao Zhang 
2806d1d8577SJunchao Zhang /*
2816d1d8577SJunchao Zhang   Avoid compiler warnings like
2826d1d8577SJunchao Zhang     scanner.c, line 3181: warning: integer conversion resulted in a change of sign
2836d1d8577SJunchao Zhang                           *(string.pointer++) = '\xC2';
2846d1d8577SJunchao Zhang 
2856d1d8577SJunchao Zhang   Once yaml fixes them, we can remove the pragmas
2866d1d8577SJunchao Zhang */
2876d1d8577SJunchao Zhang #pragma GCC diagnostic push
2886d1d8577SJunchao Zhang #pragma GCC diagnostic ignored "-Wsign-conversion"
289951eb098SLisandro Dalcin #include <../src/sys/yaml/src/scanner.c>
2906d1d8577SJunchao Zhang #pragma GCC diagnostic pop
291951eb098SLisandro Dalcin 
292951eb098SLisandro Dalcin /* Silence a few unused-function warnings */
293951eb098SLisandro Dalcin static PETSC_UNUSED void petsc_yaml_unused(void)
294951eb098SLisandro Dalcin {
295951eb098SLisandro Dalcin   (void)yaml_parser_scan;
296951eb098SLisandro Dalcin   (void)yaml_document_get_node;
297951eb098SLisandro Dalcin   (void)yaml_parser_set_encoding;
298951eb098SLisandro Dalcin   (void)yaml_parser_set_input;
299951eb098SLisandro Dalcin   (void)yaml_parser_set_input_file;
300951eb098SLisandro Dalcin }
301951eb098SLisandro Dalcin 
302951eb098SLisandro Dalcin #endif
303