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