source: libyaml/trunk/src/emitter.c @ 214

Revision 214, 50.1 KB checked in by xi, 8 years ago (diff)

Implement everything except tag and scalar writers.

RevLine 
[212]1
2#include "yaml_private.h"
3
4/*
[214]5 * Flush the buffer if needed.
6 */
7
8#define FLUSH(emitter)                                                          \
9    ((emitter->buffer.pointer+5 < emitter->buffer.end)                          \
10     || yaml_emitter_flush(emitter))
11
12/*
13 * Put a character to the output buffer.
14 */
15
16#define PUT(emitter,value)                                                      \
17    (FLUSH(emitter)                                                             \
18     && (*(emitter->buffer.pointer++) = (yaml_char_t)(value),                   \
19         emitter->column ++,                                                    \
20         1))
21
22/*
23 * Put a line break to the output buffer.
24 */
25
26#define PUT_BREAK(emitter)                                                      \
27    (FLUSH(emitter)                                                             \
28     && ((emitter->line_break == YAML_CR_BREAK ?                                \
29             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') :              \
30          emitter->line_break == YAML_LN_BREAK ?                                \
31             (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') :              \
32          emitter->line_break == YAML_CRLN_BREAK ?                              \
33             (*(emitter->buffer.pointer++) = (yaml_char_t) '\r',                \
34              *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0),          \
35         emitter->column = 0,                                                   \
36         emitter->line ++,                                                      \
37         1))
38
39/*
40 * Copy a character from a string into buffer.
41 */
42
43#define WRITE(emitter,string)                                                   \
44    (FLUSH(emitter)                                                             \
45     && (COPY(emitter->buffer,string),                                          \
46         emitter->column ++,                                                    \
47         1))
48
49/*
50 * Copy a line break character from a string into buffer.
51 */
52
53#define WRITE_BREAK(emitter,string)                                             \
54    (FLUSH(emitter)                                                             \
55     && (COPY(emitter->buffer,string),                                          \
56         emitter->column = 0,                                                   \
57         emitter->line ++,                                                      \
58         1))
59
60/*
[212]61 * API functions.
62 */
63
64YAML_DECLARE(int)
65yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
66
[213]67/*
68 * Utility functions.
69 */
70
71static int
72yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
73
74static int
75yaml_emitter_need_more_events(yaml_emitter_t *emitter);
76
77static int
78yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
79        yaml_tag_directive_t value, int allow_duplicates);
80
81static int
82yaml_emitter_increase_indent(yaml_emitter_t *emitter,
83        int flow, int indentless);
84
85/*
86 * State functions.
87 */
88
89static int
90yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
91
92static int
[212]93yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
[213]94        yaml_event_t *event);
[212]95
[213]96static int
[212]97yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
[213]98        yaml_event_t *event, int first);
[212]99
[213]100static int
101yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
102        yaml_event_t *event);
[212]103
[213]104static int
105yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
106        yaml_event_t *event);
[212]107
[213]108static int
109yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
110        yaml_event_t *event, int first);
111
112static int
113yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
114        yaml_event_t *event, int first);
115
116static int
117yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
118        yaml_event_t *event, int simple);
119
120static int
121yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
122        yaml_event_t *event, int first);
123
124static int
125yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
126        yaml_event_t *event, int first);
127
128static int
129yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
130        yaml_event_t *event, int simple);
131
132static int
133yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
134        int root, int sequence, int mapping, int simple_key);
135
136static int
137yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
138
139static int
140yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
141
142static int
143yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
144
145static int
146yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
147
148/*
149 * Checkers.
150 */
151
152static int
153yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
154
155static int
156yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
157
158static int
159yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
160
161static int
162yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
163
[214]164static int
165yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
166
[213]167/*
168 * Processors.
169 */
170
171static int
[214]172yaml_emitter_process_anchor(yaml_emitter_t *emitter);
173
174static int
175yaml_emitter_process_tag(yaml_emitter_t *emitter);
176
177static int
178yaml_emitter_process_scalar(yaml_emitter_t *emitter);
179
180/*
181 * Analyzers.
182 */
183
184static int
185yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
186        yaml_version_directive_t version_directive);
187
188static int
189yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
190        yaml_tag_directive_t tag_directive);
191
192static int
193yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
[213]194        yaml_char_t *anchor, int alias);
195
196static int
[214]197yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
[213]198        yaml_char_t *tag);
199
200static int
[214]201yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
202        yaml_char_t *value, size_t length);
[212]203
[214]204static int
205yaml_emitter_analyze_event(yaml_emitter_t *emitter,
206        yaml_event_t *event);
207
[213]208/*
209 * Writers.
210 */
[212]211
[213]212static int
213yaml_emitter_write_bom(yaml_emitter_t *emitter);
[212]214
[213]215static int
216yaml_emitter_write_indent(yaml_emitter_t *emitter);
217
218static int
219yaml_emitter_write_indicator(yaml_emitter_t *emitter,
220        char *indicator, int need_whitespace,
221        int is_whitespace, int is_indention);
222
[214]223static int
224yaml_emitter_write_anchor(yaml_emitter_t *emitter,
225        yaml_char_t *value, size_t length);
226
227static int
228yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
229        yaml_char_t *value, size_t length);
230
231static int
232yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
233        yaml_char_t *value, size_t length);
234
235static int
236yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
237        yaml_char_t *value, size_t length, int allow_breaks);
238
239static int
240yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
241        yaml_char_t *value, size_t length, int allow_breaks);
242
243static int
244yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
245        yaml_char_t *value, size_t length, int allow_breaks);
246
247static int
248yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
249        yaml_char_t *value, size_t length);
250
251static int
252yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
253        yaml_char_t *value, size_t length);
254
[212]255/*
[213]256 * Set an emitter error and return 0.
[212]257 */
258
[213]259static int
260yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
[212]261{
[213]262    emitter->error = YAML_EMITTER_ERROR;
263    emitter->problem = problem;
[212]264
[213]265    return 0;
[212]266}
267
268/*
[213]269 * Emit an event.
[212]270 */
271
272YAML_DECLARE(int)
[213]273yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
[212]274{
[213]275    if (!ENQUEUE(emitter, emitter->events, *event)) {
276        yaml_event_delete(event);
277        return 0;
278    }
[212]279
[213]280    while (!yaml_emitter_need_more_events(emitter)) {
[214]281        if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
[213]282            return 0;
[214]283        if (!yaml_emitter_state_machine(emitter, emitter->events.head))
284            return 0;
[213]285        DEQUEUE(emitter, emitter->events);
286    }
[212]287
[213]288    return 1;
[212]289}
290
291/*
[213]292 * Check if we need to accumulate more events before emitting.
293 *
294 * We accumulate extra
295 *  - 1 event for DOCUMENT-START
296 *  - 2 events for SEQUENCE-START
297 *  - 3 events for MAPPING-START
[212]298 */
299
[213]300static int
301yaml_emitter_need_more_events(yaml_emitter_t *emitter)
[212]302{
[213]303    int level = 0;
304    int accumulate = 0;
305    yaml_event_t *event;
[212]306
[213]307    if (QUEUE_EMPTY(emitter, emitter->events))
308        return 1;
[212]309
[213]310    switch (emitter->events.head->type) {
311        case YAML_DOCUMENT_START_EVENT:
312            accumulate = 1;
313            break;
314        case YAML_SEQUENCE_START_EVENT:
315            accumulate = 2;
316            break;
317        case YAML_MAPPING_START_EVENT:
318            accumulate = 3;
319            break;
320        default:
321            return 0;
[212]322    }
323
[213]324    if (emitter->events.tail - emitter->events.head > accumulate)
325        return 0;
326
327    for (event = emitter->events.head; event != emitter->events.tail; event ++) {
328        switch (event->type) {
329            case YAML_STREAM_START_EVENT:
330            case YAML_DOCUMENT_START_EVENT:
331            case YAML_SEQUENCE_START_EVENT:
332            case YAML_MAPPING_START_EVENT:
333                level += 1;
334                break;
335            case YAML_STREAM_END_EVENT:
336            case YAML_DOCUMENT_END_EVENT:
337            case YAML_SEQUENCE_END_EVENT:
338            case YAML_MAPPING_END_EVENT:
339                level -= 1;
340                break;
341            default:
342                break;
[212]343        }
[213]344        if (!level)
345            return 0;
[212]346    }
347
[213]348    return 1;
349}
[212]350
[213]351/*
352 * Append a directive to the directives stack.
353 */
354
355static int
356yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
357        yaml_tag_directive_t value, int allow_duplicates)
358{
359    yaml_tag_directive_t *tag_directive;
360    yaml_tag_directive_t copy = { NULL, NULL };
361
362    for (tag_directive = emitter->tag_directives.start;
363            tag_directive != emitter->tag_directives.top; tag_directive ++) {
364        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
365            if (allow_duplicates)
366                return 1;
367            return yaml_emitter_set_emitter_error(emitter,
368                    "duplicate %TAG directive");
369        }
[212]370    }
371
[213]372    copy.handle = yaml_strdup(value.handle);
373    copy.prefix = yaml_strdup(value.prefix);
374    if (!copy.handle || !copy.prefix) {
375        emitter->error = YAML_MEMORY_ERROR;
376        goto error;
[212]377    }
378
[213]379    if (!PUSH(emitter, emitter->tag_directives, copy))
380        goto error;
381
382    return 1;
383
384error:
385    yaml_free(copy.handle);
386    yaml_free(copy.prefix);
[212]387    return 0;
388}
389
390/*
[213]391 * Increase the indentation level.
[212]392 */
393
[213]394static int
395yaml_emitter_increase_indent(yaml_emitter_t *emitter,
396        int flow, int indentless)
[212]397{
[213]398    if (!PUSH(emitter, emitter->indents, emitter->indent))
399        return 0;
[212]400
[213]401    if (emitter->indent < 0) {
402        emitter->indent = flow ? emitter->best_indent : 0;
403    }
404    else if (!indentless) {
405        emitter->indent += emitter->best_indent;
406    }
[212]407
[213]408    return 1;
[212]409}
410
411/*
[213]412 * State dispatcher.
[212]413 */
414
[213]415static int
416yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
[212]417{
[213]418    switch (emitter->state)
419    {
420        case YAML_EMIT_STREAM_START_STATE:
421            return yaml_emitter_emit_stream_start(emitter, event);
[212]422
[213]423        case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
424            return yaml_emitter_emit_document_start(emitter, event, 1);
[212]425
[213]426        case YAML_EMIT_DOCUMENT_START_STATE:
427            return yaml_emitter_emit_document_start(emitter, event, 0);
[212]428
[213]429        case YAML_EMIT_DOCUMENT_CONTENT_STATE:
430            return yaml_emitter_emit_document_content(emitter, event);
[212]431
[213]432        case YAML_EMIT_DOCUMENT_END_STATE:
433            return yaml_emitter_emit_document_end(emitter, event);
434
435        case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
436            return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
437
438        case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
439            return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
440
441        case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
442            return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
443
444        case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
445            return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
446
447        case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
448            return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
449
450        case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
451            return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
452
453        case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
454            return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
455
456        case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
457            return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
458
459        case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
460            return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
461
462        case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
463            return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
464
465        case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
466            return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
467
468        case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
469            return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
470
471        case YAML_EMIT_END_STATE:
472            return yaml_emitter_set_emitter_error(emitter,
473                    "expected nothing after STREAM-END");
474
475        default:
476            assert(1);      /* Invalid state. */
[212]477    }
478
479    return 0;
480}
481
482/*
[213]483 * Expect STREAM-START.
[212]484 */
485
[213]486static int
487yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
488        yaml_event_t *event)
[212]489{
[213]490    if (event->type == YAML_STREAM_START_EVENT)
491    {
492        if (!emitter->encoding) {
493            emitter->encoding = event->data.stream_start.encoding;
494        }
[212]495
[213]496        if (!emitter->encoding) {
497            emitter->encoding = YAML_UTF8_ENCODING;
498        }
[212]499
[213]500        if (emitter->best_indent < 2 || emitter->best_indent > 9) {
501            emitter->best_indent  = 2;
[212]502        }
503
[213]504        if (emitter->best_width >= 0
505                && emitter->best_width <= emitter->best_indent*2) {
506            emitter->best_width = 80;
[212]507        }
[213]508
509        if (emitter->best_width < 0) {
510            emitter->best_width = INT_MAX;
511        }
512       
513        if (!emitter->line_break) {
514            emitter->line_break = YAML_LN_BREAK;
515        }
516
517        emitter->indent = -1;
518
519        emitter->line = 0;
520        emitter->column = 0;
521        emitter->whitespace = 1;
522        emitter->indention = 1;
523
524        if (emitter->encoding != YAML_UTF8_ENCODING) {
525            if (!yaml_emitter_write_bom(emitter))
526                return 0;
527        }
528
529        emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
530
531        return 1;
[212]532    }
533
[213]534    return yaml_emitter_set_emitter_error(emitter,
535            "expected STREAM-START");
536}
537
[214]538/*
539 * Expect DOCUMENT-START or STREAM-END.
540 */
541
[213]542static int
543yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
544        yaml_event_t *event, int first)
545{
546    if (event->type == YAML_DOCUMENT_START_EVENT)
547    {
548        yaml_tag_directive_t default_tag_directives[] = {
549            {(yaml_char_t *)"!", (yaml_char_t *)"!"},
550            {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
551            {NULL, NULL}
552        };
553        yaml_tag_directive_t *tag_directive;
554        int implicit;
555
556        if (event->data.document_start.version_directive) {
[214]557            if (!yaml_emitter_analyze_version_directive(emitter,
558                        *event->data.document_start.version_directive))
559                return 0;
[213]560        }
561
562        for (tag_directive = event->data.document_start.tag_directives.start;
563                tag_directive != event->data.document_start.tag_directives.end;
564                tag_directive ++) {
[214]565            if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
566                return 0;
[213]567            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
568                return 0;
569        }
570
571        for (tag_directive = default_tag_directives;
572                tag_directive->handle; tag_directive ++) {
573            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
574                return 0;
575        }
576
577        implicit = event->data.document_start.implicit;
578        if (!first || emitter->canonical) {
579            implicit = 0;
580        }
581
582        if (event->data.document_start.version_directive) {
583            implicit = 0;
[214]584            if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
[213]585                return 0;
[214]586            if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
587                return 0;
588            if (!yaml_emitter_write_indent(emitter))
589                return 0;
[213]590        }
591       
592        if (event->data.document_start.tag_directives.start
593                != event->data.document_start.tag_directives.end) {
594            implicit = 0;
595            for (tag_directive = event->data.document_start.tag_directives.start;
596                    tag_directive != event->data.document_start.tag_directives.end;
597                    tag_directive ++) {
[214]598                if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
[213]599                    return 0;
[214]600                if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
601                            strlen((char *)tag_directive->handle)))
602                    return 0;
603                if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
604                            strlen((char *)tag_directive->prefix)))
605                    return 0;
606                if (!yaml_emitter_write_indent(emitter))
607                    return 0;
[213]608            }
609        }
610
611        if (yaml_emitter_check_empty_document(emitter)) {
612            implicit = 0;
613        }
614
615        if (!implicit) {
616            if (!yaml_emitter_write_indent(emitter))
617                return 0;
618            if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
619                return 0;
620            if (emitter->canonical) {
621                if (!yaml_emitter_write_indent(emitter))
622                    return 0;
623            }
624        }
625
626        emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
627
628        return 1;
[212]629    }
630
[213]631    else if (event->type == YAML_STREAM_END_EVENT)
632    {
633        if (!yaml_emitter_flush(emitter))
634            return 0;
[212]635
[213]636        emitter->state = YAML_EMIT_END_STATE;
637
[212]638        return 1;
639    }
640
[213]641    return yaml_emitter_set_emitter_error(emitter,
642            "expected DOCUMENT-START or STREAM-END");
643}
[212]644
[214]645/*
646 * Expect the root node.
647 */
648
[213]649static int
650yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
651        yaml_event_t *event)
652{
653    if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
654        return 0;
655
656    return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
[212]657}
658
[214]659/*
660 * Expect DOCUMENT-END.
661 */
662
[213]663static int
664yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
665        yaml_event_t *event)
[212]666{
[213]667    if (event->type == YAML_DOCUMENT_END_EVENT)
668    {
669        if (!yaml_emitter_write_indent(emitter))
670            return 0;
671        if (!event->data.document_end.implicit) {
672            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
673                return 0;
674            if (!yaml_emitter_write_indent(emitter))
675                return 0;
676        }
677        if (!yaml_emitter_flush(emitter))
678            return 0;
[212]679
[213]680        emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
[212]681
[213]682        return 1;
[212]683    }
684
[213]685    return yaml_emitter_set_emitter_error(emitter,
686            "expected DOCUMENT-END");
687}
688
[214]689/*
690 * Expect a flow item node.
691 */
692
[213]693static int
694yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
695        yaml_event_t *event, int first)
696{
697    if (first)
698    {
699        if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
700            return 0;
701        if (!yaml_emitter_increase_indent(emitter, 1, 0))
702            return 0;
703        emitter->flow_level ++;
[212]704    }
705
[213]706    if (event->type == YAML_SEQUENCE_END_EVENT)
707    {
708        emitter->flow_level --;
709        emitter->indent = POP(emitter, emitter->indents);
710        if (emitter->canonical && !first) {
711            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
712                return 0;
713            if (!yaml_emitter_write_indent(emitter))
714                return 0;
715        }
716        if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
717            return 0;
718        emitter->state = POP(emitter, emitter->states);
[212]719
720        return 1;
721    }
722
[213]723    if (emitter->canonical || emitter->column > emitter->best_width) {
724        if (!yaml_emitter_write_indent(emitter))
725            return 0;
726    }
727    if (PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
728        return 0;
[212]729
[213]730    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
[212]731}
732
[214]733/*
734 * Expect a flow key node.
735 */
736
[213]737static int
738yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
739        yaml_event_t *event, int first)
[212]740{
[213]741    if (first)
742    {
743        if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
744            return 0;
745        if (!yaml_emitter_increase_indent(emitter, 1, 0))
746            return 0;
747        emitter->flow_level ++;
748    }
[212]749
[213]750    if (event->type == YAML_MAPPING_END_EVENT)
751    {
752        emitter->flow_level --;
753        emitter->indent = POP(emitter, emitter->indents);
754        if (emitter->canonical && !first) {
755            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
756                return 0;
757            if (!yaml_emitter_write_indent(emitter))
758                return 0;
759        }
760        if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
761            return 0;
762        emitter->state = POP(emitter, emitter->states);
[212]763
[213]764        return 1;
765    }
[212]766
[213]767    if (!first) {
768        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
769            return 0;
770    }
771    if (emitter->canonical || emitter->column > emitter->best_width) {
772        if (!yaml_emitter_write_indent(emitter))
773            return 0;
774    }
775
776    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
777    {
778        if (!PUSH(emitter, emitter->states,
779                    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
780            return 0;
781
782        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
783    }
784    else
785    {
786        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
787            return 0;
788        if (!PUSH(emitter, emitter->states,
789                    YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
790            return 0;
791
792        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
793    }
[212]794}
795
[214]796/*
797 * Expect a flow value node.
798 */
799
[213]800static int
801yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
802        yaml_event_t *event, int simple)
803{
804    if (simple) {
805        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
806            return 0;
807    }
808    else {
809        if (emitter->canonical || emitter->column > emitter->best_width) {
810            if (!yaml_emitter_write_indent(emitter))
811                return 0;
812        }
813        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
814            return 0;
815    }
816    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
817        return 0;
818    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
819}
[212]820
[214]821/*
822 * Expect a block item node.
823 */
824
[213]825static int
826yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
827        yaml_event_t *event, int first)
[212]828{
[213]829    if (first)
830    {
831        if (!yaml_emitter_increase_indent(emitter, 0,
832                    (emitter->mapping_context && !emitter->indention)))
833            return 0;
834    }
[212]835
[213]836    if (event->type == YAML_SEQUENCE_END_EVENT)
837    {
838        emitter->indent = POP(emitter, emitter->indents);
839        emitter->state = POP(emitter, emitter->states);
[212]840
[213]841        return 1;
[212]842    }
843
[213]844    if (!yaml_emitter_write_indent(emitter))
845        return 0;
846    if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
847        return 0;
848    if (!PUSH(emitter, emitter->states,
849                YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
850        return 0;
851
852    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
853}
854
[214]855/*
856 * Expect a block key node.
857 */
858
[213]859static int
860yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
861        yaml_event_t *event, int first)
862{
863    if (first)
864    {
865        if (!yaml_emitter_increase_indent(emitter, 0, 0))
866            return 0;
[212]867    }
868
[213]869    if (event->type == YAML_MAPPING_END_EVENT)
870    {
871        emitter->indent = POP(emitter, emitter->indents);
872        emitter->state = POP(emitter, emitter->states);
[212]873
874        return 1;
875    }
876
[213]877    if (!yaml_emitter_write_indent(emitter))
878        return 0;
[212]879
[213]880    if (yaml_emitter_check_simple_key(emitter))
881    {
882        if (!PUSH(emitter, emitter->states,
883                    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
884            return 0;
885
886        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
887    }
888    else
889    {
890        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
891            return 0;
892        if (!PUSH(emitter, emitter->states,
893                    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
894            return 0;
895
896        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
897    }
[212]898}
899
[214]900/*
901 * Expect a block value node.
902 */
903
[213]904static int
905yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
906        yaml_event_t *event, int simple)
907{
908    if (simple) {
909        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
910            return 0;
911    }
912    else {
913        if (!yaml_emitter_write_indent(emitter))
914            return 0;
915        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
916            return 0;
917    }
918    if (!PUSH(emitter, emitter->states,
919                YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
920        return 0;
[212]921
[213]922    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
923}
924
[214]925/*
926 * Expect a node.
927 */
928
[213]929static int
930yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
931        int root, int sequence, int mapping, int simple_key)
[212]932{
[213]933    emitter->root_context = root;
934    emitter->sequence_context = sequence;
935    emitter->mapping_context = mapping;
936    emitter->simple_key_context = simple_key;
[212]937
[213]938    switch (event->type)
939    {
940        case YAML_ALIAS_EVENT:
941            return yaml_emitter_emit_alias(emitter, event);
[212]942
[213]943        case YAML_SCALAR_EVENT:
944            return yaml_emitter_emit_scalar(emitter, event);
[212]945
[213]946        case YAML_SEQUENCE_START_EVENT:
947            return yaml_emitter_emit_sequence_start(emitter, event);
948
949        case YAML_MAPPING_START_EVENT:
950            return yaml_emitter_emit_mapping_start(emitter, event);
951
952        default:
953            return yaml_emitter_set_emitter_error(emitter,
954                    "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
955    }
956
957    return 0;
[212]958}
959
[214]960/*
961 * Expect ALIAS.
962 */
963
[213]964static int
965yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event)
966{
[214]967    if (!yaml_emitter_process_anchor(emitter))
[213]968        return 0;
969    emitter->state = POP(emitter, emitter->states);
[212]970
[213]971    return 1;
972}
973
[214]974/*
975 * Expect SCALAR.
976 */
977
[213]978static int
979yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
[212]980{
[214]981    if (!yaml_emitter_select_scalar_style(emitter, event))
[213]982        return 0;
[214]983    if (!yaml_emitter_process_anchor(emitter))
[213]984        return 0;
[214]985    if (!yaml_emitter_process_tag(emitter))
986        return 0;
[213]987    if (!yaml_emitter_increase_indent(emitter, 1, 0))
988        return 0;
[214]989    if (!yaml_emitter_process_scalar(emitter))
[213]990        return 0;
991    emitter->indent = POP(emitter, emitter->indents);
992    emitter->state = POP(emitter, emitter->states);
993
994    return 1;
[212]995}
996
[214]997/*
998 * Expect SEQUENCE-START.
999 */
1000
[213]1001static int
1002yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1003{
[214]1004    if (!yaml_emitter_process_anchor(emitter))
[213]1005        return 0;
[214]1006    if (!yaml_emitter_process_tag(emitter))
[213]1007        return 0;
1008
1009    if (emitter->flow_level || emitter->canonical
1010            || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1011            || yaml_emitter_check_empty_sequence(emitter)) {
1012        emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1013    }
1014    else {
1015        emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1016    }
1017
1018    return 1;
1019}
1020
[214]1021/*
1022 * Expect MAPPING-START.
1023 */
1024
[213]1025static int
1026yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1027{
[214]1028    if (!yaml_emitter_process_anchor(emitter))
[213]1029        return 0;
[214]1030    if (!yaml_emitter_process_tag(emitter))
[213]1031        return 0;
1032
1033    if (emitter->flow_level || emitter->canonical
1034            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1035            || yaml_emitter_check_empty_mapping(emitter)) {
1036        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1037    }
1038    else {
1039        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1040    }
1041
1042    return 1;
1043}
1044
[214]1045/*
1046 * Check if the document content is an empty scalar.
1047 */
1048
1049static int
1050yaml_emitter_check_empty_document(yaml_emitter_t *emitter)
1051{
1052    return 0;
1053}
1054
1055/*
1056 * Check if the next events represent an empty sequence.
1057 */
1058
1059static int
1060yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1061{
1062    if (emitter->events.tail - emitter->events.head < 2)
1063        return 0;
1064
1065    return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1066            && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1067}
1068
1069/*
1070 * Check if the next events represent an empty mapping.
1071 */
1072
1073static int
1074yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1075{
1076    if (emitter->events.tail - emitter->events.head < 2)
1077        return 0;
1078
1079    return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1080            && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1081}
1082
1083/*
1084 * Check if the next node can be expressed as a simple key.
1085 */
1086
1087static int
1088yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1089{
1090    yaml_event_t *event = emitter->events.head;
1091    size_t length = 0;
1092
1093    switch (event->type)
1094    {
1095        case YAML_ALIAS_EVENT:
1096            length += emitter->anchor_data.anchor_length;
1097            break;
1098
1099        case YAML_SCALAR_EVENT:
1100            if (emitter->scalar_data.multiline)
1101                return 0;
1102            length += emitter->anchor_data.anchor_length
1103                + emitter->tag_data.handle_length
1104                + emitter->tag_data.suffix_length
1105                + emitter->scalar_data.length;
1106            break;
1107
1108        case YAML_SEQUENCE_START_EVENT:
1109            if (!yaml_emitter_check_empty_sequence(emitter))
1110                return 0;
1111            length += emitter->anchor_data.anchor_length
1112                + emitter->tag_data.handle_length
1113                + emitter->tag_data.suffix_length;
1114            break;
1115
1116        case YAML_MAPPING_START_EVENT:
1117            if (!yaml_emitter_check_empty_sequence(emitter))
1118                return 0;
1119            length += emitter->anchor_data.anchor_length
1120                + emitter->tag_data.handle_length
1121                + emitter->tag_data.suffix_length;
1122            break;
1123
1124        default:
1125            return 0;
1126    }
1127
1128    if (length > 128)
1129        return 0;
1130
1131    return 1;
1132}
1133
1134/*
1135 * Determine an acceptable scalar style.
1136 */
1137
1138static int
1139yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1140{
1141    yaml_scalar_style_t style = event->data.scalar.style;
1142
1143    if (style == YAML_ANY_SCALAR_STYLE)
1144        style = YAML_PLAIN_SCALAR_STYLE;
1145
1146    if (emitter->canonical)
1147        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1148
1149    if (emitter->simple_key_context && emitter->scalar_data.multiline)
1150        style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1151
1152    if (style == YAML_PLAIN_SCALAR_STYLE)
1153    {
1154        if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1155                || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1156            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1157        if (!emitter->scalar_data.length
1158                && (emitter->flow_level || emitter->simple_key_context))
1159            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1160        if (!event->data.scalar.plain_implicit
1161                && !emitter->tag_data.handle && !emitter->tag_data.suffix)
1162            style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1163    }
1164
1165    if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1166    {
1167        if (!emitter->scalar_data.single_quoted_allowed)
1168            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1169    }
1170
1171    if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1172    {
1173        if (!emitter->scalar_data.block_allowed)
1174            style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1175    }
1176
1177    if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1178    {
1179        if (!event->data.scalar.plain_implicit
1180                && !event->data.scalar.quoted_implicit) {
1181            return yaml_emitter_set_emitter_error(emitter,
1182                    "neither tag nor implicit flags are specified");
1183        }
1184
1185        if (event->data.scalar.plain_implicit
1186                && style != YAML_PLAIN_SCALAR_STYLE) {
1187            emitter->tag_data.handle = (yaml_char_t *)"!";
1188            emitter->tag_data.handle_length = 1;
1189        }
1190    }
1191
1192    emitter->scalar_data.style = style;
1193
1194    return 1;
1195}
1196
1197/*
1198 * Write an achor.
1199 */
1200
1201static int
1202yaml_emitter_process_anchor(yaml_emitter_t *emitter)
1203{
1204    if (!emitter->anchor_data.anchor)
1205        return 1;
1206
1207    if (!yaml_emitter_write_indicator(emitter,
1208                (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1209        return 0;
1210
1211    return yaml_emitter_write_anchor(emitter,
1212            emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1213}
1214
1215/*
1216 * Write a tag.
1217 */
1218
1219static int
1220yaml_emitter_process_tag(yaml_emitter_t *emitter)
1221{
1222    if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1223        return 1;
1224
1225    if (emitter->tag_data.handle)
1226    {
1227        if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1228                    emitter->tag_data.handle_length))
1229            return 0;
1230        if (emitter->tag_data.suffix) {
1231            if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1232                        emitter->tag_data.suffix_length))
1233                return 0;
1234        }
1235    }
1236    else
1237    {
1238        if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1239            return 0;
1240        if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1241                    emitter->tag_data.suffix_length))
1242            return 0;
1243        if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1244            return 0;
1245    }
1246
1247    return 1;
1248}
1249
1250/*
1251 * Write a scalar.
1252 */
1253
1254static int
1255yaml_emitter_process_scalar(yaml_emitter_t *emitter)
1256{
1257    switch (emitter->scalar_data.style)
1258    {
1259        case YAML_PLAIN_SCALAR_STYLE:
1260            return yaml_emitter_write_plain_scalar(emitter,
1261                    emitter->scalar_data.value, emitter->scalar_data.length,
1262                    !emitter->simple_key_context);
1263
1264        case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1265            return yaml_emitter_write_single_quoted_scalar(emitter,
1266                    emitter->scalar_data.value, emitter->scalar_data.length,
1267                    !emitter->simple_key_context);
1268
1269        case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1270            return yaml_emitter_write_double_quoted_scalar(emitter,
1271                    emitter->scalar_data.value, emitter->scalar_data.length,
1272                    !emitter->simple_key_context);
1273
1274        case YAML_LITERAL_SCALAR_STYLE:
1275            return yaml_emitter_write_literal_scalar(emitter,
1276                    emitter->scalar_data.value, emitter->scalar_data.length);
1277
1278        case YAML_FOLDED_SCALAR_STYLE:
1279            return yaml_emitter_write_folded_scalar(emitter,
1280                    emitter->scalar_data.value, emitter->scalar_data.length);
1281
1282        default:
1283            assert(1);      /* Impossible. */
1284    }
1285
1286    return 0;
1287}
1288
1289/*
1290 * Check if a %YAML directive is valid.
1291 */
1292
1293static int
1294yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1295        yaml_version_directive_t version_directive)
1296{
1297    if (version_directive.major != 1 || version_directive.minor != 1) {
1298        return yaml_emitter_set_emitter_error(emitter,
1299                "incompatible %YAML directive");
1300    }
1301
1302    return 1;
1303}
1304
1305/*
1306 * Check if a %TAG directive is valid.
1307 */
1308
1309static int
1310yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1311        yaml_tag_directive_t tag_directive)
1312{
1313    yaml_string_t handle = STRING(tag_directive.handle,
1314            strlen((char *)tag_directive.handle));
1315    yaml_string_t prefix = STRING(tag_directive.prefix,
1316            strlen((char *)tag_directive.prefix));
1317
1318    if (handle.start == handle.end) {
1319        return yaml_emitter_set_emitter_error(emitter,
1320                "tag handle must not be empty");
1321    }
1322
1323    if (handle.start[0] != '!') {
1324        return yaml_emitter_set_emitter_error(emitter,
1325                "tag handle must start with '!'");
1326    }
1327
1328    if (handle.end[-1] != '!') {
1329        return yaml_emitter_set_emitter_error(emitter,
1330                "tag handle must end with '!'");
1331    }
1332
1333    handle.pointer ++;
1334
1335    while (handle.pointer != handle.end-1) {
1336        if (!IS_ALPHA(handle)) {
1337            return yaml_emitter_set_emitter_error(emitter,
1338                    "tag handle must contain alphanumerical characters only");
1339        }
1340        MOVE(handle);
1341    }
1342
1343    if (prefix.start == prefix.end) {
1344        return yaml_emitter_set_emitter_error(emitter,
1345                "tag prefix must not be empty");
1346    }
1347
1348    return 1;
1349}
1350
1351/*
1352 * Check if an anchor is valid.
1353 */
1354
1355static int
1356yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1357        yaml_char_t *anchor, int alias)
1358{
1359    yaml_string_t string = STRING(anchor, strlen((char *)anchor));
1360
1361    if (string.start == string.end) {
1362        return yaml_emitter_set_emitter_error(emitter, alias ?
1363                "alias value must not be empty" :
1364                "anchor value must not be empty");
1365    }
1366
1367    while (string.pointer != string.end) {
1368        if (!IS_ALPHA(string)) {
1369            return yaml_emitter_set_emitter_error(emitter, alias ?
1370                    "alias value must contain alphanumerical characters only" :
1371                    "anchor value must contain alphanumerical characters only");
1372        }
1373        MOVE(string);
1374    }
1375}
1376
1377/*
1378 * Check if a tag is valid.
1379 */
1380
1381static int
1382yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1383        yaml_char_t *tag)
1384{
1385    yaml_string_t string = STRING(tag, strlen((char *)tag));
1386    yaml_tag_directive_t *tag_directive;
1387
1388    if (string.start == string.end) {
1389        return yaml_emitter_set_emitter_error(emitter,
1390                "tag value must not be empty");
1391    }
1392
1393    for (tag_directive = emitter->tag_directives.start;
1394            tag_directive != emitter->tag_directives.end; tag_directive ++) {
1395        size_t prefix_length = strlen((char *)tag_directive->prefix);
1396        if (prefix_length < (string.end - string.start)
1397                && strncmp((char *)tag_directive->prefix, (char *)string.start,
1398                    prefix_length) == 0)
1399        {
1400            emitter->tag_data.handle = tag_directive->handle;
1401            emitter->tag_data.handle_length =
1402                strlen((char *)tag_directive->handle);
1403            emitter->tag_data.suffix = string.start + prefix_length;
1404            emitter->tag_data.suffix_length =
1405                (string.end - string.start) - prefix_length;
1406            return 1;
1407        }
1408    }
1409
1410    emitter->tag_data.suffix = string.start;
1411    emitter->tag_data.suffix_length = string.end - string.start;
1412
1413    return 1;
1414}
1415
1416/*
1417 * Check if a scalar is valid.
1418 */
1419
1420static int
1421yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1422        yaml_char_t *value, size_t length)
1423{
1424    yaml_string_t string = STRING(value, length);
1425
1426    int block_indicators = 0;
1427    int flow_indicators = 0;
1428    int line_breaks = 0;
1429    int special_characters = 0;
1430
1431    int inline_spaces = 0;
1432    int inline_breaks = 0;
1433    int leading_spaces = 0;
1434    int leading_breaks = 0;
1435    int trailing_spaces = 0;
1436    int trailing_breaks = 0;
1437    int inline_breaks_spaces = 0;
1438    int mixed_breaks_spaces = 0;
1439
1440    int preceeded_by_space = 0;
1441    int followed_by_space = 0;
1442    int spaces = 0;
1443    int breaks = 0;
1444    int mixed = 0;
1445    int leading = 0;
1446
1447    emitter->scalar_data.value = value;
1448    emitter->scalar_data.length = length;
1449
1450    if (string.start == string.end)
1451    {
1452        emitter->scalar_data.multiline = 0;
1453        emitter->scalar_data.flow_plain_allowed = 0;
1454        emitter->scalar_data.block_plain_allowed = 1;
1455        emitter->scalar_data.single_quoted_allowed = 1;
1456        emitter->scalar_data.block_allowed = 0;
1457
1458        return 1;
1459    }
1460
1461    if ((CHECK_AT(string, '-', 0)
1462                && CHECK_AT(string, '-', 1)
1463                && CHECK_AT(string, '-', 2))
1464            || (CHECK_AT(string, '.', 0)
1465                && CHECK_AT(string, '.', 1)
1466                && CHECK_AT(string, '.', 2))) {
1467        block_indicators = 1;
1468        flow_indicators = 1;
1469    }
1470
1471    preceeded_by_space = 1;
1472    followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
1473
1474    while (string.pointer != string.end)
1475    {
1476        if (string.start == string.pointer)
1477        {
1478            if (CHECK(string, '#') || CHECK(string, ',')
1479                    || CHECK(string, '[') || CHECK(string, ']')
1480                    || CHECK(string, '{') || CHECK(string, '}')
1481                    || CHECK(string, '&') || CHECK(string, '*')
1482                    || CHECK(string, '!') || CHECK(string, '|')
1483                    || CHECK(string, '>') || CHECK(string, '\'')
1484                    || CHECK(string, '"') || CHECK(string, '%')
1485                    || CHECK(string, '@') || CHECK(string, '`')) {
1486                flow_indicators = 1;
1487                block_indicators = 1;
1488            }
1489
1490            if (CHECK(string, '?') || CHECK(string, ':')) {
1491                flow_indicators = 1;
1492                if (followed_by_space) {
1493                    block_indicators = 1;
1494                }
1495            }
1496
1497            if (CHECK(string, '-') && followed_by_space) {
1498                flow_indicators = 1;
1499                block_indicators = 1;
1500            }
1501        }
1502        else
1503        {
1504            if (CHECK(string, ',') || CHECK(string, '?')
1505                    || CHECK(string, '[') || CHECK(string, ']')
1506                    || CHECK(string, '{') || CHECK(string, '}')) {
1507                flow_indicators = 1;
1508            }
1509
1510            if (CHECK(string, ':')) {
1511                flow_indicators = 1;
1512                if (followed_by_space) {
1513                    block_indicators = 1;
1514                }
1515            }
1516
1517            if (CHECK(string, '#') && preceeded_by_space) {
1518                flow_indicators = 1;
1519                block_indicators = 1;
1520            }
1521        }
1522
1523        if (!IS_PRINTABLE(string)
1524                || (!IS_ASCII(string) && !emitter->unicode)) {
1525            special_characters = 1;
1526        }
1527
1528        if (IS_BREAK(string)) {
1529            line_breaks = 1;
1530        }
1531
1532        if (IS_SPACE(string))
1533        {
1534            spaces = 1;
1535            if (string.start == string.pointer) {
1536                leading = 1;
1537            }
1538        }
1539
1540        else if (IS_BREAK(string))
1541        {
1542            if (spaces) {
1543                mixed = 1;
1544            }
1545            breaks = 1;
1546            if (string.start == string.pointer) {
1547                leading = 1;
1548            }
1549        }
1550
1551        else if (spaces || breaks)
1552        {
1553            if (leading) {
1554                if (spaces && breaks) {
1555                    mixed_breaks_spaces = 1;
1556                }
1557                else if (spaces) {
1558                    leading_spaces = 1;
1559                }
1560                else if (breaks) {
1561                    leading_breaks = 1;
1562                }
1563            }
1564            else {
1565                if (mixed) {
1566                    mixed_breaks_spaces = 1;
1567                }
1568                else if (spaces && breaks) {
1569                    inline_breaks_spaces = 1;
1570                }
1571                else if (spaces) {
1572                    inline_spaces = 1;
1573                }
1574                else if (breaks) {
1575                    inline_breaks = 1;
1576                }
1577            }
1578            spaces = breaks = mixed = leading = 0;
1579        }
1580
1581        preceeded_by_space = IS_BLANKZ(string);
1582        MOVE(string);
1583        if (string.pointer != string.end) {
1584            followed_by_space = IS_BLANKZ_AT(string, WIDTH(string));
1585        }
1586    }
1587
1588    emitter->scalar_data.multiline = line_breaks;
1589
1590    emitter->scalar_data.flow_plain_allowed = 1;
1591    emitter->scalar_data.block_plain_allowed = 1;
1592    emitter->scalar_data.single_quoted_allowed = 1;
1593    emitter->scalar_data.block_allowed = 1;
1594
1595    if (leading_spaces || leading_breaks || trailing_spaces) {
1596        emitter->scalar_data.flow_plain_allowed = 0;
1597        emitter->scalar_data.block_plain_allowed = 0;
1598        emitter->scalar_data.block_allowed = 0;
1599    }
1600
1601    if (trailing_breaks) {
1602        emitter->scalar_data.flow_plain_allowed = 0;
1603        emitter->scalar_data.block_plain_allowed = 0;
1604    }
1605
1606    if (inline_breaks_spaces) {
1607        emitter->scalar_data.flow_plain_allowed = 0;
1608        emitter->scalar_data.block_plain_allowed = 0;
1609        emitter->scalar_data.single_quoted_allowed = 0;
1610    }
1611
1612    if (mixed_breaks_spaces || special_characters) {
1613        emitter->scalar_data.flow_plain_allowed = 0;
1614        emitter->scalar_data.block_plain_allowed = 0;
1615        emitter->scalar_data.single_quoted_allowed = 0;
1616        emitter->scalar_data.block_allowed = 0;
1617    }
1618
1619    if (line_breaks) {
1620        emitter->scalar_data.flow_plain_allowed = 0;
1621        emitter->scalar_data.block_plain_allowed = 0;
1622    }
1623
1624    if (flow_indicators) {
1625        emitter->scalar_data.flow_plain_allowed = 0;
1626    }
1627
1628    if (block_indicators) {
1629        emitter->scalar_data.block_plain_allowed = 0;
1630    }
1631
1632    return 1;
1633}
1634
1635/*
1636 * Check if the event data is valid.
1637 */
1638
1639static int
1640yaml_emitter_analyze_event(yaml_emitter_t *emitter,
1641        yaml_event_t *event)
1642{
1643    emitter->anchor_data.anchor = NULL;
1644    emitter->anchor_data.anchor_length = 0;
1645    emitter->tag_data.handle = NULL;
1646    emitter->tag_data.handle_length = 0;
1647    emitter->tag_data.suffix = NULL;
1648    emitter->tag_data.suffix_length = 0;
1649    emitter->scalar_data.value = NULL;
1650    emitter->scalar_data.length = 0;
1651
1652    switch (event->type)
1653    {
1654        case YAML_ALIAS_EVENT:
1655            if (!yaml_emitter_analyze_anchor(emitter,
1656                        event->data.alias.anchor, 1))
1657                return 0;
1658            return 1;
1659
1660        case YAML_SCALAR_EVENT:
1661            if (event->data.scalar.anchor) {
1662                if (!yaml_emitter_analyze_anchor(emitter,
1663                            event->data.scalar.anchor, 0))
1664                    return 0;
1665            }
1666            if (event->data.scalar.tag && (emitter->canonical ||
1667                        (!event->data.scalar.plain_implicit
1668                         && !event->data.scalar.quoted_implicit))) {
1669                if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1670                    return 0;
1671            }
1672            if (!yaml_emitter_analyze_scalar(emitter,
1673                        event->data.scalar.value, event->data.scalar.length))
1674                return 0;
1675            return 1;
1676
1677        case YAML_SEQUENCE_START_EVENT:
1678            if (event->data.sequence_start.anchor) {
1679                if (!yaml_emitter_analyze_anchor(emitter,
1680                            event->data.sequence_start.anchor, 0))
1681                    return 0;
1682            }
1683            if (event->data.sequence_start.tag && (emitter->canonical ||
1684                        !event->data.sequence_start.implicit)) {
1685                if (!yaml_emitter_analyze_tag(emitter,
1686                            event->data.sequence_start.tag))
1687                    return 0;
1688            }
1689            return 1;
1690
1691        case YAML_MAPPING_START_EVENT:
1692            if (event->data.mapping_start.anchor) {
1693                if (!yaml_emitter_analyze_anchor(emitter,
1694                            event->data.mapping_start.anchor, 0))
1695                    return 0;
1696            }
1697            if (event->data.mapping_start.tag && (emitter->canonical ||
1698                        !event->data.mapping_start.implicit)) {
1699                if (!yaml_emitter_analyze_tag(emitter,
1700                            event->data.mapping_start.tag))
1701                    return 0;
1702            }
1703            return 1;
1704
1705        default:
1706            return 1;
1707    }
1708}
1709
1710/*
1711 * Write the BOM character.
1712 */
1713
1714static int
1715yaml_emitter_write_bom(yaml_emitter_t *emitter)
1716{
1717    if (!FLUSH(emitter)) return 0;
1718
1719    *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1720    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1721    *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1722
1723    return 1;
1724}
1725
1726static int
1727yaml_emitter_write_indent(yaml_emitter_t *emitter)
1728{
1729    int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1730
1731    if (!emitter->indention || emitter->column > indent
1732            || (emitter->column == indent && !emitter->whitespace)) {
1733        if (!PUT_BREAK(emitter)) return 0;
1734    }
1735
1736    while (emitter->column < indent) {
1737        if (!PUT(emitter, ' ')) return 0;
1738    }
1739
1740    emitter->whitespace = 1;
1741    emitter->indention = 1;
1742
1743    return 1;
1744}
1745
1746static int
1747yaml_emitter_write_indicator(yaml_emitter_t *emitter,
1748        char *indicator, int need_whitespace,
1749        int is_whitespace, int is_indention)
1750{
1751    yaml_string_t string = STRING((yaml_char_t *)indicator, strlen(indicator));
1752
1753    if (need_whitespace && !emitter->whitespace) {
1754        if (!PUT(emitter, ' ')) return 0;
1755    }
1756
1757    while (string.pointer != string.end) {
1758        if (!WRITE(emitter, string)) return 0;
1759    }
1760
1761    emitter->whitespace = is_whitespace;
1762    emitter->indention = (emitter->indention && is_indention);
1763
1764    return 1;
1765}
1766
1767static int
1768yaml_emitter_write_anchor(yaml_emitter_t *emitter,
1769        yaml_char_t *value, size_t length)
1770{
1771    yaml_string_t string = STRING(value, length);
1772
1773    while (string.pointer != string.end) {
1774        if (!WRITE(emitter, string)) return 0;
1775    }
1776
1777    emitter->whitespace = 0;
1778    emitter->indention = 0;
1779
1780    return 1;
1781}
1782
1783static int
1784yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1785        yaml_char_t *value, size_t length)
1786{
1787    yaml_string_t string = STRING(value, length);
1788
1789    while (string.pointer != string.end) {
1790        if (!WRITE(emitter, string)) return 0;
1791    }
1792
1793    emitter->whitespace = 0;
1794    emitter->indention = 0;
1795
1796    return 1;
1797}
1798
1799static int
1800yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1801        yaml_char_t *value, size_t length)
1802{
1803    return 0;
1804}
1805
1806static int
1807yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1808        yaml_char_t *value, size_t length, int allow_breaks)
1809{
1810    return 0;
1811}
1812
1813static int
1814yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1815        yaml_char_t *value, size_t length, int allow_breaks)
1816{
1817    return 0;
1818}
1819
1820static int
1821yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
1822        yaml_char_t *value, size_t length, int allow_breaks)
1823{
1824    return 0;
1825}
1826
1827static int
1828yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
1829        yaml_char_t *value, size_t length)
1830{
1831    return 0;
1832}
1833
1834static int
1835yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
1836        yaml_char_t *value, size_t length)
1837{
1838    return 0;
1839}
1840
Note: See TracBrowser for help on using the repository browser.