Ruby  2.4.2p198(2017-09-14revision59899)
loader.c
Go to the documentation of this file.
1 
2 #include "yaml_private.h"
3 
4 /*
5  * API functions.
6  */
7 
8 YAML_DECLARE(int)
10 
11 /*
12  * Error handling.
13  */
14 
15 static int
17  const char *problem, yaml_mark_t problem_mark);
18 
19 static int
21  const char *context, yaml_mark_t context_mark,
22  const char *problem, yaml_mark_t problem_mark);
23 
24 
25 /*
26  * Alias handling.
27  */
28 
29 static int
31  int index, yaml_char_t *anchor);
32 
33 /*
34  * Clean up functions.
35  */
36 
37 static void
39 
40 /*
41  * Composer functions.
42  */
43 
44 static int
46 
47 static int
48 yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
49 
50 static int
52 
53 static int
55 
56 static int
58 
59 static int
61 
62 /*
63  * Load the next document of the stream.
64  */
65 
66 YAML_DECLARE(int)
68 {
69  yaml_event_t event;
70 
71  assert(parser); /* Non-NULL parser object is expected. */
72  assert(document); /* Non-NULL document object is expected. */
73 
74  memset(document, 0, sizeof(yaml_document_t));
75  if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
76  goto error;
77 
78  if (!parser->stream_start_produced) {
79  if (!yaml_parser_parse(parser, &event)) goto error;
81  /* STREAM-START is expected. */
82  }
83 
84  if (parser->stream_end_produced) {
85  return 1;
86  }
87 
88  if (!yaml_parser_parse(parser, &event)) goto error;
89  if (event.type == YAML_STREAM_END_EVENT) {
90  return 1;
91  }
92 
93  if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
94  goto error;
95 
96  parser->document = document;
97 
98  if (!yaml_parser_load_document(parser, &event)) goto error;
99 
101  parser->document = NULL;
102 
103  return 1;
104 
105 error:
106 
108  yaml_document_delete(document);
109  parser->document = NULL;
110 
111  return 0;
112 }
113 
114 /*
115  * Set composer error.
116  */
117 
118 static int
120  const char *problem, yaml_mark_t problem_mark)
121 {
122  parser->error = YAML_COMPOSER_ERROR;
123  parser->problem = problem;
124  parser->problem_mark = problem_mark;
125 
126  return 0;
127 }
128 
129 /*
130  * Set composer error with context.
131  */
132 
133 static int
135  const char *context, yaml_mark_t context_mark,
136  const char *problem, yaml_mark_t problem_mark)
137 {
138  parser->error = YAML_COMPOSER_ERROR;
139  parser->context = context;
140  parser->context_mark = context_mark;
141  parser->problem = problem;
142  parser->problem_mark = problem_mark;
143 
144  return 0;
145 }
146 
147 /*
148  * Delete the stack of aliases.
149  */
150 
151 static void
153 {
154  while (!STACK_EMPTY(parser, parser->aliases)) {
155  yaml_free(POP(parser, parser->aliases).anchor);
156  }
157  STACK_DEL(parser, parser->aliases);
158 }
159 
160 /*
161  * Compose a document object.
162  */
163 
164 static int
166 {
167  yaml_event_t event;
168 
169  assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170  /* DOCUMENT-START is expected. */
171 
172  parser->document->version_directive
173  = first_event->data.document_start.version_directive;
174  parser->document->tag_directives.start
175  = first_event->data.document_start.tag_directives.start;
176  parser->document->tag_directives.end
177  = first_event->data.document_start.tag_directives.end;
178  parser->document->start_implicit
179  = first_event->data.document_start.implicit;
180  parser->document->start_mark = first_event->start_mark;
181 
182  if (!yaml_parser_parse(parser, &event)) return 0;
183 
184  if (!yaml_parser_load_node(parser, &event)) return 0;
185 
186  if (!yaml_parser_parse(parser, &event)) return 0;
188  /* DOCUMENT-END is expected. */
189 
190  parser->document->end_implicit = event.data.document_end.implicit;
191  parser->document->end_mark = event.end_mark;
192 
193  return 1;
194 }
195 
196 /*
197  * Compose a node.
198  */
199 
200 static int
202 {
203  switch (first_event->type) {
204  case YAML_ALIAS_EVENT:
205  return yaml_parser_load_alias(parser, first_event);
206  case YAML_SCALAR_EVENT:
207  return yaml_parser_load_scalar(parser, first_event);
209  return yaml_parser_load_sequence(parser, first_event);
211  return yaml_parser_load_mapping(parser, first_event);
212  default:
213  assert(0); /* Could not happen. */
214  return 0;
215  }
216 
217  return 0;
218 }
219 
220 /*
221  * Add an anchor.
222  */
223 
224 static int
226  int index, yaml_char_t *anchor)
227 {
228  yaml_alias_data_t data;
229  yaml_alias_data_t *alias_data;
230 
231  if (!anchor) return 1;
232 
233  data.anchor = anchor;
234  data.index = index;
235  data.mark = parser->document->nodes.start[index-1].start_mark;
236 
237  for (alias_data = parser->aliases.start;
238  alias_data != parser->aliases.top; alias_data ++) {
239  if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
240  yaml_free(anchor);
242  "found duplicate anchor; first occurrence",
243  alias_data->mark, "second occurrence", data.mark);
244  }
245  }
246 
247  if (!PUSH(parser, parser->aliases, data)) {
248  yaml_free(anchor);
249  return 0;
250  }
251 
252  return 1;
253 }
254 
255 /*
256  * Compose a node corresponding to an alias.
257  */
258 
259 static int
261 {
262  yaml_char_t *anchor = first_event->data.alias.anchor;
263  yaml_alias_data_t *alias_data;
264 
265  for (alias_data = parser->aliases.start;
266  alias_data != parser->aliases.top; alias_data ++) {
267  if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
268  yaml_free(anchor);
269  return alias_data->index;
270  }
271  }
272 
273  yaml_free(anchor);
274  return yaml_parser_set_composer_error(parser, "found undefined alias",
275  first_event->start_mark);
276 }
277 
278 /*
279  * Compose a scalar node.
280  */
281 
282 static int
284 {
285  yaml_node_t node;
286  int index;
287  yaml_char_t *tag = first_event->data.scalar.tag;
288 
289  if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
290 
291  if (!tag || strcmp((char *)tag, "!") == 0) {
292  yaml_free(tag);
294  if (!tag) goto error;
295  }
296 
297  SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
298  first_event->data.scalar.length, first_event->data.scalar.style,
299  first_event->start_mark, first_event->end_mark);
300 
301  if (!PUSH(parser, parser->document->nodes, node)) goto error;
302 
303  index = parser->document->nodes.top - parser->document->nodes.start;
304 
305  if (!yaml_parser_register_anchor(parser, index,
306  first_event->data.scalar.anchor)) return 0;
307 
308  return index;
309 
310 error:
311  yaml_free(tag);
312  yaml_free(first_event->data.scalar.anchor);
313  yaml_free(first_event->data.scalar.value);
314  return 0;
315 }
316 
317 /*
318  * Compose a sequence node.
319  */
320 
321 static int
323 {
324  yaml_event_t event;
325  yaml_node_t node;
326  struct {
327  yaml_node_item_t *start;
328  yaml_node_item_t *end;
330  } items = { NULL, NULL, NULL };
331  int index, item_index;
332  yaml_char_t *tag = first_event->data.sequence_start.tag;
333 
334  if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
335 
336  if (!tag || strcmp((char *)tag, "!") == 0) {
337  yaml_free(tag);
339  if (!tag) goto error;
340  }
341 
342  if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
343 
344  SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
345  first_event->data.sequence_start.style,
346  first_event->start_mark, first_event->end_mark);
347 
348  if (!PUSH(parser, parser->document->nodes, node)) goto error;
349 
350  index = parser->document->nodes.top - parser->document->nodes.start;
351 
352  if (!yaml_parser_register_anchor(parser, index,
353  first_event->data.sequence_start.anchor)) return 0;
354 
355  if (!yaml_parser_parse(parser, &event)) return 0;
356 
357  while (event.type != YAML_SEQUENCE_END_EVENT) {
358  if (!STACK_LIMIT(parser,
359  parser->document->nodes.start[index-1].data.sequence.items,
360  INT_MAX-1)) return 0;
361  item_index = yaml_parser_load_node(parser, &event);
362  if (!item_index) return 0;
363  if (!PUSH(parser,
364  parser->document->nodes.start[index-1].data.sequence.items,
365  item_index)) return 0;
366  if (!yaml_parser_parse(parser, &event)) return 0;
367  }
368 
369  parser->document->nodes.start[index-1].end_mark = event.end_mark;
370 
371  return index;
372 
373 error:
374  yaml_free(tag);
375  yaml_free(first_event->data.sequence_start.anchor);
376  return 0;
377 }
378 
379 /*
380  * Compose a mapping node.
381  */
382 
383 static int
385 {
386  yaml_event_t event;
387  yaml_node_t node;
388  struct {
389  yaml_node_pair_t *start;
390  yaml_node_pair_t *end;
392  } pairs = { NULL, NULL, NULL };
393  int index;
394  yaml_node_pair_t pair;
395  yaml_char_t *tag = first_event->data.mapping_start.tag;
396 
397  if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
398 
399  if (!tag || strcmp((char *)tag, "!") == 0) {
400  yaml_free(tag);
402  if (!tag) goto error;
403  }
404 
405  if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
406 
407  MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
408  first_event->data.mapping_start.style,
409  first_event->start_mark, first_event->end_mark);
410 
411  if (!PUSH(parser, parser->document->nodes, node)) goto error;
412 
413  index = parser->document->nodes.top - parser->document->nodes.start;
414 
415  if (!yaml_parser_register_anchor(parser, index,
416  first_event->data.mapping_start.anchor)) return 0;
417 
418  if (!yaml_parser_parse(parser, &event)) return 0;
419 
420  while (event.type != YAML_MAPPING_END_EVENT) {
421  if (!STACK_LIMIT(parser,
422  parser->document->nodes.start[index-1].data.mapping.pairs,
423  INT_MAX-1)) return 0;
424  pair.key = yaml_parser_load_node(parser, &event);
425  if (!pair.key) return 0;
426  if (!yaml_parser_parse(parser, &event)) return 0;
427  pair.value = yaml_parser_load_node(parser, &event);
428  if (!pair.value) return 0;
429  if (!PUSH(parser,
430  parser->document->nodes.start[index-1].data.mapping.pairs,
431  pair)) return 0;
432  if (!yaml_parser_parse(parser, &event)) return 0;
433  }
434 
435  parser->document->nodes.start[index-1].end_mark = event.end_mark;
436 
437  return index;
438 
439 error:
440  yaml_free(tag);
441  yaml_free(first_event->data.mapping_start.anchor);
442  return 0;
443 }
444 
yaml_strdup(const yaml_char_t *str)
Definition: api.c:61
static int yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:322
yaml_mark_t mark
The anchor mark.
Definition: yaml.h:1071
#define PUSH(x)
Definition: bigdecimal.c:69
yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
Parse the input stream and produce the next parsing event.
Definition: parser.c:170
The pointer position.
Definition: yaml.h:145
The event structure.
Definition: yaml.h:384
yaml_version_directive_t * version_directive
The version directive.
Definition: yaml.h:791
int end_implicit
Is the document end indicator implicit?
Definition: yaml.h:804
yaml_mark_t start_mark
The beginning of the node.
Definition: yaml.h:771
A SEQUENCE-START event.
Definition: yaml.h:373
Cannot compose a YAML document.
Definition: yaml.h:136
static int yaml_parser_register_anchor(yaml_parser_t *parser, int index, yaml_char_t *anchor)
Definition: loader.c:225
A MAPPING-START event.
Definition: yaml.h:378
struct yaml_document_s::@74 tag_directives
The list of tag directives.
The parser structure.
Definition: yaml.h:1081
yaml_node_t * end
The end of the stack.
Definition: yaml.h:785
yaml_mark_t end_mark
The end of the event.
Definition: yaml.h:474
#define INITIAL_STACK_SIZE
Definition: yaml_private.h:87
struct yaml_event_s::@58::@64 sequence_start
The sequence parameters (for YAML_SEQUENCE_START_EVENT).
unsigned char yaml_char_t
The character type (UTF-8 octet).
Definition: yaml.h:78
const unsigned char * start
The string start pointer.
Definition: yaml.h:1123
const char * context
The error context.
Definition: yaml.h:1099
#define STACK_LIMIT(context, stack, size)
Definition: yaml_private.h:441
union yaml_event_s::@58 data
The event data.
#define assert(x)
Definition: dlmalloc.c:1176
static int yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:165
An element of a mapping node.
Definition: yaml.h:709
#define SCALAR_NODE_INIT(node, node_tag, node_value, node_length, node_style, start_mark, end_mark)
Definition: yaml_private.h:641
yaml_document_delete(yaml_document_t *document)
Delete a YAML document and all its nodes.
Definition: api.c:1117
int yaml_node_item_t
An element of a sequence node.
Definition: yaml.h:706
The node structure.
Definition: yaml.h:717
yaml_char_t * anchor
The anchor.
Definition: yaml.h:1067
#define STACK_EMPTY(context, stack)
Definition: yaml_private.h:438
int key
The key of the element.
Definition: yaml.h:711
yaml_free(void *ptr)
Definition: api.c:51
#define YAML_DEFAULT_SEQUENCE_TAG
The default sequence tag is !!seq.
Definition: yaml.h:685
static int yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:260
static int yaml_parser_set_composer_error(yaml_parser_t *parser, const char *problem, yaml_mark_t problem_mark)
Definition: loader.c:119
int * top
The top of the stack.
Definition: yaml.h:1216
struct yaml_parser_s::@84 aliases
The alias data.
#define MAPPING_NODE_INIT(node, node_tag, node_pairs_start, node_pairs_end, node_style, start_mark, end_mark)
Definition: yaml_private.h:656
int index
The node id.
Definition: yaml.h:1069
union yaml_node_s::@67 data
The node data.
static int yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:384
yaml_mark_t end_mark
The end of the node.
Definition: yaml.h:773
struct yaml_node_s::@67::@69 sequence
The sequence parameters (for YAML_SEQUENCE_NODE).
A DOCUMENT-START event.
Definition: yaml.h:363
#define YAML_DECLARE(type)
The public API declaration.
Definition: yaml.h:38
static void yaml_parser_delete_aliases(yaml_parser_t *parser)
Definition: loader.c:152
A MAPPING-END event.
Definition: yaml.h:380
#define STACK_DEL(context, stack)
Definition: yaml_private.h:434
yaml_node_t * top
The top of the stack.
Definition: yaml.h:787
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
Parse the input stream and produce the next YAML document.
Definition: loader.c:67
This structure holds aliases data.
Definition: yaml.h:1065
yaml_error_type_t error
Error type.
Definition: yaml.h:1089
int start_implicit
Is the document start indicator implicit?
Definition: yaml.h:802
A SEQUENCE-END event.
Definition: yaml.h:375
int value
The value of the element.
Definition: yaml.h:713
yaml_node_item_t * start
The beginning of the stack.
Definition: yaml.h:743
yaml_mark_t start_mark
The beginning of the document.
Definition: yaml.h:807
static int yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:283
yaml_mark_t context_mark
The context position.
Definition: yaml.h:1101
yaml_mark_t problem_mark
The problem position.
Definition: yaml.h:1097
static int yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
Definition: loader.c:201
unsigned int top
Definition: nkf.c:4310
A DOCUMENT-END event.
Definition: yaml.h:365
struct yaml_event_s::@58::@60 document_start
The document parameters (for YAML_DOCUMENT_START_EVENT).
#define YAML_DEFAULT_SCALAR_TAG
The default scalar tag is !!str.
Definition: yaml.h:683
A SCALAR event.
Definition: yaml.h:370
A STREAM-END event.
Definition: yaml.h:360
struct yaml_document_s::@73 nodes
The document nodes.
#define POP(context, stack)
Definition: yaml_private.h:456
yaml_node_t * start
The beginning of the stack.
Definition: yaml.h:783
static int yaml_parser_set_composer_error_context(yaml_parser_t *parser, const char *context, yaml_mark_t context_mark, const char *problem, yaml_mark_t problem_mark)
Definition: loader.c:134
struct yaml_event_s::@58::@62 alias
The alias parameters (for YAML_ALIAS_EVENT).
struct yaml_event_s::@58::@63 scalar
The scalar parameters (for YAML_SCALAR_EVENT).
yaml_document_t * document
The currently parsed document.
Definition: yaml.h:1297
#define SEQUENCE_NODE_INIT(node, node_tag, node_items_start, node_items_end, node_style, start_mark, end_mark)
Definition: yaml_private.h:648
A STREAM-START event.
Definition: yaml.h:358
const char * problem
Error description.
Definition: yaml.h:1091
#define STACK_INIT(context, stack, size)
Definition: yaml_private.h:426
#define YAML_DEFAULT_MAPPING_TAG
The default mapping tag is !!map.
Definition: yaml.h:687
#define NULL
Definition: _sdbm.c:102
The document structure.
Definition: yaml.h:778
yaml_event_type_t type
The event type.
Definition: yaml.h:387
struct yaml_event_s::@58::@65 mapping_start
The mapping parameters (for YAML_MAPPING_START_EVENT).
yaml_mark_t end_mark
The end of the document.
Definition: yaml.h:809
An ALIAS event.
Definition: yaml.h:368
yaml_mark_t start_mark
The beginning of the event.
Definition: yaml.h:472
struct yaml_node_s::@67::@70 mapping
The mapping parameters (for YAML_MAPPING_NODE).