Changeset 213

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

Implement Emitter state machine.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • libyaml/trunk/include/yaml.h

    r212 r213  
    170170 
    171171    YAML_BLOCK_MAPPING_STYLE, 
    172     YAML_FLOW_MAPPING_STYLE, 
    173     YAML_FLOW_SET_MAPPING_STYLE 
     172    YAML_FLOW_MAPPING_STYLE 
     173/*    YAML_FLOW_SET_MAPPING_STYLE   */ 
    174174} yaml_mapping_style_t; 
    175175 
     
    413413 
    414414} yaml_event_t; 
     415 
     416/** 
     417 * Create the STREAM-START event. 
     418 * 
     419 * @param[in]   event       An empty event object. 
     420 * 
     421 * @returns @c 1 if the function succeeded, @c 0 on error. 
     422 */ 
     423 
     424YAML_DECLARE(int) 
     425yaml_stream_start_event_initialize(yaml_event_t *event, 
     426        yaml_encoding_t encoding); 
     427 
     428/** 
     429 * Create the STREAM-END event. 
     430 * 
     431 * @param[in]   event       An empty event object. 
     432 * 
     433 * @returns @c 1 if the function succeeded, @c 0 on error. 
     434 */ 
     435 
     436YAML_DECLARE(int) 
     437yaml_stream_end_event_initialize(yaml_event_t *event); 
     438 
     439/** 
     440 * Create the DOCUMENT-START event. 
     441 * 
     442 * The @a implicit argument is considered as a stylistic parameter and may be 
     443 * ignored by the emitter. 
     444 * 
     445 * @param[in]   event                   An empty event object. 
     446 * @param[in]   version_directive       The %YAML directive value or @c NULL. 
     447 * @param[in]   tag_directives_start    The beginning of the %TAG directives list. 
     448 * @param[in]   tag_directives_end      The end of the %TAG directives list. 
     449 * @param[in]   implicit                If the document start indicator is implicit. 
     450 * 
     451 * @returns @c 1 if the function succeeded, @c 0 on error. 
     452 */ 
     453 
     454YAML_DECLARE(int) 
     455yaml_document_start_event_initialize(yaml_event_t *event, 
     456        yaml_version_directive_t *version_directive, 
     457        yaml_tag_directive_t *tag_directives_start, 
     458        yaml_tag_directive_t *tag_directives_end, 
     459        int implicit); 
     460 
     461/** 
     462 * Create the DOCUMENT-END event. 
     463 * 
     464 * The @a implicit argument is considered as a stylistic parameter and may be 
     465 * ignored by the emitter. 
     466 * 
     467 * @param[in]   event       An empty event object. 
     468 * @param[in]   implicit    If the document end indicator is implicit. 
     469 * 
     470 * @returns @c 1 if the function succeeded, @c 0 on error. 
     471 */ 
     472 
     473YAML_DECLARE(int) 
     474yaml_document_end_event_initialize(yaml_event_t *event, int implicit); 
     475 
     476/** 
     477 * Create an ALIAS event. 
     478 * 
     479 * @param[in]   event       An empty event object. 
     480 * @param[in]   anchor      The anchor value. 
     481 * 
     482 * @returns @c 1 if the function succeeded, @c 0 on error. 
     483 */ 
     484 
     485YAML_DECLARE(int) 
     486yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); 
     487 
     488/** 
     489 * Create a SCALAR event. 
     490 * 
     491 * The @a style argument may be ignored by the emitter. 
     492 * 
     493 * Either the @a tag attribute or one of the @a plain_implicit and 
     494 * @a quoted_implicit flags must be set. 
     495 * 
     496 * @param[in]   event           An empty event object. 
     497 * @param[in]   anchor          The scalar anchor or @c NULL. 
     498 * @param[in]   tag             The scalar tag or @c NULL. 
     499 * @param[in]   value           The scalar value. 
     500 * @param[in]   length          The length of the scalar value. 
     501 * @param[in]   plain_implicit  If the tag may be omitted for the plain style. 
     502 * @param[in]   quoted_implicit If the tag may be omitted for any non-plain style. 
     503 * @param[in]   style           The scalar style. 
     504 * 
     505 * @returns @c 1 if the function succeeded, @c 0 on error. 
     506 */ 
     507 
     508YAML_DECLARE(int) 
     509yaml_scalar_event_initialize(yaml_event_t *event, 
     510        yaml_char_t *anchor, yaml_char_t *tag, 
     511        yaml_char_t *value, size_t length, 
     512        int plain_implicit, int quoted_implicit, 
     513        yaml_scalar_style_t style); 
     514 
     515/** 
     516 * Create a SEQUENCE-START event. 
     517 * 
     518 * The @a style argument may be ignored by the emitter. 
     519 * 
     520 * Either the @a tag attribute or the @a implicit flag must be set. 
     521 * 
     522 * @param[in]   event       An empty event object. 
     523 * @param[in]   anchor      The sequence anchor or @c NULL. 
     524 * @param[in]   tag         The sequence tag or @c NULL. 
     525 * @param[in]   implicit    If the tag may be omitted. 
     526 * @param[in]   style       The sequence style. 
     527 * 
     528 * @returns @c 1 if the function succeeded, @c 0 on error. 
     529 */ 
     530 
     531YAML_DECLARE(int) 
     532yaml_sequence_start_event_initialize(yaml_event_t *event, 
     533        yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
     534        yaml_sequence_style_t style); 
     535 
     536/** 
     537 * Create a SEQUENCE-END event. 
     538 * 
     539 * @param[in]   event       An empty event object. 
     540 * 
     541 * @returns @c 1 if the function succeeded, @c 0 on error. 
     542 */ 
     543 
     544YAML_DECLARE(int) 
     545yaml_sequence_end_event_initialize(yaml_event_t *event); 
     546 
     547/** 
     548 * Create a MAPPING-START event. 
     549 * 
     550 * The @a style argument may be ignored by the emitter. 
     551 * 
     552 * Either the @a tag attribute or the @a implicit flag must be set. 
     553 * 
     554 * @param[in]   event       An empty event object. 
     555 * @param[in]   anchor      The mapping anchor or @c NULL. 
     556 * @param[in]   tag         The mapping tag or @c NULL. 
     557 * @param[in]   implicit    If the tag may be omitted. 
     558 * @param[in]   style       The mapping style. 
     559 * 
     560 * @returns @c 1 if the function succeeded, @c 0 on error. 
     561 */ 
     562 
     563YAML_DECLARE(int) 
     564yaml_mapping_start_event_initialize(yaml_event_t *event, 
     565        yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
     566        yaml_mapping_style_t style); 
     567 
     568/** 
     569 * Create a MAPPING-END event. 
     570 * 
     571 * @param[in]   event       An empty event object. 
     572 * 
     573 * @returns @c 1 if the function succeeded, @c 0 on error. 
     574 */ 
     575 
     576YAML_DECLARE(int) 
     577yaml_mapping_end_event_initialize(yaml_event_t *event); 
    415578 
    416579/** 
     
    8711034    YAML_EMIT_BLOCK_MAPPING_KEY_STATE, 
    8721035    YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, 
    873     YAML_EMIT_BLOCK_MAPPING_VALUE_STATE 
     1036    YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, 
     1037    YAML_EMIT_END_STATE 
    8741038} yaml_emitter_state_t; 
    8751039 
     
    9961160    } events; 
    9971161 
    998     /** The current event. */ 
    999     yaml_event_t event; 
    1000  
    10011162    /** The stack of indentation levels. */ 
    10021163    struct { 
     
    11801341 * 
    11811342 * The event object may be generated using the @c yaml_parser_parse function. 
    1182  * The emitter will destroy the event object if the function succeeds.  If the 
    1183  * function fails, the application is responsible for destroing the event 
    1184  * object
     1343 * The emitter takes the responsibility for the event object and destroys its 
     1344 * content after it is emitted. The event object is destroyed even if the 
     1345 * function fails
    11851346 * 
    11861347 * @param[in]   emitter     An emitter object. 
     
    11921353YAML_DECLARE(int) 
    11931354yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); 
    1194  
    1195 /** 
    1196  * Emit the STREAM-START event. 
    1197  * 
    1198  * @param[in]   emitter     An emitter object. 
    1199  * @param[in]   encoding    The stream encoding. 
    1200  * 
    1201  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1202  */ 
    1203  
    1204 YAML_DECLARE(int) 
    1205 yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 
    1206         yaml_encoding_t encoding); 
    1207  
    1208 /** 
    1209  * Emit the STREAM-END event. 
    1210  * 
    1211  * @param[in]   emitter     An emitter object. 
    1212  * 
    1213  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1214  */ 
    1215  
    1216 YAML_DECLARE(int) 
    1217 yaml_emitter_emit_stream_end(yaml_emitter_t *emitter); 
    1218  
    1219 /** 
    1220  * Emit the DOCUMENT-START event. 
    1221  * 
    1222  * The @a implicit argument is considered as a stylistic parameter and may be 
    1223  * ignored by the emitter. 
    1224  * 
    1225  * @param[in]   emitter                 An emitter object. 
    1226  * @param[in]   version_directive       The %YAML directive value or @c NULL. 
    1227  * @param[in]   tag_directives_start    The beginning of the %TAG directives list. 
    1228  * @param[in]   tag_directives_end      The end of the %TAG directives list. 
    1229  * @param[in]   implicit                If the document start indicator is implicit. 
    1230  * 
    1231  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1232  */ 
    1233  
    1234 YAML_DECLARE(int) 
    1235 yaml_emitter_emit_document_start(yaml_emitter_t *emitter, 
    1236         yaml_version_directive_t *version_directive, 
    1237         yaml_tag_directive_t *tag_directives_start, 
    1238         yaml_tag_directive_t *tag_directives_end, 
    1239         int implicit); 
    1240  
    1241 /** 
    1242  * Emit the DOCUMENT-END event. 
    1243  * 
    1244  * The @a implicit argument is considered as a stylistic parameter and may be 
    1245  * ignored by the emitter. 
    1246  * 
    1247  * @param[in]   emitter     An emitter object. 
    1248  * @param[in]   implicit    If the document end indicator is implicit. 
    1249  * 
    1250  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1251  */ 
    1252  
    1253 YAML_DECLARE(int) 
    1254 yaml_emitter_emit_document_end(yaml_emitter_t *emitter, int implicit); 
    1255  
    1256 /** 
    1257  * Emit an ALIAS event. 
    1258  * 
    1259  * @param[in]   emitter     An emitter object. 
    1260  * @param[in]   anchor      The anchor value. 
    1261  * 
    1262  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1263  */ 
    1264  
    1265 YAML_DECLARE(int) 
    1266 yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_char_t *anchor); 
    1267  
    1268 /** 
    1269  * Emit a SCALAR event. 
    1270  * 
    1271  * The @a style argument may be ignored by the emitter. 
    1272  * 
    1273  * Either the @a tag attribute or one of the @a plain_implicit and 
    1274  * @a quoted_implicit flags must be set. 
    1275  * 
    1276  * @param[in]   emitter         An emitter object. 
    1277  * @param[in]   anchor          The scalar anchor or @c NULL. 
    1278  * @param[in]   tag             The scalar tag or @c NULL. 
    1279  * @param[in]   value           The scalar value. 
    1280  * @param[in]   length          The length of the scalar value. 
    1281  * @param[in]   plain_implicit  If the tag may be omitted for the plain style. 
    1282  * @param[in]   quoted_implicit If the tag may be omitted for any non-plain style. 
    1283  * @param[in]   style           The scalar style. 
    1284  * 
    1285  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1286  */ 
    1287  
    1288 YAML_DECLARE(int) 
    1289 yaml_emitter_emit_scalar(yaml_emitter_t *emitter, 
    1290         yaml_char_t *anchor, yaml_char_t *tag, 
    1291         yaml_char_t *value, size_t length, 
    1292         int plain_implicit, int quoted_implicit, 
    1293         yaml_scalar_style_t style); 
    1294  
    1295 /** 
    1296  * Emit a SEQUENCE-START event. 
    1297  * 
    1298  * The @a style argument may be ignored by the emitter. 
    1299  * 
    1300  * Either the @a tag attribute or the @a implicit flag must be set. 
    1301  * 
    1302  * @param[in]   emitter     An emitter object. 
    1303  * @param[in]   anchor      The sequence anchor or @c NULL. 
    1304  * @param[in]   tag         The sequence tag or @c NULL. 
    1305  * @param[in]   implicit    If the tag may be omitted. 
    1306  * @param[in]   style       The sequence style. 
    1307  * 
    1308  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1309  */ 
    1310  
    1311 YAML_DECLARE(int) 
    1312 yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, 
    1313         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    1314         yaml_sequence_style_t style); 
    1315  
    1316 /** 
    1317  * Emit a SEQUENCE-END event. 
    1318  * 
    1319  * @param[in]   emitter     An emitter object. 
    1320  * 
    1321  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1322  */ 
    1323  
    1324 YAML_DECLARE(int) 
    1325 yaml_emitter_emit_sequence_end(yaml_emitter_t *emitter); 
    1326  
    1327 /** 
    1328  * Emit a MAPPING-START event. 
    1329  * 
    1330  * The @a style argument may be ignored by the emitter. 
    1331  * 
    1332  * Either the @a tag attribute or the @a implicit flag must be set. 
    1333  * 
    1334  * @param[in]   emitter     An emitter object. 
    1335  * @param[in]   anchor      The mapping anchor or @c NULL. 
    1336  * @param[in]   tag         The mapping tag or @c NULL. 
    1337  * @param[in]   implicit    If the tag may be omitted. 
    1338  * @param[in]   style       The mapping style. 
    1339  * 
    1340  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1341  */ 
    1342  
    1343 YAML_DECLARE(int) 
    1344 yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, 
    1345         yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
    1346         yaml_mapping_style_t style); 
    1347  
    1348 /** 
    1349  * Emit a MAPPING-END event. 
    1350  * 
    1351  * @param[in]   emitter     An emitter object. 
    1352  * 
    1353  * @returns @c 1 if the function succeeded, @c 0 on error. 
    1354  */ 
    1355  
    1356 YAML_DECLARE(int) 
    1357 yaml_emitter_emit_mapping_end(yaml_emitter_t *emitter); 
    13581355 
    13591356/** 
  • libyaml/trunk/src/api.c

    r212 r213  
    393393    } 
    394394    STACK_DEL(emitter, emitter->indents); 
    395     yaml_event_delete(&emitter->event); 
    396395    while (!STACK_EMPTY(empty, emitter->tag_directives)) { 
    397396        yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); 
     
    606605 
    607606    memset(token, 0, sizeof(yaml_token_t)); 
     607} 
     608 
     609/* 
     610 * Check if a string is a valid UTF-8 sequence. 
     611 * 
     612 * Check 'reader.c' for more details on UTF-8 encoding. 
     613 */ 
     614 
     615static int 
     616yaml_check_utf8(yaml_char_t *start, size_t length) 
     617{ 
     618    yaml_char_t *end = start+length; 
     619    yaml_char_t *pointer = start; 
     620 
     621    while (pointer < end) { 
     622        unsigned char octet; 
     623        unsigned int width; 
     624        unsigned int value; 
     625        int k; 
     626 
     627        octet = pointer[0]; 
     628        width = (octet & 0x80) == 0x00 ? 1 : 
     629                (octet & 0xE0) == 0xC0 ? 2 : 
     630                (octet & 0xF0) == 0xE0 ? 3 : 
     631                (octet & 0xF8) == 0xF0 ? 4 : 0; 
     632       value = (octet & 0x80) == 0x00 ? octet & 0x7F : 
     633                (octet & 0xE0) == 0xC0 ? octet & 0x1F : 
     634                (octet & 0xF0) == 0xE0 ? octet & 0x0F : 
     635                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 
     636        if (!width) return 0; 
     637        if (pointer+width > end) return 0; 
     638        for (k = 1; k < width; k ++) { 
     639            octet = pointer[k]; 
     640            if ((octet & 0xC0) != 0x80) return 0; 
     641            value = (value << 6) + (octet & 0x3F); 
     642        } 
     643        if (!((width == 1) || 
     644            (width == 2 && value >= 0x80) || 
     645            (width == 3 && value >= 0x800) || 
     646            (width == 4 && value >= 0x10000))) return 0; 
     647 
     648        pointer += width; 
     649    } 
     650 
     651    return 1; 
     652} 
     653 
     654/* 
     655 * Create STREAM-START. 
     656 */ 
     657 
     658YAML_DECLARE(int) 
     659yaml_stream_start_event_initialize(yaml_event_t *event, 
     660        yaml_encoding_t encoding) 
     661{ 
     662    yaml_mark_t mark = { 0, 0, 0 }; 
     663 
     664    assert(event);  /* Non-NULL event object is expected. */ 
     665 
     666    STREAM_START_EVENT_INIT(*event, encoding, mark, mark); 
     667 
     668    return 1; 
     669} 
     670 
     671/* 
     672 * Create STREAM-END. 
     673 */ 
     674 
     675YAML_DECLARE(int) 
     676yaml_stream_end_event_initialize(yaml_event_t *event) 
     677{ 
     678    yaml_mark_t mark = { 0, 0, 0 }; 
     679 
     680    assert(event);  /* Non-NULL event object is expected. */ 
     681 
     682    STREAM_END_EVENT_INIT(*event, mark, mark); 
     683 
     684    return 1; 
     685} 
     686 
     687/* 
     688 * Create DOCUMENT-START. 
     689 */ 
     690 
     691YAML_DECLARE(int) 
     692yaml_document_start_event_initialize(yaml_event_t *event, 
     693        yaml_version_directive_t *version_directive, 
     694        yaml_tag_directive_t *tag_directives_start, 
     695        yaml_tag_directive_t *tag_directives_end, 
     696        int implicit) 
     697{ 
     698    struct { 
     699        yaml_error_type_t error; 
     700    } context; 
     701    yaml_mark_t mark = { 0, 0, 0 }; 
     702    yaml_version_directive_t *version_directive_copy = NULL; 
     703    struct { 
     704        yaml_tag_directive_t *start; 
     705        yaml_tag_directive_t *end; 
     706        yaml_tag_directive_t *top; 
     707    } tag_directives_copy = { NULL, NULL, NULL }; 
     708    yaml_tag_directive_t value = { NULL, NULL }; 
     709 
     710    assert(event);          /* Non-NULL event object is expected. */ 
     711    assert((tag_directives_start && tag_directives_end) || 
     712            (tag_directives_start == tag_directives_end)); 
     713                            /* Valid tag directives are expected. */ 
     714 
     715    if (version_directive) { 
     716        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); 
     717        if (!version_directive_copy) goto error; 
     718        version_directive_copy->major = version_directive->major; 
     719        version_directive_copy->minor = version_directive->minor; 
     720    } 
     721 
     722    if (tag_directives_start != tag_directives_end) { 
     723        yaml_tag_directive_t *tag_directive; 
     724        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) 
     725            goto error; 
     726        for (tag_directive = tag_directives_start; 
     727                tag_directive != tag_directives_end; tag_directive ++) { 
     728            assert(tag_directive->handle); 
     729            assert(tag_directive->prefix); 
     730            if (!yaml_check_utf8(tag_directive->handle, 
     731                        strlen((char *)tag_directive->handle))) 
     732                goto error; 
     733            if (!yaml_check_utf8(tag_directive->prefix, 
     734                        strlen((char *)tag_directive->prefix))) 
     735                goto error; 
     736            value.handle = yaml_strdup(tag_directive->handle); 
     737            value.prefix = yaml_strdup(tag_directive->prefix); 
     738            if (!value.handle || !value.prefix) goto error; 
     739            if (!PUSH(&context, tag_directives_copy, value)) 
     740                goto error; 
     741            value.handle = NULL; 
     742            value.prefix = NULL; 
     743        } 
     744    } 
     745 
     746    DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, 
     747            tag_directives_copy.start, tag_directives_copy.end, 
     748            implicit, mark, mark); 
     749 
     750    return 1; 
     751 
     752error: 
     753    yaml_free(version_directive_copy); 
     754    while (!STACK_EMPTY(context, tag_directives_copy)) { 
     755        yaml_tag_directive_t value = POP(context, tag_directives_copy); 
     756        yaml_free(value.handle); 
     757        yaml_free(value.prefix); 
     758    } 
     759    STACK_DEL(context, tag_directives_copy); 
     760    yaml_free(value.handle); 
     761    yaml_free(value.prefix); 
     762 
     763    return 0; 
     764} 
     765 
     766/* 
     767 * Create DOCUMENT-END. 
     768 */ 
     769 
     770YAML_DECLARE(int) 
     771yaml_document_end_event_initialize(yaml_event_t *event, int implicit) 
     772{ 
     773    yaml_mark_t mark = { 0, 0, 0 }; 
     774 
     775    assert(event);      /* Non-NULL emitter object is expected. */ 
     776 
     777    DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark); 
     778 
     779    return 1; 
     780} 
     781 
     782/* 
     783 * Create ALIAS. 
     784 */ 
     785 
     786YAML_DECLARE(int) 
     787yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor) 
     788{ 
     789    yaml_mark_t mark = { 0, 0, 0 }; 
     790    yaml_char_t *anchor_copy = NULL; 
     791 
     792    assert(event);      /* Non-NULL event object is expected. */ 
     793    assert(anchor);     /* Non-NULL anchor is expected. */ 
     794 
     795    if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0; 
     796 
     797    anchor_copy = yaml_strdup(anchor); 
     798    if (!anchor_copy) 
     799        return 0; 
     800 
     801    ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); 
     802 
     803    return 1; 
     804} 
     805 
     806/* 
     807 * Create SCALAR. 
     808 */ 
     809 
     810YAML_DECLARE(int) 
     811yaml_scalar_event_initialize(yaml_event_t *event, 
     812        yaml_char_t *anchor, yaml_char_t *tag, 
     813        yaml_char_t *value, size_t length, 
     814        int plain_implicit, int quoted_implicit, 
     815        yaml_scalar_style_t style) 
     816{ 
     817    yaml_mark_t mark = { 0, 0, 0 }; 
     818    yaml_char_t *anchor_copy = NULL; 
     819    yaml_char_t *tag_copy = NULL; 
     820    yaml_char_t *value_copy = NULL; 
     821 
     822    assert(event);      /* Non-NULL event object is expected. */ 
     823    assert(value);      /* Non-NULL anchor is expected. */ 
     824 
     825 
     826    if (anchor) { 
     827        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
     828        anchor_copy = yaml_strdup(anchor); 
     829        if (!anchor_copy) goto error; 
     830    } 
     831 
     832    if (tag) { 
     833        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
     834        tag_copy = yaml_strdup(tag); 
     835        if (!tag_copy) goto error; 
     836    } 
     837 
     838    if (!yaml_check_utf8(value, length)) goto error; 
     839    value_copy = yaml_malloc(length+1); 
     840    if (!value_copy) goto error; 
     841    memcpy(value_copy, value, length); 
     842    value_copy[length] = '\0'; 
     843 
     844    SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, 
     845            plain_implicit, quoted_implicit, style, mark, mark); 
     846 
     847    return 1; 
     848 
     849error: 
     850    yaml_free(anchor_copy); 
     851    yaml_free(tag_copy); 
     852    yaml_free(value_copy); 
     853 
     854    return 0; 
     855} 
     856 
     857/* 
     858 * Create SEQUENCE-START. 
     859 */ 
     860 
     861YAML_DECLARE(int) 
     862yaml_sequence_start_event_initialize(yaml_event_t *event, 
     863        yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
     864        yaml_sequence_style_t style) 
     865{ 
     866    yaml_mark_t mark = { 0, 0, 0 }; 
     867    yaml_char_t *anchor_copy = NULL; 
     868    yaml_char_t *tag_copy = NULL; 
     869 
     870    assert(event);      /* Non-NULL event object is expected. */ 
     871 
     872    if (anchor) { 
     873        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
     874        anchor_copy = yaml_strdup(anchor); 
     875        if (!anchor_copy) goto error; 
     876    } 
     877 
     878    if (tag) { 
     879        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
     880        tag_copy = yaml_strdup(tag); 
     881        if (!tag_copy) goto error; 
     882    } 
     883 
     884    SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     885            implicit, style, mark, mark); 
     886 
     887    return 1; 
     888 
     889error: 
     890    yaml_free(anchor_copy); 
     891    yaml_free(tag_copy); 
     892 
     893    return 0; 
     894} 
     895 
     896/* 
     897 * Create SEQUENCE-END. 
     898 */ 
     899 
     900YAML_DECLARE(int) 
     901yaml_sequence_end_event_initialize(yaml_event_t *event) 
     902{ 
     903    yaml_mark_t mark = { 0, 0, 0 }; 
     904 
     905    assert(event);      /* Non-NULL event object is expected. */ 
     906 
     907    SEQUENCE_END_EVENT_INIT(*event, mark, mark); 
     908 
     909    return 1; 
     910} 
     911 
     912/* 
     913 * Create MAPPING-START. 
     914 */ 
     915 
     916YAML_DECLARE(int) 
     917yaml_mapping_start_event_initialize(yaml_event_t *event, 
     918        yaml_char_t *anchor, yaml_char_t *tag, int implicit, 
     919        yaml_mapping_style_t style) 
     920{ 
     921    yaml_mark_t mark = { 0, 0, 0 }; 
     922    yaml_char_t *anchor_copy = NULL; 
     923    yaml_char_t *tag_copy = NULL; 
     924 
     925    assert(event);      /* Non-NULL event object is expected. */ 
     926 
     927    if (anchor) { 
     928        if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; 
     929        anchor_copy = yaml_strdup(anchor); 
     930        if (!anchor_copy) goto error; 
     931    } 
     932 
     933    if (tag) { 
     934        if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; 
     935        tag_copy = yaml_strdup(tag); 
     936        if (!tag_copy) goto error; 
     937    } 
     938 
     939    MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, 
     940            implicit, style, mark, mark); 
     941 
     942    return 1; 
     943 
     944error: 
     945    yaml_free(anchor_copy); 
     946    yaml_free(tag_copy); 
     947 
     948    return 0; 
     949} 
     950 
     951/* 
     952 * Create MAPPING-END. 
     953 */ 
     954 
     955YAML_DECLARE(int) 
     956yaml_mapping_end_event_initialize(yaml_event_t *event) 
     957{ 
     958    yaml_mark_t mark = { 0, 0, 0 }; 
     959 
     960    assert(event);      /* Non-NULL event object is expected. */ 
     961 
     962    MAPPING_END_EVENT_INIT(*event, mark, mark); 
     963 
     964    return 1; 
    608965} 
    609966 
  • 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       &nbs