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/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 
Note: See TracChangeset for help on using the changeset viewer.