psych 2.0.14-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +7 -0
  2. data/.autotest +18 -0
  3. data/.gemtest +0 -0
  4. data/.travis.yml +16 -0
  5. data/CHANGELOG.rdoc +576 -0
  6. data/Manifest.txt +114 -0
  7. data/README.rdoc +71 -0
  8. data/Rakefile +123 -0
  9. data/ext/psych/depend +3 -0
  10. data/ext/psych/extconf.rb +38 -0
  11. data/ext/psych/psych.c +34 -0
  12. data/ext/psych/psych.h +20 -0
  13. data/ext/psych/psych_emitter.c +555 -0
  14. data/ext/psych/psych_emitter.h +8 -0
  15. data/ext/psych/psych_parser.c +597 -0
  16. data/ext/psych/psych_parser.h +6 -0
  17. data/ext/psych/psych_to_ruby.c +43 -0
  18. data/ext/psych/psych_to_ruby.h +8 -0
  19. data/ext/psych/psych_yaml_tree.c +24 -0
  20. data/ext/psych/psych_yaml_tree.h +8 -0
  21. data/ext/psych/yaml/LICENSE +19 -0
  22. data/ext/psych/yaml/api.c +1415 -0
  23. data/ext/psych/yaml/config.h +10 -0
  24. data/ext/psych/yaml/dumper.c +394 -0
  25. data/ext/psych/yaml/emitter.c +2329 -0
  26. data/ext/psych/yaml/loader.c +459 -0
  27. data/ext/psych/yaml/parser.c +1370 -0
  28. data/ext/psych/yaml/reader.c +469 -0
  29. data/ext/psych/yaml/scanner.c +3576 -0
  30. data/ext/psych/yaml/writer.c +141 -0
  31. data/ext/psych/yaml/yaml.h +1971 -0
  32. data/ext/psych/yaml/yaml_private.h +664 -0
  33. data/lib/psych.jar +0 -0
  34. data/lib/psych.rb +504 -0
  35. data/lib/psych/class_loader.rb +101 -0
  36. data/lib/psych/coder.rb +94 -0
  37. data/lib/psych/core_ext.rb +35 -0
  38. data/lib/psych/deprecated.rb +85 -0
  39. data/lib/psych/exception.rb +13 -0
  40. data/lib/psych/handler.rb +249 -0
  41. data/lib/psych/handlers/document_stream.rb +22 -0
  42. data/lib/psych/handlers/recorder.rb +39 -0
  43. data/lib/psych/json/ruby_events.rb +19 -0
  44. data/lib/psych/json/stream.rb +16 -0
  45. data/lib/psych/json/tree_builder.rb +12 -0
  46. data/lib/psych/json/yaml_events.rb +29 -0
  47. data/lib/psych/nodes.rb +77 -0
  48. data/lib/psych/nodes/alias.rb +18 -0
  49. data/lib/psych/nodes/document.rb +60 -0
  50. data/lib/psych/nodes/mapping.rb +56 -0
  51. data/lib/psych/nodes/node.rb +55 -0
  52. data/lib/psych/nodes/scalar.rb +67 -0
  53. data/lib/psych/nodes/sequence.rb +81 -0
  54. data/lib/psych/nodes/stream.rb +37 -0
  55. data/lib/psych/omap.rb +4 -0
  56. data/lib/psych/parser.rb +51 -0
  57. data/lib/psych/scalar_scanner.rb +149 -0
  58. data/lib/psych/set.rb +4 -0
  59. data/lib/psych/stream.rb +37 -0
  60. data/lib/psych/streaming.rb +27 -0
  61. data/lib/psych/syntax_error.rb +21 -0
  62. data/lib/psych/tree_builder.rb +96 -0
  63. data/lib/psych/versions.rb +3 -0
  64. data/lib/psych/visitors.rb +6 -0
  65. data/lib/psych/visitors/depth_first.rb +26 -0
  66. data/lib/psych/visitors/emitter.rb +51 -0
  67. data/lib/psych/visitors/json_tree.rb +24 -0
  68. data/lib/psych/visitors/to_ruby.rb +404 -0
  69. data/lib/psych/visitors/visitor.rb +19 -0
  70. data/lib/psych/visitors/yaml_tree.rb +605 -0
  71. data/lib/psych/y.rb +9 -0
  72. data/lib/psych_jars.rb +5 -0
  73. data/test/psych/handlers/test_recorder.rb +25 -0
  74. data/test/psych/helper.rb +121 -0
  75. data/test/psych/json/test_stream.rb +109 -0
  76. data/test/psych/nodes/test_enumerable.rb +43 -0
  77. data/test/psych/test_alias_and_anchor.rb +96 -0
  78. data/test/psych/test_array.rb +57 -0
  79. data/test/psych/test_boolean.rb +36 -0
  80. data/test/psych/test_class.rb +36 -0
  81. data/test/psych/test_coder.rb +206 -0
  82. data/test/psych/test_date_time.rb +38 -0
  83. data/test/psych/test_deprecated.rb +214 -0
  84. data/test/psych/test_document.rb +46 -0
  85. data/test/psych/test_emitter.rb +93 -0
  86. data/test/psych/test_encoding.rb +259 -0
  87. data/test/psych/test_exception.rb +157 -0
  88. data/test/psych/test_hash.rb +94 -0
  89. data/test/psych/test_json_tree.rb +65 -0
  90. data/test/psych/test_merge_keys.rb +180 -0
  91. data/test/psych/test_nil.rb +18 -0
  92. data/test/psych/test_null.rb +19 -0
  93. data/test/psych/test_numeric.rb +45 -0
  94. data/test/psych/test_object.rb +44 -0
  95. data/test/psych/test_object_references.rb +71 -0
  96. data/test/psych/test_omap.rb +75 -0
  97. data/test/psych/test_parser.rb +339 -0
  98. data/test/psych/test_psych.rb +168 -0
  99. data/test/psych/test_safe_load.rb +97 -0
  100. data/test/psych/test_scalar.rb +11 -0
  101. data/test/psych/test_scalar_scanner.rb +106 -0
  102. data/test/psych/test_serialize_subclasses.rb +38 -0
  103. data/test/psych/test_set.rb +49 -0
  104. data/test/psych/test_stream.rb +93 -0
  105. data/test/psych/test_string.rb +226 -0
  106. data/test/psych/test_struct.rb +49 -0
  107. data/test/psych/test_symbol.rb +25 -0
  108. data/test/psych/test_tainted.rb +130 -0
  109. data/test/psych/test_to_yaml_properties.rb +63 -0
  110. data/test/psych/test_tree_builder.rb +79 -0
  111. data/test/psych/test_yaml.rb +1292 -0
  112. data/test/psych/test_yamldbm.rb +193 -0
  113. data/test/psych/test_yamlstore.rb +85 -0
  114. data/test/psych/visitors/test_depth_first.rb +49 -0
  115. data/test/psych/visitors/test_emitter.rb +144 -0
  116. data/test/psych/visitors/test_to_ruby.rb +333 -0
  117. data/test/psych/visitors/test_yaml_tree.rb +173 -0
  118. metadata +240 -0
