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: }