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