diff options
author | why <why@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-10-17 20:53:39 +0000 |
---|---|---|
committer | why <why@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-10-17 20:53:39 +0000 |
commit | 71a8bebf5a130735b6455426b25a817fb31463c8 (patch) | |
tree | 12451184c932388ec7fa18a76b855054027589e2 /ext/syck/yaml2byte.c | |
parent | 23f6b5bdc450abc5ce3a3dc7540a668f5d166dea (diff) | |
download | ruby-71a8bebf5a130735b6455426b25a817fb31463c8.tar.gz |
* ext/syck/rubyext.c: YAML::Syck::compile method.
* ext/syck/syck.c: Buffer edge bug.
* ext/syck/yaml2byte.c: YAML to bytecode converter.
* ext/syck/bytecode.c: Bytecode parser fixes to empty collections
and empty strings.
* ext/syck/token.c: Ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4799 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/syck/yaml2byte.c')
-rw-r--r-- | ext/syck/yaml2byte.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/ext/syck/yaml2byte.c b/ext/syck/yaml2byte.c new file mode 100644 index 0000000000..54493c0021 --- /dev/null +++ b/ext/syck/yaml2byte.c @@ -0,0 +1,251 @@ +// +// ybext.c +// +// $Author$ +// $Date$ +// +// Copyright (C) 2003 why the lucky stiff, clark evans +// +// WARNING WARNING WARNING --- THIS IS *NOT JUST* PLAYING +// ANYMORE! -- WHY HAS EMBRACED THIS AS THE REAL THING! +// +#include <syck.h> +#include <assert.h> +#define YAMLBYTE_UTF8 +#include "yamlbyte.h" +#include "ruby.h" + +#include <stdio.h> +#define TRACE0(a) \ + do { printf(a); printf("\n"); fflush(stdout); } while(0) +#define TRACE1(a,b) \ + do { printf(a,b); printf("\n"); fflush(stdout); } while(0) +#define TRACE2(a,b,c) \ + do { printf(a,b,c); printf("\n"); fflush(stdout); } while(0) +#define TRACE3(a,b,c,d) \ + do { printf(a,b,c,d); printf("\n"); fflush(stdout); } while(0) + +/* Reinvent the wheel... */ +#define CHUNKSIZE 64 +#define HASH ((long)0xCAFECAFECAFECAFE) +typedef struct { + long hash; + char *buffer; + long length; + long remaining; + int printed; +} bytestring_t; +bytestring_t *bytestring_alloc() { + bytestring_t *ret; + //TRACE0("bytestring_alloc()"); + ret = S_ALLOC(bytestring_t); + ret->hash = HASH; + ret->length = CHUNKSIZE; + ret->remaining = ret->length; + ret->buffer = S_ALLOC_N(char, ret->length + 1 ); + ret->buffer[0] = 0; + ret->printed = 0; + return ret; +} +void bytestring_append(bytestring_t *str, char code, + char *start, char *finish) +{ + long grow; + long length = 2; /* CODE + LF */ + char *curr; + assert(str && HASH == str->hash); + //TRACE0("bytestring_append()"); + if(start) { + if(!finish) + finish = start + strlen(start); + length += (finish-start); + } + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 ); + assert(str->buffer); + } + curr = str->buffer + (str->length - str->remaining); + *curr = code; + curr += 1; + if(start) + while(start < finish) + *curr ++ = *start ++; + *curr = '\n'; + curr += 1; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); +} +void bytestring_extend(bytestring_t *str, bytestring_t *ext) +{ + char *from; + char *curr; + char *stop; + long grow; + long length; + assert(str && HASH == str->hash); + assert(ext && HASH == ext->hash); + if(ext->printed) { + assert(ext->buffer[0] ==YAMLBYTE_ANCHOR); + curr = ext->buffer; + while( '\n' != *curr) + curr++; + bytestring_append(str, YAMLBYTE_ALIAS, ext->buffer + 1, curr); + } else { + ext->printed = 1; + length = (ext->length - ext->remaining); + if(length > str->remaining) { + grow = (length - str->remaining) + CHUNKSIZE; + str->remaining += grow; + str->length += grow; + str->buffer = S_REALLOC_N( str->buffer, char, str->length + 1 ); + } + curr = str->buffer + (str->length - str->remaining); + from = ext->buffer; + stop = ext->buffer + length; + while( from < stop ) + *curr ++ = *from ++; + *curr = 0; + str->remaining = str->remaining - length; + assert( (str->buffer + str->length) - str->remaining ); + } +} + +/* convert SyckNode into yamlbyte_buffer_t objects */ +SYMID +syck_yaml2byte_handler(p, n) + SyckParser *p; + SyckNode *n; +{ + SYMID oid; + long i; + char ch; + char nextcode; + char *start; + char *current; + char *finish; + bytestring_t *val = NULL; + bytestring_t *sav = NULL; + //TRACE0("syck_yaml2byte_handler()"); + val = bytestring_alloc(); + if(n->anchor) bytestring_append(val,YAMLBYTE_ANCHOR, n->anchor, NULL); + if ( n->type_id ) + { + if ( p->taguri_expansion ) + { + bytestring_append(val,YAMLBYTE_TRANSFER, n->type_id, NULL); + } + else + { + char *type_tag = S_ALLOC_N( char, strlen( n->type_id ) + 1 ); + type_tag[0] = '\0'; + strcat( type_tag, "!" ); + strcat( type_tag, n->type_id ); + bytestring_append( val, YAMLBYTE_TRANSFER, type_tag, NULL); + } + } + switch (n->kind) + { + case syck_str_kind: + nextcode = YAMLBYTE_SCALAR; + start = n->data.str->ptr; + finish = start + n->data.str->len - 1; + current = start; + //TRACE2("SCALAR: %s %d", start, n->data.str->len); + while(1) { + ch = *current; + if('\n' == ch || 0 == ch || current > finish) { + if(current >= start) { + bytestring_append(val, nextcode, start, current); + nextcode = YAMLBYTE_CONTINUE; + } + start = current + 1; + if(current > finish) + { + break; + } + else if('\n' == ch ) + { + bytestring_append(val,YAMLBYTE_NEWLINE,NULL,NULL); + } + else if(0 == ch) + { + bytestring_append(val,YAMLBYTE_NULLCHAR,NULL,NULL); + } + else + { + assert("oops"); + } + } + current += 1; + } + break; + case syck_seq_kind: + bytestring_append(val,YAMLBYTE_SEQUENCE,NULL,NULL); + for ( i = 0; i < n->data.list->idx; i++ ) + { + oid = syck_seq_read( n, i ); + syck_lookup_sym( p, oid, (char **)&sav ); + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + case syck_map_kind: + bytestring_append(val,YAMLBYTE_MAPPING,NULL,NULL); + for ( i = 0; i < n->data.pairs->idx; i++ ) + { + oid = syck_map_read( n, map_key, i ); + syck_lookup_sym( p, oid, (char **)&sav ); + bytestring_extend(val, sav); + oid = syck_map_read( n, map_value, i ); + syck_lookup_sym( p, oid, (char **)&sav ); + bytestring_extend(val, sav); + } + bytestring_append(val,YAMLBYTE_END_BRANCH,NULL,NULL); + break; + } + oid = syck_add_sym( p, (char *) val ); + //TRACE1("Saving: %s", val->buffer ); + return oid; +} + +char * +syck_yaml2byte(char *yamlstr) +{ + SYMID oid; + char *ret; + bytestring_t *sav; + + SyckParser *parser = syck_new_parser(); + syck_parser_str_auto( parser, yamlstr, NULL ); + syck_parser_handler( parser, syck_yaml2byte_handler ); + syck_parser_error_handler( parser, NULL ); + syck_parser_implicit_typing( parser, 1 ); + syck_parser_taguri_expansion( parser, 1 ); + oid = syck_parse( parser ); + syck_lookup_sym( parser, oid, (char **)&sav ); + + ret = S_ALLOC_N( char, strlen( sav->buffer ) + 3 ); + ret[0] = '\0'; + strcat( ret, "D\n" ); + strcat( ret, sav->buffer ); + + syck_free_parser( parser ); + return ret; +} + +#ifdef TEST_YBEXT +#include <stdio.h> +int main() { + char *yaml = "test: 1\nand: \"with new\\nline\\n\"\nalso: &3 three\nmore: *3"; + printf("--- # YAML \n"); + printf(yaml); + printf("\n...\n"); + printf(syck_yaml2byte(yaml)); + return 0; +} +#endif + |