source: libyaml/branches/stable/src/emitter.c @ 309

Revision 309, 62.8 KB checked in by xi, 5 years ago (diff)

Rewritten whitespace detection in the scalar analyzer and block scalar writers (ported from PyYAML).

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