| 1 |  | 
|---|
| 2 | /* | 
|---|
| 3 |  * The parser implements the following grammar: | 
|---|
| 4 |  * | 
|---|
| 5 |  * stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END | 
|---|
| 6 |  * implicit_document    ::= block_node DOCUMENT-END* | 
|---|
| 7 |  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | 
|---|
| 8 |  * block_node_or_indentless_sequence    ::= | 
|---|
| 9 |  *                          ALIAS | 
|---|
| 10 |  *                          | properties (block_content | indentless_block_sequence)? | 
|---|
| 11 |  *                          | block_content | 
|---|
| 12 |  *                          | indentless_block_sequence | 
|---|
| 13 |  * block_node           ::= ALIAS | 
|---|
| 14 |  *                          | properties block_content? | 
|---|
| 15 |  *                          | block_content | 
|---|
| 16 |  * flow_node            ::= ALIAS | 
|---|
| 17 |  *                          | properties flow_content? | 
|---|
| 18 |  *                          | flow_content | 
|---|
| 19 |  * properties           ::= TAG ANCHOR? | ANCHOR TAG? | 
|---|
| 20 |  * block_content        ::= block_collection | flow_collection | SCALAR | 
|---|
| 21 |  * flow_content         ::= flow_collection | SCALAR | 
|---|
| 22 |  * block_collection     ::= block_sequence | block_mapping | 
|---|
| 23 |  * flow_collection      ::= flow_sequence | flow_mapping | 
|---|
| 24 |  * block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END | 
|---|
| 25 |  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+ | 
|---|
| 26 |  * block_mapping        ::= BLOCK-MAPPING_START | 
|---|
| 27 |  *                          ((KEY block_node_or_indentless_sequence?)? | 
|---|
| 28 |  *                          (VALUE block_node_or_indentless_sequence?)?)* | 
|---|
| 29 |  *                          BLOCK-END | 
|---|
| 30 |  * flow_sequence        ::= FLOW-SEQUENCE-START | 
|---|
| 31 |  *                          (flow_sequence_entry FLOW-ENTRY)* | 
|---|
| 32 |  *                          flow_sequence_entry? | 
|---|
| 33 |  *                          FLOW-SEQUENCE-END | 
|---|
| 34 |  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 35 |  * flow_mapping         ::= FLOW-MAPPING-START | 
|---|
| 36 |  *                          (flow_mapping_entry FLOW-ENTRY)* | 
|---|
| 37 |  *                          flow_mapping_entry? | 
|---|
| 38 |  *                          FLOW-MAPPING-END | 
|---|
| 39 |  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 40 |  */ | 
|---|
| 41 |  | 
|---|
| 42 | #include "yaml_private.h" | 
|---|
| 43 |  | 
|---|
| 44 | /* | 
|---|
| 45 |  * Peek the next token in the token queue. | 
|---|
| 46 |  */ | 
|---|
| 47 |  | 
|---|
| 48 | #define PEEK_TOKEN(parser)                                                      \ | 
|---|
| 49 |     ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \ | 
|---|
| 50 |         parser->tokens.head : NULL) | 
|---|
| 51 |  | 
|---|
| 52 | /* | 
|---|
| 53 |  * Remove the next token from the queue (must be called after PEEK_TOKEN). | 
|---|
| 54 |  */ | 
|---|
| 55 |  | 
|---|
| 56 | #define SKIP_TOKEN(parser)                                                      \ | 
|---|
| 57 |     (parser->token_available = 0,                                               \ | 
|---|
| 58 |      parser->tokens_parsed ++,                                                  \ | 
|---|
| 59 |      parser->stream_end_produced =                                              \ | 
|---|
| 60 |         (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \ | 
|---|
| 61 |      parser->tokens.head ++) | 
|---|
| 62 |  | 
|---|
| 63 | /* | 
|---|
| 64 |  * Public API declarations. | 
|---|
| 65 |  */ | 
|---|
| 66 |  | 
|---|
| 67 | YAML_DECLARE(int) | 
|---|
| 68 | yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); | 
|---|
| 69 |  | 
|---|
| 70 | /* | 
|---|
| 71 |  * Error handling. | 
|---|
| 72 |  */ | 
|---|
| 73 |  | 
|---|
| 74 | static int | 
|---|
| 75 | yaml_parser_set_parser_error(yaml_parser_t *parser, | 
|---|
| 76 |         const char *problem, yaml_mark_t problem_mark); | 
|---|
| 77 |  | 
|---|
| 78 | static int | 
|---|
| 79 | yaml_parser_set_parser_error_context(yaml_parser_t *parser, | 
|---|
| 80 |         const char *context, yaml_mark_t context_mark, | 
|---|
| 81 |         const char *problem, yaml_mark_t problem_mark); | 
|---|
| 82 |  | 
|---|
| 83 | /* | 
|---|
| 84 |  * State functions. | 
|---|
| 85 |  */ | 
|---|
| 86 |  | 
|---|
| 87 | static int | 
|---|
| 88 | yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event); | 
|---|
| 89 |  | 
|---|
| 90 | static int | 
|---|
| 91 | yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event); | 
|---|
| 92 |  | 
|---|
| 93 | static int | 
|---|
| 94 | yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, | 
|---|
| 95 |         int implicit); | 
|---|
| 96 |  | 
|---|
| 97 | static int | 
|---|
| 98 | yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event); | 
|---|
| 99 |  | 
|---|
| 100 | static int | 
|---|
| 101 | yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event); | 
|---|
| 102 |  | 
|---|
| 103 | static int | 
|---|
| 104 | yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, | 
|---|
| 105 |         int block, int indentless_sequence); | 
|---|
| 106 |  | 
|---|
| 107 | static int | 
|---|
| 108 | yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, | 
|---|
| 109 |         yaml_event_t *event, int first); | 
|---|
| 110 |  | 
|---|
| 111 | static int | 
|---|
| 112 | yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, | 
|---|
| 113 |         yaml_event_t *event); | 
|---|
| 114 |  | 
|---|
| 115 | static int | 
|---|
| 116 | yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, | 
|---|
| 117 |         yaml_event_t *event, int first); | 
|---|
| 118 |  | 
|---|
| 119 | static int | 
|---|
| 120 | yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, | 
|---|
| 121 |         yaml_event_t *event); | 
|---|
| 122 |  | 
|---|
| 123 | static int | 
|---|
| 124 | yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, | 
|---|
| 125 |         yaml_event_t *event, int first); | 
|---|
| 126 |  | 
|---|
| 127 | static int | 
|---|
| 128 | yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, | 
|---|
| 129 |         yaml_event_t *event); | 
|---|
| 130 |  | 
|---|
| 131 | static int | 
|---|
| 132 | yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, | 
|---|
| 133 |         yaml_event_t *event); | 
|---|
| 134 |  | 
|---|
| 135 | static int | 
|---|
| 136 | yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, | 
|---|
| 137 |         yaml_event_t *event); | 
|---|
| 138 |  | 
|---|
| 139 | static int | 
|---|
| 140 | yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, | 
|---|
| 141 |         yaml_event_t *event, int first); | 
|---|
| 142 |  | 
|---|
| 143 | static int | 
|---|
| 144 | yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, | 
|---|
| 145 |         yaml_event_t *event, int empty); | 
|---|
| 146 |  | 
|---|
| 147 | /* | 
|---|
| 148 |  * Utility functions. | 
|---|
| 149 |  */ | 
|---|
| 150 |  | 
|---|
| 151 | static int | 
|---|
| 152 | yaml_parser_process_empty_scalar(yaml_parser_t *parser, | 
|---|
| 153 |         yaml_event_t *event, yaml_mark_t mark); | 
|---|
| 154 |  | 
|---|
| 155 | static int | 
|---|
| 156 | yaml_parser_process_directives(yaml_parser_t *parser, | 
|---|
| 157 |         yaml_version_directive_t **version_directive_ref, | 
|---|
| 158 |         yaml_tag_directive_t **tag_directives_start_ref, | 
|---|
| 159 |         yaml_tag_directive_t **tag_directives_end_ref); | 
|---|
| 160 |  | 
|---|
| 161 | static int | 
|---|
| 162 | yaml_parser_append_tag_directive(yaml_parser_t *parser, | 
|---|
| 163 |         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark); | 
|---|
| 164 |  | 
|---|
| 165 | /* | 
|---|
| 166 |  * Get the next event. | 
|---|
| 167 |  */ | 
|---|
| 168 |  | 
|---|
| 169 | YAML_DECLARE(int) | 
|---|
| 170 | yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event) | 
|---|
| 171 | { | 
|---|
| 172 |     assert(parser);     /* Non-NULL parser object is expected. */ | 
|---|
| 173 |     assert(event);      /* Non-NULL event object is expected. */ | 
|---|
| 174 |  | 
|---|
| 175 |     /* Erase the event object. */ | 
|---|
| 176 |  | 
|---|
| 177 |     memset(event, 0, sizeof(yaml_event_t)); | 
|---|
| 178 |  | 
|---|
| 179 |     /* No events after the end of the stream or error. */ | 
|---|
| 180 |  | 
|---|
| 181 |     if (parser->stream_end_produced || parser->error || | 
|---|
| 182 |             parser->state == YAML_PARSE_END_STATE) { | 
|---|
| 183 |         return 1; | 
|---|
| 184 |     } | 
|---|
| 185 |  | 
|---|
| 186 |     /* Generate the next event. */ | 
|---|
| 187 |  | 
|---|
| 188 |     return yaml_parser_state_machine(parser, event); | 
|---|
| 189 | } | 
|---|
| 190 |  | 
|---|
| 191 | /* | 
|---|
| 192 |  * Set parser error. | 
|---|
| 193 |  */ | 
|---|
| 194 |  | 
|---|
| 195 | static int | 
|---|
| 196 | yaml_parser_set_parser_error(yaml_parser_t *parser, | 
|---|
| 197 |         const char *problem, yaml_mark_t problem_mark) | 
|---|
| 198 | { | 
|---|
| 199 |     parser->error = YAML_PARSER_ERROR; | 
|---|
| 200 |     parser->problem = problem; | 
|---|
| 201 |     parser->problem_mark = problem_mark; | 
|---|
| 202 |  | 
|---|
| 203 |     return 0; | 
|---|
| 204 | } | 
|---|
| 205 |  | 
|---|
| 206 | static int | 
|---|
| 207 | yaml_parser_set_parser_error_context(yaml_parser_t *parser, | 
|---|
| 208 |         const char *context, yaml_mark_t context_mark, | 
|---|
| 209 |         const char *problem, yaml_mark_t problem_mark) | 
|---|
| 210 | { | 
|---|
| 211 |     parser->error = YAML_PARSER_ERROR; | 
|---|
| 212 |     parser->context = context; | 
|---|
| 213 |     parser->context_mark = context_mark; | 
|---|
| 214 |     parser->problem = problem; | 
|---|
| 215 |     parser->problem_mark = problem_mark; | 
|---|
| 216 |  | 
|---|
| 217 |     return 0; | 
|---|
| 218 | } | 
|---|
| 219 |  | 
|---|
| 220 |  | 
|---|
| 221 | /* | 
|---|
| 222 |  * State dispatcher. | 
|---|
| 223 |  */ | 
|---|
| 224 |  | 
|---|
| 225 | static int | 
|---|
| 226 | yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event) | 
|---|
| 227 | { | 
|---|
| 228 |     switch (parser->state) | 
|---|
| 229 |     { | 
|---|
| 230 |         case YAML_PARSE_STREAM_START_STATE: | 
|---|
| 231 |             return yaml_parser_parse_stream_start(parser, event); | 
|---|
| 232 |  | 
|---|
| 233 |         case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: | 
|---|
| 234 |             return yaml_parser_parse_document_start(parser, event, 1); | 
|---|
| 235 |  | 
|---|
| 236 |         case YAML_PARSE_DOCUMENT_START_STATE: | 
|---|
| 237 |             return yaml_parser_parse_document_start(parser, event, 0); | 
|---|
| 238 |  | 
|---|
| 239 |         case YAML_PARSE_DOCUMENT_CONTENT_STATE: | 
|---|
| 240 |             return yaml_parser_parse_document_content(parser, event); | 
|---|
| 241 |  | 
|---|
| 242 |         case YAML_PARSE_DOCUMENT_END_STATE: | 
|---|
| 243 |             return yaml_parser_parse_document_end(parser, event); | 
|---|
| 244 |  | 
|---|
| 245 |         case YAML_PARSE_BLOCK_NODE_STATE: | 
|---|
| 246 |             return yaml_parser_parse_node(parser, event, 1, 0); | 
|---|
| 247 |  | 
|---|
| 248 |         case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: | 
|---|
| 249 |             return yaml_parser_parse_node(parser, event, 1, 1); | 
|---|
| 250 |  | 
|---|
| 251 |         case YAML_PARSE_FLOW_NODE_STATE: | 
|---|
| 252 |             return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 253 |  | 
|---|
| 254 |         case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: | 
|---|
| 255 |             return yaml_parser_parse_block_sequence_entry(parser, event, 1); | 
|---|
| 256 |  | 
|---|
| 257 |         case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: | 
|---|
| 258 |             return yaml_parser_parse_block_sequence_entry(parser, event, 0); | 
|---|
| 259 |  | 
|---|
| 260 |         case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: | 
|---|
| 261 |             return yaml_parser_parse_indentless_sequence_entry(parser, event); | 
|---|
| 262 |  | 
|---|
| 263 |         case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: | 
|---|
| 264 |             return yaml_parser_parse_block_mapping_key(parser, event, 1); | 
|---|
| 265 |  | 
|---|
| 266 |         case YAML_PARSE_BLOCK_MAPPING_KEY_STATE: | 
|---|
| 267 |             return yaml_parser_parse_block_mapping_key(parser, event, 0); | 
|---|
| 268 |  | 
|---|
| 269 |         case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: | 
|---|
| 270 |             return yaml_parser_parse_block_mapping_value(parser, event); | 
|---|
| 271 |  | 
|---|
| 272 |         case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: | 
|---|
| 273 |             return yaml_parser_parse_flow_sequence_entry(parser, event, 1); | 
|---|
| 274 |  | 
|---|
| 275 |         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: | 
|---|
| 276 |             return yaml_parser_parse_flow_sequence_entry(parser, event, 0); | 
|---|
| 277 |  | 
|---|
| 278 |         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: | 
|---|
| 279 |             return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event); | 
|---|
| 280 |  | 
|---|
| 281 |         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: | 
|---|
| 282 |             return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event); | 
|---|
| 283 |  | 
|---|
| 284 |         case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: | 
|---|
| 285 |             return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event); | 
|---|
| 286 |  | 
|---|
| 287 |         case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: | 
|---|
| 288 |             return yaml_parser_parse_flow_mapping_key(parser, event, 1); | 
|---|
| 289 |  | 
|---|
| 290 |         case YAML_PARSE_FLOW_MAPPING_KEY_STATE: | 
|---|
| 291 |             return yaml_parser_parse_flow_mapping_key(parser, event, 0); | 
|---|
| 292 |  | 
|---|
| 293 |         case YAML_PARSE_FLOW_MAPPING_VALUE_STATE: | 
|---|
| 294 |             return yaml_parser_parse_flow_mapping_value(parser, event, 0); | 
|---|
| 295 |  | 
|---|
| 296 |         case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: | 
|---|
| 297 |             return yaml_parser_parse_flow_mapping_value(parser, event, 1); | 
|---|
| 298 |  | 
|---|
| 299 |         default: | 
|---|
| 300 |             assert(1);      /* Invalid state. */ | 
|---|
| 301 |     } | 
|---|
| 302 |  | 
|---|
| 303 |     return 0; | 
|---|
| 304 | } | 
|---|
| 305 |  | 
|---|
| 306 | /* | 
|---|
| 307 |  * Parse the production: | 
|---|
| 308 |  * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END | 
|---|
| 309 |  *              ************ | 
|---|
| 310 |  */ | 
|---|
| 311 |  | 
|---|
| 312 | static int | 
|---|
| 313 | yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event) | 
|---|
| 314 | { | 
|---|
| 315 |     yaml_token_t *token; | 
|---|
| 316 |  | 
|---|
| 317 |     token = PEEK_TOKEN(parser); | 
|---|
| 318 |     if (!token) return 0; | 
|---|
| 319 |  | 
|---|
| 320 |     if (token->type != YAML_STREAM_START_TOKEN) { | 
|---|
| 321 |         return yaml_parser_set_parser_error(parser, | 
|---|
| 322 |                 "did not found expected <stream-start>", token->start_mark); | 
|---|
| 323 |     } | 
|---|
| 324 |  | 
|---|
| 325 |     parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; | 
|---|
| 326 |     STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding, | 
|---|
| 327 |             token->start_mark, token->start_mark); | 
|---|
| 328 |     SKIP_TOKEN(parser); | 
|---|
| 329 |  | 
|---|
| 330 |     return 1; | 
|---|
| 331 | } | 
|---|
| 332 |  | 
|---|
| 333 | /* | 
|---|
| 334 |  * Parse the productions: | 
|---|
| 335 |  * implicit_document    ::= block_node DOCUMENT-END* | 
|---|
| 336 |  *                          * | 
|---|
| 337 |  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | 
|---|
| 338 |  *                          ************************* | 
|---|
| 339 |  */ | 
|---|
| 340 |  | 
|---|
| 341 | static int | 
|---|
| 342 | yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, | 
|---|
| 343 |         int implicit) | 
|---|
| 344 | { | 
|---|
| 345 |     yaml_token_t *token; | 
|---|
| 346 |     yaml_version_directive_t *version_directive = NULL; | 
|---|
| 347 |     struct { | 
|---|
| 348 |         yaml_tag_directive_t *start; | 
|---|
| 349 |         yaml_tag_directive_t *end; | 
|---|
| 350 |     } tag_directives = { NULL, NULL }; | 
|---|
| 351 |  | 
|---|
| 352 |     token = PEEK_TOKEN(parser); | 
|---|
| 353 |     if (!token) return 0; | 
|---|
| 354 |  | 
|---|
| 355 |     /* Parse extra document end indicators. */ | 
|---|
| 356 |  | 
|---|
| 357 |     if (!implicit) | 
|---|
| 358 |     { | 
|---|
| 359 |         while (token->type == YAML_DOCUMENT_END_TOKEN) { | 
|---|
| 360 |             SKIP_TOKEN(parser); | 
|---|
| 361 |             token = PEEK_TOKEN(parser); | 
|---|
| 362 |             if (!token) return 0; | 
|---|
| 363 |         } | 
|---|
| 364 |     } | 
|---|
| 365 |  | 
|---|
| 366 |     /* Parse an implicit document. */ | 
|---|
| 367 |  | 
|---|
| 368 |     if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN && | 
|---|
| 369 |             token->type != YAML_TAG_DIRECTIVE_TOKEN && | 
|---|
| 370 |             token->type != YAML_DOCUMENT_START_TOKEN && | 
|---|
| 371 |             token->type != YAML_STREAM_END_TOKEN) | 
|---|
| 372 |     { | 
|---|
| 373 |         if (!yaml_parser_process_directives(parser, NULL, NULL, NULL)) | 
|---|
| 374 |             return 0; | 
|---|
| 375 |         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) | 
|---|
| 376 |             return 0; | 
|---|
| 377 |         parser->state = YAML_PARSE_BLOCK_NODE_STATE; | 
|---|
| 378 |         DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1, | 
|---|
| 379 |                 token->start_mark, token->start_mark); | 
|---|
| 380 |         return 1; | 
|---|
| 381 |     } | 
|---|
| 382 |  | 
|---|
| 383 |     /* Parse an explicit document. */ | 
|---|
| 384 |  | 
|---|
| 385 |     else if (token->type != YAML_STREAM_END_TOKEN) | 
|---|
| 386 |     { | 
|---|
| 387 |         yaml_mark_t start_mark, end_mark; | 
|---|
| 388 |         start_mark = token->start_mark; | 
|---|
| 389 |         if (!yaml_parser_process_directives(parser, &version_directive, | 
|---|
| 390 |                     &tag_directives.start, &tag_directives.end)) | 
|---|
| 391 |             return 0; | 
|---|
| 392 |         token = PEEK_TOKEN(parser); | 
|---|
| 393 |         if (!token) goto error; | 
|---|
| 394 |         if (token->type != YAML_DOCUMENT_START_TOKEN) { | 
|---|
| 395 |             yaml_parser_set_parser_error(parser, | 
|---|
| 396 |                     "did not found expected <document start>", token->start_mark); | 
|---|
| 397 |             goto error; | 
|---|
| 398 |         } | 
|---|
| 399 |         if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) | 
|---|
| 400 |             goto error; | 
|---|
| 401 |         parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE; | 
|---|
| 402 |         end_mark = token->end_mark; | 
|---|
| 403 |         DOCUMENT_START_EVENT_INIT(*event, version_directive, | 
|---|
| 404 |                 tag_directives.start, tag_directives.end, 0, | 
|---|
| 405 |                 start_mark, end_mark); | 
|---|
| 406 |         SKIP_TOKEN(parser); | 
|---|
| 407 |         version_directive = NULL; | 
|---|
| 408 |         tag_directives.start = tag_directives.end = NULL; | 
|---|
| 409 |         return 1; | 
|---|
| 410 |     } | 
|---|
| 411 |  | 
|---|
| 412 |     /* Parse the stream end. */ | 
|---|
| 413 |  | 
|---|
| 414 |     else | 
|---|
| 415 |     { | 
|---|
| 416 |         parser->state = YAML_PARSE_END_STATE; | 
|---|
| 417 |         STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark); | 
|---|
| 418 |         SKIP_TOKEN(parser); | 
|---|
| 419 |         return 1; | 
|---|
| 420 |     } | 
|---|
| 421 |  | 
|---|
| 422 | error: | 
|---|
| 423 |     yaml_free(version_directive); | 
|---|
| 424 |     while (tag_directives.start != tag_directives.end) { | 
|---|
| 425 |         yaml_free(tag_directives.end[-1].handle); | 
|---|
| 426 |         yaml_free(tag_directives.end[-1].prefix); | 
|---|
| 427 |         tag_directives.end --; | 
|---|
| 428 |     } | 
|---|
| 429 |     yaml_free(tag_directives.start); | 
|---|
| 430 |     return 0; | 
|---|
| 431 | } | 
|---|
| 432 |  | 
|---|
| 433 | /* | 
|---|
| 434 |  * Parse the productions: | 
|---|
| 435 |  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | 
|---|
| 436 |  *                                                    *********** | 
|---|
| 437 |  */ | 
|---|
| 438 |  | 
|---|
| 439 | static int | 
|---|
| 440 | yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event) | 
|---|
| 441 | { | 
|---|
| 442 |     yaml_token_t *token; | 
|---|
| 443 |  | 
|---|
| 444 |     token = PEEK_TOKEN(parser); | 
|---|
| 445 |     if (!token) return 0; | 
|---|
| 446 |  | 
|---|
| 447 |     if (token->type == YAML_VERSION_DIRECTIVE_TOKEN || | 
|---|
| 448 |             token->type == YAML_TAG_DIRECTIVE_TOKEN || | 
|---|
| 449 |             token->type == YAML_DOCUMENT_START_TOKEN || | 
|---|
| 450 |             token->type == YAML_DOCUMENT_END_TOKEN || | 
|---|
| 451 |             token->type == YAML_STREAM_END_TOKEN) { | 
|---|
| 452 |         parser->state = POP(parser, parser->states); | 
|---|
| 453 |         return yaml_parser_process_empty_scalar(parser, event, | 
|---|
| 454 |                 token->start_mark); | 
|---|
| 455 |     } | 
|---|
| 456 |     else { | 
|---|
| 457 |         return yaml_parser_parse_node(parser, event, 1, 0); | 
|---|
| 458 |     } | 
|---|
| 459 | } | 
|---|
| 460 |  | 
|---|
| 461 | /* | 
|---|
| 462 |  * Parse the productions: | 
|---|
| 463 |  * implicit_document    ::= block_node DOCUMENT-END* | 
|---|
| 464 |  *                                     ************* | 
|---|
| 465 |  * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* | 
|---|
| 466 |  *                                                                ************* | 
|---|
| 467 |  */ | 
|---|
| 468 |  | 
|---|
| 469 | static int | 
|---|
| 470 | yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event) | 
|---|
| 471 | { | 
|---|
| 472 |     yaml_token_t *token; | 
|---|
| 473 |     yaml_mark_t start_mark, end_mark; | 
|---|
| 474 |     int implicit = 1; | 
|---|
| 475 |  | 
|---|
| 476 |     token = PEEK_TOKEN(parser); | 
|---|
| 477 |     if (!token) return 0; | 
|---|
| 478 |  | 
|---|
| 479 |     start_mark = end_mark = token->start_mark; | 
|---|
| 480 |  | 
|---|
| 481 |     if (token->type == YAML_DOCUMENT_END_TOKEN) { | 
|---|
| 482 |         end_mark = token->end_mark; | 
|---|
| 483 |         SKIP_TOKEN(parser); | 
|---|
| 484 |         implicit = 0; | 
|---|
| 485 |     } | 
|---|
| 486 |  | 
|---|
| 487 |     while (!STACK_EMPTY(parser, parser->tag_directives)) { | 
|---|
| 488 |         yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); | 
|---|
| 489 |         yaml_free(tag_directive.handle); | 
|---|
| 490 |         yaml_free(tag_directive.prefix); | 
|---|
| 491 |     } | 
|---|
| 492 |  | 
|---|
| 493 |     parser->state = YAML_PARSE_DOCUMENT_START_STATE; | 
|---|
| 494 |     DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark); | 
|---|
| 495 |  | 
|---|
| 496 |     return 1; | 
|---|
| 497 | } | 
|---|
| 498 |  | 
|---|
| 499 | /* | 
|---|
| 500 |  * Parse the productions: | 
|---|
| 501 |  * block_node_or_indentless_sequence    ::= | 
|---|
| 502 |  *                          ALIAS | 
|---|
| 503 |  *                          ***** | 
|---|
| 504 |  *                          | properties (block_content | indentless_block_sequence)? | 
|---|
| 505 |  *                            **********  * | 
|---|
| 506 |  *                          | block_content | indentless_block_sequence | 
|---|
| 507 |  *                            * | 
|---|
| 508 |  * block_node           ::= ALIAS | 
|---|
| 509 |  *                          ***** | 
|---|
| 510 |  *                          | properties block_content? | 
|---|
| 511 |  *                            ********** * | 
|---|
| 512 |  *                          | block_content | 
|---|
| 513 |  *                            * | 
|---|
| 514 |  * flow_node            ::= ALIAS | 
|---|
| 515 |  *                          ***** | 
|---|
| 516 |  *                          | properties flow_content? | 
|---|
| 517 |  *                            ********** * | 
|---|
| 518 |  *                          | flow_content | 
|---|
| 519 |  *                            * | 
|---|
| 520 |  * properties           ::= TAG ANCHOR? | ANCHOR TAG? | 
|---|
| 521 |  *                          ************************* | 
|---|
| 522 |  * block_content        ::= block_collection | flow_collection | SCALAR | 
|---|
| 523 |  *                                                               ****** | 
|---|
| 524 |  * flow_content         ::= flow_collection | SCALAR | 
|---|
| 525 |  *                                            ****** | 
|---|
| 526 |  */ | 
|---|
| 527 |  | 
|---|
| 528 | static int | 
|---|
| 529 | yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, | 
|---|
| 530 |         int block, int indentless_sequence) | 
|---|
| 531 | { | 
|---|
| 532 |     yaml_token_t *token; | 
|---|
| 533 |     yaml_char_t *anchor = NULL; | 
|---|
| 534 |     yaml_char_t *tag_handle = NULL; | 
|---|
| 535 |     yaml_char_t *tag_suffix = NULL; | 
|---|
| 536 |     yaml_char_t *tag = NULL; | 
|---|
| 537 |     yaml_mark_t start_mark, end_mark, tag_mark; | 
|---|
| 538 |     int implicit; | 
|---|
| 539 |  | 
|---|
| 540 |     token = PEEK_TOKEN(parser); | 
|---|
| 541 |     if (!token) return 0; | 
|---|
| 542 |  | 
|---|
| 543 |     if (token->type == YAML_ALIAS_TOKEN) | 
|---|
| 544 |     { | 
|---|
| 545 |         parser->state = POP(parser, parser->states); | 
|---|
| 546 |         ALIAS_EVENT_INIT(*event, token->data.alias.value, | 
|---|
| 547 |                 token->start_mark, token->end_mark); | 
|---|
| 548 |         SKIP_TOKEN(parser); | 
|---|
| 549 |         return 1; | 
|---|
| 550 |     } | 
|---|
| 551 |  | 
|---|
| 552 |     else | 
|---|
| 553 |     { | 
|---|
| 554 |         start_mark = end_mark = token->start_mark; | 
|---|
| 555 |  | 
|---|
| 556 |         if (token->type == YAML_ANCHOR_TOKEN) | 
|---|
| 557 |         { | 
|---|
| 558 |             anchor = token->data.anchor.value; | 
|---|
| 559 |             start_mark = token->start_mark; | 
|---|
| 560 |             end_mark = token->end_mark; | 
|---|
| 561 |             SKIP_TOKEN(parser); | 
|---|
| 562 |             token = PEEK_TOKEN(parser); | 
|---|
| 563 |             if (!token) goto error; | 
|---|
| 564 |             if (token->type == YAML_TAG_TOKEN) | 
|---|
| 565 |             { | 
|---|
| 566 |                 tag_handle = token->data.tag.handle; | 
|---|
| 567 |                 tag_suffix = token->data.tag.suffix; | 
|---|
| 568 |                 tag_mark = token->start_mark; | 
|---|
| 569 |                 end_mark = token->end_mark; | 
|---|
| 570 |                 SKIP_TOKEN(parser); | 
|---|
| 571 |                 token = PEEK_TOKEN(parser); | 
|---|
| 572 |                 if (!token) goto error; | 
|---|
| 573 |             } | 
|---|
| 574 |         } | 
|---|
| 575 |         else if (token->type == YAML_TAG_TOKEN) | 
|---|
| 576 |         { | 
|---|
| 577 |             tag_handle = token->data.tag.handle; | 
|---|
| 578 |             tag_suffix = token->data.tag.suffix; | 
|---|
| 579 |             start_mark = tag_mark = token->start_mark; | 
|---|
| 580 |             end_mark = token->end_mark; | 
|---|
| 581 |             SKIP_TOKEN(parser); | 
|---|
| 582 |             token = PEEK_TOKEN(parser); | 
|---|
| 583 |             if (!token) goto error; | 
|---|
| 584 |             if (token->type == YAML_ANCHOR_TOKEN) | 
|---|
| 585 |             { | 
|---|
| 586 |                 anchor = token->data.anchor.value; | 
|---|
| 587 |                 end_mark = token->end_mark; | 
|---|
| 588 |                 SKIP_TOKEN(parser); | 
|---|
| 589 |                 token = PEEK_TOKEN(parser); | 
|---|
| 590 |                 if (!token) goto error; | 
|---|
| 591 |             } | 
|---|
| 592 |         } | 
|---|
| 593 |  | 
|---|
| 594 |         if (tag_handle) { | 
|---|
| 595 |             if (!*tag_handle) { | 
|---|
| 596 |                 tag = tag_suffix; | 
|---|
| 597 |                 yaml_free(tag_handle); | 
|---|
| 598 |                 tag_handle = tag_suffix = NULL; | 
|---|
| 599 |             } | 
|---|
| 600 |             else { | 
|---|
| 601 |                 yaml_tag_directive_t *tag_directive; | 
|---|
| 602 |                 for (tag_directive = parser->tag_directives.start; | 
|---|
| 603 |                         tag_directive != parser->tag_directives.top; | 
|---|
| 604 |                         tag_directive ++) { | 
|---|
| 605 |                     if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) { | 
|---|
| 606 |                         size_t prefix_len = strlen((char *)tag_directive->prefix); | 
|---|
| 607 |                         size_t suffix_len = strlen((char *)tag_suffix); | 
|---|
| 608 |                         tag = yaml_malloc(prefix_len+suffix_len+1); | 
|---|
| 609 |                         if (!tag) { | 
|---|
| 610 |                             parser->error = YAML_MEMORY_ERROR; | 
|---|
| 611 |                             goto error; | 
|---|
| 612 |                         } | 
|---|
| 613 |                         memcpy(tag, tag_directive->prefix, prefix_len); | 
|---|
| 614 |                         memcpy(tag+prefix_len, tag_suffix, suffix_len); | 
|---|
| 615 |                         tag[prefix_len+suffix_len] = '\0'; | 
|---|
| 616 |                         yaml_free(tag_handle); | 
|---|
| 617 |                         yaml_free(tag_suffix); | 
|---|
| 618 |                         tag_handle = tag_suffix = NULL; | 
|---|
| 619 |                         break; | 
|---|
| 620 |                     } | 
|---|
| 621 |                 } | 
|---|
| 622 |                 if (!tag) { | 
|---|
| 623 |                     yaml_parser_set_parser_error_context(parser, | 
|---|
| 624 |                             "while parsing a node", start_mark, | 
|---|
| 625 |                             "found undefined tag handle", tag_mark); | 
|---|
| 626 |                     goto error; | 
|---|
| 627 |                 } | 
|---|
| 628 |             } | 
|---|
| 629 |         } | 
|---|
| 630 |  | 
|---|
| 631 |         implicit = (!tag || !*tag); | 
|---|
| 632 |         if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) { | 
|---|
| 633 |             end_mark = token->end_mark; | 
|---|
| 634 |             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; | 
|---|
| 635 |             SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, | 
|---|
| 636 |                     YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); | 
|---|
| 637 |             return 1; | 
|---|
| 638 |         } | 
|---|
| 639 |         else { | 
|---|
| 640 |             if (token->type == YAML_SCALAR_TOKEN) { | 
|---|
| 641 |                 int plain_implicit = 0; | 
|---|
| 642 |                 int quoted_implicit = 0; | 
|---|
| 643 |                 end_mark = token->end_mark; | 
|---|
| 644 |                 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag) | 
|---|
| 645 |                         || (tag && strcmp((char *)tag, "!") == 0)) { | 
|---|
| 646 |                     plain_implicit = 1; | 
|---|
| 647 |                 } | 
|---|
| 648 |                 else if (!tag) { | 
|---|
| 649 |                     quoted_implicit = 1; | 
|---|
| 650 |                 } | 
|---|
| 651 |                 parser->state = POP(parser, parser->states); | 
|---|
| 652 |                 SCALAR_EVENT_INIT(*event, anchor, tag, | 
|---|
| 653 |                         token->data.scalar.value, token->data.scalar.length, | 
|---|
| 654 |                         plain_implicit, quoted_implicit, | 
|---|
| 655 |                         token->data.scalar.style, start_mark, end_mark); | 
|---|
| 656 |                 SKIP_TOKEN(parser); | 
|---|
| 657 |                 return 1; | 
|---|
| 658 |             } | 
|---|
| 659 |             else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) { | 
|---|
| 660 |                 end_mark = token->end_mark; | 
|---|
| 661 |                 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; | 
|---|
| 662 |                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, | 
|---|
| 663 |                         YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark); | 
|---|
| 664 |                 return 1; | 
|---|
| 665 |             } | 
|---|
| 666 |             else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) { | 
|---|
| 667 |                 end_mark = token->end_mark; | 
|---|
| 668 |                 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; | 
|---|
| 669 |                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, | 
|---|
| 670 |                         YAML_FLOW_MAPPING_STYLE, start_mark, end_mark); | 
|---|
| 671 |                 return 1; | 
|---|
| 672 |             } | 
|---|
| 673 |             else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) { | 
|---|
| 674 |                 end_mark = token->end_mark; | 
|---|
| 675 |                 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; | 
|---|
| 676 |                 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, | 
|---|
| 677 |                         YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); | 
|---|
| 678 |                 return 1; | 
|---|
| 679 |             } | 
|---|
| 680 |             else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) { | 
|---|
| 681 |                 end_mark = token->end_mark; | 
|---|
| 682 |                 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; | 
|---|
| 683 |                 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, | 
|---|
| 684 |                         YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark); | 
|---|
| 685 |                 return 1; | 
|---|
| 686 |             } | 
|---|
| 687 |             else if (anchor || tag) { | 
|---|
| 688 |                 yaml_char_t *value = yaml_malloc(1); | 
|---|
| 689 |                 if (!value) { | 
|---|
| 690 |                     parser->error = YAML_MEMORY_ERROR; | 
|---|
| 691 |                     goto error; | 
|---|
| 692 |                 } | 
|---|
| 693 |                 value[0] = '\0'; | 
|---|
| 694 |                 parser->state = POP(parser, parser->states); | 
|---|
| 695 |                 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0, | 
|---|
| 696 |                         implicit, 0, YAML_PLAIN_SCALAR_STYLE, | 
|---|
| 697 |                         start_mark, end_mark); | 
|---|
| 698 |                 return 1; | 
|---|
| 699 |             } | 
|---|
| 700 |             else { | 
|---|
| 701 |                 yaml_parser_set_parser_error_context(parser, | 
|---|
| 702 |                         (block ? "while parsing a block node" | 
|---|
| 703 |                          : "while parsing a flow node"), start_mark, | 
|---|
| 704 |                         "did not found expected node content", token->start_mark); | 
|---|
| 705 |                 goto error; | 
|---|
| 706 |             } | 
|---|
| 707 |         } | 
|---|
| 708 |     } | 
|---|
| 709 |  | 
|---|
| 710 | error: | 
|---|
| 711 |     yaml_free(anchor); | 
|---|
| 712 |     yaml_free(tag_handle); | 
|---|
| 713 |     yaml_free(tag_suffix); | 
|---|
| 714 |     yaml_free(tag); | 
|---|
| 715 |  | 
|---|
| 716 |     return 0; | 
|---|
| 717 | } | 
|---|
| 718 |  | 
|---|
| 719 | /* | 
|---|
| 720 |  * Parse the productions: | 
|---|
| 721 |  * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END | 
|---|
| 722 |  *                    ********************  *********** *             ********* | 
|---|
| 723 |  */ | 
|---|
| 724 |  | 
|---|
| 725 | static int | 
|---|
| 726 | yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, | 
|---|
| 727 |         yaml_event_t *event, int first) | 
|---|
| 728 | { | 
|---|
| 729 |     yaml_token_t *token; | 
|---|
| 730 |  | 
|---|
| 731 |     if (first) { | 
|---|
| 732 |         token = PEEK_TOKEN(parser); | 
|---|
| 733 |         if (!PUSH(parser, parser->marks, token->start_mark)) | 
|---|
| 734 |             return 0; | 
|---|
| 735 |         SKIP_TOKEN(parser); | 
|---|
| 736 |     } | 
|---|
| 737 |  | 
|---|
| 738 |     token = PEEK_TOKEN(parser); | 
|---|
| 739 |     if (!token) return 0; | 
|---|
| 740 |  | 
|---|
| 741 |     if (token->type == YAML_BLOCK_ENTRY_TOKEN) | 
|---|
| 742 |     { | 
|---|
| 743 |         yaml_mark_t mark = token->end_mark; | 
|---|
| 744 |         SKIP_TOKEN(parser); | 
|---|
| 745 |         token = PEEK_TOKEN(parser); | 
|---|
| 746 |         if (!token) return 0; | 
|---|
| 747 |         if (token->type != YAML_BLOCK_ENTRY_TOKEN && | 
|---|
| 748 |                 token->type != YAML_BLOCK_END_TOKEN) { | 
|---|
| 749 |             if (!PUSH(parser, parser->states, | 
|---|
| 750 |                         YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)) | 
|---|
| 751 |                 return 0; | 
|---|
| 752 |             return yaml_parser_parse_node(parser, event, 1, 0); | 
|---|
| 753 |         } | 
|---|
| 754 |         else { | 
|---|
| 755 |             parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; | 
|---|
| 756 |             return yaml_parser_process_empty_scalar(parser, event, mark); | 
|---|
| 757 |         } | 
|---|
| 758 |     } | 
|---|
| 759 |  | 
|---|
| 760 |     else if (token->type == YAML_BLOCK_END_TOKEN) | 
|---|
| 761 |     { | 
|---|
| 762 |         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */ | 
|---|
| 763 |         parser->state = POP(parser, parser->states); | 
|---|
| 764 |         dummy_mark = POP(parser, parser->marks); | 
|---|
| 765 |         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); | 
|---|
| 766 |         SKIP_TOKEN(parser); | 
|---|
| 767 |         return 1; | 
|---|
| 768 |     } | 
|---|
| 769 |  | 
|---|
| 770 |     else | 
|---|
| 771 |     { | 
|---|
| 772 |         return yaml_parser_set_parser_error_context(parser, | 
|---|
| 773 |                 "while parsing a block collection", POP(parser, parser->marks), | 
|---|
| 774 |                 "did not found expected '-' indicator", token->start_mark); | 
|---|
| 775 |     } | 
|---|
| 776 | } | 
|---|
| 777 |  | 
|---|
| 778 | /* | 
|---|
| 779 |  * Parse the productions: | 
|---|
| 780 |  * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+ | 
|---|
| 781 |  *                           *********** * | 
|---|
| 782 |  */ | 
|---|
| 783 |  | 
|---|
| 784 | static int | 
|---|
| 785 | yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, | 
|---|
| 786 |         yaml_event_t *event) | 
|---|
| 787 | { | 
|---|
| 788 |     yaml_token_t *token; | 
|---|
| 789 |  | 
|---|
| 790 |     token = PEEK_TOKEN(parser); | 
|---|
| 791 |     if (!token) return 0; | 
|---|
| 792 |  | 
|---|
| 793 |     if (token->type == YAML_BLOCK_ENTRY_TOKEN) | 
|---|
| 794 |     { | 
|---|
| 795 |         yaml_mark_t mark = token->end_mark; | 
|---|
| 796 |         SKIP_TOKEN(parser); | 
|---|
| 797 |         token = PEEK_TOKEN(parser); | 
|---|
| 798 |         if (!token) return 0; | 
|---|
| 799 |         if (token->type != YAML_BLOCK_ENTRY_TOKEN && | 
|---|
| 800 |                 token->type != YAML_KEY_TOKEN && | 
|---|
| 801 |                 token->type != YAML_VALUE_TOKEN && | 
|---|
| 802 |                 token->type != YAML_BLOCK_END_TOKEN) { | 
|---|
| 803 |             if (!PUSH(parser, parser->states, | 
|---|
| 804 |                         YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)) | 
|---|
| 805 |                 return 0; | 
|---|
| 806 |             return yaml_parser_parse_node(parser, event, 1, 0); | 
|---|
| 807 |         } | 
|---|
| 808 |         else { | 
|---|
| 809 |             parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; | 
|---|
| 810 |             return yaml_parser_process_empty_scalar(parser, event, mark); | 
|---|
| 811 |         } | 
|---|
| 812 |     } | 
|---|
| 813 |  | 
|---|
| 814 |     else | 
|---|
| 815 |     { | 
|---|
| 816 |         parser->state = POP(parser, parser->states); | 
|---|
| 817 |         SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark); | 
|---|
| 818 |         return 1; | 
|---|
| 819 |     } | 
|---|
| 820 | } | 
|---|
| 821 |  | 
|---|
| 822 | /* | 
|---|
| 823 |  * Parse the productions: | 
|---|
| 824 |  * block_mapping        ::= BLOCK-MAPPING_START | 
|---|
| 825 |  *                          ******************* | 
|---|
| 826 |  *                          ((KEY block_node_or_indentless_sequence?)? | 
|---|
| 827 |  *                            *** * | 
|---|
| 828 |  *                          (VALUE block_node_or_indentless_sequence?)?)* | 
|---|
| 829 |  * | 
|---|
| 830 |  *                          BLOCK-END | 
|---|
| 831 |  *                          ********* | 
|---|
| 832 |  */ | 
|---|
| 833 |  | 
|---|
| 834 | static int | 
|---|
| 835 | yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, | 
|---|
| 836 |         yaml_event_t *event, int first) | 
|---|
| 837 | { | 
|---|
| 838 |     yaml_token_t *token; | 
|---|
| 839 |  | 
|---|
| 840 |     if (first) { | 
|---|
| 841 |         token = PEEK_TOKEN(parser); | 
|---|
| 842 |         if (!PUSH(parser, parser->marks, token->start_mark)) | 
|---|
| 843 |             return 0; | 
|---|
| 844 |         SKIP_TOKEN(parser); | 
|---|
| 845 |     } | 
|---|
| 846 |  | 
|---|
| 847 |     token = PEEK_TOKEN(parser); | 
|---|
| 848 |     if (!token) return 0; | 
|---|
| 849 |  | 
|---|
| 850 |     if (token->type == YAML_KEY_TOKEN) | 
|---|
| 851 |     { | 
|---|
| 852 |         yaml_mark_t mark = token->end_mark; | 
|---|
| 853 |         SKIP_TOKEN(parser); | 
|---|
| 854 |         token = PEEK_TOKEN(parser); | 
|---|
| 855 |         if (!token) return 0; | 
|---|
| 856 |         if (token->type != YAML_KEY_TOKEN && | 
|---|
| 857 |                 token->type != YAML_VALUE_TOKEN && | 
|---|
| 858 |                 token->type != YAML_BLOCK_END_TOKEN) { | 
|---|
| 859 |             if (!PUSH(parser, parser->states, | 
|---|
| 860 |                         YAML_PARSE_BLOCK_MAPPING_VALUE_STATE)) | 
|---|
| 861 |                 return 0; | 
|---|
| 862 |             return yaml_parser_parse_node(parser, event, 1, 1); | 
|---|
| 863 |         } | 
|---|
| 864 |         else { | 
|---|
| 865 |             parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; | 
|---|
| 866 |             return yaml_parser_process_empty_scalar(parser, event, mark); | 
|---|
| 867 |         } | 
|---|
| 868 |     } | 
|---|
| 869 |  | 
|---|
| 870 |     else if (token->type == YAML_BLOCK_END_TOKEN) | 
|---|
| 871 |     { | 
|---|
| 872 |         yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */ | 
|---|
| 873 |         parser->state = POP(parser, parser->states); | 
|---|
| 874 |         dummy_mark = POP(parser, parser->marks); | 
|---|
| 875 |         MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); | 
|---|
| 876 |         SKIP_TOKEN(parser); | 
|---|
| 877 |         return 1; | 
|---|
| 878 |     } | 
|---|
| 879 |  | 
|---|
| 880 |     else | 
|---|
| 881 |     { | 
|---|
| 882 |         return yaml_parser_set_parser_error_context(parser, | 
|---|
| 883 |                 "while parsing a block mapping", POP(parser, parser->marks), | 
|---|
| 884 |                 "did not found expected key", token->start_mark); | 
|---|
| 885 |     } | 
|---|
| 886 | } | 
|---|
| 887 |  | 
|---|
| 888 | /* | 
|---|
| 889 |  * Parse the productions: | 
|---|
| 890 |  * block_mapping        ::= BLOCK-MAPPING_START | 
|---|
| 891 |  * | 
|---|
| 892 |  *                          ((KEY block_node_or_indentless_sequence?)? | 
|---|
| 893 |  * | 
|---|
| 894 |  *                          (VALUE block_node_or_indentless_sequence?)?)* | 
|---|
| 895 |  *                           ***** * | 
|---|
| 896 |  *                          BLOCK-END | 
|---|
| 897 |  * | 
|---|
| 898 |  */ | 
|---|
| 899 |  | 
|---|
| 900 | static int | 
|---|
| 901 | yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, | 
|---|
| 902 |         yaml_event_t *event) | 
|---|
| 903 | { | 
|---|
| 904 |     yaml_token_t *token; | 
|---|
| 905 |  | 
|---|
| 906 |     token = PEEK_TOKEN(parser); | 
|---|
| 907 |     if (!token) return 0; | 
|---|
| 908 |  | 
|---|
| 909 |     if (token->type == YAML_VALUE_TOKEN) | 
|---|
| 910 |     { | 
|---|
| 911 |         yaml_mark_t mark = token->end_mark; | 
|---|
| 912 |         SKIP_TOKEN(parser); | 
|---|
| 913 |         token = PEEK_TOKEN(parser); | 
|---|
| 914 |         if (!token) return 0; | 
|---|
| 915 |         if (token->type != YAML_KEY_TOKEN && | 
|---|
| 916 |                 token->type != YAML_VALUE_TOKEN && | 
|---|
| 917 |                 token->type != YAML_BLOCK_END_TOKEN) { | 
|---|
| 918 |             if (!PUSH(parser, parser->states, | 
|---|
| 919 |                         YAML_PARSE_BLOCK_MAPPING_KEY_STATE)) | 
|---|
| 920 |                 return 0; | 
|---|
| 921 |             return yaml_parser_parse_node(parser, event, 1, 1); | 
|---|
| 922 |         } | 
|---|
| 923 |         else { | 
|---|
| 924 |             parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; | 
|---|
| 925 |             return yaml_parser_process_empty_scalar(parser, event, mark); | 
|---|
| 926 |         } | 
|---|
| 927 |     } | 
|---|
| 928 |  | 
|---|
| 929 |     else | 
|---|
| 930 |     { | 
|---|
| 931 |         parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; | 
|---|
| 932 |         return yaml_parser_process_empty_scalar(parser, event, token->start_mark); | 
|---|
| 933 |     } | 
|---|
| 934 | } | 
|---|
| 935 |  | 
|---|
| 936 | /* | 
|---|
| 937 |  * Parse the productions: | 
|---|
| 938 |  * flow_sequence        ::= FLOW-SEQUENCE-START | 
|---|
| 939 |  *                          ******************* | 
|---|
| 940 |  *                          (flow_sequence_entry FLOW-ENTRY)* | 
|---|
| 941 |  *                           *                   ********** | 
|---|
| 942 |  *                          flow_sequence_entry? | 
|---|
| 943 |  *                          * | 
|---|
| 944 |  *                          FLOW-SEQUENCE-END | 
|---|
| 945 |  *                          ***************** | 
|---|
| 946 |  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 947 |  *                          * | 
|---|
| 948 |  */ | 
|---|
| 949 |  | 
|---|
| 950 | static int | 
|---|
| 951 | yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, | 
|---|
| 952 |         yaml_event_t *event, int first) | 
|---|
| 953 | { | 
|---|
| 954 |     yaml_token_t *token; | 
|---|
| 955 |     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */ | 
|---|
| 956 |  | 
|---|
| 957 |     if (first) { | 
|---|
| 958 |         token = PEEK_TOKEN(parser); | 
|---|
| 959 |         if (!PUSH(parser, parser->marks, token->start_mark)) | 
|---|
| 960 |             return 0; | 
|---|
| 961 |         SKIP_TOKEN(parser); | 
|---|
| 962 |     } | 
|---|
| 963 |  | 
|---|
| 964 |     token = PEEK_TOKEN(parser); | 
|---|
| 965 |     if (!token) return 0; | 
|---|
| 966 |  | 
|---|
| 967 |     if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) | 
|---|
| 968 |     { | 
|---|
| 969 |         if (!first) { | 
|---|
| 970 |             if (token->type == YAML_FLOW_ENTRY_TOKEN) { | 
|---|
| 971 |                 SKIP_TOKEN(parser); | 
|---|
| 972 |                 token = PEEK_TOKEN(parser); | 
|---|
| 973 |                 if (!token) return 0; | 
|---|
| 974 |             } | 
|---|
| 975 |             else { | 
|---|
| 976 |                 return yaml_parser_set_parser_error_context(parser, | 
|---|
| 977 |                         "while parsing a flow sequence", POP(parser, parser->marks), | 
|---|
| 978 |                         "did not found expected ',' or ']'", token->start_mark); | 
|---|
| 979 |             } | 
|---|
| 980 |         } | 
|---|
| 981 |  | 
|---|
| 982 |         if (token->type == YAML_KEY_TOKEN) { | 
|---|
| 983 |             parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; | 
|---|
| 984 |             MAPPING_START_EVENT_INIT(*event, NULL, NULL, | 
|---|
| 985 |                     1, YAML_FLOW_MAPPING_STYLE, | 
|---|
| 986 |                     token->start_mark, token->end_mark); | 
|---|
| 987 |             SKIP_TOKEN(parser); | 
|---|
| 988 |             return 1; | 
|---|
| 989 |         } | 
|---|
| 990 |  | 
|---|
| 991 |         else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { | 
|---|
| 992 |             if (!PUSH(parser, parser->states, | 
|---|
| 993 |                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE)) | 
|---|
| 994 |                 return 0; | 
|---|
| 995 |             return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 996 |         } | 
|---|
| 997 |     } | 
|---|
| 998 |  | 
|---|
| 999 |     parser->state = POP(parser, parser->states); | 
|---|
| 1000 |     dummy_mark = POP(parser, parser->marks); | 
|---|
| 1001 |     SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); | 
|---|
| 1002 |     SKIP_TOKEN(parser); | 
|---|
| 1003 |     return 1; | 
|---|
| 1004 | } | 
|---|
| 1005 |  | 
|---|
| 1006 | /* | 
|---|
| 1007 |  * Parse the productions: | 
|---|
| 1008 |  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 1009 |  *                                      *** * | 
|---|
| 1010 |  */ | 
|---|
| 1011 |  | 
|---|
| 1012 | static int | 
|---|
| 1013 | yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, | 
|---|
| 1014 |         yaml_event_t *event) | 
|---|
| 1015 | { | 
|---|
| 1016 |     yaml_token_t *token; | 
|---|
| 1017 |  | 
|---|
| 1018 |     token = PEEK_TOKEN(parser); | 
|---|
| 1019 |     if (!token) return 0; | 
|---|
| 1020 |  | 
|---|
| 1021 |     if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN | 
|---|
| 1022 |             && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { | 
|---|
| 1023 |         if (!PUSH(parser, parser->states, | 
|---|
| 1024 |                     YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)) | 
|---|
| 1025 |             return 0; | 
|---|
| 1026 |         return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 1027 |     } | 
|---|
| 1028 |     else { | 
|---|
| 1029 |         yaml_mark_t mark = token->end_mark; | 
|---|
| 1030 |         SKIP_TOKEN(parser); | 
|---|
| 1031 |         parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; | 
|---|
| 1032 |         return yaml_parser_process_empty_scalar(parser, event, mark); | 
|---|
| 1033 |     } | 
|---|
| 1034 | } | 
|---|
| 1035 |  | 
|---|
| 1036 | /* | 
|---|
| 1037 |  * Parse the productions: | 
|---|
| 1038 |  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 1039 |  *                                                      ***** * | 
|---|
| 1040 |  */ | 
|---|
| 1041 |  | 
|---|
| 1042 | static int | 
|---|
| 1043 | yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, | 
|---|
| 1044 |         yaml_event_t *event) | 
|---|
| 1045 | { | 
|---|
| 1046 |     yaml_token_t *token; | 
|---|
| 1047 |  | 
|---|
| 1048 |     token = PEEK_TOKEN(parser); | 
|---|
| 1049 |     if (!token) return 0; | 
|---|
| 1050 |  | 
|---|
| 1051 |     if (token->type == YAML_VALUE_TOKEN) { | 
|---|
| 1052 |         SKIP_TOKEN(parser); | 
|---|
| 1053 |         token = PEEK_TOKEN(parser); | 
|---|
| 1054 |         if (!token) return 0; | 
|---|
| 1055 |         if (token->type != YAML_FLOW_ENTRY_TOKEN | 
|---|
| 1056 |                 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { | 
|---|
| 1057 |             if (!PUSH(parser, parser->states, | 
|---|
| 1058 |                         YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)) | 
|---|
| 1059 |                 return 0; | 
|---|
| 1060 |             return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 1061 |         } | 
|---|
| 1062 |     } | 
|---|
| 1063 |     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; | 
|---|
| 1064 |     return yaml_parser_process_empty_scalar(parser, event, token->start_mark); | 
|---|
| 1065 | } | 
|---|
| 1066 |  | 
|---|
| 1067 | /* | 
|---|
| 1068 |  * Parse the productions: | 
|---|
| 1069 |  * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 1070 |  *                                                                      * | 
|---|
| 1071 |  */ | 
|---|
| 1072 |  | 
|---|
| 1073 | static int | 
|---|
| 1074 | yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, | 
|---|
| 1075 |         yaml_event_t *event) | 
|---|
| 1076 | { | 
|---|
| 1077 |     yaml_token_t *token; | 
|---|
| 1078 |  | 
|---|
| 1079 |     token = PEEK_TOKEN(parser); | 
|---|
| 1080 |     if (!token) return 0; | 
|---|
| 1081 |  | 
|---|
| 1082 |     parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; | 
|---|
| 1083 |  | 
|---|
| 1084 |     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark); | 
|---|
| 1085 |     return 1; | 
|---|
| 1086 | } | 
|---|
| 1087 |  | 
|---|
| 1088 | /* | 
|---|
| 1089 |  * Parse the productions: | 
|---|
| 1090 |  * flow_mapping         ::= FLOW-MAPPING-START | 
|---|
| 1091 |  *                          ****************** | 
|---|
| 1092 |  *                          (flow_mapping_entry FLOW-ENTRY)* | 
|---|
| 1093 |  *                           *                  ********** | 
|---|
| 1094 |  *                          flow_mapping_entry? | 
|---|
| 1095 |  *                          ****************** | 
|---|
| 1096 |  *                          FLOW-MAPPING-END | 
|---|
| 1097 |  *                          **************** | 
|---|
| 1098 |  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 1099 |  *                          *           *** * | 
|---|
| 1100 |  */ | 
|---|
| 1101 |  | 
|---|
| 1102 | static int | 
|---|
| 1103 | yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, | 
|---|
| 1104 |         yaml_event_t *event, int first) | 
|---|
| 1105 | { | 
|---|
| 1106 |     yaml_token_t *token; | 
|---|
| 1107 |     yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */ | 
|---|
| 1108 |  | 
|---|
| 1109 |     if (first) { | 
|---|
| 1110 |         token = PEEK_TOKEN(parser); | 
|---|
| 1111 |         if (!PUSH(parser, parser->marks, token->start_mark)) | 
|---|
| 1112 |             return 0; | 
|---|
| 1113 |         SKIP_TOKEN(parser); | 
|---|
| 1114 |     } | 
|---|
| 1115 |  | 
|---|
| 1116 |     token = PEEK_TOKEN(parser); | 
|---|
| 1117 |     if (!token) return 0; | 
|---|
| 1118 |  | 
|---|
| 1119 |     if (token->type != YAML_FLOW_MAPPING_END_TOKEN) | 
|---|
| 1120 |     { | 
|---|
| 1121 |         if (!first) { | 
|---|
| 1122 |             if (token->type == YAML_FLOW_ENTRY_TOKEN) { | 
|---|
| 1123 |                 SKIP_TOKEN(parser); | 
|---|
| 1124 |                 token = PEEK_TOKEN(parser); | 
|---|
| 1125 |                 if (!token) return 0; | 
|---|
| 1126 |             } | 
|---|
| 1127 |             else { | 
|---|
| 1128 |                 return yaml_parser_set_parser_error_context(parser, | 
|---|
| 1129 |                         "while parsing a flow mapping", POP(parser, parser->marks), | 
|---|
| 1130 |                         "did not found expected ',' or '}'", token->start_mark); | 
|---|
| 1131 |             } | 
|---|
| 1132 |         } | 
|---|
| 1133 |  | 
|---|
| 1134 |         if (token->type == YAML_KEY_TOKEN) { | 
|---|
| 1135 |             SKIP_TOKEN(parser); | 
|---|
| 1136 |             token = PEEK_TOKEN(parser); | 
|---|
| 1137 |             if (!token) return 0; | 
|---|
| 1138 |             if (token->type != YAML_VALUE_TOKEN | 
|---|
| 1139 |                     && token->type != YAML_FLOW_ENTRY_TOKEN | 
|---|
| 1140 |                     && token->type != YAML_FLOW_MAPPING_END_TOKEN) { | 
|---|
| 1141 |                 if (!PUSH(parser, parser->states, | 
|---|
| 1142 |                             YAML_PARSE_FLOW_MAPPING_VALUE_STATE)) | 
|---|
| 1143 |                     return 0; | 
|---|
| 1144 |                 return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 1145 |             } | 
|---|
| 1146 |             else { | 
|---|
| 1147 |                 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE; | 
|---|
| 1148 |                 return yaml_parser_process_empty_scalar(parser, event, | 
|---|
| 1149 |                         token->start_mark); | 
|---|
| 1150 |             } | 
|---|
| 1151 |         } | 
|---|
| 1152 |         else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) { | 
|---|
| 1153 |             if (!PUSH(parser, parser->states, | 
|---|
| 1154 |                         YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)) | 
|---|
| 1155 |                 return 0; | 
|---|
| 1156 |             return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 1157 |         } | 
|---|
| 1158 |     } | 
|---|
| 1159 |  | 
|---|
| 1160 |     parser->state = POP(parser, parser->states); | 
|---|
| 1161 |     dummy_mark = POP(parser, parser->marks); | 
|---|
| 1162 |     MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); | 
|---|
| 1163 |     SKIP_TOKEN(parser); | 
|---|
| 1164 |     return 1; | 
|---|
| 1165 | } | 
|---|
| 1166 |  | 
|---|
| 1167 | /* | 
|---|
| 1168 |  * Parse the productions: | 
|---|
| 1169 |  * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)? | 
|---|
| 1170 |  *                                   *                  ***** * | 
|---|
| 1171 |  */ | 
|---|
| 1172 |  | 
|---|
| 1173 | static int | 
|---|
| 1174 | yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, | 
|---|
| 1175 |         yaml_event_t *event, int empty) | 
|---|
| 1176 | { | 
|---|
| 1177 |     yaml_token_t *token; | 
|---|
| 1178 |  | 
|---|
| 1179 |     token = PEEK_TOKEN(parser); | 
|---|
| 1180 |     if (!token) return 0; | 
|---|
| 1181 |  | 
|---|
| 1182 |     if (empty) { | 
|---|
| 1183 |         parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; | 
|---|
| 1184 |         return yaml_parser_process_empty_scalar(parser, event, | 
|---|
| 1185 |                 token->start_mark); | 
|---|
| 1186 |     } | 
|---|
| 1187 |  | 
|---|
| 1188 |     if (token->type == YAML_VALUE_TOKEN) { | 
|---|
| 1189 |         SKIP_TOKEN(parser); | 
|---|
| 1190 |         token = PEEK_TOKEN(parser); | 
|---|
| 1191 |         if (!token) return 0; | 
|---|
| 1192 |         if (token->type != YAML_FLOW_ENTRY_TOKEN | 
|---|
| 1193 |                 && token->type != YAML_FLOW_MAPPING_END_TOKEN) { | 
|---|
| 1194 |             if (!PUSH(parser, parser->states, | 
|---|
| 1195 |                         YAML_PARSE_FLOW_MAPPING_KEY_STATE)) | 
|---|
| 1196 |                 return 0; | 
|---|
| 1197 |             return yaml_parser_parse_node(parser, event, 0, 0); | 
|---|
| 1198 |         } | 
|---|
| 1199 |     } | 
|---|
| 1200 |  | 
|---|
| 1201 |     parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; | 
|---|
| 1202 |     return yaml_parser_process_empty_scalar(parser, event, token->start_mark); | 
|---|
| 1203 | } | 
|---|
| 1204 |  | 
|---|
| 1205 | /* | 
|---|
| 1206 |  * Generate an empty scalar event. | 
|---|
| 1207 |  */ | 
|---|
| 1208 |  | 
|---|
| 1209 | static int | 
|---|
| 1210 | yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, | 
|---|
| 1211 |         yaml_mark_t mark) | 
|---|
| 1212 | { | 
|---|
| 1213 |     yaml_char_t *value; | 
|---|
| 1214 |  | 
|---|
| 1215 |     value = yaml_malloc(1); | 
|---|
| 1216 |     if (!value) { | 
|---|
| 1217 |         parser->error = YAML_MEMORY_ERROR; | 
|---|
| 1218 |         return 0; | 
|---|
| 1219 |     } | 
|---|
| 1220 |     value[0] = '\0'; | 
|---|
| 1221 |  | 
|---|
| 1222 |     SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0, | 
|---|
| 1223 |             1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark); | 
|---|
| 1224 |  | 
|---|
| 1225 |     return 1; | 
|---|
| 1226 | } | 
|---|
| 1227 |  | 
|---|
| 1228 | /* | 
|---|
| 1229 |  * Parse directives. | 
|---|
| 1230 |  */ | 
|---|
| 1231 |  | 
|---|
| 1232 | static int | 
|---|
| 1233 | yaml_parser_process_directives(yaml_parser_t *parser, | 
|---|
| 1234 |         yaml_version_directive_t **version_directive_ref, | 
|---|
| 1235 |         yaml_tag_directive_t **tag_directives_start_ref, | 
|---|
| 1236 |         yaml_tag_directive_t **tag_directives_end_ref) | 
|---|
| 1237 | { | 
|---|
| 1238 |     yaml_tag_directive_t default_tag_directives[] = { | 
|---|
| 1239 |         {(yaml_char_t *)"!", (yaml_char_t *)"!"}, | 
|---|
| 1240 |         {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, | 
|---|
| 1241 |         {NULL, NULL} | 
|---|
| 1242 |     }; | 
|---|
| 1243 |     yaml_tag_directive_t *default_tag_directive; | 
|---|
| 1244 |     yaml_version_directive_t *version_directive = NULL; | 
|---|
| 1245 |     struct { | 
|---|
| 1246 |         yaml_tag_directive_t *start; | 
|---|
| 1247 |         yaml_tag_directive_t *end; | 
|---|
| 1248 |         yaml_tag_directive_t *top; | 
|---|
| 1249 |     } tag_directives = { NULL, NULL, NULL }; | 
|---|
| 1250 |     yaml_token_t *token; | 
|---|
| 1251 |  | 
|---|
| 1252 |     if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE)) | 
|---|
| 1253 |         goto error; | 
|---|
| 1254 |  | 
|---|
| 1255 |     token = PEEK_TOKEN(parser); | 
|---|
| 1256 |     if (!token) goto error; | 
|---|
| 1257 |  | 
|---|
| 1258 |     while (token->type == YAML_VERSION_DIRECTIVE_TOKEN || | 
|---|
| 1259 |             token->type == YAML_TAG_DIRECTIVE_TOKEN) | 
|---|
| 1260 |     { | 
|---|
| 1261 |         if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) { | 
|---|
| 1262 |             if (version_directive) { | 
|---|
| 1263 |                 yaml_parser_set_parser_error(parser, | 
|---|
| 1264 |                         "found duplicate %YAML directive", token->start_mark); | 
|---|
| 1265 |                 goto error; | 
|---|
| 1266 |             } | 
|---|
| 1267 |             if (token->data.version_directive.major != 1 | 
|---|
| 1268 |                     || token->data.version_directive.minor != 1) { | 
|---|
| 1269 |                 yaml_parser_set_parser_error(parser, | 
|---|
| 1270 |                         "found incompatible YAML document", token->start_mark); | 
|---|
| 1271 |                 goto error; | 
|---|
| 1272 |             } | 
|---|
| 1273 |             version_directive = yaml_malloc(sizeof(yaml_version_directive_t)); | 
|---|
| 1274 |             if (!version_directive) { | 
|---|
| 1275 |                 parser->error = YAML_MEMORY_ERROR; | 
|---|
| 1276 |                 goto error; | 
|---|
| 1277 |             } | 
|---|
| 1278 |             version_directive->major = token->data.version_directive.major; | 
|---|
| 1279 |             version_directive->minor = token->data.version_directive.minor; | 
|---|
| 1280 |         } | 
|---|
| 1281 |  | 
|---|
| 1282 |         else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { | 
|---|
| 1283 |             yaml_tag_directive_t value = { | 
|---|
| 1284 |                 token->data.tag_directive.handle, | 
|---|
| 1285 |                 token->data.tag_directive.prefix | 
|---|
| 1286 |             }; | 
|---|
| 1287 |             if (!yaml_parser_append_tag_directive(parser, value, 0, | 
|---|
| 1288 |                         token->start_mark)) | 
|---|
| 1289 |                 goto error; | 
|---|
| 1290 |             if (!PUSH(parser, tag_directives, value)) | 
|---|
| 1291 |                 goto error; | 
|---|
| 1292 |         } | 
|---|
| 1293 |  | 
|---|
| 1294 |         SKIP_TOKEN(parser); | 
|---|
| 1295 |         token = PEEK_TOKEN(parser); | 
|---|
| 1296 |         if (!token) goto error; | 
|---|
| 1297 |     } | 
|---|
| 1298 |      | 
|---|
| 1299 |     for (default_tag_directive = default_tag_directives; | 
|---|
| 1300 |             default_tag_directive->handle; default_tag_directive++) { | 
|---|
| 1301 |         if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, | 
|---|
| 1302 |                     token->start_mark)) | 
|---|
| 1303 |             goto error; | 
|---|
| 1304 |     } | 
|---|
| 1305 |  | 
|---|
| 1306 |     if (version_directive_ref) { | 
|---|
| 1307 |         *version_directive_ref = version_directive; | 
|---|
| 1308 |     } | 
|---|
| 1309 |     if (tag_directives_start_ref) { | 
|---|
| 1310 |         if (STACK_EMPTY(parser, tag_directives)) { | 
|---|
| 1311 |             *tag_directives_start_ref = *tag_directives_end_ref = NULL; | 
|---|
| 1312 |             STACK_DEL(parser, tag_directives); | 
|---|
| 1313 |         } | 
|---|
| 1314 |         else { | 
|---|
| 1315 |             *tag_directives_start_ref = tag_directives.start; | 
|---|
| 1316 |             *tag_directives_end_ref = tag_directives.top; | 
|---|
| 1317 |         } | 
|---|
| 1318 |     } | 
|---|
| 1319 |     else { | 
|---|
| 1320 |         STACK_DEL(parser, tag_directives); | 
|---|
| 1321 |     } | 
|---|
| 1322 |  | 
|---|
| 1323 |     return 1; | 
|---|
| 1324 |  | 
|---|
| 1325 | error: | 
|---|
| 1326 |     yaml_free(version_directive); | 
|---|
| 1327 |     while (!STACK_EMPTY(parser, tag_directives)) { | 
|---|
| 1328 |         yaml_tag_directive_t tag_directive = POP(parser, tag_directives); | 
|---|
| 1329 |         yaml_free(tag_directive.handle); | 
|---|
| 1330 |         yaml_free(tag_directive.prefix); | 
|---|
| 1331 |     } | 
|---|
| 1332 |     STACK_DEL(parser, tag_directives); | 
|---|
| 1333 |     return 0; | 
|---|
| 1334 | } | 
|---|
| 1335 |  | 
|---|
| 1336 | /* | 
|---|
| 1337 |  * Append a tag directive to the directives stack. | 
|---|
| 1338 |  */ | 
|---|
| 1339 |  | 
|---|
| 1340 | static int | 
|---|
| 1341 | yaml_parser_append_tag_directive(yaml_parser_t *parser, | 
|---|
| 1342 |         yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) | 
|---|
| 1343 | { | 
|---|
| 1344 |     yaml_tag_directive_t *tag_directive; | 
|---|
| 1345 |     yaml_tag_directive_t copy = { NULL, NULL }; | 
|---|
| 1346 |  | 
|---|
| 1347 |     for (tag_directive = parser->tag_directives.start; | 
|---|
| 1348 |             tag_directive != parser->tag_directives.top; tag_directive ++) { | 
|---|
| 1349 |         if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { | 
|---|
| 1350 |             if (allow_duplicates) | 
|---|
| 1351 |                 return 1; | 
|---|
| 1352 |             return yaml_parser_set_parser_error(parser, | 
|---|
| 1353 |                     "found duplicate %TAG directive", mark); | 
|---|
| 1354 |         } | 
|---|
| 1355 |     } | 
|---|
| 1356 |  | 
|---|
| 1357 |     copy.handle = yaml_strdup(value.handle); | 
|---|
| 1358 |     copy.prefix = yaml_strdup(value.prefix); | 
|---|
| 1359 |     if (!copy.handle || !copy.prefix) { | 
|---|
| 1360 |         parser->error = YAML_MEMORY_ERROR; | 
|---|
| 1361 |         goto error; | 
|---|
| 1362 |     } | 
|---|
| 1363 |  | 
|---|
| 1364 |     if (!PUSH(parser, parser->tag_directives, copy)) | 
|---|
| 1365 |         goto error; | 
|---|
| 1366 |  | 
|---|
| 1367 |     return 1; | 
|---|
| 1368 |  | 
|---|
| 1369 | error: | 
|---|
| 1370 |     yaml_free(copy.handle); | 
|---|
| 1371 |     yaml_free(copy.prefix); | 
|---|
| 1372 |     return 0; | 
|---|
| 1373 | } | 
|---|
| 1374 |  | 
|---|