loader.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. #include "yaml_private.h"
  2. /*
  3. * API functions.
  4. */
  5. YAML_DECLARE(int)
  6. yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
  7. /*
  8. * Error handling.
  9. */
  10. static int
  11. yaml_parser_set_composer_error(yaml_parser_t *parser,
  12. const char *problem, yaml_mark_t problem_mark);
  13. static int
  14. yaml_parser_set_composer_error_context(yaml_parser_t *parser,
  15. const char *context, yaml_mark_t context_mark,
  16. const char *problem, yaml_mark_t problem_mark);
  17. /*
  18. * Alias handling.
  19. */
  20. static int
  21. yaml_parser_register_anchor(yaml_parser_t *parser,
  22. int index, yaml_char_t *anchor);
  23. /*
  24. * Clean up functions.
  25. */
  26. static void
  27. yaml_parser_delete_aliases(yaml_parser_t *parser);
  28. /*
  29. * Composer functions.
  30. */
  31. static int
  32. yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
  33. static int
  34. yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
  35. static int
  36. yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
  37. static int
  38. yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
  39. static int
  40. yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
  41. static int
  42. yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
  43. /*
  44. * Load the next document of the stream.
  45. */
  46. YAML_DECLARE(int)
  47. yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
  48. {
  49. yaml_event_t event;
  50. assert(parser); /* Non-NULL parser object is expected. */
  51. assert(document); /* Non-NULL document object is expected. */
  52. memset(document, 0, sizeof(yaml_document_t));
  53. if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
  54. goto error;
  55. if (!parser->stream_start_produced) {
  56. if (!yaml_parser_parse(parser, &event)) goto error;
  57. assert(event.type == YAML_STREAM_START_EVENT);
  58. /* STREAM-START is expected. */
  59. }
  60. if (parser->stream_end_produced) {
  61. return 1;
  62. }
  63. if (!yaml_parser_parse(parser, &event)) goto error;
  64. if (event.type == YAML_STREAM_END_EVENT) {
  65. return 1;
  66. }
  67. if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
  68. goto error;
  69. parser->document = document;
  70. if (!yaml_parser_load_document(parser, &event)) goto error;
  71. yaml_parser_delete_aliases(parser);
  72. parser->document = NULL;
  73. return 1;
  74. error:
  75. yaml_parser_delete_aliases(parser);
  76. yaml_document_delete(document);
  77. parser->document = NULL;
  78. return 0;
  79. }
  80. /*
  81. * Set composer error.
  82. */
  83. static int
  84. yaml_parser_set_composer_error(yaml_parser_t *parser,
  85. const char *problem, yaml_mark_t problem_mark)
  86. {
  87. parser->error = YAML_COMPOSER_ERROR;
  88. parser->problem = problem;
  89. parser->problem_mark = problem_mark;
  90. return 0;
  91. }
  92. /*
  93. * Set composer error with context.
  94. */
  95. static int
  96. yaml_parser_set_composer_error_context(yaml_parser_t *parser,
  97. const char *context, yaml_mark_t context_mark,
  98. const char *problem, yaml_mark_t problem_mark)
  99. {
  100. parser->error = YAML_COMPOSER_ERROR;
  101. parser->context = context;
  102. parser->context_mark = context_mark;
  103. parser->problem = problem;
  104. parser->problem_mark = problem_mark;
  105. return 0;
  106. }
  107. /*
  108. * Delete the stack of aliases.
  109. */
  110. static void
  111. yaml_parser_delete_aliases(yaml_parser_t *parser)
  112. {
  113. while (!STACK_EMPTY(parser, parser->aliases)) {
  114. yaml_free(POP(parser, parser->aliases).anchor);
  115. }
  116. STACK_DEL(parser, parser->aliases);
  117. }
  118. /*
  119. * Compose a document object.
  120. */
  121. static int
  122. yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
  123. {
  124. yaml_event_t event;
  125. assert(first_event->type == YAML_DOCUMENT_START_EVENT);
  126. /* DOCUMENT-START is expected. */
  127. parser->document->version_directive
  128. = first_event->data.document_start.version_directive;
  129. parser->document->tag_directives.start
  130. = first_event->data.document_start.tag_directives.start;
  131. parser->document->tag_directives.end
  132. = first_event->data.document_start.tag_directives.end;
  133. parser->document->start_implicit
  134. = first_event->data.document_start.implicit;
  135. parser->document->start_mark = first_event->start_mark;
  136. if (!yaml_parser_parse(parser, &event)) return 0;
  137. if (!yaml_parser_load_node(parser, &event)) return 0;
  138. if (!yaml_parser_parse(parser, &event)) return 0;
  139. assert(event.type == YAML_DOCUMENT_END_EVENT);
  140. /* DOCUMENT-END is expected. */
  141. parser->document->end_implicit = event.data.document_end.implicit;
  142. parser->document->end_mark = event.end_mark;
  143. return 1;
  144. }
  145. /*
  146. * Compose a node.
  147. */
  148. static int
  149. yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
  150. {
  151. switch (first_event->type) {
  152. case YAML_ALIAS_EVENT:
  153. return yaml_parser_load_alias(parser, first_event);
  154. case YAML_SCALAR_EVENT:
  155. return yaml_parser_load_scalar(parser, first_event);
  156. case YAML_SEQUENCE_START_EVENT:
  157. return yaml_parser_load_sequence(parser, first_event);
  158. case YAML_MAPPING_START_EVENT:
  159. return yaml_parser_load_mapping(parser, first_event);
  160. default:
  161. assert(0); /* Could not happen. */
  162. return 0;
  163. }
  164. return 0;
  165. }
  166. /*
  167. * Add an anchor.
  168. */
  169. static int
  170. yaml_parser_register_anchor(yaml_parser_t *parser,
  171. int index, yaml_char_t *anchor)
  172. {
  173. yaml_alias_data_t data;
  174. yaml_alias_data_t *alias_data;
  175. if (!anchor) return 1;
  176. data.anchor = anchor;
  177. data.index = index;
  178. data.mark = parser->document->nodes.start[index-1].start_mark;
  179. for (alias_data = parser->aliases.start;
  180. alias_data != parser->aliases.top; alias_data ++) {
  181. if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
  182. yaml_free(anchor);
  183. return yaml_parser_set_composer_error_context(parser,
  184. "found duplicate anchor; first occurence",
  185. alias_data->mark, "second occurence", data.mark);
  186. }
  187. }
  188. if (!PUSH(parser, parser->aliases, data)) {
  189. yaml_free(anchor);
  190. return 0;
  191. }
  192. return 1;
  193. }
  194. /*
  195. * Compose a node corresponding to an alias.
  196. */
  197. static int
  198. yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
  199. {
  200. yaml_char_t *anchor = first_event->data.alias.anchor;
  201. yaml_alias_data_t *alias_data;
  202. for (alias_data = parser->aliases.start;
  203. alias_data != parser->aliases.top; alias_data ++) {
  204. if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
  205. yaml_free(anchor);
  206. return alias_data->index;
  207. }
  208. }
  209. yaml_free(anchor);
  210. return yaml_parser_set_composer_error(parser, "found undefined alias",
  211. first_event->start_mark);
  212. }
  213. /*
  214. * Compose a scalar node.
  215. */
  216. static int
  217. yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
  218. {
  219. yaml_node_t node;
  220. int index;
  221. yaml_char_t *tag = first_event->data.scalar.tag;
  222. if (!tag || strcmp((char *)tag, "!") == 0) {
  223. yaml_free(tag);
  224. tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
  225. if (!tag) goto error;
  226. }
  227. SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
  228. first_event->data.scalar.length, first_event->data.scalar.style,
  229. first_event->start_mark, first_event->end_mark);
  230. if (!PUSH(parser, parser->document->nodes, node)) goto error;
  231. index = parser->document->nodes.top - parser->document->nodes.start;
  232. if (!yaml_parser_register_anchor(parser, index,
  233. first_event->data.scalar.anchor)) return 0;
  234. return index;
  235. error:
  236. yaml_free(tag);
  237. yaml_free(first_event->data.scalar.anchor);
  238. yaml_free(first_event->data.scalar.value);
  239. return 0;
  240. }
  241. /*
  242. * Compose a sequence node.
  243. */
  244. static int
  245. yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
  246. {
  247. yaml_event_t event;
  248. yaml_node_t node;
  249. struct {
  250. yaml_node_item_t *start;
  251. yaml_node_item_t *end;
  252. yaml_node_item_t *top;
  253. } items = { NULL, NULL, NULL };
  254. int index, item_index;
  255. yaml_char_t *tag = first_event->data.sequence_start.tag;
  256. if (!tag || strcmp((char *)tag, "!") == 0) {
  257. yaml_free(tag);
  258. tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
  259. if (!tag) goto error;
  260. }
  261. if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
  262. SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
  263. first_event->data.sequence_start.style,
  264. first_event->start_mark, first_event->end_mark);
  265. if (!PUSH(parser, parser->document->nodes, node)) goto error;
  266. index = parser->document->nodes.top - parser->document->nodes.start;
  267. if (!yaml_parser_register_anchor(parser, index,
  268. first_event->data.sequence_start.anchor)) return 0;
  269. if (!yaml_parser_parse(parser, &event)) return 0;
  270. while (event.type != YAML_SEQUENCE_END_EVENT) {
  271. item_index = yaml_parser_load_node(parser, &event);
  272. if (!item_index) return 0;
  273. if (!PUSH(parser,
  274. parser->document->nodes.start[index-1].data.sequence.items,
  275. item_index)) return 0;
  276. if (!yaml_parser_parse(parser, &event)) return 0;
  277. }
  278. parser->document->nodes.start[index-1].end_mark = event.end_mark;
  279. return index;
  280. error:
  281. yaml_free(tag);
  282. yaml_free(first_event->data.sequence_start.anchor);
  283. return 0;
  284. }
  285. /*
  286. * Compose a mapping node.
  287. */
  288. static int
  289. yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
  290. {
  291. yaml_event_t event;
  292. yaml_node_t node;
  293. struct {
  294. yaml_node_pair_t *start;
  295. yaml_node_pair_t *end;
  296. yaml_node_pair_t *top;
  297. } pairs = { NULL, NULL, NULL };
  298. int index;
  299. yaml_node_pair_t pair;
  300. yaml_char_t *tag = first_event->data.mapping_start.tag;
  301. if (!tag || strcmp((char *)tag, "!") == 0) {
  302. yaml_free(tag);
  303. tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
  304. if (!tag) goto error;
  305. }
  306. if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
  307. MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
  308. first_event->data.mapping_start.style,
  309. first_event->start_mark, first_event->end_mark);
  310. if (!PUSH(parser, parser->document->nodes, node)) goto error;
  311. index = parser->document->nodes.top - parser->document->nodes.start;
  312. if (!yaml_parser_register_anchor(parser, index,
  313. first_event->data.mapping_start.anchor)) return 0;
  314. if (!yaml_parser_parse(parser, &event)) return 0;
  315. while (event.type != YAML_MAPPING_END_EVENT) {
  316. pair.key = yaml_parser_load_node(parser, &event);
  317. if (!pair.key) return 0;
  318. if (!yaml_parser_parse(parser, &event)) return 0;
  319. pair.value = yaml_parser_load_node(parser, &event);
  320. if (!pair.value) return 0;
  321. if (!PUSH(parser,
  322. parser->document->nodes.start[index-1].data.mapping.pairs,
  323. pair)) return 0;
  324. if (!yaml_parser_parse(parser, &event)) return 0;
  325. }
  326. parser->document->nodes.start[index-1].end_mark = event.end_mark;
  327. return index;
  328. error:
  329. yaml_free(tag);
  330. yaml_free(first_event->data.mapping_start.anchor);
  331. return 0;
  332. }