+yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, int empty)
+{
+ yaml_token_t *token;
+ yaml_event_t *event;
+
+ token = yaml_parser_peek_token(parser);
+ if (!token) return;
+
+ if (empty) {
+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, token->start_mark);
+ }
+
+ if (token->type == YAML_VALUE_TOKEN) {
+ yaml_token_delete(yaml_parser_get_token(parser));
+ token = yaml_parser_peek_token(parser);
+ if (!token) return NULL;
+ if (token->type != YAML_FLOW_ENTRY_TOKEN
+ && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
+ if (!yaml_parser_append_state(parser,
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE))
+ return NULL;
+ return yaml_parser_parse_node(parser, 0, 0);
+ }
+ }
+
+ parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(parser, token->start_mark);
+}
+
+/*
+ * Generate an empty scalar event.
+ */
+
+static yaml_event_t *
+yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_mark_t mark)
+{
+ yaml_event_t *event;
+ yaml_char_t *value;
+
+ value = yaml_malloc(1);
+ if (!value) {
+ parser->error = YAML_MEMORY_ERROR;
+ return NULL;
+ }
+ value[0] = '\0';
+
+ event = yaml_scalar_event_new(NULL, NULL, value, 0,
+ 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
+ if (!event) {
+ yaml_free(value);
+ parser->error = YAML_MEMORY_ERROR;
+ return NULL;
+ }
+
+ return event;
+}
+
+/*
+ * Parse directives.
+ */
+
+static int
+yaml_parser_process_directives(yaml_parser_t *parser)
+{
+ yaml_tag_directive_t default_tag_directives[] = {
+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
+ {NULL, NULL}
+ };
+ yaml_tag_directive_t *ref;
+ yaml_tag_directive_t *default_tag_directive;
+ yaml_tag_directive_t **tag_directive;
+ yaml_token_t *token;
+
+ token = yaml_parser_peek_token(parser);
+ if (!token) return 0;
+
+ while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
+ token->type == YAML_TAG_DIRECTIVE_TOKEN)
+ {
+ if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
+ if (parser->version_directive) {
+ return yaml_parser_set_parser_error(parser,
+ "found duplicate %YAML directive", token->start_mark);
+ }
+ if (token->data.version_directive.major != 1
+ && token->data.version_directive.minor != 1) {
+ return yaml_parser_set_parser_error(parser,
+ "found incompatible YAML document", token->start_mark);
+ }
+ parser->version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
+ if (!parser->version_directive) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ parser->version_directive->major = token->data.version_directive.major;
+ parser->version_directive->minor = token->data.version_directive.minor;
+ }
+
+ else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
+ yaml_tag_directive_t value = {
+ token->data.tag_directive.handle,
+ token->data.tag_directive.prefix
+ };
+ for (tag_directive = parser->tag_directives;
+ *tag_directive; tag_directive++) {
+ if (strcmp((char *)value.handle,
+ (char *)(*tag_directive)->handle) == 0) {
+ return yaml_parser_set_parser_error(parser,
+ "found duplicate %TAG directive", token->start_mark);
+ }
+ }
+ ref = yaml_malloc(sizeof(yaml_tag_directive_t));
+ if (!ref) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ *ref = value;
+ if (!yaml_parser_append_tag_directive(parser, ref)) {
+ yaml_free(ref);
+ return 0;
+ }
+ }
+ yaml_free(yaml_parser_get_token(parser));
+ token = yaml_parser_peek_token(parser);
+ if (!token) return 0;
+ }
+
+ for (default_tag_directive = default_tag_directives;
+ default_tag_directive->handle; default_tag_directive++) {
+ int found = 0;
+ for (tag_directive = parser->tag_directives;
+ *tag_directive; tag_directive++) {
+ if (strcmp((char *)default_tag_directive->handle,
+ (char *)(*tag_directive)->handle) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ ref = yaml_malloc(sizeof(yaml_tag_directive_t));
+ if (!ref) {
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ ref->handle = yaml_malloc(strlen((char *)default_tag_directive->handle)+1);
+ if (!ref->handle) {
+ yaml_free(ref);
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ ref->prefix = yaml_malloc(strlen((char *)default_tag_directive->prefix)+1);
+ if (!ref->prefix) {
+ yaml_free(ref->handle);
+ yaml_free(ref);
+ parser->error = YAML_MEMORY_ERROR;
+ return 0;
+ }
+ memcpy(ref->handle, default_tag_directive->handle,
+ strlen((char *)default_tag_directive->handle)+1);
+ memcpy(ref->prefix, default_tag_directive->prefix,
+ strlen((char *)default_tag_directive->prefix)+1);
+ if (!yaml_parser_append_tag_directive(parser, ref)) {
+ yaml_free(ref);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}