Ignore:
Timestamp:
07/26/06 16:32:16 (8 years ago)
Author:
xi
Message:

Implement Emitter state machine.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libyaml/trunk/src/emitter.c

    r212 r213  
    99yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); 
    1010 
    11 YAML_DECLARE(int) 
     11/* 
     12 * Utility functions. 
     13 */ 
     14 
     15static int 
     16yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem); 
     17 
     18static int 
     19yaml_emitter_need_more_events(yaml_emitter_t *emitter); 
     20 
     21static int 
     22yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, 
     23        yaml_tag_directive_t value, int allow_duplicates); 
     24 
     25static int 
     26yaml_emitter_increase_indent(yaml_emitter_t *emitter, 
     27        int flow, int indentless); 
     28 
     29/* 
     30 * State functions. 
     31 */ 
     32 
     33static int 
     34yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event); 
     35 
     36static int 
    1237yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 
    13         yaml_encoding_t encoding); 
    14  
    15 YAML_DECLARE(int) 
    16 yaml_emitter_emit_stream_end(yaml_emitter_t *emitter); 
    17  
    18 YAML_DECLARE(int) 
     38        yaml_event_t *event); 
     39 
     40static int 
    1941yaml_emitter_emit_document_start(yaml_emitter_t *emitter, 
    20         yaml_version_directive_t *version_directive, 
    21         yaml_tag_directive_t *tag_directives_start, 
    22         yaml_tag_directive_t *tag_directives_end, 
    23         int implicit); 
    24  
    25 YAML_DECLARE(int) 
    26 yaml_emitter_emit_document_end(yaml_emitter_t *emitter, int implicit); 
    27  
    28 YAML_DECLARE(int) 
    29 yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_char_t *anchor); 
    30  
    31 YAML_DECLARE(int) 
    32 yaml_emitter_emit_scalar(yaml_emitter_t *emitter, 
    33         yaml_char_t *anchor, yaml_char_t *tag, 
     42        yaml_event_t *event, int first); 
     43 
     44static int 
     45yaml_emitter_emit_document_content(yaml_emitter_t *emitter, 
     46        yaml_event_t *event); 
     47 
     48static int 
     49yaml_emitter_emit_document_end(yaml_emitter_t *emitter, 
     50        yaml_event_t *event); 
     51 
     52static int 
     53yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, 
     54        yaml_event_t *event, int first); 
     55 
     56static int 
     57yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, 
     58        yaml_event_t *event, int first); 
     59 
     60static int 
     61yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, 
     62        yaml_event_t *event, int simple); 
     63 
     64static int 
     65yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, 
     66        yaml_event_t *event, int first); 
     67 
     68static int 
     69yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, 
     70        yaml_event_t *event, int first); 
     71 
     72static int 
     73yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, 
     74        yaml_event_t *event, int simple); 
     75 
     76static int 
     77yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, 
     78        int root, int sequence, int mapping, int simple_key); 
     79 
     80static int 
     81yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event); 
     82 
     83static int 
     84yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event); 
     85 
     86static int 
     87yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event); 
     88 
     89static int 
     90yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event); 
     91 
     92/* 
     93 * Checkers. 
     94 */ 
     95 
     96static int 
     97yaml_emitter_check_empty_document(yaml_emitter_t *emitter); 
     98 
     99static int 
     100yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter); 
     101 
     102static int 
     103yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter); 
     104 
     105static int 
     106yaml_emitter_check_simple_key(yaml_emitter_t *emitter); 
     107 
     108/* 
     109 * Processors. 
     110 */ 
     111 
     112static int 
     113yaml_emitter_process_anchor(yaml_emitter_t *emitter, 
     114        yaml_char_t *anchor, int alias); 
     115 
     116static int 
     117yaml_emitter_process_tag(yaml_emitter_t *emitter, 
     118        yaml_char_t *tag); 
     119 
     120static int 
     121yaml_emitter_process_scalar(yaml_emitter_t *emitter, 
    34122        yaml_char_t *value, size_t length, 
    35123        int plain_implicit, int quoted_implicit, 
    36124        yaml_scalar_style_t style); 
    37125 
     126/* 
     127 * Writers. 
     128 */ 
     129 
     130static int 
     131yaml_emitter_write_bom(yaml_emitter_t *emitter); 
     132 
     133static int 
     134yaml_emitter_write_version_directive(yaml_emitter_t *emitter, 
     135        yaml_version_directive_t version_directive); 
     136 
     137static int 
     138yaml_emitter_write_tag_directive(yaml_emitter_t *emitter, 
     139        yaml_tag_directive_t tag_directive); 
     140 
     141static int 
     142yaml_emitter_write_indent(yaml_emitter_t *emitter); 
     143 
     144static int 
     145yaml_emitter_write_indicator(yaml_emitter_t *emitter, 
     146        char *indicator, int need_whitespace, 
     147        int is_whitespace, int is_indention); 
     148 
     149/* 
     150 * Set an emitter error and return 0. 
     151 */ 
     152 
     153static int 
     154yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem) 
     155{ 
     156    emitter->error = YAML_EMITTER_ERROR; 
     157    emitter->problem = problem; 
     158 
     159    return 0; 
     160} 
     161 
     162/* 
     163 * Emit an event. 
     164 */ 
     165 
    38166YAML_DECLARE(int) 
    39 yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, 
    40         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    41         yaml_sequence_style_t style); 
    42  
    43 YAML_DECLARE(int) 
    44 yaml_emitter_emit_sequence_end(yaml_emitter_t *emitter); 
    45  
    46 YAML_DECLARE(int) 
    47 yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, 
    48         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    49         yaml_mapping_style_t style); 
    50  
    51 YAML_DECLARE(int) 
    52 yaml_emitter_emit_mapping_end(yaml_emitter_t *emitter); 
    53  
    54 /* 
    55  * Emit STREAM-START. 
    56  */ 
    57  
    58 YAML_DECLARE(int) 
    59 yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 
    60         yaml_encoding_t encoding) 
    61 { 
    62     yaml_event_t event; 
    63     yaml_mark_t mark = { 0, 0, 0 }; 
    64  
    65     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    66  
    67     STREAM_START_EVENT_INIT(event, encoding, mark, mark); 
    68  
    69     return yaml_emitter_emit(emitter, &event); 
    70 } 
    71  
    72 /* 
    73  * Emit STREAM-END. 
    74  */ 
    75  
    76 YAML_DECLARE(int) 
    77 yaml_emitter_emit_stream_end(yaml_emitter_t *emitter) 
    78 { 
    79     yaml_event_t event; 
    80     yaml_mark_t mark = { 0, 0, 0 }; 
    81  
    82     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    83  
    84     STREAM_END_EVENT_INIT(event, mark, mark); 
    85  
    86     return yaml_emitter_emit(emitter, &event); 
    87 } 
    88  
    89 /* 
    90  * Emit DOCUMENT-START. 
    91  */ 
    92  
    93 YAML_DECLARE(int) 
    94 yaml_emitter_emit_document_start(yaml_emitter_t *emitter, 
    95         yaml_version_directive_t *version_directive, 
    96         yaml_tag_directive_t *tag_directives_start, 
    97         yaml_tag_directive_t *tag_directives_end, 
    98         int implicit) 
    99 { 
    100     yaml_event_t event; 
    101     yaml_mark_t mark = { 0, 0, 0 }; 
    102     yaml_version_directive_t *version_directive_copy = NULL; 
    103     struct { 
    104         yaml_tag_directive_t *start; 
    105         yaml_tag_directive_t *end; 
    106         yaml_tag_directive_t *top; 
    107     } tag_directives_copy = { NULL, NULL, NULL }; 
    108     yaml_tag_directive_t value = { NULL, NULL }; 
    109  
    110     assert(emitter);        /* Non-NULL emitter object is expected. */ 
    111     assert((tag_directives_start && tag_directives_end) || 
    112             (tag_directives_start == tag_directives_end)); 
    113                             /* Valid tag directives are expected. */ 
    114  
    115     if (version_directive) { 
    116         version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
    117         if (!version_directive_copy) { 
    118             emitter->error = YAML_MEMORY_ERROR; 
    119             goto error; 
    120         } 
    121         version_directive_copy->major = version_directive->major; 
    122         version_directive_copy->minor = version_directive->minor; 
    123     } 
    124  
    125     if (tag_directives_start != tag_directives_end) { 
    126         yaml_tag_directive_t *tag_directive; 
    127         if (!STACK_INIT(emitter, tag_directives_copy, INITIAL_STACK_SIZE)) 
    128             goto error; 
    129         for (tag_directive = tag_directives_start; 
    130                 tag_directive != tag_directives_end; tag_directive ++) { 
    131             value.handle = yaml_strdup(tag_directive->handle); 
    132             value.prefix = yaml_strdup(tag_directive->prefix); 
    133             if (!value.handle || !value.prefix) { 
    134                 emitter->error = YAML_MEMORY_ERROR; 
    135                 goto error; 
    136             } 
    137             if (!PUSH(emitter, tag_directives_copy, value)) 
    138                 goto error; 
    139             value.handle = NULL; 
    140             value.prefix = NULL; 
    141         } 
    142     } 
    143  
    144     DOCUMENT_START_EVENT_INIT(event, version_directive_copy, 
    145             tag_directives_copy.start, tag_directives_copy.end, 
    146             implicit, mark, mark); 
    147  
    148     if (yaml_emitter_emit(emitter, &event)) { 
     167yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) 
     168{ 
     169    if (!ENQUEUE(emitter, emitter->events, *event)) { 
     170        yaml_event_delete(event); 
     171        return 0; 
     172    } 
     173 
     174    while (!yaml_emitter_need_more_events(emitter)) { 
     175        if (!yaml_emitter_state_machine(emitter, emitter->events.head)) { 
     176            return 0; 
     177        } 
     178        DEQUEUE(emitter, emitter->events); 
     179    } 
     180 
     181    return 1; 
     182} 
     183 
     184/* 
     185 * Check if we need to accumulate more events before emitting. 
     186 * 
     187 * We accumulate extra 
     188 *  - 1 event for DOCUMENT-START 
     189 *  - 2 events for SEQUENCE-START 
     190 *  - 3 events for MAPPING-START 
     191 */ 
     192 
     193static int 
     194yaml_emitter_need_more_events(yaml_emitter_t *emitter) 
     195{ 
     196    int level = 0; 
     197    int accumulate = 0; 
     198    yaml_event_t *event; 
     199 
     200    if (QUEUE_EMPTY(emitter, emitter->events)) 
    149201        return 1; 
    150     } 
    151  
    152 error: 
    153     yaml_free(version_directive_copy); 
    154     while (!STACK_EMPTY(emitter, tag_directives_copy)) { 
    155         yaml_tag_directive_t value = POP(emitter, tag_directives_copy); 
    156         yaml_free(value.handle); 
    157         yaml_free(value.prefix); 
    158     } 
    159     STACK_DEL(emitter, tag_directives_copy); 
    160     yaml_free(value.handle); 
    161     yaml_free(value.prefix); 
    162  
    163     return 0; 
    164 } 
    165  
    166 /* 
    167  * Emit DOCUMENT-END. 
    168  */ 
    169  
    170 YAML_DECLARE(int) 
    171 yaml_emitter_emit_document_end(yaml_emitter_t *emitter, int implicit) 
    172 { 
    173     yaml_event_t event; 
    174     yaml_mark_t mark = { 0, 0, 0 }; 
    175  
    176     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    177  
    178     DOCUMENT_END_EVENT_INIT(event, implicit, mark, mark); 
    179  
    180     return yaml_emitter_emit(emitter, &event); 
    181 } 
    182  
    183 /* 
    184  * Emit ALIAS. 
    185  */ 
    186  
    187 YAML_DECLARE(int) 
    188 yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_char_t *anchor) 
    189 { 
    190     yaml_event_t event; 
    191     yaml_mark_t mark = { 0, 0, 0 }; 
    192     yaml_char_t *anchor_copy = NULL; 
    193  
    194     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    195     assert(anchor);     /* Non-NULL anchor is expected. */ 
    196  
    197     anchor_copy = yaml_strdup(anchor); 
    198     if (!anchor_copy) { 
    199         emitter->error = YAML_MEMORY_ERROR; 
    200         return 0; 
    201     } 
    202  
    203     ALIAS_EVENT_INIT(event, anchor_copy, mark, mark); 
    204  
    205     if (yaml_emitter_emit(emitter, &event)) { 
    206         return 1; 
    207     } 
    208  
    209     yaml_free(anchor_copy); 
    210  
    211     return 0; 
    212 } 
    213  
    214 /* 
    215  * Emit SCALAR. 
    216  */ 
    217  
    218 YAML_DECLARE(int) 
    219 yaml_emitter_emit_scalar(yaml_emitter_t *emitter, 
    220         yaml_char_t *anchor, yaml_char_t *tag, 
    221         yaml_char_t *value, size_t length, 
    222         int plain_implicit, int quoted_implicit, 
    223         yaml_scalar_style_t style) 
    224 { 
    225     yaml_event_t event; 
    226     yaml_mark_t mark = { 0, 0, 0 }; 
    227     yaml_char_t *anchor_copy = NULL; 
    228     yaml_char_t *tag_copy = NULL; 
    229     yaml_char_t *value_copy = NULL; 
    230  
    231     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    232     assert(value);      /* Non-NULL anchor is expected. */ 
    233  
    234     if (anchor) { 
    235         anchor_copy = yaml_strdup(anchor); 
    236         if (!anchor_copy) { 
    237             emitter->error = YAML_MEMORY_ERROR; 
    238             goto error; 
    239         } 
    240     } 
    241  
    242     if (tag) { 
    243         tag_copy = yaml_strdup(tag); 
    244         if (!tag_copy) { 
    245             emitter->error = YAML_MEMORY_ERROR; 
    246             goto error; 
    247         } 
    248     } 
    249  
    250     value_copy = yaml_malloc(length+1); 
    251     if (!value_copy) { 
     202 
     203    switch (emitter->events.head->type) { 
     204        case YAML_DOCUMENT_START_EVENT: 
     205            accumulate = 1; 
     206            break; 
     207        case YAML_SEQUENCE_START_EVENT: 
     208            accumulate = 2; 
     209            break; 
     210        case YAML_MAPPING_START_EVENT: 
     211            accumulate = 3; 
     212            break; 
     213        default: 
     214            return 0; 
     215    } 
     216 
     217    if (emitter->events.tail - emitter->events.head > accumulate) 
     218        return 0; 
     219 
     220    for (event = emitter->events.head; event != emitter->events.tail; event ++) { 
     221        switch (event->type) { 
     222            case YAML_STREAM_START_EVENT: 
     223            case YAML_DOCUMENT_START_EVENT: 
     224            case YAML_SEQUENCE_START_EVENT: 
     225            case YAML_MAPPING_START_EVENT: 
     226                level += 1; 
     227                break; 
     228            case YAML_STREAM_END_EVENT: 
     229            case YAML_DOCUMENT_END_EVENT: 
     230            case YAML_SEQUENCE_END_EVENT: 
     231            case YAML_MAPPING_END_EVENT: 
     232                level -= 1; 
     233                break; 
     234            default: 
     235                break; 
     236        } 
     237        if (!level) 
     238            return 0; 
     239    } 
     240 
     241    return 1; 
     242} 
     243 
     244/* 
     245 * Append a directive to the directives stack. 
     246 */ 
     247 
     248static int 
     249yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, 
     250        yaml_tag_directive_t value, int allow_duplicates) 
     251{ 
     252    yaml_tag_directive_t *tag_directive; 
     253    yaml_tag_directive_t copy = { NULL, NULL }; 
     254 
     255    for (tag_directive = emitter->tag_directives.start; 
     256            tag_directive != emitter->tag_directives.top; tag_directive ++) { 
     257        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { 
     258            if (allow_duplicates) 
     259                return 1; 
     260            return yaml_emitter_set_emitter_error(emitter, 
     261                    "duplicate %TAG directive"); 
     262        } 
     263    } 
     264 
     265    copy.handle = yaml_strdup(value.handle); 
     266    copy.prefix = yaml_strdup(value.prefix); 
     267    if (!copy.handle || !copy.prefix) { 
    252268        emitter->error = YAML_MEMORY_ERROR; 
    253269        goto error; 
    254270    } 
    255     memcpy(value_copy, value, length); 
    256     value_copy[length] = '\0'; 
    257  
    258     SCALAR_EVENT_INIT(event, anchor_copy, tag_copy, value_copy, length, 
    259             plain_implicit, quoted_implicit, style, mark, mark); 
    260  
    261     if (yaml_emitter_emit(emitter, &event)) { 
     271 
     272    if (!PUSH(emitter, emitter->tag_directives, copy)) 
     273        goto error; 
     274 
     275    return 1; 
     276 
     277error: 
     278    yaml_free(copy.handle); 
     279    yaml_free(copy.prefix); 
     280    return 0; 
     281} 
     282 
     283/* 
     284 * Increase the indentation level. 
     285 */ 
     286 
     287static int 
     288yaml_emitter_increase_indent(yaml_emitter_t *emitter, 
     289        int flow, int indentless) 
     290{ 
     291    if (!PUSH(emitter, emitter->indents, emitter->indent)) 
     292        return 0; 
     293 
     294    if (emitter->indent < 0) { 
     295        emitter->indent = flow ? emitter->best_indent : 0; 
     296    } 
     297    else if (!indentless) { 
     298        emitter->indent += emitter->best_indent; 
     299    } 
     300 
     301    return 1; 
     302} 
     303 
     304/* 
     305 * State dispatcher. 
     306 */ 
     307 
     308static int 
     309yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event) 
     310{ 
     311    switch (emitter->state) 
     312    { 
     313        case YAML_EMIT_STREAM_START_STATE: 
     314            return yaml_emitter_emit_stream_start(emitter, event); 
     315 
     316        case YAML_EMIT_FIRST_DOCUMENT_START_STATE: 
     317            return yaml_emitter_emit_document_start(emitter, event, 1); 
     318 
     319        case YAML_EMIT_DOCUMENT_START_STATE: 
     320            return yaml_emitter_emit_document_start(emitter, event, 0); 
     321 
     322        case YAML_EMIT_DOCUMENT_CONTENT_STATE: 
     323            return yaml_emitter_emit_document_content(emitter, event); 
     324 
     325        case YAML_EMIT_DOCUMENT_END_STATE: 
     326            return yaml_emitter_emit_document_end(emitter, event); 
     327 
     328        case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: 
     329            return yaml_emitter_emit_flow_sequence_item(emitter, event, 1); 
     330 
     331        case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: 
     332            return yaml_emitter_emit_flow_sequence_item(emitter, event, 0); 
     333 
     334        case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: 
     335            return yaml_emitter_emit_flow_mapping_key(emitter, event, 1); 
     336 
     337        case YAML_EMIT_FLOW_MAPPING_KEY_STATE: 
     338            return yaml_emitter_emit_flow_mapping_key(emitter, event, 0); 
     339 
     340        case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: 
     341            return yaml_emitter_emit_flow_mapping_value(emitter, event, 1); 
     342 
     343        case YAML_EMIT_FLOW_MAPPING_VALUE_STATE: 
     344            return yaml_emitter_emit_flow_mapping_value(emitter, event, 0); 
     345 
     346        case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: 
     347            return yaml_emitter_emit_block_sequence_item(emitter, event, 1); 
     348 
     349        case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: 
     350            return yaml_emitter_emit_block_sequence_item(emitter, event, 0); 
     351 
     352        case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: 
     353            return yaml_emitter_emit_block_mapping_key(emitter, event, 1); 
     354 
     355        case YAML_EMIT_BLOCK_MAPPING_KEY_STATE: 
     356            return yaml_emitter_emit_block_mapping_key(emitter, event, 0); 
     357 
     358        case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: 
     359            return yaml_emitter_emit_block_mapping_value(emitter, event, 1); 
     360 
     361        case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: 
     362            return yaml_emitter_emit_block_mapping_value(emitter, event, 0); 
     363 
     364        case YAML_EMIT_END_STATE: 
     365            return yaml_emitter_set_emitter_error(emitter, 
     366                    "expected nothing after STREAM-END"); 
     367 
     368        default: 
     369            assert(1);      /* Invalid state. */ 
     370    } 
     371 
     372    return 0; 
     373} 
     374 
     375/* 
     376 * Expect STREAM-START. 
     377 */ 
     378 
     379static int 
     380yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 
     381        yaml_event_t *event) 
     382{ 
     383    if (event->type == YAML_STREAM_START_EVENT) 
     384    { 
     385        if (!emitter->encoding) { 
     386            emitter->encoding = event->data.stream_start.encoding; 
     387        } 
     388 
     389        if (!emitter->encoding) { 
     390            emitter->encoding = YAML_UTF8_ENCODING; 
     391        } 
     392 
     393        if (emitter->best_indent < 2 || emitter->best_indent > 9) { 
     394            emitter->best_indent  = 2; 
     395        } 
     396 
     397        if (emitter->best_width >= 0 
     398                && emitter->best_width <= emitter->best_indent*2) { 
     399            emitter->best_width = 80; 
     400        } 
     401 
     402        if (emitter->best_width < 0) { 
     403            emitter->best_width = INT_MAX; 
     404        } 
     405         
     406        if (!emitter->line_break) { 
     407            emitter->line_break = YAML_LN_BREAK; 
     408        } 
     409 
     410        emitter->indent = -1; 
     411 
     412        emitter->line = 0; 
     413        emitter->column = 0; 
     414        emitter->whitespace = 1; 
     415        emitter->indention = 1; 
     416 
     417        if (emitter->encoding != YAML_UTF8_ENCODING) { 
     418            if (!yaml_emitter_write_bom(emitter)) 
     419                return 0; 
     420        } 
     421 
     422        emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE; 
     423 
    262424        return 1; 
    263425    } 
    264426 
    265 error: 
    266     yaml_free(anchor_copy); 
    267     yaml_free(tag_copy); 
    268     yaml_free(value_copy); 
     427    return yaml_emitter_set_emitter_error(emitter, 
     428            "expected STREAM-START"); 
     429} 
     430 
     431static int 
     432yaml_emitter_emit_document_start(yaml_emitter_t *emitter, 
     433        yaml_event_t *event, int first) 
     434{ 
     435    if (event->type == YAML_DOCUMENT_START_EVENT) 
     436    { 
     437        yaml_tag_directive_t default_tag_directives[] = { 
     438            {(yaml_char_t *)"!", (yaml_char_t *)"!"}, 
     439            {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, 
     440            {NULL, NULL} 
     441        }; 
     442        yaml_tag_directive_t *tag_directive; 
     443        int implicit; 
     444 
     445        if (event->data.document_start.version_directive) { 
     446            if (event->data.document_start.version_directive->major != 1 
     447                    || event->data.document_start.version_directive-> minor != 1) { 
     448                return yaml_emitter_set_emitter_error(emitter, 
     449                        "incompatible %YAML directive"); 
     450            } 
     451        } 
     452 
     453        for (tag_directive = event->data.document_start.tag_directives.start; 
     454                tag_directive != event->data.document_start.tag_directives.end; 
     455                tag_directive ++) { 
     456            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0)) 
     457                return 0; 
     458        } 
     459 
     460        for (tag_directive = default_tag_directives; 
     461                tag_directive->handle; tag_directive ++) { 
     462            if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1)) 
     463                return 0; 
     464        } 
     465 
     466        implicit = event->data.document_start.implicit; 
     467        if (!first || emitter->canonical) { 
     468            implicit = 0; 
     469        } 
     470 
     471        if (event->data.document_start.version_directive) { 
     472            implicit = 0; 
     473            if (!yaml_emitter_write_version_directive(emitter, 
     474                        *event->data.document_start.version_directive)) 
     475                return 0; 
     476        } 
     477         
     478        if (event->data.document_start.tag_directives.start 
     479                != event->data.document_start.tag_directives.end) { 
     480            implicit = 0; 
     481            for (tag_directive = event->data.document_start.tag_directives.start; 
     482                    tag_directive != event->data.document_start.tag_directives.end; 
     483                    tag_directive ++) { 
     484                if (!yaml_emitter_write_tag_directive(emitter, *tag_directive)) 
     485                    return 0; 
     486            } 
     487        } 
     488 
     489        if (yaml_emitter_check_empty_document(emitter)) { 
     490            implicit = 0; 
     491        } 
     492 
     493        if (!implicit) { 
     494            if (!yaml_emitter_write_indent(emitter)) 
     495                return 0; 
     496            if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0)) 
     497                return 0; 
     498            if (emitter->canonical) { 
     499                if (!yaml_emitter_write_indent(emitter)) 
     500                    return 0; 
     501            } 
     502        } 
     503 
     504        emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE; 
     505 
     506        return 1; 
     507    } 
     508 
     509    else if (event->type == YAML_STREAM_END_EVENT) 
     510    { 
     511        if (!yaml_emitter_flush(emitter)) 
     512            return 0; 
     513 
     514        emitter->state = YAML_EMIT_END_STATE; 
     515 
     516        return 1; 
     517    } 
     518 
     519    return yaml_emitter_set_emitter_error(emitter, 
     520            "expected DOCUMENT-START or STREAM-END"); 
     521} 
     522 
     523static int 
     524yaml_emitter_emit_document_content(yaml_emitter_t *emitter, 
     525        yaml_event_t *event) 
     526{ 
     527    if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE)) 
     528        return 0; 
     529 
     530    return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0); 
     531} 
     532 
     533static int 
     534yaml_emitter_emit_document_end(yaml_emitter_t *emitter, 
     535        yaml_event_t *event) 
     536{ 
     537    if (event->type == YAML_DOCUMENT_END_EVENT) 
     538    { 
     539        if (!yaml_emitter_write_indent(emitter)) 
     540            return 0; 
     541        if (!event->data.document_end.implicit) { 
     542            if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) 
     543                return 0; 
     544            if (!yaml_emitter_write_indent(emitter)) 
     545                return 0; 
     546        } 
     547        if (!yaml_emitter_flush(emitter)) 
     548            return 0; 
     549 
     550        emitter->state = YAML_EMIT_DOCUMENT_START_STATE; 
     551 
     552        return 1; 
     553    } 
     554 
     555    return yaml_emitter_set_emitter_error(emitter, 
     556            "expected DOCUMENT-END"); 
     557} 
     558 
     559static int 
     560yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, 
     561        yaml_event_t *event, int first) 
     562{ 
     563    if (first) 
     564    { 
     565        if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0)) 
     566            return 0; 
     567        if (!yaml_emitter_increase_indent(emitter, 1, 0)) 
     568            return 0; 
     569        emitter->flow_level ++; 
     570    } 
     571 
     572    if (event->type == YAML_SEQUENCE_END_EVENT) 
     573    { 
     574        emitter->flow_level --; 
     575        emitter->indent = POP(emitter, emitter->indents); 
     576        if (emitter->canonical && !first) { 
     577            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 
     578                return 0; 
     579            if (!yaml_emitter_write_indent(emitter)) 
     580                return 0; 
     581        } 
     582        if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0)) 
     583            return 0; 
     584        emitter->state = POP(emitter, emitter->states); 
     585 
     586        return 1; 
     587    } 
     588 
     589    if (emitter->canonical || emitter->column > emitter->best_width) { 
     590        if (!yaml_emitter_write_indent(emitter)) 
     591            return 0; 
     592    } 
     593    if (PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE)) 
     594        return 0; 
     595 
     596    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); 
     597} 
     598 
     599static int 
     600yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, 
     601        yaml_event_t *event, int first) 
     602{ 
     603    if (first) 
     604    { 
     605        if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0)) 
     606            return 0; 
     607        if (!yaml_emitter_increase_indent(emitter, 1, 0)) 
     608            return 0; 
     609        emitter->flow_level ++; 
     610    } 
     611 
     612    if (event->type == YAML_MAPPING_END_EVENT) 
     613    { 
     614        emitter->flow_level --; 
     615        emitter->indent = POP(emitter, emitter->indents); 
     616        if (emitter->canonical && !first) { 
     617            if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 
     618                return 0; 
     619            if (!yaml_emitter_write_indent(emitter)) 
     620                return 0; 
     621        } 
     622        if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0)) 
     623            return 0; 
     624        emitter->state = POP(emitter, emitter->states); 
     625 
     626        return 1; 
     627    } 
     628 
     629    if (!first) { 
     630        if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 
     631            return 0; 
     632    } 
     633    if (emitter->canonical || emitter->column > emitter->best_width) { 
     634        if (!yaml_emitter_write_indent(emitter)) 
     635            return 0; 
     636    } 
     637 
     638    if (!emitter->canonical && yaml_emitter_check_simple_key(emitter)) 
     639    { 
     640        if (!PUSH(emitter, emitter->states, 
     641                    YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)) 
     642            return 0; 
     643 
     644        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); 
     645    } 
     646    else 
     647    { 
     648        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0)) 
     649            return 0; 
     650        if (!PUSH(emitter, emitter->states, 
     651                    YAML_EMIT_FLOW_MAPPING_VALUE_STATE)) 
     652            return 0; 
     653 
     654        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 
     655    } 
     656} 
     657 
     658static int 
     659yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, 
     660        yaml_event_t *event, int simple) 
     661{ 
     662    if (simple) { 
     663        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) 
     664            return 0; 
     665    } 
     666    else { 
     667        if (emitter->canonical || emitter->column > emitter->best_width) { 
     668            if (!yaml_emitter_write_indent(emitter)) 
     669                return 0; 
     670        } 
     671        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0)) 
     672            return 0; 
     673    } 
     674    if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE)) 
     675        return 0; 
     676    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 
     677} 
     678 
     679static int 
     680yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, 
     681        yaml_event_t *event, int first) 
     682{ 
     683    if (first) 
     684    { 
     685        if (!yaml_emitter_increase_indent(emitter, 0, 
     686                    (emitter->mapping_context && !emitter->indention))) 
     687            return 0; 
     688    } 
     689 
     690    if (event->type == YAML_SEQUENCE_END_EVENT) 
     691    { 
     692        emitter->indent = POP(emitter, emitter->indents); 
     693        emitter->state = POP(emitter, emitter->states); 
     694 
     695        return 1; 
     696    } 
     697 
     698    if (!yaml_emitter_write_indent(emitter)) 
     699        return 0; 
     700    if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1)) 
     701        return 0; 
     702    if (!PUSH(emitter, emitter->states, 
     703                YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE)) 
     704        return 0; 
     705 
     706    return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); 
     707} 
     708 
     709static int 
     710yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, 
     711        yaml_event_t *event, int first) 
     712{ 
     713    if (first) 
     714    { 
     715        if (!yaml_emitter_increase_indent(emitter, 0, 0)) 
     716            return 0; 
     717    } 
     718 
     719    if (event->type == YAML_MAPPING_END_EVENT) 
     720    { 
     721        emitter->indent = POP(emitter, emitter->indents); 
     722        emitter->state = POP(emitter, emitter->states); 
     723 
     724        return 1; 
     725    } 
     726 
     727    if (!yaml_emitter_write_indent(emitter)) 
     728        return 0; 
     729 
     730    if (yaml_emitter_check_simple_key(emitter)) 
     731    { 
     732        if (!PUSH(emitter, emitter->states, 
     733                    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)) 
     734            return 0; 
     735 
     736        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); 
     737    } 
     738    else 
     739    { 
     740        if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1)) 
     741            return 0; 
     742        if (!PUSH(emitter, emitter->states, 
     743                    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE)) 
     744            return 0; 
     745 
     746        return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 
     747    } 
     748} 
     749 
     750static int 
     751yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, 
     752        yaml_event_t *event, int simple) 
     753{ 
     754    if (simple) { 
     755        if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) 
     756            return 0; 
     757    } 
     758    else { 
     759        if (!yaml_emitter_write_indent(emitter)) 
     760            return 0; 
     761        if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1)) 
     762            return 0; 
     763    } 
     764    if (!PUSH(emitter, emitter->states, 
     765                YAML_EMIT_BLOCK_MAPPING_KEY_STATE)) 
     766        return 0; 
     767 
     768    return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 
     769} 
     770 
     771static int 
     772yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, 
     773        int root, int sequence, int mapping, int simple_key) 
     774{ 
     775    emitter->root_context = root; 
     776    emitter->sequence_context = sequence; 
     777    emitter->mapping_context = mapping; 
     778    emitter->simple_key_context = simple_key; 
     779 
     780    switch (event->type) 
     781    { 
     782        case YAML_ALIAS_EVENT: 
     783            return yaml_emitter_emit_alias(emitter, event); 
     784 
     785        case YAML_SCALAR_EVENT: 
     786            return yaml_emitter_emit_scalar(emitter, event); 
     787 
     788        case YAML_SEQUENCE_START_EVENT: 
     789            return yaml_emitter_emit_sequence_start(emitter, event); 
     790 
     791        case YAML_MAPPING_START_EVENT: 
     792            return yaml_emitter_emit_mapping_start(emitter, event); 
     793 
     794        default: 
     795            return yaml_emitter_set_emitter_error(emitter, 
     796                    "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS"); 
     797    } 
    269798 
    270799    return 0; 
    271800} 
    272801 
    273 /* 
    274  * Emit SEQUENCE-START. 
    275  */ 
    276  
    277 YAML_DECLARE(int) 
    278 yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, 
    279         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    280         yaml_sequence_style_t style) 
    281 { 
    282     yaml_event_t event; 
    283     yaml_mark_t mark = { 0, 0, 0 }; 
    284     yaml_char_t *anchor_copy = NULL; 
    285     yaml_char_t *tag_copy = NULL; 
    286  
    287     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    288  
    289     if (anchor) { 
    290         anchor_copy = yaml_strdup(anchor); 
    291         if (!anchor_copy) { 
    292             emitter->error = YAML_MEMORY_ERROR; 
    293             goto error; 
    294         } 
    295     } 
    296  
    297     if (tag) { 
    298         tag_copy = yaml_strdup(tag); 
    299         if (!tag_copy) { 
    300             emitter->error = YAML_MEMORY_ERROR; 
    301             goto error; 
    302         } 
    303     } 
    304  
    305     SEQUENCE_START_EVENT_INIT(event, anchor_copy, tag_copy, 
    306             implicit, style, mark, mark); 
    307  
    308     if (yaml_emitter_emit(emitter, &event)) { 
    309         return 1; 
    310     } 
    311  
    312 error: 
    313     yaml_free(anchor_copy); 
    314     yaml_free(tag_copy); 
    315  
    316     return 0; 
    317 } 
    318  
    319 /* 
    320  * Emit SEQUENCE-END. 
    321  */ 
    322  
    323 YAML_DECLARE(int) 
    324 yaml_emitter_emit_sequence_end(yaml_emitter_t *emitter) 
    325 { 
    326     yaml_event_t event; 
    327     yaml_mark_t mark = { 0, 0, 0 }; 
    328  
    329     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    330  
    331     SEQUENCE_END_EVENT_INIT(event, mark, mark); 
    332  
    333     return yaml_emitter_emit(emitter, &event); 
    334 } 
    335  
    336 /* 
    337  * Emit MAPPING-START. 
    338  */ 
    339  
    340 YAML_DECLARE(int) 
    341 yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, 
    342         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    343         yaml_mapping_style_t style) 
    344 { 
    345     yaml_event_t event; 
    346     yaml_mark_t mark = { 0, 0, 0 }; 
    347     yaml_char_t *anchor_copy = NULL; 
    348     yaml_char_t *tag_copy = NULL; 
    349  
    350     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    351  
    352     if (anchor) { 
    353         anchor_copy = yaml_strdup(anchor); 
    354         if (!anchor_copy) { 
    355             emitter->error = YAML_MEMORY_ERROR; 
    356             goto error; 
    357         } 
    358     } 
    359  
    360     if (tag) { 
    361         tag_copy = yaml_strdup(tag); 
    362         if (!tag_copy) { 
    363             emitter->error = YAML_MEMORY_ERROR; 
    364             goto error; 
    365         } 
    366     } 
    367  
    368     MAPPING_START_EVENT_INIT(event, anchor_copy, tag_copy, 
    369             implicit, style, mark, mark); 
    370  
    371     if (yaml_emitter_emit(emitter, &event)) { 
    372         return 1; 
    373     } 
    374  
    375 error: 
    376     yaml_free(anchor_copy); 
    377     yaml_free(tag_copy); 
    378  
    379     return 0; 
    380 } 
    381  
    382 /* 
    383  * Emit MAPPING-END. 
    384  */ 
    385  
    386 YAML_DECLARE(int) 
    387 yaml_emitter_emit_mapping_end(yaml_emitter_t *emitter) 
    388 { 
    389     yaml_event_t event; 
    390     yaml_mark_t mark = { 0, 0, 0 }; 
    391  
    392     assert(emitter);    /* Non-NULL emitter object is expected. */ 
    393  
    394     MAPPING_END_EVENT_INIT(event, mark, mark); 
    395  
    396     return yaml_emitter_emit(emitter, &event); 
    397 } 
    398  
    399 /* 
    400  * Emit an event. 
    401  */ 
    402  
    403 YAML_DECLARE(int) 
    404 yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) 
    405 { 
    406     return 0; 
    407 } 
    408  
     802static int 
     803yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event) 
     804{ 
     805    if (!yaml_emitter_process_anchor(emitter, event->data.alias.anchor, 1)) 
     806        return 0; 
     807    emitter->state = POP(emitter, emitter->states); 
     808 
     809    return 1; 
     810} 
     811 
     812static int 
     813yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event) 
     814{ 
     815    if (!yaml_emitter_process_anchor(emitter, event->data.scalar.anchor, 0)) 
     816        return 0; 
     817    if (!yaml_emitter_process_tag(emitter, event->data.scalar.tag)) 
     818        return 0; 
     819    if (!yaml_emitter_increase_indent(emitter, 1, 0)) 
     820        return 0; 
     821    if (!yaml_emitter_process_scalar(emitter, 
     822                event->data.scalar.value, event->data.scalar.length, 
     823                event->data.scalar.plain_implicit, 
     824                event->data.scalar.quoted_implicit, 
     825                event->data.scalar.style)) 
     826        return 0; 
     827    emitter->indent = POP(emitter, emitter->indents); 
     828    emitter->state = POP(emitter, emitter->states); 
     829 
     830    return 1; 
     831} 
     832 
     833static int 
     834yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event) 
     835{ 
     836    if (!yaml_emitter_process_anchor(emitter, 
     837                event->data.sequence_start.anchor, 0)) 
     838        return 0; 
     839    if (!yaml_emitter_process_tag(emitter, 
     840                event->data.sequence_start.tag)) 
     841        return 0; 
     842 
     843    if (emitter->flow_level || emitter->canonical 
     844            || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE 
     845            || yaml_emitter_check_empty_sequence(emitter)) { 
     846        emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; 
     847    } 
     848    else { 
     849        emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; 
     850    } 
     851 
     852    return 1; 
     853} 
     854 
     855static int 
     856yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event) 
     857{ 
     858    if (!yaml_emitter_process_anchor(emitter, 
     859                event->data.mapping_start.anchor, 0)) 
     860        return 0; 
     861    if (!yaml_emitter_process_tag(emitter, 
     862                event->data.mapping_start.tag)) 
     863        return 0; 
     864 
     865    if (emitter->flow_level || emitter->canonical 
     866            || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE 
     867            || yaml_emitter_check_empty_mapping(emitter)) { 
     868        emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; 
     869    } 
     870    else { 
     871        emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; 
     872    } 
     873 
     874    return 1; 
     875} 
     876 
Note: See TracChangeset for help on using the changeset viewer.