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

Add functions for constructing, parsing and emitting YAML documents.

File:
1 edited

Legend:

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

    r237 r238  
    400400    } 
    401401    STACK_DEL(emitter, emitter->tag_directives); 
     402    yaml_free(emitter->anchors); 
    402403 
    403404    memset(emitter, 0, sizeof(yaml_emitter_t)); 
     
    10201021} 
    10211022 
    1022 #if 0 
    1023  
    1024 /* 
    1025  * Create a SCALAR node. 
    1026  */ 
    1027  
    1028 YAML_DECLARE(int) 
    1029 yaml_scalar_node_initialize(yaml_node_t *node, 
     1023/* 
     1024 * Create a document object. 
     1025 */ 
     1026 
     1027YAML_DECLARE(int) 
     1028yaml_document_initialize(yaml_document_t *document, 
     1029        yaml_version_directive_t *version_directive, 
     1030        yaml_tag_directive_t *tag_directives_start, 
     1031        yaml_tag_directive_t *tag_directives_end, 
     1032        int start_implicit, int end_implicit) 
     1033{ 
     1034    struct { 
     1035        yaml_error_type_t error; 
     1036    } context; 
     1037    struct { 
     1038        yaml_node_t *start; 
     1039        yaml_node_t *end; 
     1040        yaml_node_t *top; 
     1041    } nodes = { NULL, NULL, NULL }; 
     1042    yaml_version_directive_t *version_directive_copy = NULL; 
     1043    struct { 
     1044        yaml_tag_directive_t *start; 
     1045        yaml_tag_directive_t *end; 
     1046        yaml_tag_directive_t *top; 
     1047    } tag_directives_copy = { NULL, NULL, NULL }; 
     1048    yaml_tag_directive_t value = { NULL, NULL }; 
     1049    yaml_mark_t mark = { 0, 0, 0 }; 
     1050 
     1051    assert(document);       /* Non-NULL document object is expected. */ 
     1052    assert((tag_directives_start && tag_directives_end) || 
     1053            (tag_directives_start == tag_directives_end)); 
     1054                            /* Valid tag directives are expected. */ 
     1055 
     1056    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error; 
     1057 
     1058    if (version_directive) { 
     1059        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
     1060        if (!version_directive_copy) goto error; 
     1061        version_directive_copy->major = version_directive->major; 
     1062        version_directive_copy->minor = version_directive->minor; 
     1063    } 
     1064 
     1065    if (tag_directives_start != tag_directives_end) { 
     1066        yaml_tag_directive_t *tag_directive; 
     1067        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) 
     1068            goto error; 
     1069        for (tag_directive = tag_directives_start; 
     1070                tag_directive != tag_directives_end; tag_directive ++) { 
     1071            assert(tag_directive->handle); 
     1072            assert(tag_directive->prefix); 
     1073            if (!yaml_check_utf8(tag_directive->handle, 
     1074                        strlen((char *)tag_directive->handle))) 
     1075                goto error; 
     1076            if (!yaml_check_utf8(tag_directive->prefix, 
     1077                        strlen((char *)tag_directive->prefix))) 
     1078                goto error; 
     1079            value.handle = yaml_strdup(tag_directive->handle); 
     1080            value.prefix = yaml_strdup(tag_directive->prefix); 
     1081            if (!value.handle || !value.prefix) goto error; 
     1082            if (!PUSH(&context, tag_directives_copy, value)) 
     1083                goto error; 
     1084            value.handle = NULL; 
     1085            value.prefix = NULL; 
     1086        } 
     1087    } 
     1088 
     1089    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, 
     1090            tag_directives_copy.start, tag_directives_copy.top, 
     1091            start_implicit, end_implicit, mark, mark); 
     1092 
     1093    return 1; 
     1094 
     1095error: 
     1096    STACK_DEL(&context, nodes); 
     1097    yaml_free(version_directive_copy); 
     1098    while (!STACK_EMPTY(&context, tag_directives_copy)) { 
     1099        yaml_tag_directive_t value = POP(&context, tag_directives_copy); 
     1100        yaml_free(value.handle); 
     1101        yaml_free(value.prefix); 
     1102    } 
     1103    STACK_DEL(&context, tag_directives_copy); 
     1104    yaml_free(value.handle); 
     1105    yaml_free(value.prefix); 
     1106 
     1107    return 0; 
     1108} 
     1109 
     1110/* 
     1111 * Destroy a document object. 
     1112 */ 
     1113 
     1114YAML_DECLARE(void) 
     1115yaml_document_delete(yaml_document_t *document) 
     1116{ 
     1117    struct { 
     1118        yaml_error_type_t error; 
     1119    } context; 
     1120    yaml_tag_directive_t *tag_directive; 
     1121 
     1122    assert(document);   /* Non-NULL document object is expected. */ 
     1123 
     1124    while (!STACK_EMPTY(&context, document->nodes)) { 
     1125        yaml_node_t node = POP(&context, document->nodes); 
     1126        yaml_free(node.tag); 
     1127        switch (node.type) { 
     1128            case YAML_SCALAR_NODE: 
     1129                yaml_free(node.data.scalar.value); 
     1130                break; 
     1131            case YAML_SEQUENCE_NODE: 
     1132                STACK_DEL(&context, node.data.sequence.items); 
     1133                break; 
     1134            case YAML_MAPPING_NODE: 
     1135                STACK_DEL(&context, node.data.mapping.pairs); 
     1136                break; 
     1137            default: 
     1138                assert(0);  /* Should not happen. */ 
     1139        } 
     1140    } 
     1141    STACK_DEL(&context, document->nodes); 
     1142 
     1143    yaml_free(document->version_directive); 
     1144    for (tag_directive = document->tag_directives.start; 
     1145            tag_directive != document->tag_directives.end; 
     1146            tag_directive++) { 
     1147        yaml_free(tag_directive->handle); 
     1148        yaml_free(tag_directive->prefix); 
     1149    } 
     1150    yaml_free(document->tag_directives.start); 
     1151 
     1152    memset(document, 0, sizeof(yaml_document_t)); 
     1153} 
     1154 
     1155/** 
     1156 * Get a document node. 
     1157 */ 
     1158 
     1159YAML_DECLARE(yaml_node_t *) 
     1160yaml_document_get_node(yaml_document_t *document, int node) 
     1161{ 
     1162    assert(document);   /* Non-NULL document object is expected. */ 
     1163 
     1164    if (node > 0 && document->nodes.start + node <= document->nodes.top) { 
     1165        return document->nodes.start + node - 1; 
     1166    } 
     1167    return NULL; 
     1168} 
     1169 
     1170/** 
     1171 * Get the root object. 
     1172 */ 
     1173 
     1174YAML_DECLARE(yaml_node_t *) 
     1175yaml_document_get_root_node(yaml_document_t *document) 
     1176{ 
     1177    assert(document);   /* Non-NULL document object is expected. */ 
     1178 
     1179    if (document->nodes.top != document->nodes.start) { 
     1180        return document->nodes.start; 
     1181    } 
     1182    return NULL; 
     1183} 
     1184 
     1185/* 
     1186 * Add a scalar node to a document. 
     1187 */ 
     1188 
     1189YAML_DECLARE(int) 
     1190yaml_document_add_scalar(yaml_document_t *document, 
    10301191        yaml_char_t *tag, yaml_char_t *value, int length, 
    10311192        yaml_scalar_style_t style) 
    10321193{ 
     1194    struct { 
     1195        yaml_error_type_t error; 
     1196    } context; 
    10331197    yaml_mark_t mark = { 0, 0, 0 }; 
    10341198    yaml_char_t *tag_copy = NULL; 
    10351199    yaml_char_t *value_copy = NULL; 
    1036  
    1037     assert(node);       /* Non-NULL node object is expected. */ 
    1038     assert(value);      /* Non-NULL anchor is expected. */ 
     1200    yaml_node_t node; 
     1201 
     1202    assert(document);   /* Non-NULL document object is expected. */ 
     1203    assert(value);      /* Non-NULL value is expected. */ 
    10391204 
    10401205    if (!tag) { 
     
    10561221    value_copy[length] = '\0'; 
    10571222 
    1058     SCALAR_NODE_INIT(*node, tag_copy, value_copy, length, style, mark, mark); 
    1059  
    1060     return 1; 
     1223    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); 
     1224    if (!PUSH(&context, document->nodes, node)) goto error; 
     1225 
     1226    return document->nodes.top - document->nodes.start; 
    10611227 
    10621228error: 
     
    10681234 
    10691235/* 
    1070  * Create a SEQUENCE node. 
    1071  */ 
    1072  
    1073 YAML_DECLARE(int) 
    1074 yaml_sequence_node_initialize(yaml_node_t *node, 
     1236 * Add a sequence node to a document. 
     1237 */ 
     1238 
     1239YAML_DECLARE(int) 
     1240yaml_document_add_sequence(yaml_document_t *document, 
    10751241        yaml_char_t *tag, yaml_sequence_style_t style) 
    10761242{ 
     
    10851251        yaml_node_item_t *top; 
    10861252    } items = { NULL, NULL, NULL }; 
    1087  
    1088     assert(node);   /* Non-NULL node object is expected. */ 
     1253    yaml_node_t node; 
     1254 
     1255    assert(document);   /* Non-NULL document object is expected. */ 
    10891256 
    10901257    if (!tag) { 
     
    10921259    } 
    10931260 
    1094     if (tag) { 
    1095         if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    1096         tag_copy = yaml_strdup(tag); 
    1097         if (!tag_copy) goto error; 
    1098     } 
    1099  
    1100     if (!STACK_INIT(context, items, INITIAL_STACK_SIZE)) goto error; 
    1101  
    1102     SEQUENCE_NODE_INIT(*node, tag_copy, items.start, item.end, style, 
    1103             mark, mark); 
    1104  
    1105     return 1; 
     1261    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
     1262    tag_copy = yaml_strdup(tag); 
     1263    if (!tag_copy) goto error; 
     1264 
     1265    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error; 
     1266 
     1267    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, 
     1268            style, mark, mark); 
     1269    if (!PUSH(&context, document->nodes, node)) goto error; 
     1270 
     1271    return document->nodes.top - document->nodes.start; 
    11061272 
    11071273error: 
     1274    STACK_DEL(&context, items); 
    11081275    yaml_free(tag_copy); 
    1109     STACK_DEL(context, items); 
    11101276 
    11111277    return 0; 
     
    11131279 
    11141280/* 
    1115  * Create a MAPPING node. 
    1116  */ 
    1117  
    1118 YAML_DECLARE(int) 
    1119 yaml_mapping_node_initialize(yaml_node_t *node, 
     1281 * Add a mapping node to a document. 
     1282 */ 
     1283 
     1284YAML_DECLARE(int) 
     1285yaml_document_add_mapping(yaml_document_t *document, 
    11201286        yaml_char_t *tag, yaml_mapping_style_t style) 
    11211287{ 
     
    11301296        yaml_node_pair_t *top; 
    11311297    } pairs = { NULL, NULL, NULL }; 
    1132  
    1133     assert(node);   /* Non-NULL node object is expected. */ 
     1298    yaml_node_t node; 
     1299 
     1300    assert(document);   /* Non-NULL document object is expected. */ 
    11341301 
    11351302    if (!tag) { 
     
    11371304    } 
    11381305 
    1139     if (tag) { 
    1140         if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
    1141         tag_copy = yaml_strdup(tag); 
    1142         if (!tag_copy) goto error; 
    1143     } 
    1144  
    1145     if (!STACK_INIT(context, pairs, INITIAL_STACK_SIZE)) goto error; 
    1146  
    1147     MAPPING_NODE_INIT(*node, tag_copy, pairs.start, pairs.end, style, 
    1148             mark, mark); 
    1149  
    1150     return 1; 
     1306    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
     1307    tag_copy = yaml_strdup(tag); 
     1308    if (!tag_copy) goto error; 
     1309 
     1310    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error; 
     1311 
     1312    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, 
     1313            style, mark, mark); 
     1314    if (!PUSH(&context, document->nodes, node)) goto error; 
     1315 
     1316    return document->nodes.top - document->nodes.start; 
    11511317 
    11521318error: 
     1319    STACK_DEL(&context, pairs); 
    11531320    yaml_free(tag_copy); 
    1154     STACK_DEL(context, pairs); 
    11551321 
    11561322    return 0; 
     
    11581324 
    11591325/* 
    1160  * Delete a node and its subnodes. 
    1161  */ 
    1162  
    1163 YAML_DECLARE(void) 
    1164 yaml_node_delete(yaml_node_t *node) 
     1326 * Append an item to a sequence node. 
     1327 */ 
     1328 
     1329YAML_DECLARE(int) 
     1330yaml_document_append_sequence_item(yaml_document_t *document, 
     1331        int sequence, int item) 
    11651332{ 
    11661333    struct { 
    11671334        yaml_error_type_t error; 
    11681335    } context; 
     1336 
     1337    assert(document);       /* Non-NULL document is required. */ 
     1338    assert(sequence > 0 
     1339            && document->nodes.start + sequence <= document->nodes.top); 
     1340                            /* Valid sequence id is required. */ 
     1341    assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); 
     1342                            /* A sequence node is required. */ 
     1343    assert(item > 0 && document->nodes.start + item <= document->nodes.top); 
     1344                            /* Valid item id is required. */ 
     1345 
     1346    if (!PUSH(&context, 
     1347                document->nodes.start[sequence-1].data.sequence.items, item)) 
     1348        return 0; 
     1349 
     1350    return 1; 
     1351} 
     1352 
     1353/* 
     1354 * Append a pair of a key and a value to a mapping node. 
     1355 */ 
     1356 
     1357YAML_DECLARE(int) 
     1358yaml_document_append_mapping_pair(yaml_document_t *document, 
     1359        int mapping, int key, int value) 
     1360{ 
    11691361    struct { 
    1170         yaml_node_item_t *start; 
    1171         yaml_node_item_t *end; 
    1172         yaml_node_item_t *head; 
    1173         yaml_node_item_t *tail; 
    1174     } queue = { NULL, NULL, NULL, NULL }; 
    1175  
    1176     assert(node);   /* Non-NULL node object is expected. */ 
    1177  
    1178     if (node->type == YAML_SCALAR_NODE) { 
    1179         yaml_free(node->data.scalar.tag); 
    1180         yaml_free(node->data.scalar.value); 
    1181         memset(node, 0, sizeof(yaml_node_t)); 
    1182         return; 
    1183     } 
    1184  
    1185     if (!QUEUE_INIT(context, queue, INITIAL_QUEUE_SIZE)) goto error; 
    1186     if (!ENQUEUE(context, queue, node)) goto error; 
    1187  
    1188     while (!QUEUE_EMPTY(context, queue)) { 
    1189         yaml_node_t node = DEQUEUE(context, queue); 
    1190         if (node.type == YAML_SCALAR_NODE) { 
    1191             if (!node->reference) 
    1192         } 
    1193         if (node->type == YAML_SEQUENCE_NODE) { 
    1194             while (!STACK_EMPTY(context, node->data.sequence.items)) { 
    1195                 yaml_node_t *item =  
    1196             } 
    1197         } 
    1198     } 
    1199 } 
    1200  
    1201 #endif 
    1202  
     1362        yaml_error_type_t error; 
     1363    } context; 
     1364    yaml_node_pair_t pair = { key, value }; 
     1365 
     1366    assert(document);       /* Non-NULL document is required. */ 
     1367    assert(mapping > 0 
     1368            && document->nodes.start + mapping <= document->nodes.top); 
     1369                            /* Valid mapping id is required. */ 
     1370    assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); 
     1371                            /* A mapping node is required. */ 
     1372    assert(key > 0 && document->nodes.start + key <= document->nodes.top); 
     1373                            /* Valid key id is required. */ 
     1374    assert(value > 0 && document->nodes.start + value <= document->nodes.top); 
     1375                            /* Valid value id is required. */ 
     1376 
     1377    if (!PUSH(&context, 
     1378                document->nodes.start[mapping-1].data.mapping.pairs, pair)) 
     1379        return 0; 
     1380 
     1381    return 1; 
     1382} 
     1383 
Note: See TracChangeset for help on using the changeset viewer.