Пример #1
0
static JSON::Value parse(yaml_parser_t &parser)
{
    JSON::Value result;
    yaml_document_t document;
    if (!yaml_parser_load(&parser, &document)) {
        yaml_error_type_t error = parser.error;
        MORDOR_ASSERT(error != YAML_NO_ERROR);
        Exception exception(parser.problem, parser.context);
        yaml_parser_delete(&parser);
        switch (error) {
            case YAML_MEMORY_ERROR:
                MORDOR_THROW_EXCEPTION(std::bad_alloc());
            case YAML_READER_ERROR:
                MORDOR_THROW_EXCEPTION(InvalidUnicodeException());
            default:
                MORDOR_THROW_EXCEPTION(exception);
        }
    }

    try {
        convertNode(result, yaml_document_get_root_node(&document), document);
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        return result;
    } catch (...) {
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        throw;
    }
}
Пример #2
0
static void
yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
{
    int index;

    if (!emitter->anchors) {
        yaml_document_delete(emitter->document);
        emitter->document = NULL;
        return;
    }

    for (index = 0; emitter->document->nodes.start + index
            < emitter->document->nodes.top; index ++) {
        yaml_node_t node = emitter->document->nodes.start[index];
        if (!emitter->anchors[index].serialized) {
            yaml_free(node.tag);
            if (node.type == YAML_SCALAR_NODE) {
                yaml_free(node.data.scalar.value);
            }
        }
        if (node.type == YAML_SEQUENCE_NODE) {
            STACK_DEL(emitter, node.data.sequence.items);
        }
        if (node.type == YAML_MAPPING_NODE) {
            STACK_DEL(emitter, node.data.mapping.pairs);
        }
    }

    STACK_DEL(emitter, emitter->document->nodes);
    yaml_free(emitter->anchors);

    emitter->anchors = NULL;
    emitter->last_anchor_id = 0;
    emitter->document = NULL;
}
Пример #3
0
static int
parse_fatso_yml(struct fatso_project* p, const char* file, char** out_error_message) {
  int r = 1;
  yaml_parser_t parser;
  yaml_document_t doc;

  yaml_parser_initialize(&parser);

  FILE* fp = fopen(file, "r");
  if (!fp) {
    *out_error_message = strdup(strerror(errno));
    goto out;
  }

  yaml_parser_set_input_file(&parser, fp);
  if (!yaml_parser_load(&parser, &doc)) {
    *out_error_message = strdup(parser.problem);
    goto out_doc;
  }

  yaml_node_t* root = yaml_document_get_root_node(&doc);
  if (root == NULL) {
    *out_error_message = strdup("YAML file does not contain a document");
    goto out_doc;
  }

  r = fatso_package_parse(&p->package, &doc, root, out_error_message);
out_doc:
  yaml_document_delete(&doc);
out:
  yaml_parser_delete(&parser);
  fclose(fp);
  return r;
}
Пример #4
0
mrb_value
mrb_yaml_dump(mrb_state *mrb, mrb_value self)
{
  yaml_emitter_t emitter;
  yaml_document_t document;

  mrb_value root;
  yaml_write_data_t write_data;

  /* Extract arguments */
  mrb_get_args(mrb, "o", &root);

  /* Build the document */
  yaml_document_initialize(&document, NULL, NULL, NULL, 0, 0);
  value_to_node(mrb, &document, root);

  /* Initialize the emitter */
  yaml_emitter_initialize(&emitter);

  write_data.mrb = mrb;
  write_data.str = mrb_str_new(mrb, NULL, 0);
  yaml_emitter_set_output(&emitter, &yaml_write_handler, &write_data);

  /* Dump the document */
  yaml_emitter_open(&emitter);
  yaml_emitter_dump(&emitter, &document);
  yaml_emitter_close(&emitter);

  /* Clean up */
  yaml_emitter_delete(&emitter);
  yaml_document_delete(&document);

  return write_data.str;
}
Пример #5
0
int
main(int argc, char *argv[])
{
    int number;

    if (argc < 2) {
        printf("Usage: %s file1.yaml ...\n", argv[0]);
        return 0;
    }

    for (number = 1; number < argc; number ++)
    {
        FILE *file;
        yaml_parser_t parser;
        yaml_document_t document;
        int done = 0;
        int count = 0;
        int error = 0;

        printf("[%d] Loading '%s': ", number, argv[number]);
        fflush(stdout);

        file = fopen(argv[number], "rb");
        assert(file);

        assert(yaml_parser_initialize(&parser));

        yaml_parser_set_input_file(&parser, file);

        while (!done)
        {
            if (!yaml_parser_load(&parser, &document)) {
                error = 1;
                break;
            }

            done = (!yaml_document_get_root_node(&document));

            yaml_document_delete(&document);

            if (!done) count ++;
        }

        yaml_parser_delete(&parser);

        assert(!fclose(file));

        printf("%s (%d documents)\n", (error ? "FAILURE" : "SUCCESS"), count);
    }

    return 0;
}
Пример #6
0
static rstatus_t
conf_validate_document(struct conf *cf)
{
    rstatus_t status;
    uint32_t count;
    bool done;

    status = conf_yaml_init(cf);
    if (status != NC_OK) {
        return status;
    }

    count = 0;
    done = false;
    do {
        yaml_document_t document;
        yaml_node_t *node;
        int rv;

        rv = yaml_parser_load(&cf->parser, &document);
        if (!rv) {
            log_error("conf: failed (err %d) to get the next yaml document",
                      cf->parser.error);
            conf_yaml_deinit(cf);
            return NC_ERROR;
        }

        node = yaml_document_get_root_node(&document);
        if (node == NULL) {
            done = true;
        } else {
            count++;
        }

        yaml_document_delete(&document);
    } while (!done);

    conf_yaml_deinit(cf);

    if (count != 1) {
        log_error("conf: '%s' must contain only 1 document; found %"PRIu32" "
                  "documents", cf->fname, count);
        return NC_ERROR;
    }

    return NC_OK;
}
Пример #7
0
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
{
    yaml_event_t event;

    assert(parser);     /* Non-NULL parser object is expected. */
    assert(document);   /* Non-NULL document object is expected. */

    memset(document, 0, sizeof(yaml_document_t));
    if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
        goto error;

    if (!parser->stream_start_produced) {
        if (!yaml_parser_parse(parser, &event)) goto error;
        assert(event.type == YAML_STREAM_START_EVENT);
                        /* STREAM-START is expected. */
    }

    if (parser->stream_end_produced) {
        return 1;
    }

    if (!yaml_parser_parse(parser, &event)) goto error;
    if (event.type == YAML_STREAM_END_EVENT) {
        return 1;
    }

    if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
        goto error;

    parser->document = document;

    if (!yaml_parser_load_document(parser, &event)) goto error;

    yaml_parser_delete_aliases(parser);
    parser->document = NULL;

    return 1;

error:

    yaml_parser_delete_aliases(parser);
    yaml_document_delete(document);
    parser->document = NULL;

    return 0;
}
Пример #8
0
void parse_file(char * fileData, int length)
{
  // start yaml parser
  yaml_parser_t parser;
  yaml_document_t document;
  yaml_parser_initialize(&parser);

  const unsigned char * input = reinterpret_cast<const unsigned char *>(fileData);

  yaml_parser_set_input_string(&parser, input, length);
  yaml_parser_load(&parser, &document);
  
  mustache_spec_parse_document(&document);
  
  yaml_document_delete(&document);
  yaml_parser_delete(&parser);
}
Пример #9
0
void tap_yaml_write(const char *yaml, va_list vl)
{
	yaml_parser_t parser;
	yaml_document_t document;
	yaml_emitter_t emitter;
	char buffer[8192];
	size_t length;

	if (yaml == NULL) {
		return;
	}

	length = vsnprintf(buffer, 8192, yaml, vl);

	yaml_parser_initialize(&parser);
	yaml_parser_set_input_string(&parser, (unsigned char*) buffer, length);
	if (yaml_parser_load(&parser, &document)) {
		document.start_implicit = 0;
		document.end_implicit = 0;

		tap_yaml_document_set_block_style(&document);

		yaml_emitter_initialize(&emitter);
		yaml_emitter_set_output(&emitter, tap_yaml_write_handler, NULL);
		yaml_emitter_set_indent(&emitter, 2);

		// Initial indent
		tap_puts("  ");

		yaml_emitter_open(&emitter);
		yaml_emitter_dump(&emitter, &document);
		yaml_emitter_close(&emitter);

		yaml_parser_delete(&parser);
		yaml_emitter_delete(&emitter);
		yaml_document_delete(&document);
	} else {
		fprintf(stderr, "Error: %s %s at offset %zu\n",
			parser.problem, parser.context,
			parser.problem_mark.index);
	}
}
Пример #10
0
int load_documents(char *config_file_path) {
  int rv = 0;
  FILE *config_file = NULL;
  yaml_parser_t parser;
  yaml_document_t document;

  config_file = fopen(config_file_path, "r");

  if (config_file == NULL) {
    printf("ERROR: failed to open file %s\n", config_file_path);
    return ERR_FILE_OPEN_FAIL;
  }
  if (!yaml_parser_initialize(&parser)) {
    printf("ERROR: failed to initialize YAML parser\n");
    return ERR_YAML_INIT_FAIL;
  }

  yaml_parser_set_input_file(&parser, config_file);

  int done = 0;
  while (!done) {
    if (!yaml_parser_load(&parser, &document)) {
      printf("ERROR: failed to load document\n");
      return ERR_DOC_LOAD_FAIL;
    }

    yaml_node_t *root_node = yaml_document_get_root_node(&document);
    if (root_node == NULL) {
      done = 1;
    } else {
      print_document(&document, root_node);
    }
    yaml_document_delete(&document);
  }

  yaml_parser_delete(&parser);
  fclose(config_file);
  return rv;
}
Пример #11
0
mrb_value
mrb_yaml_load(mrb_state *mrb, mrb_value self)
{
  yaml_parser_t parser;
  yaml_document_t document;
  yaml_node_t *root;

  mrb_value yaml_str;
  mrb_value result;

  /* Extract arguments */
  mrb_get_args(mrb, "S", &yaml_str);

  /* Initialize the YAML parser */
  yaml_parser_initialize(&parser);
  yaml_parser_set_input_string(&parser,
    (unsigned char *) RSTRING_PTR(yaml_str), RSTRING_LEN(yaml_str));

  /* Load the document */
  yaml_parser_load(&parser, &document);

  /* Error handling */
  if (parser.error != YAML_NO_ERROR)
  {
    raise_parser_problem(mrb, &parser);
    return mrb_nil_value();
  }

  /* Convert the root node to an MRuby value */
  root = yaml_document_get_root_node(&document);
  result = node_to_value(mrb, &document, root);

  /* Clean up */
  yaml_document_delete(&document);
  yaml_parser_delete(&parser);

  return result;
}
Пример #12
0
int
main(int argc, char *argv[])
{
    int help = 0;
    int canonical = 0;
    int unicode = 0;
    int k;
    int done = 0;

    yaml_parser_t parser;
    yaml_emitter_t emitter;
    yaml_event_t input_event;
    yaml_document_t output_document;

    int root;

    /* Clear the objects. */

    memset(&parser, 0, sizeof(parser));
    memset(&emitter, 0, sizeof(emitter));
    memset(&input_event, 0, sizeof(input_event));
    memset(&output_document, 0, sizeof(output_document));

    /* Analyze command line options. */

    for (k = 1; k < argc; k ++)
    {
        if (strcmp(argv[k], "-h") == 0
                || strcmp(argv[k], "--help") == 0) {
            help = 1;
        }

        else if (strcmp(argv[k], "-c") == 0
                || strcmp(argv[k], "--canonical") == 0) {
            canonical = 1;
        }

        else if (strcmp(argv[k], "-u") == 0
                || strcmp(argv[k], "--unicode") == 0) {
            unicode = 1;
        }

        else {
            fprintf(stderr, "Unrecognized option: %s\n"
                    "Try `%s --help` for more information.\n",
                    argv[k], argv[0]);
            return 1;
        }
    }

    /* Display the help string. */

    if (help)
    {
        printf("%s <input\n"
                "or\n%s -h | --help\nDeconstruct a YAML stream\n\nOptions:\n"
                "-h, --help\t\tdisplay this help and exit\n"
                "-c, --canonical\t\toutput in the canonical YAML format\n"
                "-u, --unicode\t\toutput unescaped non-ASCII characters\n",
                argv[0], argv[0]);
        return 0;
    }

    /* Initialize the parser and emitter objects. */

    if (!yaml_parser_initialize(&parser)) {
        fprintf(stderr, "Could not initialize the parser object\n");
        return 1;
    }

    if (!yaml_emitter_initialize(&emitter)) {
        yaml_parser_delete(&parser);
        fprintf(stderr, "Could not inialize the emitter object\n");
        return 1;
    }

    /* Set the parser parameters. */

    yaml_parser_set_input_file(&parser, stdin);

    /* Set the emitter parameters. */

    yaml_emitter_set_output_file(&emitter, stdout);

    yaml_emitter_set_canonical(&emitter, canonical);
    yaml_emitter_set_unicode(&emitter, unicode);

    /* Create and emit the STREAM-START event. */

    if (!yaml_emitter_open(&emitter))
        goto emitter_error;

    /* Create a output_document object. */

    if (!yaml_document_initialize(&output_document, NULL, NULL, NULL, 0, 0))
        goto document_error;

    /* Create the root sequence. */

    root = yaml_document_add_sequence(&output_document, NULL,
            YAML_BLOCK_SEQUENCE_STYLE);
    if (!root) goto document_error;

    /* Loop through the input events. */

    while (!done)
    {
        int properties, key, value, map, seq;

        /* Get the next event. */

        if (!yaml_parser_parse(&parser, &input_event))
            goto parser_error;

        /* Check if this is the stream end. */

        if (input_event.type == YAML_STREAM_END_EVENT) {
            done = 1;
        }

        /* Create a mapping node and attach it to the root sequence. */

        properties = yaml_document_add_mapping(&output_document, NULL,
                YAML_BLOCK_MAPPING_STYLE);
        if (!properties) goto document_error;
        if (!yaml_document_append_sequence_item(&output_document,
                    root, properties)) goto document_error;

        /* Analyze the event. */

        switch (input_event.type)
        {
            case YAML_STREAM_START_EVENT:

                /* Add 'type': 'STREAM-START'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "STREAM-START", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'encoding': <encoding>. */

                if (input_event.data.stream_start.encoding)
                {
                    yaml_encoding_t encoding
                        = input_event.data.stream_start.encoding;

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "encoding", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            (encoding == YAML_UTF8_ENCODING ? "utf-8" :
                             encoding == YAML_UTF16LE_ENCODING ? "utf-16-le" :
                             encoding == YAML_UTF16BE_ENCODING ? "utf-16-be" :
                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }
                    
                break;

            case YAML_STREAM_END_EVENT:

                /* Add 'type': 'STREAM-END'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "STREAM-END", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            case YAML_DOCUMENT_START_EVENT:

                /* Add 'type': 'DOCUMENT-START'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "DOCUMENT-START", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Display the output_document version numbers. */

                if (input_event.data.document_start.version_directive)
                {
                    yaml_version_directive_t *version
                        = input_event.data.document_start.version_directive;
                    char number[64];

                    /* Add 'version': {}. */
                    
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "version", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    map = yaml_document_add_mapping(&output_document, NULL,
                            YAML_FLOW_MAPPING_STYLE);
                    if (!map) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, map)) goto document_error;

                    /* Add 'major': <number>. */

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "major", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    sprintf(number, "%d", version->major);
                    value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
                        number, -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                map, key, value)) goto document_error;

                    /* Add 'minor': <number>. */

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "minor", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    sprintf(number, "%d", version->minor);
                    value = yaml_document_add_scalar(&output_document, YAML_INT_TAG,
                        number, -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                map, key, value)) goto document_error;
                }

                /* Display the output_document tag directives. */

                if (input_event.data.document_start.tag_directives.start
                        != input_event.data.document_start.tag_directives.end)
                {
                    yaml_tag_directive_t *tag;

                    /* Add 'tags': []. */
                    
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "tags", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    seq = yaml_document_add_sequence(&output_document, NULL,
                            YAML_BLOCK_SEQUENCE_STYLE);
                    if (!seq) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, seq)) goto document_error;

                    for (tag = input_event.data.document_start.tag_directives.start;
                            tag != input_event.data.document_start.tag_directives.end;
                            tag ++)
                    {
                        /* Add {}. */

                        map = yaml_document_add_mapping(&output_document, NULL,
                                YAML_FLOW_MAPPING_STYLE);
                        if (!map) goto document_error;
                        if (!yaml_document_append_sequence_item(&output_document,
                                    seq, map)) goto document_error;

                        /* Add 'handle': <handle>. */

                        key = yaml_document_add_scalar(&output_document, NULL,
                            "handle", -1, YAML_PLAIN_SCALAR_STYLE);
                        if (!key) goto document_error;
                        value = yaml_document_add_scalar(&output_document, NULL,
                            tag->handle, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                        if (!value) goto document_error;
                        if (!yaml_document_append_mapping_pair(&output_document,
                                    map, key, value)) goto document_error;

                        /* Add 'prefix': <prefix>. */

                        key = yaml_document_add_scalar(&output_document, NULL,
                            "prefix", -1, YAML_PLAIN_SCALAR_STYLE);
                        if (!key) goto document_error;
                        value = yaml_document_add_scalar(&output_document, NULL,
                            tag->prefix, -1, YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                        if (!value) goto document_error;
                        if (!yaml_document_append_mapping_pair(&output_document,
                                    map, key, value)) goto document_error;
                    }
                }

                /* Add 'implicit': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.document_start.implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            case YAML_DOCUMENT_END_EVENT:

                /* Add 'type': 'DOCUMENT-END'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "DOCUMENT-END", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'implicit': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.document_end.implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            case YAML_ALIAS_EVENT:

                /* Add 'type': 'ALIAS'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "ALIAS", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'anchor': <anchor>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                        input_event.data.alias.anchor, -1,
                        YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            case YAML_SCALAR_EVENT:

                /* Add 'type': 'SCALAR'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "SCALAR", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'anchor': <anchor>. */

                if (input_event.data.scalar.anchor)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.scalar.anchor, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'tag': <tag>. */

                if (input_event.data.scalar.tag)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.scalar.tag, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'value': <value>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "value", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                        input_event.data.scalar.value,
                        input_event.data.scalar.length,
                        YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Display if the scalar tag is implicit. */

                /* Add 'implicit': {} */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "version", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                map = yaml_document_add_mapping(&output_document, NULL,
                        YAML_FLOW_MAPPING_STYLE);
                if (!map) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, map)) goto document_error;

                /* Add 'plain': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "plain", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.scalar.plain_implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            map, key, value)) goto document_error;

                /* Add 'quoted': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "quoted", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.scalar.quoted_implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            map, key, value)) goto document_error;

                /* Display the style information. */

                if (input_event.data.scalar.style)
                {
                    yaml_scalar_style_t style = input_event.data.scalar.style;

                    /* Add 'style': <style>. */

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            (style == YAML_PLAIN_SCALAR_STYLE ? "plain" :
                             style == YAML_SINGLE_QUOTED_SCALAR_STYLE ?
                                    "single-quoted" :
                             style == YAML_DOUBLE_QUOTED_SCALAR_STYLE ?
                                    "double-quoted" :
                             style == YAML_LITERAL_SCALAR_STYLE ? "literal" :
                             style == YAML_FOLDED_SCALAR_STYLE ? "folded" :
                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                break;

            case YAML_SEQUENCE_START_EVENT:

                /* Add 'type': 'SEQUENCE-START'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "SEQUENCE-START", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'anchor': <anchor>. */

                if (input_event.data.sequence_start.anchor)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.sequence_start.anchor, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'tag': <tag>. */

                if (input_event.data.sequence_start.tag)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.sequence_start.tag, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'implicit': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.sequence_start.implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Display the style information. */

                if (input_event.data.sequence_start.style)
                {
                    yaml_sequence_style_t style
                        = input_event.data.sequence_start.style;

                    /* Add 'style': <style>. */

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            (style == YAML_BLOCK_SEQUENCE_STYLE ? "block" :
                             style == YAML_FLOW_SEQUENCE_STYLE ? "flow" :
                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                break;

            case YAML_SEQUENCE_END_EVENT:

                /* Add 'type': 'SEQUENCE-END'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "SEQUENCE-END", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            case YAML_MAPPING_START_EVENT:

                /* Add 'type': 'MAPPING-START'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "MAPPING-START", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Add 'anchor': <anchor>. */

                if (input_event.data.mapping_start.anchor)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "anchor", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.mapping_start.anchor, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'tag': <tag>. */

                if (input_event.data.mapping_start.tag)
                {
                    key = yaml_document_add_scalar(&output_document, NULL,
                        "tag", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            input_event.data.mapping_start.tag, -1,
                            YAML_DOUBLE_QUOTED_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                /* Add 'implicit': <flag>. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "implicit", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, YAML_BOOL_TAG,
                        (input_event.data.mapping_start.implicit ?
                         "true" : "false"), -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                /* Display the style information. */

                if (input_event.data.sequence_start.style)
                {
                    yaml_sequence_style_t style
                        = input_event.data.mapping_start.style;

                    /* Add 'style': <style>. */

                    key = yaml_document_add_scalar(&output_document, NULL,
                        "style", -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!key) goto document_error;
                    value = yaml_document_add_scalar(&output_document, NULL,
                            (style == YAML_BLOCK_MAPPING_STYLE ? "block" :
                             style == YAML_FLOW_MAPPING_STYLE ? "flow" :
                             "unknown"), -1, YAML_PLAIN_SCALAR_STYLE);
                    if (!value) goto document_error;
                    if (!yaml_document_append_mapping_pair(&output_document,
                                properties, key, value)) goto document_error;
                }

                break;

            case YAML_MAPPING_END_EVENT:

                /* Add 'type': 'MAPPING-END'. */

                key = yaml_document_add_scalar(&output_document, NULL,
                    "type", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!key) goto document_error;
                value = yaml_document_add_scalar(&output_document, NULL,
                    "MAPPING-END", -1, YAML_PLAIN_SCALAR_STYLE);
                if (!value) goto document_error;
                if (!yaml_document_append_mapping_pair(&output_document,
                            properties, key, value)) goto document_error;

                break;

            default:
                /* It couldn't really happen. */
                break;
        }

        /* Delete the event object. */

        yaml_event_delete(&input_event);
    }

    if (!yaml_emitter_dump(&emitter, &output_document))
        goto emitter_error;
    if (!yaml_emitter_close(&emitter))
        goto emitter_error;

    yaml_parser_delete(&parser);
    yaml_emitter_delete(&emitter);

    return 0;

parser_error:

    /* Display a parser error message. */

    switch (parser.error)
    {
        case YAML_MEMORY_ERROR:
            fprintf(stderr, "Memory error: Not enough memory for parsing\n");
            break;

        case YAML_READER_ERROR:
            if (parser.problem_value != -1) {
                fprintf(stderr, "Reader error: %s: #%X at %zd\n", parser.problem,
                        parser.problem_value, parser.problem_offset);
            }
            else {
                fprintf(stderr, "Reader error: %s at %zd\n", parser.problem,
                        parser.problem_offset);
            }
            break;

        case YAML_SCANNER_ERROR:
            if (parser.context) {
                fprintf(stderr, "Scanner error: %s at line %lu, column %lu\n"
                        "%s at line %lu, column %lu\n", parser.context,
                        parser.context_mark.line+1, parser.context_mark.column+1,
                        parser.problem, parser.problem_mark.line+1,
                        parser.problem_mark.column+1);
            }
            else {
                fprintf(stderr, "Scanner error: %s at line %lu, column %lu\n",
                        parser.problem, parser.problem_mark.line+1,
                        parser.problem_mark.column+1);
            }
            break;

        case YAML_PARSER_ERROR:
            if (parser.context) {
                fprintf(stderr, "Parser error: %s at line %lu, column %lu\n"
                        "%s at line %lu, column %lu\n", parser.context,
                        parser.context_mark.line+1, parser.context_mark.column+1,
                        parser.problem, parser.problem_mark.line+1,
                        parser.problem_mark.column+1);
            }
            else {
                fprintf(stderr, "Parser error: %s at line %lu, column %lu\n",
                        parser.problem, parser.problem_mark.line+1,
                        parser.problem_mark.column+1);
            }
            break;

        default:
            /* Couldn't happen. */
            fprintf(stderr, "Internal error\n");
            break;
    }

    yaml_event_delete(&input_event);
    yaml_document_delete(&output_document);
    yaml_parser_delete(&parser);
    yaml_emitter_delete(&emitter);

    return 1;

emitter_error:

    /* Display an emitter error message. */

    switch (emitter.error)
    {
        case YAML_MEMORY_ERROR:
            fprintf(stderr, "Memory error: Not enough memory for emitting\n");
            break;

        case YAML_WRITER_ERROR:
            fprintf(stderr, "Writer error: %s\n", emitter.problem);
            break;

        case YAML_EMITTER_ERROR:
            fprintf(stderr, "Emitter error: %s\n", emitter.problem);
            break;

        default:
            /* Couldn't happen. */
            fprintf(stderr, "Internal error\n");
            break;
    }

    yaml_event_delete(&input_event);
    yaml_document_delete(&output_document);
    yaml_parser_delete(&parser);
    yaml_emitter_delete(&emitter);

    return 1;

document_error:

    fprintf(stderr, "Memory error: Not enough memory for creating a document\n");

    yaml_event_delete(&input_event);
    yaml_document_delete(&output_document);
    yaml_parser_delete(&parser);
    yaml_emitter_delete(&emitter);

    return 1;
}
Пример #13
0
/* this is where the magic happens */
static set* _cluster_keys(range_request* rr, apr_pool_t* pool,
                          const char* cluster, const char* cluster_file)
{
    apr_array_header_t* working_range;
    set* sections;
    char* section;
    char* cur_section;
    apr_pool_t* req_pool = range_request_pool(rr);
    yaml_node_t *node;
    yaml_node_t *rootnode;
    yaml_node_t *keynode;
    yaml_node_t *valuenode;
    yaml_parser_t parser;
    yaml_node_item_t *item;
    yaml_node_pair_t *pair;
    
    yaml_document_t document;
    
    FILE* fp = fopen(cluster_file, "r");

    /* make sure we can open the file and parse it */
    if (!fp) {
        range_request_warn(rr, "%s: %s not readable", cluster, cluster_file);
        return set_new(pool, 0);
    }

    if (!yaml_parser_initialize(&parser)) {
        range_request_warn(rr, "%s: cannot initialize yaml parser", cluster);
        fclose(fp);
        return set_new(pool, 0);
    }

    yaml_parser_set_input_file(&parser, fp);
    if(!yaml_parser_load(&parser, &document)) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        fclose(fp);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }
    fclose(fp);
    
    rootnode = yaml_document_get_root_node(&document);
    /* make sure it's just a simple dictionary */
    if(rootnode->type != YAML_MAPPING_NODE) {
        range_request_warn(rr, "%s: malformatted cluster definition %s",
                           cluster, cluster_file);
        yaml_document_delete(&document);
        yaml_parser_delete(&parser);
        return set_new(pool, 0);
    }

    /* "sections" refers to cluster sections - %cluster:SECTION
       it's what we're going to return */
    sections = set_new(pool, 0);
    section = cur_section = NULL;

    for(pair = rootnode->data.mapping.pairs.start;
        pair < rootnode->data.mapping.pairs.top;
        pair++) { /* these are the keys */
        keynode = yaml_document_get_node(&document, pair->key);
        /* cur_section is the keyname - the WHATEVER in %cluster:WHATEVER */
        cur_section = apr_pstrdup(pool, (char *)(keynode->data.scalar.value));
        valuenode = yaml_document_get_node(&document, pair->value);
        /* if the value is a scalar, that's our answer */
        if(valuenode->type == YAML_SCALAR_NODE) {
            set_add(sections, cur_section,
                    apr_psprintf(pool, "%s", valuenode->data.scalar.value));
        } else if (valuenode->type == YAML_SEQUENCE_NODE) {
            /* otherwise, glue together all the values in the list */
            working_range = apr_array_make(req_pool, 1, sizeof(char*));
            for(item = valuenode->data.sequence.items.start;
                item < valuenode->data.sequence.items.top;
                item++) {
                node = yaml_document_get_node(&document, (int)*item);
                if(node->type != YAML_SCALAR_NODE) { /* only scalars allowed */
                    range_request_warn(rr,
                                       "%s: malformed cluster definition %s",
                                       cluster, cluster_file);
                    yaml_document_delete(&document);
                    yaml_parser_delete(&parser);
                    return set_new(pool, 0);
                } else { /* add to the working set */
                    /* include it in () because we're going to comma it
                       together later */
                    *(char**)apr_array_push(working_range) =
                        apr_psprintf(pool, "(%s)", _substitute_dollars(pool,
                          cluster, node->data.scalar.value));
                }
            }
            /* glue the list items together with commas */
            set_add(sections, cur_section,
                    apr_array_pstrcat(pool, working_range, ','));
        }
    }

    /* Add a "KEYS" toplevel key that lists all the other keys */
    /* TODO: make an error if somebody tries to specify KEYS manually? */
    set_add(sections, "KEYS", _join_elements(pool, ',', sections));
    yaml_document_delete(&document);
    yaml_parser_delete(&parser);
    return sections;
}
Пример #14
0
int
main(int argc, char *argv[])
{
    int number;
    int canonical = 0;
    int unicode = 0;

    number = 1;
    while (number < argc) {
        if (strcmp(argv[number], "-c") == 0) {
            canonical = 1;
        }
        else if (strcmp(argv[number], "-u") == 0) {
            unicode = 1;
        }
        else if (argv[number][0] == '-') {
            printf("Unknown option: '%s'\n", argv[number]);
            return 0;
        }
        if (argv[number][0] == '-') {
            if (number < argc-1) {
                memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
            }
            argc --;
        }
        else {
            number ++;
        }
    }

    if (argc < 2) {
        printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
        return 0;
    }

    for (number = 1; number < argc; number ++)
    {
        FILE *file;
        yaml_parser_t parser;
        yaml_emitter_t emitter;

        yaml_document_t document;
        unsigned char buffer[BUFFER_SIZE];
        size_t written = 0;
        yaml_document_t documents[MAX_DOCUMENTS];
        size_t document_number = 0;
        int done = 0;
        int count = 0;
        int error = 0;
        int k;
        memset(buffer, 0, BUFFER_SIZE);
        memset(documents, 0, MAX_DOCUMENTS*sizeof(yaml_document_t));

        printf("[%d] Loading, dumping, and loading again '%s': ", number, argv[number]);
        fflush(stdout);

        file = fopen(argv[number], "rb");
        assert(file);

        assert(yaml_parser_initialize(&parser));
        yaml_parser_set_input_file(&parser, file);
        assert(yaml_emitter_initialize(&emitter));
        if (canonical) {
            yaml_emitter_set_canonical(&emitter, 1);
        }
        if (unicode) {
            yaml_emitter_set_unicode(&emitter, 1);
        }
        yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
        yaml_emitter_open(&emitter);

        while (!done)
        {
            if (!yaml_parser_load(&parser, &document)) {
                error = 1;
                break;
            }

            done = (!yaml_document_get_root_node(&document));
            if (!done) {
                assert(document_number < MAX_DOCUMENTS);
                assert(copy_document(&(documents[document_number++]), &document));
                assert(yaml_emitter_dump(&emitter, &document) ||
                        (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
                count ++;
            }
            else {
                yaml_document_delete(&document);
            }
        }

        yaml_parser_delete(&parser);
        assert(!fclose(file));
        yaml_emitter_close(&emitter);
        yaml_emitter_delete(&emitter);

        if (!error)
        {
            count = done = 0;
            assert(yaml_parser_initialize(&parser));
            yaml_parser_set_input_string(&parser, buffer, written);

            while (!done)
            {
                assert(yaml_parser_load(&parser, &document) || print_output(argv[number], buffer, written, count));
                done = (!yaml_document_get_root_node(&document));
                if (!done) {
                    assert(compare_documents(documents+count, &document) || print_output(argv[number], buffer, written, count));
                    count ++;
                }
                yaml_document_delete(&document);
            }
            yaml_parser_delete(&parser);
        }

        for (k = 0; k < document_number; k ++) {
            yaml_document_delete(documents+k);
        }

        printf("PASSED (length: %d)\n", written);
        print_output(argv[number], buffer, written, -1);
    }

    return 0;
}
Пример #15
0
int copy_document(yaml_document_t *document_to, yaml_document_t *document_from)
{
    yaml_node_t *node;
    yaml_node_item_t *item;
    yaml_node_pair_t *pair;

    if (!yaml_document_initialize(document_to, document_from->version_directive,
                document_from->tag_directives.start,
                document_from->tag_directives.end,
                document_from->start_implicit, document_from->end_implicit))
        return 0;

    for (node = document_from->nodes.start;
            node < document_from->nodes.top; node ++) {
        switch (node->type) {
            case YAML_SCALAR_NODE:
                if (!yaml_document_add_scalar(document_to, node->tag,
                            node->data.scalar.value, node->data.scalar.length,
                            node->data.scalar.style)) goto error;
                break;
            case YAML_SEQUENCE_NODE:
                if (!yaml_document_add_sequence(document_to, node->tag,
                            node->data.sequence.style)) goto error;
                break;
            case YAML_MAPPING_NODE:
                if (!yaml_document_add_mapping(document_to, node->tag,
                            node->data.mapping.style)) goto error;
                break;
            default:
                assert(0);
                break;
        }
    }

    for (node = document_from->nodes.start;
            node < document_from->nodes.top; node ++) {
        switch (node->type) {
            case YAML_SEQUENCE_NODE:
                for (item = node->data.sequence.items.start;
                        item < node->data.sequence.items.top; item ++) {
                    if (!yaml_document_append_sequence_item(document_to,
                                node - document_from->nodes.start + 1,
                                *item)) goto error;
                }
                break;
            case YAML_MAPPING_NODE:
                for (pair = node->data.mapping.pairs.start;
                        pair < node->data.mapping.pairs.top; pair ++) {
                    if (!yaml_document_append_mapping_pair(document_to,
                                node - document_from->nodes.start + 1,
                                pair->key, pair->value)) goto error;
                }
                break;
            default:
                break;
        }
    }
    return 1;

error:
    yaml_document_delete(document_to);
    return 0;
}
Пример #16
0
void load_config()
{
    FILE * file;

    yaml_parser_t parser;
    yaml_document_t document;

    yaml_node_t * root;

    yaml_node_t * map;
    yaml_node_pair_t * pair;

    yaml_node_t * key, * value;

    char name[256];

    /* Look for velox.yaml in the config directories */
    file = open_config_file("velox.yaml");

    /* Nothing to do if there is no configuration file */
    if (file == NULL) return;

    yaml_parser_initialize(&parser);
    yaml_parser_set_input_file(&parser, file);

    if (!yaml_parser_load(&parser, &document))
    {
        fprintf(stderr, "Error parsing config file\n");
        goto cleanup;
    }

    /* The root node should be a mapping */
    map = yaml_document_get_root_node(&document);
    assert(map->type == YAML_MAPPING_NODE);

    /* For each key/value pair in the root mapping */
    for (pair = map->data.mapping.pairs.start; pair < map->data.mapping.pairs.top; ++pair)
    {
        key = yaml_document_get_node(&document, pair->key);
        value = yaml_document_get_node(&document, pair->value);

        assert(key->type == YAML_SCALAR_NODE);

        /* The module section */
        if (strcmp((const char *) key->data.scalar.value, "modules") == 0)
        {
            yaml_node_item_t * module_item;
            yaml_node_t * node;

            assert(value->type == YAML_SEQUENCE_NODE);

            printf("\n** Loading Modules **\n");

            /* For each module */
            for (module_item = value->data.sequence.items.start;
                module_item < value->data.sequence.items.top;
                ++module_item)
            {
                node = yaml_document_get_node(&document, *module_item);

                load_module((const char *) node->data.scalar.value);
            }
        }
        /* The border_width property */
        else if (strcmp((const char *) key->data.scalar.value, "border_width") == 0)
        {
            assert(value->type == YAML_SCALAR_NODE);

            border_width = strtoul((const char *) value->data.scalar.value, NULL, 10);
        }
    }

    yaml_document_delete(&document);

    printf("\n** Configuring Modules **\n");

    /* While we still have documents to parse */
    while (yaml_parser_load(&parser, &document))
    {
        /* If the document contains no root node, we are at the end */
        if (yaml_document_get_root_node(&document) == NULL)
        {
            yaml_document_delete(&document);
            break;
        }

        sscanf((const char *) yaml_document_get_root_node(&document)->tag, "!velox:%s", name);

        /* Configure the specified module with this YAML document */
        configure_module(name, &document);

        yaml_document_delete(&document);
    }

    cleanup:
        yaml_parser_delete(&parser);
        fclose(file);
}