Ignore:
Timestamp:
01/07/07 15:11:16 (8 years ago)
Author:
xi
Message:

Add functions for constructing, parsing and emitting YAML documents.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • libyaml/trunk/tests/run-dumper.c

    r217 r238  
    77 
    88#define BUFFER_SIZE 65536 
    9 #define MAX_EVENTS  1024 
    10  
    11 int copy_event(yaml_event_t *event_to, yaml_event_t *event_from) 
    12 { 
    13     switch (event_from->type) 
    14     { 
    15         case YAML_STREAM_START_EVENT: 
    16             return yaml_stream_start_event_initialize(event_to, 
    17                     event_from->data.stream_start.encoding); 
    18  
    19         case YAML_STREAM_END_EVENT: 
    20             return yaml_stream_end_event_initialize(event_to); 
    21  
    22         case YAML_DOCUMENT_START_EVENT: 
    23             return yaml_document_start_event_initialize(event_to, 
    24                     event_from->data.document_start.version_directive, 
    25                     event_from->data.document_start.tag_directives.start, 
    26                     event_from->data.document_start.tag_directives.end, 
    27                     event_from->data.document_start.implicit); 
    28  
    29         case YAML_DOCUMENT_END_EVENT: 
    30             return yaml_document_end_event_initialize(event_to, 
    31                     event_from->data.document_end.implicit); 
    32  
    33         case YAML_ALIAS_EVENT: 
    34             return yaml_alias_event_initialize(event_to, 
    35                     event_from->data.alias.anchor); 
    36  
    37         case YAML_SCALAR_EVENT: 
    38             return yaml_scalar_event_initialize(event_to, 
    39                     event_from->data.scalar.anchor, 
    40                     event_from->data.scalar.tag, 
    41                     event_from->data.scalar.value, 
    42                     event_from->data.scalar.length, 
    43                     event_from->data.scalar.plain_implicit, 
    44                     event_from->data.scalar.quoted_implicit, 
    45                     event_from->data.scalar.style); 
    46  
    47         case YAML_SEQUENCE_START_EVENT: 
    48             return yaml_sequence_start_event_initialize(event_to, 
    49                     event_from->data.sequence_start.anchor, 
    50                     event_from->data.sequence_start.tag, 
    51                     event_from->data.sequence_start.implicit, 
    52                     event_from->data.sequence_start.style); 
    53  
    54         case YAML_SEQUENCE_END_EVENT: 
    55             return yaml_sequence_end_event_initialize(event_to); 
    56  
    57         case YAML_MAPPING_START_EVENT: 
    58             return yaml_mapping_start_event_initialize(event_to, 
    59                     event_from->data.mapping_start.anchor, 
    60                     event_from->data.mapping_start.tag, 
    61                     event_from->data.mapping_start.implicit, 
    62                     event_from->data.mapping_start.style); 
    63  
    64         case YAML_MAPPING_END_EVENT: 
    65             return yaml_mapping_end_event_initialize(event_to); 
    66  
    67         default: 
    68             assert(1); 
    69     } 
    70  
     9#define MAX_DOCUMENTS  16 
     10 
     11int copy_document(yaml_document_t *document_to, yaml_document_t *document_from) 
     12{ 
     13    yaml_node_t *node; 
     14    yaml_node_item_t *item; 
     15    yaml_node_pair_t *pair; 
     16 
     17    if (!yaml_document_initialize(document_to, document_from->version_directive, 
     18                document_from->tag_directives.start, 
     19                document_from->tag_directives.end, 
     20                document_from->start_implicit, document_from->end_implicit)) 
     21        return 0; 
     22 
     23    for (node = document_from->nodes.start; 
     24            node < document_from->nodes.top; node ++) { 
     25        switch (node->type) { 
     26            case YAML_SCALAR_NODE: 
     27                if (!yaml_document_add_scalar(document_to, node->tag, 
     28                            node->data.scalar.value, node->data.scalar.length, 
     29                            node->data.scalar.style)) goto error; 
     30                break; 
     31            case YAML_SEQUENCE_NODE: 
     32                if (!yaml_document_add_sequence(document_to, node->tag, 
     33                            node->data.sequence.style)) goto error; 
     34                break; 
     35            case YAML_MAPPING_NODE: 
     36                if (!yaml_document_add_mapping(document_to, node->tag, 
     37                            node->data.mapping.style)) goto error; 
     38                break; 
     39            default: 
     40                assert(0); 
     41                break; 
     42        } 
     43    } 
     44 
     45    for (node = document_from->nodes.start; 
     46            node < document_from->nodes.top; node ++) { 
     47        switch (node->type) { 
     48            case YAML_SEQUENCE_NODE: 
     49                for (item = node->data.sequence.items.start; 
     50                        item < node->data.sequence.items.top; item ++) { 
     51                    if (!yaml_document_append_sequence_item(document_to, 
     52                                node - document_from->nodes.start + 1, 
     53                                *item)) goto error; 
     54                } 
     55                break; 
     56            case YAML_MAPPING_NODE: 
     57                for (pair = node->data.mapping.pairs.start; 
     58                        pair < node->data.mapping.pairs.top; pair ++) { 
     59                    if (!yaml_document_append_mapping_pair(document_to, 
     60                                node - document_from->nodes.start + 1, 
     61                                pair->key, pair->value)) goto error; 
     62                } 
     63                break; 
     64            default: 
     65                break; 
     66        } 
     67    } 
     68    return 1; 
     69 
     70error: 
     71    yaml_document_delete(document_to); 
    7172    return 0; 
    7273} 
    7374 
    74 int compare_events(yaml_event_t *event1, yaml_event_t *event2) 
    75 { 
     75int compare_nodes(yaml_document_t *document1, int index1, 
     76        yaml_document_t *document2, int index2) 
     77{ 
     78    yaml_node_t *node1 = yaml_document_get_node(document1, index1); 
     79    yaml_node_t *node2 = yaml_document_get_node(document2, index2); 
    7680    int k; 
    7781 
    78     if (event1->type != event2->type) 
    79         return 0; 
    80  
    81     switch (event1->type) 
    82     { 
    83         case YAML_STREAM_START_EVENT: 
    84             return 1; 
    85             /* return (event1->data.stream_start.encoding == 
    86                     event2->data.stream_start.encoding); */ 
    87  
    88         case YAML_DOCUMENT_START_EVENT: 
    89             if ((event1->data.document_start.version_directive && !event2->data.document_start.version_directive) 
    90                     || (!event1->data.document_start.version_directive && event2->data.document_start.version_directive) 
    91                     || (event1->data.document_start.version_directive && event2->data.document_start.version_directive 
    92                         && (event1->data.document_start.version_directive->major != event2->data.document_start.version_directive->major 
    93                             || event1->data.document_start.version_directive->minor != event2->data.document_start.version_directive->minor))) 
     82    assert(node1); 
     83    assert(node2); 
     84 
     85    if (node1->type != node2->type) 
     86        return 0; 
     87 
     88    if (strcmp((char *)node1->tag, (char *)node2->tag) != 0) return 0; 
     89 
     90    switch (node1->type) { 
     91        case YAML_SCALAR_NODE: 
     92            if (node1->data.scalar.length != node2->data.scalar.length) 
    9493                return 0; 
    95             if ((event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start) != 
    96                     (event2->data.document_start.tag_directives.end - event2->data.document_start.tag_directives.start)) 
     94            if (strncmp((char *)node1->data.scalar.value, (char *)node2->data.scalar.value, 
     95                        node1->data.scalar.length) != 0) return 0; 
     96            break; 
     97        case YAML_SEQUENCE_NODE: 
     98            if ((node1->data.sequence.items.top - node1->data.sequence.items.start) != 
     99                    (node2->data.sequence.items.top - node2->data.sequence.items.start)) 
    97100                return 0; 
    98             for (k = 0; k < (event1->data.document_start.tag_directives.end - event1->data.document_start.tag_directives.start); k ++) { 
    99                 if ((strcmp((char *)event1->data.document_start.tag_directives.start[k].handle, 
    100                                 (char *)event2->data.document_start.tag_directives.start[k].handle) != 0) 
    101                         || (strcmp((char *)event1->data.document_start.tag_directives.start[k].prefix, 
    102                             (char *)event2->data.document_start.tag_directives.start[k].prefix) != 0)) 
    103                     return 0; 
    104             } 
    105             /* if (event1->data.document_start.implicit != event2->data.document_start.implicit) 
    106                 return 0; */ 
    107             return 1; 
    108  
    109         case YAML_DOCUMENT_END_EVENT: 
    110             return 1; 
    111             /* return (event1->data.document_end.implicit == 
    112                     event2->data.document_end.implicit); */ 
    113  
    114         case YAML_ALIAS_EVENT: 
    115             return (strcmp((char *)event1->data.alias.anchor, 
    116                         (char *)event2->data.alias.anchor) == 0); 
    117  
    118         case YAML_SCALAR_EVENT: 
    119             if ((event1->data.scalar.anchor && !event2->data.scalar.anchor) 
    120                     || (!event1->data.scalar.anchor && event2->data.scalar.anchor) 
    121                     || (event1->data.scalar.anchor && event2->data.scalar.anchor 
    122                         && strcmp((char *)event1->data.scalar.anchor, 
    123                             (char *)event2->data.scalar.anchor) != 0)) 
     101            for (k = 0; k < (node1->data.sequence.items.top - node1->data.sequence.items.start); k ++) { 
     102                if (!compare_nodes(document1, node1->data.sequence.items.start[k], 
     103                            document2, node2->data.sequence.items.start[k])) return 0; 
     104            } 
     105            break; 
     106        case YAML_MAPPING_NODE: 
     107            if ((node1->data.mapping.pairs.top - node1->data.mapping.pairs.start) != 
     108                    (node2->data.mapping.pairs.top - node2->data.mapping.pairs.start)) 
    124109                return 0; 
    125             if ((event1->data.scalar.tag && !event2->data.scalar.tag 
    126                         && strcmp((char *)event1->data.scalar.tag, "!") != 0) 
    127                     || (!event1->data.scalar.tag && event2->data.scalar.tag 
    128                         && strcmp((char *)event2->data.scalar.tag, "!") != 0) 
    129                     || (event1->data.scalar.tag && event2->data.scalar.tag 
    130                         && strcmp((char *)event1->data.scalar.tag, 
    131                             (char *)event2->data.scalar.tag) != 0)) 
    132                 return 0; 
    133             if ((event1->data.scalar.length != event2->data.scalar.length) 
    134                     || memcmp(event1->data.scalar.value, event2->data.scalar.value, 
    135                         event1->data.scalar.length) != 0) 
    136                 return 0; 
    137             if ((event1->data.scalar.plain_implicit != event2->data.scalar.plain_implicit) 
    138                     || (event2->data.scalar.quoted_implicit != event2->data.scalar.quoted_implicit) 
    139                     /* || (event2->data.scalar.style != event2->data.scalar.style) */) 
    140                 return 0; 
    141             return 1; 
    142  
    143         case YAML_SEQUENCE_START_EVENT: 
    144             if ((event1->data.sequence_start.anchor && !event2->data.sequence_start.anchor) 
    145                     || (!event1->data.sequence_start.anchor && event2->data.sequence_start.anchor) 
    146                     || (event1->data.sequence_start.anchor && event2->data.sequence_start.anchor 
    147                         && strcmp((char *)event1->data.sequence_start.anchor, 
    148                             (char *)event2->data.sequence_start.anchor) != 0)) 
    149                 return 0; 
    150             if ((event1->data.sequence_start.tag && !event2->data.sequence_start.tag) 
    151                     || (!event1->data.sequence_start.tag && event2->data.sequence_start.tag) 
    152                     || (event1->data.sequence_start.tag && event2->data.sequence_start.tag 
    153                         && strcmp((char *)event1->data.sequence_start.tag, 
    154                             (char *)event2->data.sequence_start.tag) != 0)) 
    155                 return 0; 
    156             if ((event1->data.sequence_start.implicit != event2->data.sequence_start.implicit) 
    157                     /* || (event2->data.sequence_start.style != event2->data.sequence_start.style) */) 
    158                 return 0; 
    159             return 1; 
    160  
    161         case YAML_MAPPING_START_EVENT: 
    162             if ((event1->data.mapping_start.anchor && !event2->data.mapping_start.anchor) 
    163                     || (!event1->data.mapping_start.anchor && event2->data.mapping_start.anchor) 
    164                     || (event1->data.mapping_start.anchor && event2->data.mapping_start.anchor 
    165                         && strcmp((char *)event1->data.mapping_start.anchor, 
    166                             (char *)event2->data.mapping_start.anchor) != 0)) 
    167                 return 0; 
    168             if ((event1->data.mapping_start.tag && !event2->data.mapping_start.tag) 
    169                     || (!event1->data.mapping_start.tag && event2->data.mapping_start.tag) 
    170                     || (event1->data.mapping_start.tag && event2->data.mapping_start.tag 
    171                         && strcmp((char *)event1->data.mapping_start.tag, 
    172                             (char *)event2->data.mapping_start.tag) != 0)) 
    173                 return 0; 
    174             if ((event1->data.mapping_start.implicit != event2->data.mapping_start.implicit) 
    175                     /* || (event2->data.mapping_start.style != event2->data.mapping_start.style) */) 
    176                 return 0; 
    177             return 1; 
    178  
    179         default: 
    180             return 1; 
    181     } 
     110            for (k = 0; k < (node1->data.mapping.pairs.top - node1->data.mapping.pairs.start); k ++) { 
     111                if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].key, 
     112                            document2, node2->data.mapping.pairs.start[k].key)) return 0; 
     113                if (!compare_nodes(document1, node1->data.mapping.pairs.start[k].value, 
     114                            document2, node2->data.mapping.pairs.start[k].value)) return 0; 
     115            } 
     116            break; 
     117 
     118    } 
     119    return 1; 
     120} 
     121 
     122int compare_documents(yaml_document_t *document1, yaml_document_t *document2) 
     123{ 
     124    int k; 
     125 
     126    if ((document1->version_directive && !document2->version_directive) 
     127            || (!document1->version_directive && document2->version_directive) 
     128            || (document1->version_directive && document2->version_directive 
     129                && (document1->version_directive->major != document2->version_directive->major 
     130                    || document1->version_directive->minor != document2->version_directive->minor))) 
     131        return 0; 
     132 
     133    if ((document1->tag_directives.end - document1->tag_directives.start) != 
     134            (document2->tag_directives.end - document2->tag_directives.start)) 
     135        return 0; 
     136    for (k = 0; k < (document1->tag_directives.end - document1->tag_directives.start); k ++) { 
     137        if ((strcmp((char *)document1->tag_directives.start[k].handle, 
     138                        (char *)document2->tag_directives.start[k].handle) != 0) 
     139                || (strcmp((char *)document1->tag_directives.start[k].prefix, 
     140                    (char *)document2->tag_directives.start[k].prefix) != 0)) 
     141            return 0; 
     142    } 
     143 
     144    if ((document1->nodes.top - document1->nodes.start) != 
     145            (document2->nodes.top - document2->nodes.start)) 
     146        return 0; 
     147 
     148    if (document1->nodes.top != document1->nodes.start) { 
     149        if (!compare_nodes(document1, 1, document2, 1)) 
     150            return 0; 
     151    } 
     152 
     153    return 1; 
    182154} 
    183155 
     
    189161    size_t total_size = 0; 
    190162    if (count >= 0) { 
    191         printf("FAILED (at the event #%d)\nSOURCE:\n", count+1); 
     163        printf("FAILED (at the document #%d)\nSOURCE:\n", count+1); 
    192164    } 
    193165    file = fopen(name, "rb"); 
     
    247219        yaml_parser_t parser; 
    248220        yaml_emitter_t emitter; 
    249         yaml_event_t event; 
     221 
     222        yaml_document_t document; 
    250223        unsigned char buffer[BUFFER_SIZE]; 
    251224        size_t written = 0; 
    252         yaml_event_t events[MAX_EVENTS]; 
    253         size_t event_number = 0; 
     225        yaml_document_t documents[MAX_DOCUMENTS]; 
     226        size_t document_number = 0; 
    254227        int done = 0; 
    255228        int count = 0; 
     
    257230        int k; 
    258231        memset(buffer, 0, BUFFER_SIZE); 
    259         memset(events, 0, MAX_EVENTS); 
    260  
    261         printf("[%d] Parsing, emitting, and parsing again '%s': ", number, argv[number]); 
     232        memset(documents, 0, MAX_DOCUMENTS*sizeof(yaml_document_t)); 
     233 
     234        printf("[%d] Loading, dumping, and loading again '%s': ", number, argv[number]); 
    262235        fflush(stdout); 
    263236 
     
    275248        } 
    276249        yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written); 
     250        yaml_emitter_open(&emitter); 
    277251 
    278252        while (!done) 
    279253        { 
    280             if (!yaml_parser_parse(&parser, &event)) { 
     254            if (!yaml_parser_load(&parser, &document)) { 
    281255                error = 1; 
    282256                break; 
    283257            } 
    284258 
    285             done = (event.type == YAML_STREAM_END_EVENT); 
    286             assert(event_number < MAX_EVENTS); 
    287             assert(copy_event(&(events[event_number++]), &event)); 
    288             assert(yaml_emitter_emit(&emitter, &event) ||  
    289                     (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count))); 
    290             count ++; 
     259            done = (!yaml_document_get_root_node(&document)); 
     260            if (!done) { 
     261                assert(document_number < MAX_DOCUMENTS); 
     262                assert(copy_document(&(documents[document_number++]), &document)); 
     263                assert(yaml_emitter_dump(&emitter, &document) ||  
     264                        (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count))); 
     265                count ++; 
     266            } 
     267            else { 
     268                yaml_document_delete(&document); 
     269            } 
    291270        } 
    292271 
    293272        yaml_parser_delete(&parser); 
    294273        assert(!fclose(file)); 
     274        yaml_emitter_close(&emitter); 
    295275        yaml_emitter_delete(&emitter); 
    296276 
     
    303283            while (!done) 
    304284            { 
    305                 assert(yaml_parser_parse(&parser, &event) || print_output(argv[number], buffer, written, count)); 
    306                 done = (event.type == YAML_STREAM_END_EVENT); 
    307                 assert(compare_events(events+count, &event) || print_output(argv[number], buffer, written, count)); 
    308                 yaml_event_delete(&event); 
    309                 count ++; 
     285                assert(yaml_parser_load(&parser, &document) || print_output(argv[number], buffer, written, count)); 
     286                done = (!yaml_document_get_root_node(&document)); 
     287                if (!done) { 
     288                    assert(compare_documents(documents+count, &document) || print_output(argv[number], buffer, written, count)); 
     289                    count ++; 
     290                } 
     291                yaml_document_delete(&document); 
    310292            } 
    311293            yaml_parser_delete(&parser); 
    312294        } 
    313295 
    314         for (k = 0; k < event_number; k ++) { 
    315             yaml_event_delete(events+k); 
     296        for (k = 0; k < document_number; k ++) { 
     297            yaml_document_delete(documents+k); 
    316298        } 
    317299 
Note: See TracChangeset for help on using the changeset viewer.