Actual source code: yamlimpls.c
petsc-3.3-p7 2013-05-11
1: #include "yamlimpls.h"
3: void options_list_delete(options_list_t *options_list) {
4: int i, j;
6: for(i=0; i<(*options_list).count; i++)
7: {
8: for(j=0; j<(*options_list).options[i].arguments.count; j++) {
9: if((*options_list).options[i].arguments.args[j]) {
10: free((*options_list).options[i].arguments.args[j]);
11: }
12: }
13: if((*options_list).options[i].arguments.args) {
14: free((*options_list).options[i].arguments.args);
15: }
16: if((*options_list).options[i].name) {
17: free((*options_list).options[i].name);
18: }
19: if((*options_list).options[i].group) {
20: free((*options_list).options[i].group);
21: }
22: }
23: if((*options_list).options) {
24: free((*options_list).options);
25: }
26: }
28: int options_list_populate_yaml(char *str, options_list_t *options_list) {
29: yaml_parser_t parser;
30: yaml_event_t event, *events=0;
31: int i, j, k, ii; /* generic counters */
32: int alias_count, events_length, sequence_stack, mapping_stack, mapping_end_index;; /* named counters */
33: alias_list_t list;
34: grouping_stack_t grouping_stack;
35: const int MAX_NESTED_GROUPS = 10;
36: /* This can be edited later as needed, this is for memory allocation purposes for the grouping_stack */
38: /* Initialize objects and check for errors. */
39: if (!yaml_parser_initialize(&parser)) {
40: fprintf(stderr, "Failed to initialize parser. (%s:%d)\n", __FILE__, __LINE__-1);
41: return 0;
42: }
43: yaml_parser_set_input_string(&parser, (unsigned char*) str, strlen(str));
45: /* Counting things for memory allocation purposes */
46: if(!yaml_parser_parse(&parser, &event)) {
47: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
48: return 0;
49: }
50: i=0;
51: while(event.type != YAML_STREAM_END_EVENT) {
52: if(event.type == YAML_DOCUMENT_START_EVENT) {
53: yaml_event_delete(&event);
54: if(!yaml_parser_parse(&parser, &event)) {
55: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
56: return 0;
57: }
58: if(event.type == YAML_MAPPING_START_EVENT) {
59: yaml_event_delete(&event);
60: if(!yaml_parser_parse(&parser, &event)) {
61: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
62: return 0;
63: }
64: if(event.type == YAML_SCALAR_EVENT) {
65: if(strcmp((char*) event.data.scalar.value, "Options") == 0
66: || strcmp((char*) event.data.scalar.value, "options") == 0) {
67: i=3;alias_count=0;
68: while(event.type != YAML_DOCUMENT_END_EVENT) {
69: yaml_event_delete(&event);
70: if(!yaml_parser_parse(&parser, &event)) {
71: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
72: return 0;
73: }
74: i++;
75: }
76: }
77: }
78: }
79: }
80: yaml_event_delete(&event);
81: if(!yaml_parser_parse(&parser, &event)) {
82: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
83: return 0;
84: }
85: }
86: yaml_event_delete(&event);
87: yaml_parser_delete(&parser);
89: /* Populating the alias list. */
90: if(!alias_list_populate_yaml(str, &list)) {
91: fprintf(stderr, "error alias_list_populate_yaml (%s:%d)", __FILE__, __LINE__-1);
92: return 0;
93: }
95: /* Allocating memory based on counts from above */
96: events = (yaml_event_t*) calloc((i+1)*4, sizeof(yaml_event_t));
97: /* Multiplied by four because I am not counting the alias events this needs to be worked on later */
98: /* We could overallocate by a lot and realloc once we get the actual number of events in the array later */
100: /* Time to load the events to an array so I can better play with them */
101: yaml_parser_initialize(&parser);
102: yaml_parser_set_input_string(&parser, (unsigned char*) str, strlen(str));
103: if(!yaml_parser_parse(&parser, &event)) {
104: fprintf(stderr, "Parser error. (%s:%d)\n", __FILE__, __LINE__-1);
105: return 0;
106: }
107: while(event.type != YAML_STREAM_END_EVENT) {
108: i=0;j=0;sequence_stack=0;
109: if(event.type == YAML_DOCUMENT_START_EVENT) {
110: if(!yaml_event_initialize(&events[i], &event)) {
111: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n",__FILE__,__LINE__-1);
112: return 0;
113: }
114: yaml_event_delete(&event);
115: if(!yaml_parser_parse(&parser, &event)) {
116: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
117: return 0;
118: }
119: i++;
120: if(event.type == YAML_MAPPING_START_EVENT) {
121: if(!yaml_event_initialize(&events[i], &event)) {
122: fprintf(stderr, "error, yamL_event_initialize (%s:%d)\n", __FILE__, __LINE__);
123: return 0;
124: }
125: yaml_event_delete(&event);
126: if(!yaml_parser_parse(&parser, &event)) {
127: fprintf(stderr, "Parser error. (%s:%d)\n", __FILE__, __LINE__-1);
128: return 0;
129: }
130: i++;
131: if(event.type == YAML_SCALAR_EVENT) {
132: if(!yaml_event_initialize(&events[i], &event)) {
133: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
134: return 0;
135: }
136: i++;
137: if(strcmp((char*) event.data.scalar.value, "options") == 0
138: || strcmp((char*) event.data.scalar.value, "Options") == 0) {
139: yaml_event_delete(&event);
140: if(!yaml_parser_parse(&parser, &event)) {
141: fprintf(stderr, "Parser error. (%s:%d)\n", __FILE__, __LINE__-1);
142: return 0;
143: }
144: while(event.type != YAML_DOCUMENT_END_EVENT) {
145: switch(event.type) {
146: case YAML_ALIAS_EVENT:
147: /* Copy all of the alias event info from the alias list */
148: for(j=0; j<list.count; j++) {
149: if(strcmp(list.list[j].alias, (char*) event.data.alias.anchor) == 0) {
150: if(!yaml_event_initialize(&events[i], &list.list[j].event)) {
151: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
152: return 0;
153: }
154: i++;
155: }
156: }
157: break;
158: default:
159: yaml_event_initialize(&events[i], &event);
160: i++;
161: break;
162: }
163: yaml_event_delete(&event);
164: if(!yaml_parser_parse(&parser, &event)) {
165: fprintf(stderr, "Parser error. (%s:%d)\n", __FILE__, __LINE__-1);
166: return 0;
167: }
168: if(event.type == YAML_DOCUMENT_END_EVENT) {
169: if(!yaml_event_initialize(&events[i], &event)) {
170: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
171: return 0;
172: }
173: i++;
174: }
175: }
176: events_length = i;
177: break;
178: } else {
179: for(i--; i>=0; i--) {
180: yaml_event_delete(&events[i]);
181: }
182: }
183: } else {
184: for(i--; i>=0; i--) {
185: yaml_event_delete(&events[i]);
186: }
187: }
188: } else {
189: for(i--; i>=0; i--) {
190: yaml_event_delete(&events[i]);
191: }
192: }
193: }
194: yaml_event_delete(&event);
195: if(!yaml_parser_parse(&parser, &event)) {
196: fprintf(stderr, "Parser error. (%s:%d)", __FILE__, __LINE__-1);
197: return 0;
198: }
199: }
200: yaml_event_delete(&event);
201: yaml_parser_delete(&parser);
202: alias_list_delete(&list);
204: /* Making sure the last block of code ran properly and my config file was written properly */
205: if(events[0].type != YAML_DOCUMENT_START_EVENT
206: || events[1].type != YAML_MAPPING_START_EVENT
207: || events[2].type != YAML_SCALAR_EVENT
208: ||(strcmp((char*) events[2].data.scalar.value, "options") != 0
209: && strcmp((char*) events[2].data.scalar.value, "Options") != 0)
210: || events[3].type != YAML_SEQUENCE_START_EVENT) {
211: fprintf(stderr, "Events did not load properly. (%s:%d)\n", __FILE__, __LINE__);
212: return 0;
213: }
214: for(i=0; i<events_length; i++) {
215: if(events[i].type == YAML_NO_EVENT) {
216: fprintf(stderr, "Events did not load properly. (%s:%d)\n", __FILE__, __LINE__);
217: return 0;
218: }
219: }
221: /* Getting the number of options */
222: j=0;
223: for(i=0; i<events_length; i++) {
224: if(events[i].type == YAML_MAPPING_START_EVENT
225: && events[i+1].type == YAML_SCALAR_EVENT
226: &&(events[i+2].type == YAML_SCALAR_EVENT
227: ||(events[i+2].type == YAML_SEQUENCE_START_EVENT
228: && events[i+3].type == YAML_SCALAR_EVENT))) {
229: j++;
230: }
231: }
232: (*options_list).count = j;
234: /* Allocating memory for the options_list options */
235: (*options_list).options = (option_t*) calloc((*options_list).count+30, sizeof(option_t));
237: /* Time to populate the options_list */
238: /* Start out by putting a fork in the garbage disposal */
239: /* Set up the grouping stack before use */
240: grouping_stack.count = 0;
241: grouping_stack.groups = (grouping_stack_group_t*) calloc(MAX_NESTED_GROUPS, sizeof(grouping_stack_group_t));
242: for(i=0; i<MAX_NESTED_GROUPS; i++) {
243: grouping_stack.groups[i].name = 0;
244: grouping_stack.groups[i].start = 0;
245: grouping_stack.groups[i].end = 0;
246: }
247: grouping_stack.groups[0].name = (char*) calloc(8, sizeof(char));
248: strcpy(grouping_stack.groups[0].name, "default");
249: grouping_stack.groups[0].start = 0;
250: grouping_stack.groups[0].end = 0;
251: grouping_stack.count = 1;
253: j=0; mapping_end_index = 0;
254: for(i=3; i<events_length; i++) {
255: if(grouping_stack.groups[grouping_stack.count-1].end == i) {
256: if(grouping_stack.groups[grouping_stack.count-1].name) {
257: free(grouping_stack.groups[grouping_stack.count-1].name);
258: grouping_stack.groups[grouping_stack.count-1].name = 0;
259: }
260: grouping_stack.groups[grouping_stack.count-1].end = 0;
261: grouping_stack.groups[grouping_stack.count-1].start = 0;
262: grouping_stack.count--;
263: if(grouping_stack.count == 0) {
264: grouping_stack.count = 1;
265: grouping_stack.groups[0].name = (char*) calloc(8, sizeof(char));
266: strcpy(grouping_stack.groups[0].name, "default");
267: grouping_stack.groups[0].start = 0;
268: grouping_stack.groups[0].end = 0;
269: }
270: }
271: if(events[i].type == YAML_MAPPING_START_EVENT
272: && events[i+1].type == YAML_SCALAR_EVENT) {
273: if(events[i+2].type == YAML_SCALAR_EVENT
274: && events[i+3].type == YAML_MAPPING_END_EVENT) {
275: /* We have an option with only one arg */
276: ii=0;
277: for(k=0; k<grouping_stack.count; k++) {
278: if(grouping_stack.groups[k].name) {
279: ii+=strlen(grouping_stack.groups[k].name);
280: }
281: }
282: (*options_list).options[j].name = (char*) calloc(events[i+1].data.scalar.length+1, sizeof(char));
283: strcpy((*options_list).options[j].name, (char*)events[i+1].data.scalar.value);
284: (*options_list).options[j].group = (char*) calloc(ii + grouping_stack.count, sizeof(char));
285: strcpy((*options_list).options[j].group, grouping_stack.groups[0].name);
286: for(k=1; k<grouping_stack.count; k++) {
287: strcat((*options_list).options[j].group, "_");
288: strcat((*options_list).options[j].group, grouping_stack.groups[k].name);
289: }
290: (*options_list).options[j].arguments.count = 1;
291: (*options_list).options[j].arguments.args = (char**) calloc(
292: (*options_list).options[j].arguments.count+1, sizeof(char*));
293: (*options_list).options[j].arguments.args[0] = (char*) calloc(
294: events[i+2].data.scalar.length+1, sizeof(char));
295: strcpy((*options_list).options[j].arguments.args[0], (char*) events[i+2].data.scalar.value);
296: j++;i+=2;
297: } else if(events[i+2].type == YAML_SEQUENCE_START_EVENT) {
298: if(events[i+3].type == YAML_SCALAR_EVENT) {
299: /* We have an option that has a sequence of args */
300: /* First lets do what we can before performing a count of the args */
301: ii=0;
302: for(k=0; k<grouping_stack.count; k++) {
303: if(grouping_stack.groups[k].name) {
304: ii+=strlen(grouping_stack.groups[k].name);
305: }
306: }
307: (*options_list).options[j].name = (char*) calloc(events[i+1].data.scalar.length+1, sizeof(char));
308: strcpy((*options_list).options[j].name, (char*) events[i+1].data.scalar.value);
309: (*options_list).options[j].group = (char*) calloc(ii + grouping_stack.count, sizeof(char));
310: strcpy((*options_list).options[j].group, grouping_stack.groups[0].name);
311: for(k=1; k<grouping_stack.count; k++) {
312: strcat((*options_list).options[j].group, "_");
313: strcat((*options_list).options[j].group, grouping_stack.groups[k].name);
314: }
315: k=i+2+1;
316: /* 2+1 for clear thought. i+2 is the first sequence start event, so I will start at i+2+1 */
317: sequence_stack=1;
318: (*options_list).options[j].arguments.count = 0;
319: while(sequence_stack != 0) {
320: switch(events[k].type) {
321: case YAML_SEQUENCE_START_EVENT:
322: sequence_stack++;
323: break;
324: case YAML_SEQUENCE_END_EVENT:
325: sequence_stack--;
326: break;
327: case YAML_SCALAR_EVENT:
328: if(sequence_stack == 1) {
329: (*options_list).options[j].arguments.count++;
330: }
331: break;
332: default: break;
333: }
334: k++;
335: }
336: (*options_list).options[j].arguments.args = (char**) calloc(
337: (*options_list).options[j].arguments.count+1, sizeof(char*));
338: for(ii=i+2+1; ii < k; ii++) {
339: if(events[ii].type == YAML_SCALAR_EVENT) {
340: (*options_list).options[j].arguments.args[ii-i-2-1] = (char*) calloc(
341: events[ii].data.scalar.length+1, sizeof(char));
342: strcpy((*options_list).options[j].arguments.args[ii-i-2-1],
343: (char*) events[ii].data.scalar.value);
344: }
345: }
346: j++;
347: } else if(events[i+3].type == YAML_MAPPING_START_EVENT) {
348: /* We have a group of options coming up. */
349: if(grouping_stack.count == 1 && strcmp(grouping_stack.groups[0].name, "default") == 0) {
350: grouping_stack.count--;
351: }
352: if(grouping_stack.groups[grouping_stack.count].name) {
353: free(grouping_stack.groups[grouping_stack.count].name);
354: grouping_stack.groups[grouping_stack.count].name = 0;
355: }
356: grouping_stack.groups[grouping_stack.count].name = (char*) calloc(
357: events[i+1].data.scalar.length+1, sizeof(char));
358: strcpy(grouping_stack.groups[grouping_stack.count].name, (char*) events[i+1].data.scalar.value);
359: grouping_stack.groups[grouping_stack.count].start = i+3;
360: k=i+1;
361: mapping_stack=1;
362: while(mapping_stack!=0) {
363: switch(events[k].type) {
364: case YAML_MAPPING_START_EVENT:
365: mapping_stack++;
366: break;
367: case YAML_MAPPING_END_EVENT:
368: mapping_stack--;
369: break;
370: default: break;
371: }
372: k++;
373: }
374: mapping_end_index = k-1;
375: grouping_stack.groups[grouping_stack.count].end = k-1;
376: grouping_stack.count++;
377: i+=2;
378: }
379: }
380: }
381: }
383: /* Cleanup */
384: for(i=0; i<MAX_NESTED_GROUPS; i++) {
385: if(grouping_stack.groups[i].name) free(grouping_stack.groups[i].name);
386: }
387: if(grouping_stack.groups) free(grouping_stack.groups);
388: for(i=0; i<events_length; i++) {
389: yaml_event_delete(&events[i]);
390: }
391: if(events) free(events);
393: return 1;
394: }
396: int yaml_event_initialize(yaml_event_t *out, yaml_event_t *in) {
397: switch((*in).type) {
398: case YAML_STREAM_START_EVENT:
399: if(!yaml_stream_start_event_initialize(&(*out), (*in).data.stream_start.encoding)) {
400: fprintf(stderr, "error yaml_stream_start_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
401: return 0;
402: }
403: break;
404: case YAML_STREAM_END_EVENT:
405: if(!yaml_stream_end_event_initialize(&(*out))) {
406: fprintf(stderr, "error yaml_stream_end_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
407: return 0;
408: }
409: break;
410: case YAML_DOCUMENT_START_EVENT:
411: if(!yaml_document_start_event_initialize(&(*out), (*in).data.document_start.version_directive,
412: (*in).data.document_start.tag_directives.start, (*in).data.document_start.tag_directives.end,
413: (*in).data.document_start.implicit)) {
414: fprintf(stderr, "error yaml_document_start_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
415: return 0;
416: }
417: break;
418: case YAML_DOCUMENT_END_EVENT:
419: if(!yaml_document_end_event_initialize(&(*out), (*in).data.document_end.implicit)) {
420: fprintf(stderr, "error yaml_document_end_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
421: return 0;
422: }
423: break;
424: case YAML_ALIAS_EVENT:
425: if(!yaml_alias_event_initialize(&(*out), (*in).data.alias.anchor)) {
426: fprintf(stderr, "error yaml_alias_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
427: return 0;
428: }
429: break;
430: case YAML_SCALAR_EVENT:
431: if(!yaml_scalar_event_initialize(&(*out), (*in).data.scalar.anchor,
432: (*in).data.scalar.tag, (*in).data.scalar.value, (*in).data.scalar.length,
433: (*in).data.scalar.plain_implicit, (*in).data.scalar.quoted_implicit,
434: (*in).data.scalar.style)) {
435: fprintf(stderr, "error yaml_scalar_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
436: return 0;
437: }
438: break;
439: case YAML_SEQUENCE_START_EVENT:
440: if(!yaml_sequence_start_event_initialize(&(*out), (*in).data.sequence_start.anchor,
441: (*in).data.sequence_start.tag, (*in).data.sequence_start.implicit,
442: (*in).data.sequence_start.style)) {
443: fprintf(stderr, "error yaml_sequence_start_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
444: return 0;
445: }
446: break;
447: case YAML_SEQUENCE_END_EVENT:
448: if(!yaml_sequence_end_event_initialize(&(*out))) {
449: fprintf(stderr, "error yaml_sequence_end_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
450: return 0;
451: }
452: break;
453: case YAML_MAPPING_START_EVENT:
454: if(!yaml_mapping_start_event_initialize(&(*out), (*in).data.mapping_start.anchor,
455: (*in).data.mapping_start.tag, (*in).data.mapping_start.implicit,
456: (*in).data.mapping_start.style)) {
457: fprintf(stderr, "error yaml_mapping_start_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
458: return 0;
459: }
460: break;
461: case YAML_MAPPING_END_EVENT:
462: if(!yaml_mapping_end_event_initialize(&(*out))) {
463: fprintf(stderr, "error yaml_mapping_end_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
464: return 0;
465: }
466: break;
467: default:
468: fprintf(stderr, "unexpected event (%s:%d)\n", __FILE__, __LINE__);
469: return 0;
470: break;
471: }
473: return 1;
474: }
476: int alias_list_populate_yaml(char *str, alias_list_t *list) {
477: yaml_parser_t parser;
478: yaml_event_t event, *events=0;
479: int i, j, k, stacknumber, events_length;
481: if(!yaml_parser_initialize(&parser)) {
482: fprintf(stderr, "error initializing parser (%s:%d)\n", __FILE__, __LINE__-1);
483: return 0;
484: }
485: yaml_parser_set_input_string(&parser, (unsigned char*) str, strlen(str));
487: /* Getting count to allocate memory for the events array. */
488: i=0;
489: if(!yaml_parser_parse(&parser, &event)) {
490: fprintf(stderr, "error yaml_parser_parse (%s:%d)\n", __FILE__, __LINE__-1);
491: return 0;
492: }
493: while(event.type != YAML_STREAM_END_EVENT) {
494: i++;
495: yaml_event_delete(&event);
496: if(!yaml_parser_parse(&parser, &event)) {
497: fprintf(stderr, "error yaml_parser_parse (%s:%d)\n", __FILE__, __LINE__-1);
498: return 0;
499: }
500: }
501: events_length = i;
502: yaml_event_delete(&event);
503: yaml_parser_delete(&parser);
505: /* Allocate memory for the events array */
506: events = (yaml_event_t*) calloc(events_length+1, sizeof(yaml_event_t));
508: /* Now to copy everything to the events array */
509: yaml_parser_initialize(&parser);
510: yaml_parser_set_input_string(&parser, (unsigned char*) str, strlen(str));
511: for(i=0; i<events_length; i++) {
512: if(!yaml_parser_parse(&parser, &event)) {
513: fprintf(stderr, "error yaml_parser_parse (%s:%d)\n", __FILE__, __LINE__-1);
514: return 0;
515: }
516: if(!yaml_event_initialize(&events[i], &event)) {
517: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
518: return 0;
519: }
520: yaml_event_delete(&event);
521: }
522: yaml_parser_delete(&parser);
524: /* Lets count so I can later allocate memory for the alias list */
525: stacknumber = 0;
526: (*list).count = 0;
527: for(i=0; i<events_length; i++) {
528: switch(events[i].type) {
529: case YAML_SCALAR_EVENT:
530: if(events[i].data.scalar.anchor != NULL) {
531: (*list).count++;
532: }
533: break;
534: case YAML_SEQUENCE_START_EVENT:
535: if(events[i].data.sequence_start.anchor != NULL) {
536: (*list).count++;
537: stacknumber = 1;
538: j=i;j++;
539: while(stacknumber != 0) {
540: switch(events[j].type) {
541: case YAML_SEQUENCE_START_EVENT:
542: stacknumber++;
543: break;
544: case YAML_SEQUENCE_END_EVENT:
545: stacknumber--;
546: break;
547: default: break;
548: }
549: j++;
550: (*list).count++;
551: }
552: }
553: break;
554: case YAML_MAPPING_START_EVENT:
555: if(events[i].data.mapping_start.anchor != NULL) {
556: (*list).count++;
557: stacknumber = 1;
558: j=i;j++;
559: while(stacknumber != 0) {
560: switch(events[j].type) {
561: case YAML_MAPPING_START_EVENT:
562: stacknumber++;
563: break;
564: case YAML_MAPPING_END_EVENT:
565: stacknumber--;
566: break;
567: default: break;
568: }
569: j++;
570: (*list).count++;
571: }
572: }
573: break;
574: default: break;
575: }
576: }
578: /* Lets allocate memory for the alias list */
579: (*list).list = (alias_key_value_t*) calloc((*list).count+1, sizeof(alias_key_value_t));
581: /* Now to run through the same algorithm to populate the list */
582: j=0;
583: for(i=0; i<events_length; i++) {
584: switch(events[i].type) {
585: case YAML_SCALAR_EVENT:
586: if(events[i].data.scalar.anchor != NULL) {
587: (*list).list[j].alias = (char*) calloc(
588: strlen((char*) events[i].data.scalar.anchor)+1, sizeof(char));
589: strcpy((*list).list[j].alias, (char*) events[i].data.scalar.anchor);
590: if(!yaml_event_initialize(&(*list).list[j].event, &events[i])) {
591: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
592: return 0;
593: }
594: j++;
595: }
596: break;
597: case YAML_SEQUENCE_START_EVENT:
598: if(events[i].data.sequence_start.anchor != NULL) {
599: (*list).list[j].alias = (char*) calloc(
600: strlen((char*) events[i].data.sequence_start.anchor)+1, sizeof(char));
601: strcpy((*list).list[j].alias, (char*) events[i].data.sequence_start.anchor);
602: if(!yaml_event_initialize(&(*list).list[j].event, &events[i])) {
603: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
604: return 0;
605: }
606: stacknumber = 1;
607: j++;
608: k=i;k++;
609: while(stacknumber != 0) {
610: switch(events[k].type) {
611: case YAML_SEQUENCE_START_EVENT:
612: stacknumber++;
613: break;
614: case YAML_SEQUENCE_END_EVENT:
615: stacknumber--;
616: break;
617: default: break;
618: }
619: (*list).list[j].alias = (char*) calloc(strlen((*list).list[j-1].alias)+1, sizeof(char));
620: strcpy((*list).list[j].alias, (*list).list[j-1].alias);
621: if(!yaml_event_initialize(&(*list).list[j].event, &events[k])) {
622: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
623: return 0;
624: }
625: j++;k++;
626: }
627: }
628: break;
629: case YAML_MAPPING_START_EVENT:
630: if(events[i].data.mapping_start.anchor != NULL) {
631: (*list).list[j].alias = (char*) calloc(
632: strlen((char*) events[i].data.mapping_start.anchor)+1, sizeof(char));
633: strcpy((*list).list[j].alias, (char*) events[i].data.mapping_start.anchor);
634: if(!yaml_event_initialize(&(*list).list[j].event, &events[i])) {
635: fprintf(stderr, "error yaml_event_initialize (%s:%d)\n", __FILE__, __LINE__-1);
636: return 0;
637: }
638: stacknumber = 1;
639: j++;
640: k=i;k++;
641: while(stacknumber != 0) {
642: switch(events[k].type) {
643: case YAML_MAPPING_START_EVENT:
644: stacknumber++;
645: break;
646: case YAML_SEQUENCE_END_EVENT:
647: stacknumber--;
648: break;
649: default: break;
650: }
651: (*list).list[j].alias = (char*) calloc(strlen((*list).list[j-1].alias)+1, sizeof(char));
652: strcpy((*list).list[j].alias, (*list).list[j-1].alias);
653: if(!yaml_event_initialize(&(*list).list[j].event, &events[i])) {
654: fprintf(stderr, "error yaml_event_initialize(%s:%d)\n", __FILE__, __LINE__-1);
655: return 0;
656: }
657: j++;k++;
658: }
659: }
660: break;
661: default: break;
662: }
663: }
665: /* Cleanup */
666: for(i=0; i<events_length; i++) {
667: yaml_event_delete(&events[i]);
668: }
669: if(events) free(events);
671: return 1;
672: }
674: void alias_list_delete(alias_list_t *list) {
675: int i;
677: for(i=0; i<(*list).count; i++) {
678: if((*list).list[i].alias) free((*list).list[i].alias);
679: yaml_event_delete(&(*list).list[i].event);
680: }
681: if((*list).list) free((*list).list);
682: (*list).count = 0;
683: }
687: PetscErrorCode file_to_string(char* filename, char** str) {
688: FILE *fh;
689: char *line;
693: if((*str) != NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"argument: str is not NULL");
695: fh = fopen(filename, "r");
696: if(!fh) PetscFunctionReturn(1); /* Return error code , and let calling function decide about the error */
698: PetscMalloc(64000*sizeof(char), &line);
699: PetscMalloc(128000*sizeof(char), str);
700: /* might change to dynamically allocate this at a later time */
702: while(fgets(line, 64000, fh) != NULL) strcat((*str), line);
704: PetscFree(line);
705: if(fh) fclose(fh);
707: return(0);
708: }
712: PetscErrorCode PetscOptionsInsertFile_YAML(MPI_Comm comm, const char file[], PetscBool require)
713: {
714: PetscErrorCode ierr, ierr_file;
715: options_list_t options_list;
716: PetscMPIInt rank,cnt=0;
717: char *vstring = 0, fname[PETSC_MAX_PATH_LEN], *ostring = 0;
718: size_t i, len;
719: PetscBool match;
722: MPI_Comm_rank(comm,&rank);
723: if (!rank) {
724: /* Warning: assume a maximum size for all options in a string */
725: PetscMalloc(128000*sizeof(char),&vstring);
726: vstring[0] = 0;
727: cnt = 0;
729: PetscFixFilename(file,fname);
730: ierr_file = file_to_string(fname, &ostring);
731: if (ierr_file && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open YAML Options File %s",fname);
732: if (ierr_file) return(0);
734: if (options_list_populate_yaml(ostring,&options_list)) {
735: PetscInfo1(0,"Read YAML options file %s\n",file);
736: for (i=0;i<options_list.count;i++) {
737: if (options_list.options[i].arguments.count == 1) {
738: PetscStrcasecmp(options_list.options[i].arguments.args[0], "false", &match);
739: if (!match) {
740: /* The current option has one argument it is not false. Something will have to be copied */
741: PetscStrcat(vstring,"-");
742: PetscStrcasecmp(options_list.options[i].group, "default", &match);
743: if (!match) {
744: /* The current option is not in the default group. The group name and option name needs to be copied. */
745: PetscStrcat(vstring,options_list.options[i].group);
746: PetscStrcat(vstring,"_");
747: }
748: PetscStrcat(vstring,options_list.options[i].name);
749: PetscStrcat(vstring," ");
750: PetscStrcasecmp(options_list.options[i].arguments.args[0], "true", &match);
751: if (!match) {
752: /*The argument needs to be copied. */
753: PetscStrcat(vstring,options_list.options[i].arguments.args[0]);
754: PetscStrcat(vstring," ");
755: }
756: }
757: } else {
758: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid number of arguments (%s: %s)",options_list.options[i].group,options_list.options[i].name);
759: }
760: }
761: options_list_delete(&options_list);
762: PetscStrlen(vstring,&len);
763: cnt = PetscMPIIntCast(len);
764: } else if (require) {
765: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to process YAML Options File %s",fname);
766: }
767: }
769: MPI_Bcast(&cnt,1,MPI_INT,0,comm);
770: if (cnt) {
771: if (rank) {
772: PetscMalloc((cnt+1)*sizeof(char),&vstring);
773: }
774: MPI_Bcast(vstring,cnt,MPI_CHAR,0,comm);
775: vstring[cnt] = 0;
776: PetscOptionsInsertString(vstring);
777: }
778: PetscFree(vstring);
779: return(0);
780: }