@@ -0,0 +1,10 @@
1
+ #define PACKAGE_NAME "yaml"
2
+ #define PACKAGE_TARNAME "yaml"
3
+ #define PACKAGE_VERSION "0.1.6"
4
+ #define PACKAGE_STRING "yaml 0.1.6"
5
+ #define PACKAGE_BUGREPORT "http://pyyaml.org/newticket?component libyaml"
6
+ #define PACKAGE_URL ""
7
+ #define YAML_VERSION_MAJOR 0
8
+ #define YAML_VERSION_MINOR 1
9
+ #define YAML_VERSION_PATCH 6
10
+ #define YAML_VERSION_STRING "0.1.6"
@@ -0,0 +1,394 @@
1
+
2
+ #include "yaml_private.h"
3
+
4
+ /*
5
+ * API functions.
6
+ */
7
+
8
+ YAML_DECLARE(int)
9
+ yaml_emitter_open(yaml_emitter_t *emitter);
10
+
11
+ YAML_DECLARE(int)
12
+ yaml_emitter_close(yaml_emitter_t *emitter);
13
+
14
+ YAML_DECLARE(int)
15
+ yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
16
+
17
+ /*
18
+ * Clean up functions.
19
+ */
20
+
21
+ static void
22
+ yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
23
+
24
+ /*
25
+ * Anchor functions.
26
+ */
27
+
28
+ static void
29
+ yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
30
+
31
+ static yaml_char_t *
32
+ yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
33
+
34
+
35
+ /*
36
+ * Serialize functions.
37
+ */
38
+
39
+ static int
40
+ yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
41
+
42
+ static int
43
+ yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
44
+
45
+ static int
46
+ yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
47
+ yaml_char_t *anchor);
48
+
49
+ static int
50
+ yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
51
+ yaml_char_t *anchor);
52
+
53
+ static int
54
+ yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
55
+ yaml_char_t *anchor);
56
+
57
+ /*
58
+ * Issue a STREAM-START event.
59
+ */
60
+
61
+ YAML_DECLARE(int)
62
+ yaml_emitter_open(yaml_emitter_t *emitter)
63
+ {
64
+ yaml_event_t event;
65
+ yaml_mark_t mark = { 0, 0, 0 };
66
+
67
+ assert(emitter); /* Non-NULL emitter object is required. */
68
+ assert(!emitter->opened); /* Emitter should not be opened yet. */
69
+
70
+ STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
71
+
72
+ if (!yaml_emitter_emit(emitter, &event)) {
73
+ return 0;
74
+ }
75
+
76
+ emitter->opened = 1;
77
+
78
+ return 1;
79
+ }
80
+
81
+ /*
82
+ * Issue a STREAM-END event.
83
+ */
84
+
85
+ YAML_DECLARE(int)
86
+ yaml_emitter_close(yaml_emitter_t *emitter)
87
+ {
88
+ yaml_event_t event;
89
+ yaml_mark_t mark = { 0, 0, 0 };
90
+
91
+ assert(emitter); /* Non-NULL emitter object is required. */
92
+ assert(emitter->opened); /* Emitter should be opened. */
93
+
94
+ if (emitter->closed) return 1;
95
+
96
+ STREAM_END_EVENT_INIT(event, mark, mark);
97
+
98
+ if (!yaml_emitter_emit(emitter, &event)) {
99
+ return 0;
100
+ }
101
+
102
+ emitter->closed = 1;
103
+
104
+ return 1;
105
+ }
106
+
107
+ /*
108
+ * Dump a YAML document.
109
+ */
110
+
111
+ YAML_DECLARE(int)
112
+ yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
113
+ {
114
+ yaml_event_t event;
115
+ yaml_mark_t mark = { 0, 0, 0 };
116
+
117
+ assert(emitter); /* Non-NULL emitter object is required. */
118
+ assert(document); /* Non-NULL emitter object is expected. */
119
+
120
+ emitter->document = document;
121
+
122
+ if (!emitter->opened) {
123
+ if (!yaml_emitter_open(emitter)) goto error;
124
+ }
125
+
126
+ if (STACK_EMPTY(emitter, document->nodes)) {
127
+ if (!yaml_emitter_close(emitter)) goto error;
128
+ yaml_emitter_delete_document_and_anchors(emitter);
129
+ return 1;
130
+ }
131
+
132
+ assert(emitter->opened); /* Emitter should be opened. */
133
+
134
+ emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
135
+ * (document->nodes.top - document->nodes.start));
136
+ if (!emitter->anchors) goto error;
137
+ memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
138
+ * (document->nodes.top - document->nodes.start));
139
+
140
+ DOCUMENT_START_EVENT_INIT(event, document->version_directive,
141
+ document->tag_directives.start, document->tag_directives.end,
142
+ document->start_implicit, mark, mark);
143
+ if (!yaml_emitter_emit(emitter, &event)) goto error;
144
+
145
+ yaml_emitter_anchor_node(emitter, 1);
146
+ if (!yaml_emitter_dump_node(emitter, 1)) goto error;
147
+
148
+ DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
149
+ if (!yaml_emitter_emit(emitter, &event)) goto error;
150
+
151
+ yaml_emitter_delete_document_and_anchors(emitter);
152
+
153
+ return 1;
154
+
155
+ error:
156
+
157
+ yaml_emitter_delete_document_and_anchors(emitter);
158
+
159
+ return 0;
160
+ }
161
+
162
+ /*
163
+ * Clean up the emitter object after a document is dumped.
164
+ */
165
+
166
+ static void
167
+ yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
168
+ {
169
+ int index;
170
+
171
+ if (!emitter->anchors) {
172
+ yaml_document_delete(emitter->document);
173
+ emitter->document = NULL;
174
+ return;
175
+ }
176
+
177
+ for (index = 0; emitter->document->nodes.start + index
178
+ < emitter->document->nodes.top; index ++) {
179
+ yaml_node_t node = emitter->document->nodes.start[index];
180
+ if (!emitter->anchors[index].serialized) {
181
+ yaml_free(node.tag);
182
+ if (node.type == YAML_SCALAR_NODE) {
183
+ yaml_free(node.data.scalar.value);
184
+ }
185
+ }
186
+ if (node.type == YAML_SEQUENCE_NODE) {
187
+ STACK_DEL(emitter, node.data.sequence.items);
188
+ }
189
+ if (node.type == YAML_MAPPING_NODE) {
190
+ STACK_DEL(emitter, node.data.mapping.pairs);
191
+ }
192
+ }
193
+
194
+ STACK_DEL(emitter, emitter->document->nodes);
195
+ yaml_free(emitter->anchors);
196
+
197
+ emitter->anchors = NULL;
198
+ emitter->last_anchor_id = 0;
199
+ emitter->document = NULL;
200
+ }
201
+
202
+ /*
203
+ * Check the references of a node and assign the anchor id if needed.
204
+ */
205
+
206
+ static void
207
+ yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
208
+ {
209
+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
210
+ yaml_node_item_t *item;
211
+ yaml_node_pair_t *pair;
212
+
213
+ emitter->anchors[index-1].references ++;
214
+
215
+ if (emitter->anchors[index-1].references == 1) {
216
+ switch (node->type) {
217
+ case YAML_SEQUENCE_NODE:
218
+ for (item = node->data.sequence.items.start;
219
+ item < node->data.sequence.items.top; item ++) {
220
+ yaml_emitter_anchor_node(emitter, *item);
221
+ }
222
+ break;
223
+ case YAML_MAPPING_NODE:
224
+ for (pair = node->data.mapping.pairs.start;
225
+ pair < node->data.mapping.pairs.top; pair ++) {
226
+ yaml_emitter_anchor_node(emitter, pair->key);
227
+ yaml_emitter_anchor_node(emitter, pair->value);
228
+ }
229
+ break;
230
+ default:
231
+ break;
232
+ }
233
+ }
234
+
235
+ else if (emitter->anchors[index-1].references == 2) {
236
+ emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
237
+ }
238
+ }
239
+
240
+ /*
241
+ * Generate a textual representation for an anchor.
242
+ */
243
+
244
+ #define ANCHOR_TEMPLATE "id%03d"
245
+ #define ANCHOR_TEMPLATE_LENGTH 16
246
+
247
+ static yaml_char_t *
248
+ yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
249
+ {
250
+ yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
251
+
252
+ if (!anchor) return NULL;
253
+
254
+ sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
255
+
256
+ return anchor;
257
+ }
258
+
259
+ /*
260
+ * Serialize a node.
261
+ */
262
+
263
+ static int
264
+ yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
265
+ {
266
+ yaml_node_t *node = emitter->document->nodes.start + index - 1;
267
+ int anchor_id = emitter->anchors[index-1].anchor;
268
+ yaml_char_t *anchor = NULL;
269
+
270
+ if (anchor_id) {
271
+ anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
272
+ if (!anchor) return 0;
273
+ }
274
+
275
+ if (emitter->anchors[index-1].serialized) {
276
+ return yaml_emitter_dump_alias(emitter, anchor);
277
+ }
278
+
279
+ emitter->anchors[index-1].serialized = 1;
280
+
281
+ switch (node->type) {
282
+ case YAML_SCALAR_NODE:
283
+ return yaml_emitter_dump_scalar(emitter, node, anchor);
284
+ case YAML_SEQUENCE_NODE:
285
+ return yaml_emitter_dump_sequence(emitter, node, anchor);
286
+ case YAML_MAPPING_NODE:
287
+ return yaml_emitter_dump_mapping(emitter, node, anchor);
288
+ default:
289
+ assert(0); /* Could not happen. */
290
+ break;
291
+ }
292
+
293
+ return 0; /* Could not happen. */
294
+ }
295
+
296
+ /*
297
+ * Serialize an alias.
298
+ */
299
+
300
+ static int
301
+ yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
302
+ {
303
+ yaml_event_t event;
304
+ yaml_mark_t mark = { 0, 0, 0 };
305
+
306
+ ALIAS_EVENT_INIT(event, anchor, mark, mark);
307
+
308
+ return yaml_emitter_emit(emitter, &event);
309
+ }
310
+
311
+ /*
312
+ * Serialize a scalar.
313
+ */
314
+
315
+ static int
316
+ yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
317
+ yaml_char_t *anchor)
318
+ {
319
+ yaml_event_t event;
320
+ yaml_mark_t mark = { 0, 0, 0 };
321
+
322
+ int plain_implicit = (strcmp((char *)node->tag,
323
+ YAML_DEFAULT_SCALAR_TAG) == 0);
324
+ int quoted_implicit = (strcmp((char *)node->tag,
325
+ YAML_DEFAULT_SCALAR_TAG) == 0);
326
+
327
+ SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
328
+ node->data.scalar.length, plain_implicit, quoted_implicit,
329
+ node->data.scalar.style, mark, mark);
330
+
331
+ return yaml_emitter_emit(emitter, &event);
332
+ }
333
+
334
+ /*
335
+ * Serialize a sequence.
336
+ */
337
+
338
+ static int
339
+ yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
340
+ yaml_char_t *anchor)
341
+ {
342
+ yaml_event_t event;
343
+ yaml_mark_t mark = { 0, 0, 0 };
344
+
345
+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
346
+
347
+ yaml_node_item_t *item;
348
+
349
+ SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
350
+ node->data.sequence.style, mark, mark);
351
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
352
+
353
+ for (item = node->data.sequence.items.start;
354
+ item < node->data.sequence.items.top; item ++) {
355
+ if (!yaml_emitter_dump_node(emitter, *item)) return 0;
356
+ }
357
+
358
+ SEQUENCE_END_EVENT_INIT(event, mark, mark);
359
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
360
+
361
+ return 1;
362
+ }
363
+
364
+ /*
365
+ * Serialize a mapping.
366
+ */
367
+
368
+ static int
369
+ yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
370
+ yaml_char_t *anchor)
371
+ {
372
+ yaml_event_t event;
373
+ yaml_mark_t mark = { 0, 0, 0 };
374
+
375
+ int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
376
+
377
+ yaml_node_pair_t *pair;
378
+
379
+ MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
380
+ node->data.mapping.style, mark, mark);
381
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
382
+
383
+ for (pair = node->data.mapping.pairs.start;
384
+ pair < node->data.mapping.pairs.top; pair ++) {
385
+ if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
386
+ if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
387
+ }
388
+
389
+ MAPPING_END_EVENT_INIT(event, mark, mark);
390
+ if (!yaml_emitter_emit(emitter, &event)) return 0;
391
+
392
+ return 1;
393
+ }
394
+
@@ -0,0 +1,2329 @@
1
+
2
+ #include "yaml_private.h"
3
+
4
+ /*
5
+ * Flush the buffer if needed.
6
+ */
7
+
8
+ #define FLUSH(emitter) \
9
+ ((emitter->buffer.pointer+5 < emitter->buffer.end) \
10
+ || yaml_emitter_flush(emitter))
11
+
12
+ /*
13
+ * Put a character to the output buffer.
14
+ */
15
+
16
+ #define PUT(emitter,value) \
17
+ (FLUSH(emitter) \
18
+ && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
19
+ emitter->column ++, \
20
+ 1))
21
+
22
+ /*
23
+ * Put a line break to the output buffer.
24
+ */
25
+
26
+ #define PUT_BREAK(emitter) \
27
+ (FLUSH(emitter) \
28
+ && ((emitter->line_break == YAML_CR_BREAK ? \
29
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
30
+ emitter->line_break == YAML_LN_BREAK ? \
31
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
32
+ emitter->line_break == YAML_CRLN_BREAK ? \
33
+ (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
34
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
35
+ emitter->column = 0, \
36
+ emitter->line ++, \
37
+ 1))
38
+
39
+ /*
40
+ * Copy a character from a string into buffer.
41
+ */
42
+
43
+ #define WRITE(emitter,string) \
44
+ (FLUSH(emitter) \
45
+ && (COPY(emitter->buffer,string), \
46
+ emitter->column ++, \
47
+ 1))
48
+
49
+ /*
50
+ * Copy a line break character from a string into buffer.
51
+ */
52
+
53
+ #define WRITE_BREAK(emitter,string) \
54
+ (FLUSH(emitter) \
55
+ && (CHECK(string,'\n') ? \
56
+ ((void)PUT_BREAK(emitter), \
57
+ string.pointer ++, \
58
+ 1) : \
59
+ (COPY(emitter->buffer,string), \
60
+ emitter->column = 0, \
61
+ emitter->line ++, \
62
+ 1)))
63
+
64
+ /*
65
+ * API functions.
66
+ */
67
+
68
+ YAML_DECLARE(int)
69
+ yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
70
+
71
+ /*
72
+ * Utility functions.
73
+ */
74
+
75
+ static int
76
+ yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
77
+
78
+ static int
79
+ yaml_emitter_need_more_events(yaml_emitter_t *emitter);
80
+
81
+ static int
82
+ yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
83
+ yaml_tag_directive_t value, int allow_duplicates);
84
+
85
+ static int
86
+ yaml_emitter_increase_indent(yaml_emitter_t *emitter,
87
+ int flow, int indentless);
88
+
89
+ /*
90
+ * State functions.
91
+ */
92
+
93
+ static int
94
+ yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
95
+
96
+ static int
97
+ yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
98
+ yaml_event_t *event);
99
+
100
+ static int
101
+ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
102
+ yaml_event_t *event, int first);
103
+
104
+ static int
105
+ yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
106
+ yaml_event_t *event);
107
+
108
+ static int
109
+ yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
110
+ yaml_event_t *event);
111
+
112
+ static int
113
+ yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
114
+ yaml_event_t *event, int first);
115
+
116
+ static int
117
+ yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
118
+ yaml_event_t *event, int first);
119
+
120
+ static int
121
+ yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
122
+ yaml_event_t *event, int simple);
123
+
124
+ static int
125
+ yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
126
+ yaml_event_t *event, int first);
127
+
128
+ static int
129
+ yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
130
+ yaml_event_t *event, int first);
131
+
132
+ static int
133
+ yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
134
+ yaml_event_t *event, int simple);
135
+
136
+ static int
137
+ yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
138
+ int root, int sequence, int mapping, int simple_key);
139
+
140
+ static int
141
+ yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
142
+
143
+ static int
144
+ yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
145
+
146
+ static int
147
+ yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
148
+
149
+ static int
150
+ yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
151
+
152
+ /*
153
+ * Checkers.
154
+ */
155
+
156
+ static int
157
+ yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
158
+
159
+ static int
160
+ yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
161
+
162
+ static int
163
+ yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
164
+
165
+ static int
166
+ yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
167
+
168
+ static int
169
+ yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
170
+
171
+ /*
172
+ * Processors.
173
+ */
174
+
175
+ static int
176
+ yaml_emitter_process_anchor(yaml_emitter_t *emitter);
177
+
178
+ static int
179
+ yaml_emitter_process_tag(yaml_emitter_t *emitter);
180
+
181
+ static int
182
+ yaml_emitter_process_scalar(yaml_emitter_t *emitter);
183
+
184
+ /*
185
+ * Analyzers.
186
+ */
187
+
188
+ static int
189
+ yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
190
+ yaml_version_directive_t version_directive);
191
+
192
+ static int
193
+ yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
194
+ yaml_tag_directive_t tag_directive);
195
+
196
+ static int
197
+ yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
198
+ yaml_char_t *anchor, int alias);
199
+
200
+ static int
201
+ yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
202
+ yaml_char_t *tag);
203
+
204
+ static int
205
+ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
206
+ yaml_char_t *value, size_t length);
207
+
208
+ static int
209
+ yaml_emitter_analyze_event(yaml_emitter_t *emitter,
210
+ yaml_event_t *event);
211
+
212
+ /*
213
+ * Writers.
214
+ */
215
+
216
+ static int
217
+ yaml_emitter_write_bom(yaml_emitter_t *emitter);
218
+
219
+ static int
220
+ yaml_emitter_write_indent(yaml_emitter_t *emitter);
221
+
222
+ static int
223
+ yaml_emitter_write_indicator(yaml_emitter_t *emitter,
224
+ const char *indicator, int need_whitespace,
225
+ int is_whitespace, int is_indention);
226
+
227
+ static int
228
+ yaml_emitter_write_anchor(yaml_emitter_t *emitter,
229
+ yaml_char_t *value, size_t length);
230
+
231
+ static int
232
+ yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
233
+ yaml_char_t *value, size_t length);
234
+
235
+ static int
236
+ yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
237
+ yaml_char_t *value, size_t length, int need_whitespace);
238
+
239
+ static int
240
+ yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
241
+ yaml_char_t *value, size_t length, int allow_breaks);
242
+
243
+ static int
244
+ yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
245
+ yaml_char_t *value, size_t length, int allow_breaks);
246
+
247
+ static int
248
+ yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
249
+ yaml_char_t *value, size_t length, int allow_breaks);
250
+
251
+ static int
252
+ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
253
+ yaml_string_t string);
254
+
255
+ static int
256
+ yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
257
+ yaml_char_t *value, size_t length);
258
+
259
+ static int
260
+ yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
261
+ yaml_char_t *value, size_t length);
262
+
263
+ /*
264
+ * Set an emitter error and return 0.
265
+ */
266
+
267
+ static int
268
+ yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
269
+ {
270
+ emitter->error = YAML_EMITTER_ERROR;
271
+ emitter->problem = problem;
272
+
273
+ return 0;
274
+ }
275
+
276
+ /*
277
+ * Emit an event.
278
+ */
279
+
280
+ YAML_DECLARE(int)
281
+ yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
282
+ {
283
+ if (!ENQUEUE(emitter, emitter->events, *event)) {
284
+ yaml_event_delete(event);
285
+ return 0;
286
+ }
287
+
288
+ while (!yaml_emitter_need_more_events(emitter)) {
289
+ if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
290
+ return 0;
291
+ if (!yaml_emitter_state_machine(emitter, emitter->events.head))
292
+ return 0;
293
+ yaml_event_delete(&DEQUEUE(emitter, emitter->events));
294
+ }
295
+
296
+ return 1;
297
+ }
298
+
299
+ /*
300
+ * Check if we need to accumulate more events before emitting.
301
+ *
302
+ * We accumulate extra
303
+ * - 1 event for DOCUMENT-START
304
+ * - 2 events for SEQUENCE-START
305
+ * - 3 events for MAPPING-START
306
+ */
307
+
308
+ static int
309
+ yaml_emitter_need_more_events(yaml_emitter_t *emitter)
310
+ {
311
+ int level = 0;
312
+ int accumulate = 0;
313
+ yaml_event_t *event;
314
+
315
+ if (QUEUE_EMPTY(emitter, emitter->events))
316
+ return 1;
317
+
318
+ switch (emitter->events.head->type) {
319
+ case YAML_DOCUMENT_START_EVENT:
320
+ accumulate = 1;
321
+ break;
322
+ case YAML_SEQUENCE_START_EVENT:
323
+ accumulate = 2;
324
+ break;
325
+ case YAML_MAPPING_START_EVENT:
326
+ accumulate = 3;
327
+ break;
328
+ default:
329
+ return 0;
330
+ }
331
+
332
+ if (emitter->events.tail - emitter->events.head > accumulate)
333
+ return 0;
334
+
335
+ for (event = emitter->events.head; event != emitter->events.tail; event ++) {
336
+ switch (event->type) {
337
+ case YAML_STREAM_START_EVENT:
338
+ case YAML_DOCUMENT_START_EVENT:
339
+ case YAML_SEQUENCE_START_EVENT:
340
+ case YAML_MAPPING_START_EVENT:
341
+ level += 1;
342
+ break;
343
+ case YAML_STREAM_END_EVENT:
344
+ case YAML_DOCUMENT_END_EVENT:
345
+ case YAML_SEQUENCE_END_EVENT:
346
+ case YAML_MAPPING_END_EVENT:
347
+ level -= 1;
348
+ break;
349
+ default:
350
+ break;
351
+ }
352
+ if (!level)
353
+ return 0;
354
+ }
355
+
356
+ return 1;
357
+ }
358
+
359
+ /*
360
+ * Append a directive to the directives stack.
361
+ */
362
+
363
+ static int
364
+ yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
365
+ yaml_tag_directive_t value, int allow_duplicates)
366
+ {
367
+ yaml_tag_directive_t *tag_directive;
368
+ yaml_tag_directive_t copy = { NULL, NULL };
369
+
370
+ for (tag_directive = emitter->tag_directives.start;
371
+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
372
+ if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
373
+ if (allow_duplicates)
374
+ return 1;
375
+ return yaml_emitter_set_emitter_error(emitter,
376
+ "duplicate %TAG directive");
377
+ }
378
+ }
379
+
380
+ copy.handle = yaml_strdup(value.handle);
381
+ copy.prefix = yaml_strdup(value.prefix);
382
+ if (!copy.handle || !copy.prefix) {
383
+ emitter->error = YAML_MEMORY_ERROR;
384
+ goto error;
385
+ }
386
+
387
+ if (!PUSH(emitter, emitter->tag_directives, copy))
388
+ goto error;
389
+
390
+ return 1;
391
+
392
+ error:
393
+ yaml_free(copy.handle);
394
+ yaml_free(copy.prefix);
395
+ return 0;
396
+ }
397
+
398
+ /*
399
+ * Increase the indentation level.
400
+ */
401
+
402
+ static int
403
+ yaml_emitter_increase_indent(yaml_emitter_t *emitter,
404
+ int flow, int indentless)
405
+ {
406
+ if (!PUSH(emitter, emitter->indents, emitter->indent))
407
+ return 0;
408
+
409
+ if (emitter->indent < 0) {
410
+ emitter->indent = flow ? emitter->best_indent : 0;
411
+ }
412
+ else if (!indentless) {
413
+ emitter->indent += emitter->best_indent;
414
+ }
415
+
416
+ return 1;
417
+ }
418
+
419
+ /*
420
+ * State dispatcher.
421
+ */
422
+
423
+ static int
424
+ yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
425
+ {
426
+ switch (emitter->state)
427
+ {
428
+ case YAML_EMIT_STREAM_START_STATE:
429
+ return yaml_emitter_emit_stream_start(emitter, event);
430
+
431
+ case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
432
+ return yaml_emitter_emit_document_start(emitter, event, 1);
433
+
434
+ case YAML_EMIT_DOCUMENT_START_STATE:
435
+ return yaml_emitter_emit_document_start(emitter, event, 0);
436
+
437
+ case YAML_EMIT_DOCUMENT_CONTENT_STATE:
438
+ return yaml_emitter_emit_document_content(emitter, event);
439
+
440
+ case YAML_EMIT_DOCUMENT_END_STATE:
441
+ return yaml_emitter_emit_document_end(emitter, event);
442
+
443
+ case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
444
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
445
+
446
+ case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
447
+ return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
448
+
449
+ case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
450
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
451
+
452
+ case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
453
+ return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
454
+
455
+ case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
456
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
457
+
458
+ case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
459
+ return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
460
+
461
+ case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
462
+ return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
463
+
464
+ case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
465
+ return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
466
+
467
+ case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
468
+ return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
469
+
470
+ case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
471
+ return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
472
+
473
+ case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
474
+ return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
475
+
476
+ case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
477
+ return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
478
+
479
+ case YAML_EMIT_END_STATE:
480
+ return yaml_emitter_set_emitter_error(emitter,
481
+ "expected nothing after STREAM-END");
482
+
483
+ default:
484
+ assert(1); /* Invalid state. */
485
+ }
486
+
487
+ return 0;
488
+ }
489
+
490
+ /*
491
+ * Expect STREAM-START.
492
+ */
493
+
494
+ static int
495
+ yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
496
+ yaml_event_t *event)
497
+ {
498
+ if (event->type == YAML_STREAM_START_EVENT)
499
+ {
500
+ if (!emitter->encoding) {
501
+ emitter->encoding = event->data.stream_start.encoding;
502
+ }
503
+
504
+ if (!emitter->encoding) {
505
+ emitter->encoding = YAML_UTF8_ENCODING;
506
+ }
507
+
508
+ if (emitter->best_indent < 2 || emitter->best_indent > 9) {
509
+ emitter->best_indent = 2;
510
+ }
511
+
512
+ if (emitter->best_width >= 0
513
+ && emitter->best_width <= emitter->best_indent*2) {
514
+ emitter->best_width = 80;
515
+ }
516
+
517
+ if (emitter->best_width < 0) {
518
+ emitter->best_width = INT_MAX;
519
+ }
520
+
521
+ if (!emitter->line_break) {
522
+ emitter->line_break = YAML_LN_BREAK;
523
+ }
524
+
525
+ emitter->indent = -1;
526
+
527
+ emitter->line = 0;
528
+ emitter->column = 0;
529
+ emitter->whitespace = 1;
530
+ emitter->indention = 1;
531
+
532
+ if (emitter->encoding != YAML_UTF8_ENCODING) {
533
+ if (!yaml_emitter_write_bom(emitter))
534
+ return 0;
535
+ }
536
+
537
+ emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
538
+
539
+ return 1;
540
+ }
541
+
542
+ return yaml_emitter_set_emitter_error(emitter,
543
+ "expected STREAM-START");
544
+ }
545
+
546
+ /*
547
+ * Expect DOCUMENT-START or STREAM-END.
548
+ */
549
+
550
+ static int
551
+ yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
552
+ yaml_event_t *event, int first)
553
+ {
554
+ if (event->type == YAML_DOCUMENT_START_EVENT)
555
+ {
556
+ yaml_tag_directive_t default_tag_directives[] = {
557
+ {(yaml_char_t *)"!", (yaml_char_t *)"!"},
558
+ {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
559
+ {NULL, NULL}
560
+ };
561
+ yaml_tag_directive_t *tag_directive;
562
+ int implicit;
563
+
564
+ if (event->data.document_start.version_directive) {
565
+ if (!yaml_emitter_analyze_version_directive(emitter,
566
+ *event->data.document_start.version_directive))
567
+ return 0;
568
+ }
569
+
570
+ for (tag_directive = event->data.document_start.tag_directives.start;
571
+ tag_directive != event->data.document_start.tag_directives.end;
572
+ tag_directive ++) {
573
+ if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
574
+ return 0;
575
+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
576
+ return 0;
577
+ }
578
+
579
+ for (tag_directive = default_tag_directives;
580
+ tag_directive->handle; tag_directive ++) {
581
+ if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
582
+ return 0;
583
+ }
584
+
585
+ implicit = event->data.document_start.implicit;
586
+ if (!first || emitter->canonical) {
587
+ implicit = 0;
588
+ }
589
+
590
+ if ((event->data.document_start.version_directive ||
591
+ (event->data.document_start.tag_directives.start
592
+ != event->data.document_start.tag_directives.end)) &&
593
+ emitter->open_ended)
594
+ {
595
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
596
+ return 0;
597
+ if (!yaml_emitter_write_indent(emitter))
598
+ return 0;
599
+ }
600
+
601
+ if (event->data.document_start.version_directive) {
602
+ implicit = 0;
603
+ if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
604
+ return 0;
605
+ if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
606
+ return 0;
607
+ if (!yaml_emitter_write_indent(emitter))
608
+ return 0;
609
+ }
610
+
611
+ if (event->data.document_start.tag_directives.start
612
+ != event->data.document_start.tag_directives.end) {
613
+ implicit = 0;
614
+ for (tag_directive = event->data.document_start.tag_directives.start;
615
+ tag_directive != event->data.document_start.tag_directives.end;
616
+ tag_directive ++) {
617
+ if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
618
+ return 0;
619
+ if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
620
+ strlen((char *)tag_directive->handle)))
621
+ return 0;
622
+ if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
623
+ strlen((char *)tag_directive->prefix), 1))
624
+ return 0;
625
+ if (!yaml_emitter_write_indent(emitter))
626
+ return 0;
627
+ }
628
+ }
629
+
630
+ if (yaml_emitter_check_empty_document(emitter)) {
631
+ implicit = 0;
632
+ }
633
+
634
+ if (!implicit) {
635
+ if (!yaml_emitter_write_indent(emitter))
636
+ return 0;
637
+ if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
638
+ return 0;
639
+ if (emitter->canonical) {
640
+ if (!yaml_emitter_write_indent(emitter))
641
+ return 0;
642
+ }
643
+ }
644
+
645
+ emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
646
+
647
+ return 1;
648
+ }
649
+
650
+ else if (event->type == YAML_STREAM_END_EVENT)
651
+ {
652
+ if (emitter->open_ended)
653
+ {
654
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
655
+ return 0;
656
+ if (!yaml_emitter_write_indent(emitter))
657
+ return 0;
658
+ }
659
+
660
+ if (!yaml_emitter_flush(emitter))
661
+ return 0;
662
+
663
+ emitter->state = YAML_EMIT_END_STATE;
664
+
665
+ return 1;
666
+ }
667
+
668
+ return yaml_emitter_set_emitter_error(emitter,
669
+ "expected DOCUMENT-START or STREAM-END");
670
+ }
671
+
672
+ /*
673
+ * Expect the root node.
674
+ */
675
+
676
+ static int
677
+ yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
678
+ yaml_event_t *event)
679
+ {
680
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
681
+ return 0;
682
+
683
+ return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
684
+ }
685
+
686
+ /*
687
+ * Expect DOCUMENT-END.
688
+ */
689
+
690
+ static int
691
+ yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
692
+ yaml_event_t *event)
693
+ {
694
+ if (event->type == YAML_DOCUMENT_END_EVENT)
695
+ {
696
+ if (!yaml_emitter_write_indent(emitter))
697
+ return 0;
698
+ if (!event->data.document_end.implicit) {
699
+ if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
700
+ return 0;
701
+ if (!yaml_emitter_write_indent(emitter))
702
+ return 0;
703
+ }
704
+ if (!yaml_emitter_flush(emitter))
705
+ return 0;
706
+
707
+ emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
708
+
709
+ while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
710
+ yaml_tag_directive_t tag_directive = POP(emitter,
711
+ emitter->tag_directives);
712
+ yaml_free(tag_directive.handle);
713
+ yaml_free(tag_directive.prefix);
714
+ }
715
+
716
+ return 1;
717
+ }
718
+
719
+ return yaml_emitter_set_emitter_error(emitter,
720
+ "expected DOCUMENT-END");
721
+ }
722
+
723
+ /*
724
+ *
725
+ * Expect a flow item node.
726
+ */
727
+
728
+ static int
729
+ yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
730
+ yaml_event_t *event, int first)
731
+ {
732
+ if (first)
733
+ {
734
+ if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
735
+ return 0;
736
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
737
+ return 0;
738
+ emitter->flow_level ++;
739
+ }
740
+
741
+ if (event->type == YAML_SEQUENCE_END_EVENT)
742
+ {
743
+ emitter->flow_level --;
744
+ emitter->indent = POP(emitter, emitter->indents);
745
+ if (emitter->canonical && !first) {
746
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
747
+ return 0;
748
+ if (!yaml_emitter_write_indent(emitter))
749
+ return 0;
750
+ }
751
+ if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
752
+ return 0;
753
+ emitter->state = POP(emitter, emitter->states);
754
+
755
+ return 1;
756
+ }
757
+
758
+ if (!first) {
759
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
760
+ return 0;
761
+ }
762
+
763
+ if (emitter->canonical || emitter->column > emitter->best_width) {
764
+ if (!yaml_emitter_write_indent(emitter))
765
+ return 0;
766
+ }
767
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
768
+ return 0;
769
+
770
+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
771
+ }
772
+
773
+ /*
774
+ * Expect a flow key node.
775
+ */
776
+
777
+ static int
778
+ yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
779
+ yaml_event_t *event, int first)
780
+ {
781
+ if (first)
782
+ {
783
+ if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
784
+ return 0;
785
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
786
+ return 0;
787
+ emitter->flow_level ++;
788
+ }
789
+
790
+ if (event->type == YAML_MAPPING_END_EVENT)
791
+ {
792
+ emitter->flow_level --;
793
+ emitter->indent = POP(emitter, emitter->indents);
794
+ if (emitter->canonical && !first) {
795
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
796
+ return 0;
797
+ if (!yaml_emitter_write_indent(emitter))
798
+ return 0;
799
+ }
800
+ if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
801
+ return 0;
802
+ emitter->state = POP(emitter, emitter->states);
803
+
804
+ return 1;
805
+ }
806
+
807
+ if (!first) {
808
+ if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
809
+ return 0;
810
+ }
811
+ if (emitter->canonical || emitter->column > emitter->best_width) {
812
+ if (!yaml_emitter_write_indent(emitter))
813
+ return 0;
814
+ }
815
+
816
+ if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
817
+ {
818
+ if (!PUSH(emitter, emitter->states,
819
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
820
+ return 0;
821
+
822
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
823
+ }
824
+ else
825
+ {
826
+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
827
+ return 0;
828
+ if (!PUSH(emitter, emitter->states,
829
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
830
+ return 0;
831
+
832
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
833
+ }
834
+ }
835
+
836
+ /*
837
+ * Expect a flow value node.
838
+ */
839
+
840
+ static int
841
+ yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
842
+ yaml_event_t *event, int simple)
843
+ {
844
+ if (simple) {
845
+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
846
+ return 0;
847
+ }
848
+ else {
849
+ if (emitter->canonical || emitter->column > emitter->best_width) {
850
+ if (!yaml_emitter_write_indent(emitter))
851
+ return 0;
852
+ }
853
+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
854
+ return 0;
855
+ }
856
+ if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
857
+ return 0;
858
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
859
+ }
860
+
861
+ /*
862
+ * Expect a block item node.
863
+ */
864
+
865
+ static int
866
+ yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
867
+ yaml_event_t *event, int first)
868
+ {
869
+ if (first)
870
+ {
871
+ if (!yaml_emitter_increase_indent(emitter, 0,
872
+ (emitter->mapping_context && !emitter->indention)))
873
+ return 0;
874
+ }
875
+
876
+ if (event->type == YAML_SEQUENCE_END_EVENT)
877
+ {
878
+ emitter->indent = POP(emitter, emitter->indents);
879
+ emitter->state = POP(emitter, emitter->states);
880
+
881
+ return 1;
882
+ }
883
+
884
+ if (!yaml_emitter_write_indent(emitter))
885
+ return 0;
886
+ if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
887
+ return 0;
888
+ if (!PUSH(emitter, emitter->states,
889
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
890
+ return 0;
891
+
892
+ return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
893
+ }
894
+
895
+ /*
896
+ * Expect a block key node.
897
+ */
898
+
899
+ static int
900
+ yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
901
+ yaml_event_t *event, int first)
902
+ {
903
+ if (first)
904
+ {
905
+ if (!yaml_emitter_increase_indent(emitter, 0, 0))
906
+ return 0;
907
+ }
908
+
909
+ if (event->type == YAML_MAPPING_END_EVENT)
910
+ {
911
+ emitter->indent = POP(emitter, emitter->indents);
912
+ emitter->state = POP(emitter, emitter->states);
913
+
914
+ return 1;
915
+ }
916
+
917
+ if (!yaml_emitter_write_indent(emitter))
918
+ return 0;
919
+
920
+ if (yaml_emitter_check_simple_key(emitter))
921
+ {
922
+ if (!PUSH(emitter, emitter->states,
923
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
924
+ return 0;
925
+
926
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
927
+ }
928
+ else
929
+ {
930
+ if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
931
+ return 0;
932
+ if (!PUSH(emitter, emitter->states,
933
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
934
+ return 0;
935
+
936
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
937
+ }
938
+ }
939
+
940
+ /*
941
+ * Expect a block value node.
942
+ */
943
+
944
+ static int
945
+ yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
946
+ yaml_event_t *event, int simple)
947
+ {
948
+ if (simple) {
949
+ if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
950
+ return 0;
951
+ }
952
+ else {
953
+ if (!yaml_emitter_write_indent(emitter))
954
+ return 0;
955
+ if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
956
+ return 0;
957
+ }
958
+ if (!PUSH(emitter, emitter->states,
959
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
960
+ return 0;
961
+
962
+ return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
963
+ }
964
+
965
+ /*
966
+ * Expect a node.
967
+ */
968
+
969
+ static int
970
+ yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
971
+ int root, int sequence, int mapping, int simple_key)
972
+ {
973
+ emitter->root_context = root;
974
+ emitter->sequence_context = sequence;
975
+ emitter->mapping_context = mapping;
976
+ emitter->simple_key_context = simple_key;
977
+
978
+ switch (event->type)
979
+ {
980
+ case YAML_ALIAS_EVENT:
981
+ return yaml_emitter_emit_alias(emitter, event);
982
+
983
+ case YAML_SCALAR_EVENT:
984
+ return yaml_emitter_emit_scalar(emitter, event);
985
+
986
+ case YAML_SEQUENCE_START_EVENT:
987
+ return yaml_emitter_emit_sequence_start(emitter, event);
988
+
989
+ case YAML_MAPPING_START_EVENT:
990
+ return yaml_emitter_emit_mapping_start(emitter, event);
991
+
992
+ default:
993
+ return yaml_emitter_set_emitter_error(emitter,
994
+ "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
995
+ }
996
+
997
+ return 0;
998
+ }
999
+
1000
+ /*
1001
+ * Expect ALIAS.
1002
+ */
1003
+
1004
+ static int
1005
+ yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
1006
+ {
1007
+ if (!yaml_emitter_process_anchor(emitter))
1008
+ return 0;
1009
+ emitter->state = POP(emitter, emitter->states);
1010
+
1011
+ return 1;
1012
+ }
1013
+
1014
+ /*
1015
+ * Expect SCALAR.
1016
+ */
1017
+
1018
+ static int
1019
+ yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
1020
+ {
1021
+ if (!yaml_emitter_select_scalar_style(emitter, event))
1022
+ return 0;
1023
+ if (!yaml_emitter_process_anchor(emitter))
1024
+ return 0;
1025
+ if (!yaml_emitter_process_tag(emitter))
1026
+ return 0;
1027
+ if (!yaml_emitter_increase_indent(emitter, 1, 0))
1028
+ return 0;
1029
+ if (!yaml_emitter_process_scalar(emitter))
1030
+ return 0;
1031
+ emitter->indent = POP(emitter, emitter->indents);
1032
+ emitter->state = POP(emitter, emitter->states);
1033
+
1034
+ return 1;
1035
+ }
1036
+
1037
+ /*
1038
+ * Expect SEQUENCE-START.
1039
+ */
1040
+
1041
+ static int
1042
+ yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1043
+ {
1044
+ if (!yaml_emitter_process_anchor(emitter))
1045
+ return 0;
1046
+ if (!yaml_emitter_process_tag(emitter))
1047
+ return 0;
1048
+
1049
+ if (emitter->flow_level || emitter->canonical
1050
+ || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1051
+ || yaml_emitter_check_empty_sequence(emitter)) {
1052
+ emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1053
+ }
1054
+ else {
1055
+ emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1056
+ }
1057
+
1058
+ return 1;
1059
+ }
1060
+
1061
+ /*
1062
+ * Expect MAPPING-START.
1063
+ */
1064
+
1065
+ static int
1066
+ yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1067
+ {
1068
+ if (!yaml_emitter_process_anchor(emitter))
1069
+ return 0;
1070
+ if (!yaml_emitter_process_tag(emitter))
1071
+ return 0;
1072
+
1073
+ if (emitter->flow_level || emitter->canonical
1074
+ || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1075
+ || yaml_emitter_check_empty_mapping(emitter)) {
1076
+ emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1077
+ }
1078
+ else {
1079
+ emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1080
+ }
1081
+
1082
+ return 1;
1083
+ }
1084
+
1085
+ /*
1086
+ * Check if the document content is an empty scalar.
1087
+ */
1088
+
1089
+ static int
1090
+ yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
1091
+ {
1092
+ return 0;
1093
+ }
1094
+
1095
+ /*
1096
+ * Check if the next events represent an empty sequence.
1097
+ */
1098
+
1099
+ static int
1100
+ yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1101
+ {
1102
+ if (emitter->events.tail - emitter->events.head < 2)
1103
+ return 0;
1104
+
1105
+ return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1106
+ && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1107
+ }
1108
+
1109
+ /*
1110
+ * Check if the next events represent an empty mapping.
1111
+ */
1112
+
1113
+ static int
1114
+ yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1115
+ {
1116
+ if (emitter->events.tail - emitter->events.head < 2)
1117
+ return 0;
1118
+
1119
+ return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1120
+ && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1121
+ }
1122
+
1123
+ /*
1124
+ * Check if the next node can be expressed as a simple key.
1125
+ */
1126
+
1127
+ static int
1128
+ yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1129
+ {
1130
+ yaml_event_t *event = emitter->events.head;
1131
+ size_t length = 0;
1132
+
1133
+ switch (event->type)
1134
+ {
1135
+ case YAML_ALIAS_EVENT:
1136
+ length += emitter->anchor_data.anchor_length;
1137
+ break;
1138
+
1139
+ case YAML_SCALAR_EVENT:
1140
+ if (emitter->scalar_data.multiline)
1141
+ return 0;
1142
+ length += emitter->anchor_data.anchor_length
1143
+ + emitter->tag_data.handle_length
1144
+ + emitter->tag_data.suffix_length
1145
+ + emitter->scalar_data.length;
1146
+ break;
1147
+
1148
+ case YAML_SEQUENCE_START_EVENT:
1149
+ if (!yaml_emitter_check_empty_sequence(emitter))
1150
+ return 0;
1151
+ length += emitter->anchor_data.anchor_length
1152
+ + emitter->tag_data.handle_length
1153
+ + emitter->tag_data.suffix_length;
1154
+ break;
1155
+
1156
+ case YAML_MAPPING_START_EVENT:
1157
+ if (!yaml_emitter_check_empty_mapping(emitter))
1158
+ return 0;
1159
+ length += emitter->anchor_data.anchor_length
1160
+ + emitter->tag_data.handle_length
1161
+ + emitter->tag_data.suffix_length;
1162
+ break;
1163
+
1164
+ default:
1165
+ return 0;
1166
+ }
1167
+
1168
+ if (length > 128)
1169
+ return 0;
1170
+
1171
+ return 1;
1172
+ }
1173
+
1174
+ /*
1175
+ * Determine an acceptable scalar style.
1176
+ */
1177
+
1178
+ static int
1179
+ yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1180
+ {
1181
+ yaml_scalar_style_t style = event->data.scalar.style;
1182
+ int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
1183
+
1184
+ if (no_tag && !event->data.scalar.plain_implicit
1185
+ && !event->data.scalar.quoted_implicit) {
1186
+ return yaml_emitter_set_emitter_error(emitter,
1187
+ "neither tag nor implicit flags are specified");
1188
+ }
1189
+
1190
+ if (style == YAML_ANY_SCALAR_STYLE)
1191
+ style = YAML_PLAIN_SCALAR_STYLE;
1192
+
1193
+ if (emitter->canonical)
1194
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1195
+
1196
+ if (emitter->simple_key_context && emitter->scalar_data.multiline)
1197
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1198
+
1199
+ if (style == YAML_PLAIN_SCALAR_STYLE)
1200
+ {
1201
+ if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1202
+ || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1203
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1204
+ if (!emitter->scalar_data.length
1205
+ && (emitter->flow_level || emitter->simple_key_context))
1206
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1207
+ if (no_tag && !event->data.scalar.plain_implicit)
1208
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1209
+ }
1210
+
1211
+ if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1212
+ {
1213
+ if (!emitter->scalar_data.single_quoted_allowed)
1214
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1215
+ }
1216
+
1217
+ if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1218
+ {
1219
+ if (!emitter->scalar_data.block_allowed
1220
+ || emitter->flow_level || emitter->simple_key_context)
1221
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1222
+ }
1223
+
1224
+ if (no_tag && !event->data.scalar.quoted_implicit
1225
+ && style != YAML_PLAIN_SCALAR_STYLE)
1226
+ {
1227
+ emitter->tag_data.handle = (yaml_char_t *)"!";
1228
+ emitter->tag_data.handle_length = 1;
1229
+ }
1230
+
1231
+ emitter->scalar_data.style = style;
1232
+
1233
+ return 1;
1234
+ }
1235
+
1236
+ /*
1237
+ * Write an achor.
1238
+ */
1239
+
1240
+ static int
1241
+ yaml_emitter_process_anchor(yaml_emitter_t *emitter)
1242
+ {
1243
+ if (!emitter->anchor_data.anchor)
1244
+ return 1;
1245
+
1246
+ if (!yaml_emitter_write_indicator(emitter,
1247
+ (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1248
+ return 0;
1249
+
1250
+ return yaml_emitter_write_anchor(emitter,
1251
+ emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1252
+ }
1253
+
1254
+ /*
1255
+ * Write a tag.
1256
+ */
1257
+
1258
+ static int
1259
+ yaml_emitter_process_tag(yaml_emitter_t *emitter)
1260
+ {
1261
+ if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1262
+ return 1;
1263
+
1264
+ if (emitter->tag_data.handle)
1265
+ {
1266
+ if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1267
+ emitter->tag_data.handle_length))
1268
+ return 0;
1269
+ if (emitter->tag_data.suffix) {
1270
+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1271
+ emitter->tag_data.suffix_length, 0))
1272
+ return 0;
1273
+ }
1274
+ }
1275
+ else
1276
+ {
1277
+ if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1278
+ return 0;
1279
+ if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1280
+ emitter->tag_data.suffix_length, 0))
1281
+ return 0;
1282
+ if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1283
+ return 0;
1284
+ }
1285
+
1286
+ return 1;
1287
+ }
1288
+
1289
+ /*
1290
+ * Write a scalar.
1291
+ */
1292
+
1293
+ static int
1294
+ yaml_emitter_process_scalar(yaml_emitter_t *emitter)
1295
+ {
1296
+ switch (emitter->scalar_data.style)
1297
+ {
1298
+ case YAML_PLAIN_SCALAR_STYLE:
1299
+ return yaml_emitter_write_plain_scalar(emitter,
1300
+ emitter->scalar_data.value, emitter->scalar_data.length,
1301
+ !emitter->simple_key_context);
1302
+
1303
+ case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1304
+ return yaml_emitter_write_single_quoted_scalar(emitter,
1305
+ emitter->scalar_data.value, emitter->scalar_data.length,
1306
+ !emitter->simple_key_context);
1307
+
1308
+ case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1309
+ return yaml_emitter_write_double_quoted_scalar(emitter,
1310
+ emitter->scalar_data.value, emitter->scalar_data.length,
1311
+ !emitter->simple_key_context);
1312
+
1313
+ case YAML_LITERAL_SCALAR_STYLE:
1314
+ return yaml_emitter_write_literal_scalar(emitter,
1315
+ emitter->scalar_data.value, emitter->scalar_data.length);
1316
+
1317
+ case YAML_FOLDED_SCALAR_STYLE:
1318
+ return yaml_emitter_write_folded_scalar(emitter,
1319
+ emitter->scalar_data.value, emitter->scalar_data.length);
1320
+
1321
+ default:
1322
+ assert(1); /* Impossible. */
1323
+ }
1324
+
1325
+ return 0;
1326
+ }
1327
+
1328
+ /*
1329
+ * Check if a %YAML directive is valid.
1330
+ */
1331
+
1332
+ static int
1333
+ yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1334
+ yaml_version_directive_t version_directive)
1335
+ {
1336
+ if (version_directive.major != 1 || version_directive.minor != 1) {
1337
+ return yaml_emitter_set_emitter_error(emitter,
1338
+ "incompatible %YAML directive");
1339
+ }
1340
+
1341
+ return 1;
1342
+ }
1343
+
1344
+ /*
1345
+ * Check if a %TAG directive is valid.
1346
+ */
1347
+
1348
+ static int
1349
+ yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1350
+ yaml_tag_directive_t tag_directive)
1351
+ {
1352
+ yaml_string_t handle;
1353
+ yaml_string_t prefix;
1354
+ size_t handle_length;
1355
+ size_t prefix_length;
1356
+
1357
+ handle_length = strlen((char *)tag_directive.handle);
1358
+ prefix_length = strlen((char *)tag_directive.prefix);
1359
+ STRING_ASSIGN(handle, tag_directive.handle, handle_length);
1360
+ STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
1361
+
1362
+ if (handle.start == handle.end) {
1363
+ return yaml_emitter_set_emitter_error(emitter,
1364
+ "tag handle must not be empty");
1365
+ }
1366
+
1367
+ if (handle.start[0] != '!') {
1368
+ return yaml_emitter_set_emitter_error(emitter,
1369
+ "tag handle must start with '!'");
1370
+ }
1371
+
1372
+ if (handle.end[-1] != '!') {
1373
+ return yaml_emitter_set_emitter_error(emitter,
1374
+ "tag handle must end with '!'");
1375
+ }
1376
+
1377
+ handle.pointer ++;
1378
+
1379
+ while (handle.pointer < handle.end-1) {
1380
+ if (!IS_ALPHA(handle)) {
1381
+ return yaml_emitter_set_emitter_error(emitter,
1382
+ "tag handle must contain alphanumerical characters only");
1383
+ }
1384
+ MOVE(handle);
1385
+ }
1386
+
1387
+ if (prefix.start == prefix.end) {
1388
+ return yaml_emitter_set_emitter_error(emitter,
1389
+ "tag prefix must not be empty");
1390
+ }
1391
+
1392
+ return 1;
1393
+ }
1394
+
1395
+ /*
1396
+ * Check if an anchor is valid.
1397
+ */
1398
+
1399
+ static int
1400
+ yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1401
+ yaml_char_t *anchor, int alias)
1402
+ {
1403
+ size_t anchor_length;
1404
+ yaml_string_t string;
1405
+
1406
+ anchor_length = strlen((char *)anchor);
1407
+ STRING_ASSIGN(string, anchor, anchor_length);
1408
+
1409
+ if (string.start == string.end) {
1410
+ return yaml_emitter_set_emitter_error(emitter, alias ?
1411
+ "alias value must not be empty" :
1412
+ "anchor value must not be empty");
1413
+ }
1414
+
1415
+ while (string.pointer != string.end) {
1416
+ if (!IS_ALPHA(string)) {
1417
+ return yaml_emitter_set_emitter_error(emitter, alias ?
1418
+ "alias value must contain alphanumerical characters only" :
1419
+ "anchor value must contain alphanumerical characters only");
1420
+ }
1421
+ MOVE(string);
1422
+ }
1423
+
1424
+ emitter->anchor_data.anchor = string.start;
1425
+ emitter->anchor_data.anchor_length = string.end - string.start;
1426
+ emitter->anchor_data.alias = alias;
1427
+
1428
+ return 1;
1429
+ }
1430
+
1431
+ /*
1432
+ * Check if a tag is valid.
1433
+ */
1434
+
1435
+ static int
1436
+ yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1437
+ yaml_char_t *tag)
1438
+ {
1439
+ size_t tag_length;
1440
+ yaml_string_t string;
1441
+ yaml_tag_directive_t *tag_directive;
1442
+
1443
+ tag_length = strlen((char *)tag);
1444
+ STRING_ASSIGN(string, tag, tag_length);
1445
+
1446
+ if (string.start == string.end) {
1447
+ return yaml_emitter_set_emitter_error(emitter,
1448
+ "tag value must not be empty");
1449
+ }
1450
+
1451
+ for (tag_directive = emitter->tag_directives.start;
1452
+ tag_directive != emitter->tag_directives.top; tag_directive ++) {
1453
+ size_t prefix_length = strlen((char *)tag_directive->prefix);
1454
+ if (prefix_length < (size_t)(string.end - string.start)
1455
+ && strncmp((char *)tag_directive->prefix, (char *)string.start,
1456
+ prefix_length) == 0)
1457
+ {
1458
+ emitter->tag_data.handle = tag_directive->handle;
1459
+ emitter->tag_data.handle_length =
1460
+ strlen((char *)tag_directive->handle);
1461
+ emitter->tag_data.suffix = string.start + prefix_length;
1462
+ emitter->tag_data.suffix_length =
1463
+ (string.end - string.start) - prefix_length;
1464
+ return 1;
1465
+ }
1466
+ }
1467
+
1468
+ emitter->tag_data.suffix = string.start;
1469
+ emitter->tag_data.suffix_length = string.end - string.start;
1470
+
1471
+ return 1;
1472
+ }
1473
+
1474
+ /*
1475
+ * Check if a scalar is valid.
1476
+ */
1477
+
1478
+ static int
1479
+ yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1480
+ yaml_char_t *value, size_t length)
1481
+ {
1482
+ yaml_string_t string;
1483
+
1484
+ int block_indicators = 0;
1485
+ int flow_indicators = 0;
1486
+ int line_breaks = 0;
1487
+ int special_characters = 0;
1488
+
1489
+ int leading_space = 0;
1490
+ int leading_break = 0;
1491
+ int trailing_space = 0;
1492
+ int trailing_break = 0;
1493
+ int break_space = 0;
1494
+ int space_break = 0;
1495
+
1496
+ int preceeded_by_whitespace = 0;
1497
+ int followed_by_whitespace = 0;
1498
+ int previous_space = 0;
1499
+ int previous_break = 0;
1500
+
1501
+ STRING_ASSIGN(string, value, length);
1502
+
1503
+ emitter->scalar_data.value = value;
1504
+ emitter->scalar_data.length = length;
1505
+
1506
+ if (string.start == string.end)
1507
+ {
1508
+ emitter->scalar_data.multiline = 0;
1509
+ emitter->scalar_data.flow_plain_allowed = 0;
1510
+ emitter->scalar_data.block_plain_allowed = 1;
1511
+ emitter->scalar_data.single_quoted_allowed = 1;
1512
+ emitter->scalar_data.block_allowed = 0;
1513
+
1514
+ return 1;
1515
+ }
1516
+
1517
+ if ((CHECK_AT(string, '-', 0)
1518
+ && CHECK_AT(string, '-', 1)
1519
+ && CHECK_AT(string, '-', 2))
1520
+ || (CHECK_AT(string, '.', 0)
1521
+ && CHECK_AT(string, '.', 1)
1522
+ && CHECK_AT(string, '.', 2))) {
1523
+ block_indicators = 1;
1524
+ flow_indicators = 1;
1525
+ }
1526
+
1527
+ preceeded_by_whitespace = 1;
1528
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1529
+
1530
+ while (string.pointer != string.end)
1531
+ {
1532
+ if (string.start == string.pointer)
1533
+ {
1534
+ if (CHECK(string, '#') || CHECK(string, ',')
1535
+ || CHECK(string, '[') || CHECK(string, ']')
1536
+ || CHECK(string, '{') || CHECK(string, '}')
1537
+ || CHECK(string, '&') || CHECK(string, '*')
1538
+ || CHECK(string, '!') || CHECK(string, '|')
1539
+ || CHECK(string, '>') || CHECK(string, '\'')
1540
+ || CHECK(string, '"') || CHECK(string, '%')
1541
+ || CHECK(string, '@') || CHECK(string, '`')) {
1542
+ flow_indicators = 1;
1543
+ block_indicators = 1;
1544
+ }
1545
+
1546
+ if (CHECK(string, '?') || CHECK(string, ':')) {
1547
+ flow_indicators = 1;
1548
+ if (followed_by_whitespace) {
1549
+ block_indicators = 1;
1550
+ }
1551
+ }
1552
+
1553
+ if (CHECK(string, '-') && followed_by_whitespace) {
1554
+ flow_indicators = 1;
1555
+ block_indicators = 1;
1556
+ }
1557
+ }
1558
+ else
1559
+ {
1560
+ if (CHECK(string, ',') || CHECK(string, '?')
1561
+ || CHECK(string, '[') || CHECK(string, ']')
1562
+ || CHECK(string, '{') || CHECK(string, '}')) {
1563
+ flow_indicators = 1;
1564
+ }
1565
+
1566
+ if (CHECK(string, ':')) {
1567
+ flow_indicators = 1;
1568
+ if (followed_by_whitespace) {
1569
+ block_indicators = 1;
1570
+ }
1571
+ }
1572
+
1573
+ if (CHECK(string, '#') && preceeded_by_whitespace) {
1574
+ flow_indicators = 1;
1575
+ block_indicators = 1;
1576
+ }
1577
+ }
1578
+
1579
+ if (!IS_PRINTABLE(string)
1580
+ || (!IS_ASCII(string) && !emitter->unicode)) {
1581
+ special_characters = 1;
1582
+ }
1583
+
1584
+ if (IS_BREAK(string)) {
1585
+ line_breaks = 1;
1586
+ }
1587
+
1588
+ if (IS_SPACE(string))
1589
+ {
1590
+ if (string.start == string.pointer) {
1591
+ leading_space = 1;
1592
+ }
1593
+ if (string.pointer+WIDTH(string) == string.end) {
1594
+ trailing_space = 1;
1595
+ }
1596
+ if (previous_break) {
1597
+ break_space = 1;
1598
+ }
1599
+ previous_space = 1;
1600
+ previous_break = 0;
1601
+ }
1602
+ else if (IS_BREAK(string))
1603
+ {
1604
+ if (string.start == string.pointer) {
1605
+ leading_break = 1;
1606
+ }
1607
+ if (string.pointer+WIDTH(string) == string.end) {
1608
+ trailing_break = 1;
1609
+ }
1610
+ if (previous_space) {
1611
+ space_break = 1;
1612
+ }
1613
+ previous_space = 0;
1614
+ previous_break = 1;
1615
+ }
1616
+ else
1617
+ {
1618
+ previous_space = 0;
1619
+ previous_break = 0;
1620
+ }
1621
+
1622
+ preceeded_by_whitespace = IS_BLANKZ(string);
1623
+ MOVE(string);
1624
+ if (string.pointer != string.end) {
1625
+ followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1626
+ }
1627
+ }
1628
+
1629
+ emitter->scalar_data.multiline = line_breaks;
1630
+
1631
+ emitter->scalar_data.flow_plain_allowed = 1;
1632
+ emitter->scalar_data.block_plain_allowed = 1;
1633
+ emitter->scalar_data.single_quoted_allowed = 1;
1634
+ emitter->scalar_data.block_allowed = 1;
1635
+
1636
+ if (leading_space || leading_break || trailing_space || trailing_break) {
1637
+ emitter->scalar_data.flow_plain_allowed = 0;
1638
+ emitter->scalar_data.block_plain_allowed = 0;
1639
+ }
1640
+
1641
+ if (trailing_space) {
1642
+ emitter->scalar_data.block_allowed = 0;
1643
+ }
1644
+
1645
+ if (break_space) {
1646
+ emitter->scalar_data.flow_plain_allowed = 0;
1647
+ emitter->scalar_data.block_plain_allowed = 0;
1648
+ emitter->scalar_data.single_quoted_allowed = 0;
1649
+ }
1650
+
1651
+ if (space_break || special_characters) {
1652
+ emitter->scalar_data.flow_plain_allowed = 0;
1653
+ emitter->scalar_data.block_plain_allowed = 0;
1654
+ emitter->scalar_data.single_quoted_allowed = 0;
1655
+ emitter->scalar_data.block_allowed = 0;
1656
+ }
1657
+
1658
+ if (line_breaks) {
1659
+ emitter->scalar_data.flow_plain_allowed = 0;
1660
+ emitter->scalar_data.block_plain_allowed = 0;
1661
+ }
1662
+
1663
+ if (flow_indicators) {
1664
+ emitter->scalar_data.flow_plain_allowed = 0;
1665
+ }
1666
+
1667
+ if (block_indicators) {
1668
+ emitter->scalar_data.block_plain_allowed = 0;
1669
+ }
1670
+
1671
+ return 1;
1672
+ }
1673
+
1674
+ /*
1675
+ * Check if the event data is valid.
1676
+ */
1677
+
1678
+ static int
1679
+ yaml_emitter_analyze_event(yaml_emitter_t *emitter,
1680
+ yaml_event_t *event)
1681
+ {
1682
+ emitter->anchor_data.anchor = NULL;
1683
+ emitter->anchor_data.anchor_length = 0;
1684
+ emitter->tag_data.handle = NULL;
1685
+ emitter->tag_data.handle_length = 0;
1686
+ emitter->tag_data.suffix = NULL;
1687
+ emitter->tag_data.suffix_length = 0;
1688
+ emitter->scalar_data.value = NULL;
1689
+ emitter->scalar_data.length = 0;
1690
+
1691
+ switch (event->type)
1692
+ {
1693
+ case YAML_ALIAS_EVENT:
1694
+ if (!yaml_emitter_analyze_anchor(emitter,
1695
+ event->data.alias.anchor, 1))
1696
+ return 0;
1697
+ return 1;
1698
+
1699
+ case YAML_SCALAR_EVENT:
1700
+ if (event->data.scalar.anchor) {
1701
+ if (!yaml_emitter_analyze_anchor(emitter,
1702
+ event->data.scalar.anchor, 0))
1703
+ return 0;
1704
+ }
1705
+ if (event->data.scalar.tag && (emitter->canonical ||
1706
+ (!event->data.scalar.plain_implicit
1707
+ && !event->data.scalar.quoted_implicit))) {
1708
+ if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1709
+ return 0;
1710
+ }
1711
+ if (!yaml_emitter_analyze_scalar(emitter,
1712
+ event->data.scalar.value, event->data.scalar.length))
1713
+ return 0;
1714
+ return 1;
1715
+
1716
+ case YAML_SEQUENCE_START_EVENT:
1717
+ if (event->data.sequence_start.anchor) {
1718
+ if (!yaml_emitter_analyze_anchor(emitter,
1719
+ event->data.sequence_start.anchor, 0))
1720
+ return 0;
1721
+ }
1722
+ if (event->data.sequence_start.tag && (emitter->canonical ||
1723
+ !event->data.sequence_start.implicit)) {
1724
+ if (!yaml_emitter_analyze_tag(emitter,
1725
+ event->data.sequence_start.tag))
1726
+ return 0;
1727
+ }
1728
+ return 1;
1729
+
1730
+ case YAML_MAPPING_START_EVENT:
1731
+ if (event->data.mapping_start.anchor) {
1732
+ if (!yaml_emitter_analyze_anchor(emitter,
1733
+ event->data.mapping_start.anchor, 0))
1734
+ return 0;
1735
+ }
1736
+ if (event->data.mapping_start.tag && (emitter->canonical ||
1737
+ !event->data.mapping_start.implicit)) {
1738
+ if (!yaml_emitter_analyze_tag(emitter,
1739
+ event->data.mapping_start.tag))
1740
+ return 0;
1741
+ }
1742
+ return 1;
1743
+
1744
+ default:
1745
+ return 1;
1746
+ }
1747
+ }
1748
+
1749
+ /*
1750
+ * Write the BOM character.
1751
+ */
1752
+
1753
+ static int
1754
+ yaml_emitter_write_bom(yaml_emitter_t *emitter)
1755
+ {
1756
+ if (!FLUSH(emitter)) return 0;
1757
+
1758
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1759
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1760
+ *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1761
+
1762
+ return 1;
1763
+ }
1764
+
1765
+ static int
1766
+ yaml_emitter_write_indent(yaml_emitter_t *emitter)
1767
+ {
1768
+ int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1769
+
1770
+ if (!emitter->indention || emitter->column > indent
1771
+ || (emitter->column == indent && !emitter->whitespace)) {
1772
+ if (!PUT_BREAK(emitter)) return 0;
1773
+ }
1774
+
1775
+ while (emitter->column < indent) {
1776
+ if (!PUT(emitter, ' ')) return 0;
1777
+ }
1778
+
1779
+ emitter->whitespace = 1;
1780
+ emitter->indention = 1;
1781
+
1782
+ return 1;
1783
+ }
1784
+
1785
+ static int
1786
+ yaml_emitter_write_indicator(yaml_emitter_t *emitter,
1787
+ const char *indicator, int need_whitespace,
1788
+ int is_whitespace, int is_indention)
1789
+ {
1790
+ size_t indicator_length;
1791
+ yaml_string_t string;
1792
+
1793
+ indicator_length = strlen(indicator);
1794
+ STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
1795
+
1796
+ if (need_whitespace && !emitter->whitespace) {
1797
+ if (!PUT(emitter, ' ')) return 0;
1798
+ }
1799
+
1800
+ while (string.pointer != string.end) {
1801
+ if (!WRITE(emitter, string)) return 0;
1802
+ }
1803
+
1804
+ emitter->whitespace = is_whitespace;
1805
+ emitter->indention = (emitter->indention && is_indention);
1806
+ emitter->open_ended = 0;
1807
+
1808
+ return 1;
1809
+ }
1810
+
1811
+ static int
1812
+ yaml_emitter_write_anchor(yaml_emitter_t *emitter,
1813
+ yaml_char_t *value, size_t length)
1814
+ {
1815
+ yaml_string_t string;
1816
+ STRING_ASSIGN(string, value, length);
1817
+
1818
+ while (string.pointer != string.end) {
1819
+ if (!WRITE(emitter, string)) return 0;
1820
+ }
1821
+
1822
+ emitter->whitespace = 0;
1823
+ emitter->indention = 0;
1824
+
1825
+ return 1;
1826
+ }
1827
+
1828
+ static int
1829
+ yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1830
+ yaml_char_t *value, size_t length)
1831
+ {
1832
+ yaml_string_t string;
1833
+ STRING_ASSIGN(string, value, length);
1834
+
1835
+ if (!emitter->whitespace) {
1836
+ if (!PUT(emitter, ' ')) return 0;
1837
+ }
1838
+
1839
+ while (string.pointer != string.end) {
1840
+ if (!WRITE(emitter, string)) return 0;
1841
+ }
1842
+
1843
+ emitter->whitespace = 0;
1844
+ emitter->indention = 0;
1845
+
1846
+ return 1;
1847
+ }
1848
+
1849
+ static int
1850
+ yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1851
+ yaml_char_t *value, size_t length,
1852
+ int need_whitespace)
1853
+ {
1854
+ yaml_string_t string;
1855
+ STRING_ASSIGN(string, value, length);
1856
+
1857
+ if (need_whitespace && !emitter->whitespace) {
1858
+ if (!PUT(emitter, ' ')) return 0;
1859
+ }
1860
+
1861
+ while (string.pointer != string.end) {
1862
+ if (IS_ALPHA(string)
1863
+ || CHECK(string, ';') || CHECK(string, '/')
1864
+ || CHECK(string, '?') || CHECK(string, ':')
1865
+ || CHECK(string, '@') || CHECK(string, '&')
1866
+ || CHECK(string, '=') || CHECK(string, '+')
1867
+ || CHECK(string, '$') || CHECK(string, ',')
1868
+ || CHECK(string, '_') || CHECK(string, '.')
1869
+ || CHECK(string, '~') || CHECK(string, '*')
1870
+ || CHECK(string, '\'') || CHECK(string, '(')
1871
+ || CHECK(string, ')') || CHECK(string, '[')
1872
+ || CHECK(string, ']')) {
1873
+ if (!WRITE(emitter, string)) return 0;
1874
+ }
1875
+ else {
1876
+ int width = WIDTH(string);
1877
+ unsigned int value;
1878
+ while (width --) {
1879
+ value = *(string.pointer++);
1880
+ if (!PUT(emitter, '%')) return 0;
1881
+ if (!PUT(emitter, (value >> 4)
1882
+ + ((value >> 4) < 10 ? '0' : 'A' - 10)))
1883
+ return 0;
1884
+ if (!PUT(emitter, (value & 0x0F)
1885
+ + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
1886
+ return 0;
1887
+ }
1888
+ }
1889
+ }
1890
+
1891
+ emitter->whitespace = 0;
1892
+ emitter->indention = 0;
1893
+
1894
+ return 1;
1895
+ }
1896
+
1897
+ static int
1898
+ yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1899
+ yaml_char_t *value, size_t length, int allow_breaks)
1900
+ {
1901
+ yaml_string_t string;
1902
+ int spaces = 0;
1903
+ int breaks = 0;
1904
+
1905
+ STRING_ASSIGN(string, value, length);
1906
+
1907
+ if (!emitter->whitespace) {
1908
+ if (!PUT(emitter, ' ')) return 0;
1909
+ }
1910
+
1911
+ while (string.pointer != string.end)
1912
+ {
1913
+ if (IS_SPACE(string))
1914
+ {
1915
+ if (allow_breaks && !spaces
1916
+ && emitter->column > emitter->best_width
1917
+ && !IS_SPACE_AT(string, 1)) {
1918
+ if (!yaml_emitter_write_indent(emitter)) return 0;
1919
+ MOVE(string);
1920
+ }
1921
+ else {
1922
+ if (!WRITE(emitter, string)) return 0;
1923
+ }
1924
+ spaces = 1;
1925
+ }
1926
+ else if (IS_BREAK(string))
1927
+ {
1928
+ if (!breaks && CHECK(string, '\n')) {
1929
+ if (!PUT_BREAK(emitter)) return 0;
1930
+ }
1931
+ if (!WRITE_BREAK(emitter, string)) return 0;
1932
+ emitter->indention = 1;
1933
+ breaks = 1;
1934
+ }
1935
+ else
1936
+ {
1937
+ if (breaks) {
1938
+ if (!yaml_emitter_write_indent(emitter)) return 0;
1939
+ }
1940
+ if (!WRITE(emitter, string)) return 0;
1941
+ emitter->indention = 0;
1942
+ spaces = 0;
1943
+ breaks = 0;
1944
+ }
1945
+ }
1946
+
1947
+ emitter->whitespace = 0;
1948
+ emitter->indention = 0;
1949
+ if (emitter->root_context)
1950
+ {
1951
+ emitter->open_ended = 1;
1952
+ }
1953
+
1954
+ return 1;
1955
+ }
1956
+
1957
+ static int
1958
+ yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1959
+ yaml_char_t *value, size_t length, int allow_breaks)
1960
+ {
1961
+ yaml_string_t string;
1962
+ int spaces = 0;
1963
+ int breaks = 0;
1964
+
1965
+ STRING_ASSIGN(string, value, length);
1966
+
1967
+ if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
1968
+ return 0;
1969
+
1970
+ while (string.pointer != string.end)
1971
+ {
1972
+ if (IS_SPACE(string))
1973
+ {
1974
+ if (allow_breaks && !spaces
1975
+ && emitter->column > emitter->best_width
1976
+ && string.pointer != string.start
1977
+ && string.pointer != string.end - 1
1978
+ && !IS_SPACE_AT(string, 1)) {
1979
+ if (!yaml_emitter_write_indent(emitter)) return 0;
1980
+ MOVE(string);
1981
+ }
1982
+ else {
1983
+ if (!WRITE(emitter, string)) return 0;
1984
+ }
1985
+ spaces = 1;
1986
+ }
1987
+ else if (IS_BREAK(string))
1988
+ {
1989
+ if (!breaks && CHECK(string, '\n')) {
1990
+ if (!PUT_BREAK(emitter)) return 0;
1991
+ }
1992
+ if (!WRITE_BREAK(emitter, string)) return 0;
1993
+ emitter->indention = 1;
1994
+ breaks = 1;
1995
+ }
1996
+ else
1997
+ {
1998
+ if (breaks) {
1999
+ if (!yaml_emitter_write_indent(emitter)) return 0;
2000
+ }
2001
+ if (CHECK(string, '\'')) {
2002
+ if (!PUT(emitter, '\'')) return 0;
2003
+ }
2004
+ if (!WRITE(emitter, string)) return 0;
2005
+ emitter->indention = 0;
2006
+ spaces = 0;
2007
+ breaks = 0;
2008
+ }
2009
+ }
2010
+
2011
+ if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
2012
+ return 0;
2013
+
2014
+ emitter->whitespace = 0;
2015
+ emitter->indention = 0;
2016
+
2017
+ return 1;
2018
+ }
2019
+
2020
+ static int
2021
+ yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
2022
+ yaml_char_t *value, size_t length, int allow_breaks)
2023
+ {
2024
+ yaml_string_t string;
2025
+ int spaces = 0;
2026
+
2027
+ STRING_ASSIGN(string, value, length);
2028
+
2029
+ if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
2030
+ return 0;
2031
+
2032
+ while (string.pointer != string.end)
2033
+ {
2034
+ if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
2035
+ || IS_BOM(string) || IS_BREAK(string)
2036
+ || CHECK(string, '"') || CHECK(string, '\\'))
2037
+ {
2038
+ unsigned char octet;
2039
+ unsigned int width;
2040
+ unsigned int value;
2041
+ int k;
2042
+
2043
+ octet = string.pointer[0];
2044
+ width = (octet & 0x80) == 0x00 ? 1 :
2045
+ (octet & 0xE0) == 0xC0 ? 2 :
2046
+ (octet & 0xF0) == 0xE0 ? 3 :
2047
+ (octet & 0xF8) == 0xF0 ? 4 : 0;
2048
+ value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2049
+ (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2050
+ (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2051
+ (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2052
+ for (k = 1; k < (int)width; k ++) {
2053
+ octet = string.pointer[k];
2054
+ value = (value << 6) + (octet & 0x3F);
2055
+ }
2056
+ string.pointer += width;
2057
+
2058
+ if (!PUT(emitter, '\\')) return 0;
2059
+
2060
+ switch (value)
2061
+ {
2062
+ case 0x00:
2063
+ if (!PUT(emitter, '0')) return 0;
2064
+ break;
2065
+
2066
+ case 0x07:
2067
+ if (!PUT(emitter, 'a')) return 0;
2068
+ break;
2069
+
2070
+ case 0x08:
2071
+ if (!PUT(emitter, 'b')) return 0;
2072
+ break;
2073
+
2074
+ case 0x09:
2075
+ if (!PUT(emitter, 't')) return 0;
2076
+ break;
2077
+
2078
+ case 0x0A:
2079
+ if (!PUT(emitter, 'n')) return 0;
2080
+ break;
2081
+
2082
+ case 0x0B:
2083
+ if (!PUT(emitter, 'v')) return 0;
2084
+ break;
2085
+
2086
+ case 0x0C:
2087
+ if (!PUT(emitter, 'f')) return 0;
2088
+ break;
2089
+
2090
+ case 0x0D:
2091
+ if (!PUT(emitter, 'r')) return 0;
2092
+ break;
2093
+
2094
+ case 0x1B:
2095
+ if (!PUT(emitter, 'e')) return 0;
2096
+ break;
2097
+
2098
+ case 0x22:
2099
+ if (!PUT(emitter, '\"')) return 0;
2100
+ break;
2101
+
2102
+ case 0x5C:
2103
+ if (!PUT(emitter, '\\')) return 0;
2104
+ break;
2105
+
2106
+ case 0x85:
2107
+ if (!PUT(emitter, 'N')) return 0;
2108
+ break;
2109
+
2110
+ case 0xA0:
2111
+ if (!PUT(emitter, '_')) return 0;
2112
+ break;
2113
+
2114
+ case 0x2028:
2115
+ if (!PUT(emitter, 'L')) return 0;
2116
+ break;
2117
+
2118
+ case 0x2029:
2119
+ if (!PUT(emitter, 'P')) return 0;
2120
+ break;
2121
+
2122
+ default:
2123
+ if (value <= 0xFF) {
2124
+ if (!PUT(emitter, 'x')) return 0;
2125
+ width = 2;
2126
+ }
2127
+ else if (value <= 0xFFFF) {
2128
+ if (!PUT(emitter, 'u')) return 0;
2129
+ width = 4;
2130
+ }
2131
+ else {
2132
+ if (!PUT(emitter, 'U')) return 0;
2133
+ width = 8;
2134
+ }
2135
+ for (k = (width-1)*4; k >= 0; k -= 4) {
2136
+ int digit = (value >> k) & 0x0F;
2137
+ if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
2138
+ return 0;
2139
+ }
2140
+ }
2141
+ spaces = 0;
2142
+ }
2143
+ else if (IS_SPACE(string))
2144
+ {
2145
+ if (allow_breaks && !spaces
2146
+ && emitter->column > emitter->best_width
2147
+ && string.pointer != string.start
2148
+ && string.pointer != string.end - 1) {
2149
+ if (!yaml_emitter_write_indent(emitter)) return 0;
2150
+ if (IS_SPACE_AT(string, 1)) {
2151
+ if (!PUT(emitter, '\\')) return 0;
2152
+ }
2153
+ MOVE(string);
2154
+ }
2155
+ else {
2156
+ if (!WRITE(emitter, string)) return 0;
2157
+ }
2158
+ spaces = 1;
2159
+ }
2160
+ else
2161
+ {
2162
+ if (!WRITE(emitter, string)) return 0;
2163
+ spaces = 0;
2164
+ }
2165
+ }
2166
+
2167
+ if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
2168
+ return 0;
2169
+
2170
+ emitter->whitespace = 0;
2171
+ emitter->indention = 0;
2172
+
2173
+ return 1;
2174
+ }
2175
+
2176
+ static int
2177
+ yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
2178
+ yaml_string_t string)
2179
+ {
2180
+ char indent_hint[2];
2181
+ const char *chomp_hint = NULL;
2182
+
2183
+ if (IS_SPACE(string) || IS_BREAK(string))
2184
+ {
2185
+ indent_hint[0] = '0' + (char)emitter->best_indent;
2186
+ indent_hint[1] = '\0';
2187
+ if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
2188
+ return 0;
2189
+ }
2190
+
2191
+ emitter->open_ended = 0;
2192
+
2193
+ string.pointer = string.end;
2194
+ if (string.start == string.pointer)
2195
+ {
2196
+ chomp_hint = "-";
2197
+ }
2198
+ else
2199
+ {
2200
+ do {
2201
+ string.pointer --;
2202
+ } while ((*string.pointer & 0xC0) == 0x80);
2203
+ if (!IS_BREAK(string))
2204
+ {
2205
+ chomp_hint = "-";
2206
+ }
2207
+ else if (string.start == string.pointer)
2208
+ {
2209
+ chomp_hint = "+";
2210
+ emitter->open_ended = 1;
2211
+ }
2212
+ else
2213
+ {
2214
+ do {
2215
+ string.pointer --;
2216
+ } while ((*string.pointer & 0xC0) == 0x80);
2217
+ if (IS_BREAK(string))
2218
+ {
2219
+ chomp_hint = "+";
2220
+ emitter->open_ended = 1;
2221
+ }
2222
+ }
2223
+ }
2224
+
2225
+ if (chomp_hint)
2226
+ {
2227
+ if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
2228
+ return 0;
2229
+ }
2230
+
2231
+ return 1;
2232
+ }
2233
+
2234
+ static int
2235
+ yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
2236
+ yaml_char_t *value, size_t length)
2237
+ {
2238
+ yaml_string_t string;
2239
+ int breaks = 1;
2240
+
2241
+ STRING_ASSIGN(string, value, length);
2242
+
2243
+ if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
2244
+ return 0;
2245
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2246
+ return 0;
2247
+ if (!PUT_BREAK(emitter)) return 0;
2248
+ emitter->indention = 1;
2249
+ emitter->whitespace = 1;
2250
+
2251
+ while (string.pointer != string.end)
2252
+ {
2253
+ if (IS_BREAK(string))
2254
+ {
2255
+ if (!WRITE_BREAK(emitter, string)) return 0;
2256
+ emitter->indention = 1;
2257
+ breaks = 1;
2258
+ }
2259
+ else
2260
+ {
2261
+ if (breaks) {
2262
+ if (!yaml_emitter_write_indent(emitter)) return 0;
2263
+ }
2264
+ if (!WRITE(emitter, string)) return 0;
2265
+ emitter->indention = 0;
2266
+ breaks = 0;
2267
+ }
2268
+ }
2269
+
2270
+ return 1;
2271
+ }
2272
+
2273
+ static int
2274
+ yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
2275
+ yaml_char_t *value, size_t length)
2276
+ {
2277
+ yaml_string_t string;
2278
+ int breaks = 1;
2279
+ int leading_spaces = 1;
2280
+
2281
+ STRING_ASSIGN(string, value, length);
2282
+
2283
+ if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
2284
+ return 0;
2285
+ if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2286
+ return 0;
2287
+ if (!PUT_BREAK(emitter)) return 0;
2288
+ emitter->indention = 1;
2289
+ emitter->whitespace = 1;
2290
+
2291
+ while (string.pointer != string.end)
2292
+ {
2293
+ if (IS_BREAK(string))
2294
+ {
2295
+ if (!breaks && !leading_spaces && CHECK(string, '\n')) {
2296
+ int k = 0;
2297
+ while (IS_BREAK_AT(string, k)) {
2298
+ k += WIDTH_AT(string, k);
2299
+ }
2300
+ if (!IS_BLANKZ_AT(string, k)) {
2301
+ if (!PUT_BREAK(emitter)) return 0;
2302
+ }
2303
+ }
2304
+ if (!WRITE_BREAK(emitter, string)) return 0;
2305
+ emitter->indention = 1;
2306
+ breaks = 1;
2307
+ }
2308
+ else
2309
+ {
2310
+ if (breaks) {
2311
+ if (!yaml_emitter_write_indent(emitter)) return 0;
2312
+ leading_spaces = IS_BLANK(string);
2313
+ }
2314
+ if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
2315
+ && emitter->column > emitter->best_width) {
2316
+ if (!yaml_emitter_write_indent(emitter)) return 0;
2317
+ MOVE(string);
2318
+ }
2319
+ else {
2320
+ if (!WRITE(emitter, string)) return 0;
2321
+ }
2322
+ emitter->indention = 0;
2323
+ breaks = 0;
2324
+ }
2325
+ }
2326
+
2327
+ return 1;
2328
+ }
2329
+