From 4b25d0d2cb5e47907c3586ba86646b25bd25ceaf Mon Sep 17 00:00:00 2001 From: why Date: Sat, 10 May 2003 19:55:18 +0000 Subject: * ext/syck/gram.c ext/syck/handler.c ext/syck/implicit.c ext/syck/node.c ext/syck/rubyext.c ext/syck/syck.c ext/syck/syck.h ext/syck/token.c: updated to Syck 0.27 * lib/yaml/loader.rb: new YAML::Loader class * lib/yaml.rb: loading of type families leverages YAML::DefaultLoader git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3778 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/syck/gram.c | 4 +- ext/syck/handler.c | 81 ++----- ext/syck/implicit.c | 687 ++++++++++++++++++++++++++++++++++++++++++++++++---- ext/syck/rubyext.c | 244 ++++++++++++++++++- ext/syck/syck.c | 10 +- ext/syck/syck.h | 7 +- lib/yaml.rb | 102 +++++--- lib/yaml/loader.rb | 14 ++ 8 files changed, 1000 insertions(+), 149 deletions(-) create mode 100644 lib/yaml/loader.rb diff --git a/ext/syck/gram.c b/ext/syck/gram.c index 5ea28ce621..e1d0301c6c 100644 --- a/ext/syck/gram.c +++ b/ext/syck/gram.c @@ -1076,7 +1076,7 @@ yyreduce: SyckNode *n = syck_new_str( "" ); if ( ((SyckParser *)parser)->taguri_expansion == 1 ) { - syck_taguri( n, "yaml.org,2002", "null", 4 ); + n->type_id = syck_taguri( YAML_DOMAIN, "null", 4 ); } else { @@ -1111,7 +1111,7 @@ yyreduce: SyckNode *n = yyvsp[0].nodeData; if ( ((SyckParser *)parser)->taguri_expansion == 1 ) { - syck_taguri( n, "yaml.org,2002", "str", 3 ); + n->type_id = syck_taguri( YAML_DOMAIN, "str", 3 ); } else { diff --git a/ext/syck/handler.c b/ext/syck/handler.c index 50ba3e4232..c54ee0408e 100644 --- a/ext/syck/handler.c +++ b/ext/syck/handler.c @@ -30,7 +30,7 @@ SyckNode * syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n ) { n->anchor = a; - st_insert( p->anchors, (st_data_t)a, (st_data_t)n ); + st_insert( p->anchors, a, n ); return n; } @@ -39,7 +39,7 @@ syck_hdlr_add_alias( SyckParser *p, char *a ) { SyckNode *n; - if ( st_lookup( p->anchors, (st_data_t)a, (st_data_t *)&n ) ) + if ( st_lookup( p->anchors, a, &n ) ) { return n; } @@ -54,76 +54,41 @@ syck_add_transfer( char *uri, SyckNode *n, int taguri ) char *slash = uri; char *domain = NULL; - if ( taguri == 0 ) + if ( n->type_id != NULL ) { - n->type_id = uri; - return; + S_FREE( n->type_id ); } - if ( uri[0] == '!' ) + if ( taguri == 0 ) { - syck_xprivate( n, uri + 1, strlen( uri ) - 1 ); - S_FREE( uri ); + n->type_id = uri; return; } - while ( *(++slash) != '\0' ) - { - if ( *slash == '/' ) - break; - - if ( *slash == ',' ) - comma = slash; - } - - if ( *slash == '\0' ) - { - syck_taguri( n, "yaml.org,2002", uri, strlen( uri ) ); - } - else if ( comma == NULL ) - { - domain = S_ALLOC_N( char, ( slash - uri ) + 15 ); - domain[0] = '\0'; - strncat( domain, uri, slash - uri ); - strcat( domain, ".yaml.org,2002" ); - syck_taguri( n, domain, slash + 1, strlen( uri ) - ( slash - uri + 1 ) ); - S_FREE( domain ); - } - else - { - domain = S_ALLOC_N( char, slash - uri ); - domain[0] = '\0'; - strncat( domain, uri, slash - uri ); - syck_taguri( n, domain, slash + 1, strlen( uri ) - ( slash - uri + 1 ) ); - S_FREE( domain ); - } + n->type_id = syck_type_id_to_uri( uri ); S_FREE( uri ); } -void -syck_xprivate( SyckNode *n, char *type_id, int type_len ) +char * +syck_xprivate( char *type_id, int type_len ) { - if ( n->type_id != NULL ) - S_FREE( n->type_id ); - - n->type_id = S_ALLOC_N( char, type_len + 14 ); - n->type_id[0] = '\0'; - strcat( n->type_id, "x-private:" ); - strncat( n->type_id, type_id, type_len ); + char *uri = S_ALLOC_N( char, type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "x-private:" ); + strncat( uri, type_id, type_len ); + return uri; } -void -syck_taguri( SyckNode *n, char *domain, char *type_id, int type_len ) +char * +syck_taguri( char *domain, char *type_id, int type_len ) { - if ( n->type_id != NULL ) - S_FREE( n->type_id ); - - n->type_id = S_ALLOC_N( char, strlen( domain ) + type_len + 14 ); - n->type_id[0] = '\0'; - strcat( n->type_id, "taguri:" ); - strcat( n->type_id, domain ); - strcat( n->type_id, ":" ); - strncat( n->type_id, type_id, type_len ); + char *uri = S_ALLOC_N( char, strlen( domain ) + type_len + 14 ); + uri[0] = '\0'; + strcat( uri, "taguri:" ); + strcat( uri, domain ); + strcat( uri, ":" ); + strncat( uri, type_id, type_len ); + return uri; } int diff --git a/ext/syck/implicit.c b/ext/syck/implicit.c index 4ba80e243f..413568ec03 100644 --- a/ext/syck/implicit.c +++ b/ext/syck/implicit.c @@ -1,5 +1,5 @@ -/* Generated by re2c 0.5 on Mon Apr 21 23:42:24 2003 */ -#line 1 "lib/implicit.re" +/* Generated by re2c 0.5 on Sat May 10 12:56:19 2003 */ +#line 1 "implicit.re" // // implicit.re // @@ -17,24 +17,27 @@ #define YYLIMIT limit #define YYFILL(n) -#define TAG_IMPLICIT( tid ) \ - if ( taguri == 1 ) \ - { \ - syck_taguri( n, "yaml.org,2002", tid, strlen( tid ) ); \ - } else { \ - n->type_id = syck_strndup( tid, strlen( tid ) ); \ - } \ - return; - void try_tag_implicit( SyckNode *n, int taguri ) { - char *cursor, *limit, *marker; + char *tid; if ( n->kind != syck_str_kind ) return; - cursor = n->data.str->ptr; - limit = cursor + n->data.str->len; + tid = syck_match_implicit( n->data.str->ptr, n->data.str->len ); + if ( taguri == 1 ) + { + n->type_id = syck_taguri( YAML_DOMAIN, tid, strlen( tid ) ); + } else { + n->type_id = syck_strndup( tid, strlen( tid ) ); + } +} + +char *syck_match_implicit( char *str, size_t len ) +{ + char *cursor, *limit, *marker; + cursor = str; + limit = str + len; { YYCTYPE yych; @@ -133,8 +136,8 @@ yy2: YYCURSOR = YYMARKER; yy3: yych = *++YYCURSOR; if(yych <= '\000') goto yy185; yy4: -#line 99 - { TAG_IMPLICIT( "str" ); } +#line 102 + { return "str"; } yy5: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych == 'o') goto yy158; @@ -295,8 +298,8 @@ yy27: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy28: yych = *++YYCURSOR; yy29: -#line 85 - { TAG_IMPLICIT( "float#inf" ); } +#line 88 + { return "float#inf"; } yy30: yych = *++YYCURSOR; if(yych == 'f') goto yy27; goto yy2; @@ -309,8 +312,8 @@ yy33: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy34: yych = *++YYCURSOR; yy35: -#line 89 - { TAG_IMPLICIT( "float#nan" ); } +#line 92 + { return "float#nan"; } yy36: yych = *++YYCURSOR; if(yych == 'n') goto yy33; goto yy2; @@ -348,8 +351,8 @@ yy41: if(yybm[0+yych] & 2) goto yy40; } yy42: yych = *++YYCURSOR; yy43: -#line 79 - { TAG_IMPLICIT( "int" ); } +#line 82 + { return "int"; } yy44: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; @@ -364,8 +367,8 @@ yy45: if(yych <= ','){ } yy46: yych = *++YYCURSOR; yy47: -#line 81 - { TAG_IMPLICIT( "float#fix" ); } +#line 84 + { return "float#fix"; } yy48: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; @@ -387,8 +390,8 @@ yy53: if(yych <= '\000') goto yy54; goto yy2; yy54: yych = *++YYCURSOR; yy55: -#line 83 - { TAG_IMPLICIT( "float#exp" ); } +#line 86 + { return "float#exp"; } yy56: yych = *++YYCURSOR; if(yych <= '/') goto yy39; if(yych >= ':') goto yy39; @@ -421,8 +424,8 @@ yy63: yych = *++YYCURSOR; } yy64: yych = *++YYCURSOR; yy65: -#line 91 - { TAG_IMPLICIT( "timestamp#ymd" ); } +#line 94 + { return "timestamp#ymd"; } yy66: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych <= '9') goto yy112; @@ -508,8 +511,8 @@ yy86: yych = *++YYCURSOR; goto yy2; yy87: yych = *++YYCURSOR; yy88: -#line 95 - { TAG_IMPLICIT( "timestamp#spaced" ); } +#line 98 + { return "timestamp#spaced"; } yy89: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych <= '9') goto yy82; @@ -581,8 +584,8 @@ yy106: yych = *++YYCURSOR; goto yy2; yy107: yych = *++YYCURSOR; yy108: -#line 93 - { TAG_IMPLICIT( "timestamp#iso8601" ); } +#line 96 + { return "timestamp#iso8601"; } yy109: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych <= '9') goto yy102; @@ -699,12 +702,12 @@ yy132: if(yybm[0+yych] & 128) goto yy131; if(yych >= '\001') goto yy2; yy133: yych = *++YYCURSOR; yy134: -#line 75 - { TAG_IMPLICIT( "int#hex" ); } +#line 78 + { return "int#hex"; } yy135: yych = *++YYCURSOR; yy136: -#line 77 - { TAG_IMPLICIT( "int#oct" ); } +#line 80 + { return "int#oct"; } yy137: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; @@ -755,8 +758,8 @@ yy149: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy150: yych = *++YYCURSOR; yy151: -#line 87 - { TAG_IMPLICIT( "float#neginf" ); } +#line 90 + { return "float#neginf"; } yy152: yych = *++YYCURSOR; if(yych == 'f') goto yy149; goto yy2; @@ -777,8 +780,8 @@ yy158: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy159: yych = *++YYCURSOR; yy160: -#line 73 - { TAG_IMPLICIT( "bool#no" ); } +#line 76 + { return "bool#no"; } yy161: yych = *++YYCURSOR; if(yych != 'S') goto yy2; yy162: yych = *++YYCURSOR; @@ -801,8 +804,8 @@ yy168: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy169: yych = *++YYCURSOR; yy170: -#line 71 - { TAG_IMPLICIT( "bool#yes" ); } +#line 74 + { return "bool#yes"; } yy171: yych = *++YYCURSOR; if(yych == 'f') goto yy158; goto yy2; @@ -842,8 +845,8 @@ yy184: yych = *++YYCURSOR; if(yych >= '\001') goto yy2; yy185: yych = *++YYCURSOR; yy186: -#line 69 - { TAG_IMPLICIT( "null" ); } +#line 72 + { return "null"; } yy187: yych = *++YYCURSOR; if(yych == 'L') goto yy184; goto yy2; @@ -853,7 +856,601 @@ yy189: yych = *++YYCURSOR; if(yych == 'l') goto yy184; goto yy2; } -#line 101 +#line 104 + + +} + +char * +syck_type_id_to_uri( char *type_id ) +{ + char *cursor, *limit, *marker; + + cursor = type_id; + limit = type_id + strlen( type_id ); + +{ + YYCTYPE yych; + unsigned int yyaccept; + static unsigned char yybm[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 0, 0, 0, 0, 0, 0, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 128, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; + goto yy190; +yy191: ++YYCURSOR; +yy190: + if((YYLIMIT - YYCURSOR) < 20) YYFILL(20); + yych = *YYCURSOR; + if(yych <= '^'){ + if(yych <= '/'){ + if(yych <= '\000') goto yy192; + if(yych == '!') goto yy196; + goto yy199; + } else { + if(yych <= '9') goto yy198; + if(yych <= '@') goto yy199; + if(yych <= 'Z') goto yy198; + goto yy199; + } + } else { + if(yych <= 't'){ + if(yych == '`') goto yy199; + if(yych <= 's') goto yy198; + goto yy193; + } else { + if(yych == 'x') goto yy195; + if(yych <= 'z') goto yy198; + goto yy199; + } + } +yy192: YYCURSOR = YYMARKER; + switch(yyaccept){ + case 0: goto yy194; + } +yy193: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yybm[0+yych] & 64) goto yy200; + if(yych <= '@'){ + if(yych <= '.'){ + if(yych <= '+') goto yy194; + if(yych <= ',') goto yy204; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych <= '9') goto yy202; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy202; + if(yych >= '_') goto yy202; + } else { + if(yych <= '`') goto yy194; + if(yych <= 'a') goto yy233; + if(yych <= 'z') goto yy202; + } + } +yy194: +#line 156 + { return syck_taguri( YAML_DOMAIN, type_id, strlen( type_id ) ); } +yy195: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yybm[0+yych] & 64) goto yy200; + if(yych <= 'Z'){ + if(yych <= '.'){ + if(yych <= '+') goto yy194; + if(yych <= ',') goto yy204; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych <= '9') goto yy202; + if(yych <= '@') goto yy194; + goto yy202; + } + } else { + if(yych <= '`'){ + if(yych == '_') goto yy202; + goto yy194; + } else { + if(yych == 'p') goto yy224; + if(yych <= 'z') goto yy202; + goto yy194; + } + } +yy196: yych = *++YYCURSOR; +yy197: +#line 130 + { return syck_xprivate( type_id + 1, strlen( type_id ) - 1 ); } +yy198: yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yybm[0+yych] & 64) goto yy200; + if(yych <= '@'){ + if(yych <= '.'){ + if(yych <= '+') goto yy194; + if(yych <= ',') goto yy204; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych <= '9') goto yy202; + goto yy194; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy202; + if(yych <= '^') goto yy194; + goto yy202; + } else { + if(yych <= '`') goto yy194; + if(yych <= 'z') goto yy202; + goto yy194; + } + } +yy199: yych = *++YYCURSOR; + goto yy194; +yy200: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy201: if(yybm[0+yych] & 64) goto yy200; + if(yych <= 'Z'){ + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy202; + if(yych <= '@') goto yy192; + } else { + if(yych <= '_'){ + if(yych <= '^') goto yy192; + } else { + if(yych <= '`') goto yy192; + if(yych >= '{') goto yy192; + } + } +yy202: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy203: if(yybm[0+yych] & 64) goto yy200; + if(yych <= '@'){ + if(yych <= '.'){ + if(yych <= '+') goto yy192; + if(yych >= '-') goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych <= '9') goto yy202; + goto yy192; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy202; + if(yych <= '^') goto yy192; + goto yy202; + } else { + if(yych <= '`') goto yy192; + if(yych <= 'z') goto yy202; + goto yy192; + } + } +yy204: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy212; + goto yy192; +yy205: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 'Z'){ + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy208; + if(yych <= '@') goto yy192; + goto yy208; + } else { + if(yych <= '_'){ + if(yych <= '^') goto yy192; + goto yy208; + } else { + if(yych <= '`') goto yy192; + if(yych <= 'z') goto yy208; + goto yy192; + } + } +yy206: yych = *++YYCURSOR; +yy207: +#line 132 + { char *domain = S_ALLOC_N( char, ( YYCURSOR - type_id ) + 15 ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + strcat( domain, "." ); + strcat( domain, YAML_DOMAIN ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +yy208: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; +yy209: if(yych <= '9'){ + if(yych <= '-'){ + if(yych <= '+') goto yy192; + if(yych <= ',') goto yy204; + } else { + if(yych <= '.') goto yy205; + if(yych <= '/') goto yy206; + goto yy208; + } + } else { + if(yych <= '^'){ + if(yych <= '@') goto yy192; + if(yych <= 'Z') goto yy208; + goto yy192; + } else { + if(yych == '`') goto yy192; + if(yych <= 'z') goto yy208; + goto yy192; + } + } +yy210: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy211: if(yych <= '@'){ + if(yych <= '-'){ + if(yych <= ',') goto yy192; + goto yy210; + } else { + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy208; + goto yy192; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy208; + if(yych <= '^') goto yy192; + goto yy208; + } else { + if(yych <= '`') goto yy192; + if(yych <= 'z') goto yy208; + goto yy192; + } + } +yy212: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy213: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy214: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy215: yych = *++YYCURSOR; + if(yych == '-') goto yy216; + if(yych == '/') goto yy217; + goto yy192; +yy216: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy219; + goto yy192; +yy217: yych = *++YYCURSOR; +yy218: +#line 145 + { char *domain = S_ALLOC_N( char, YYCURSOR - type_id ); + char *uri; + + domain[0] = '\0'; + strncat( domain, type_id, ( YYCURSOR - type_id ) - 1 ); + uri = syck_taguri( domain, YYCURSOR, YYLIMIT - YYCURSOR ); + + S_FREE( domain ); + return uri; + } +yy219: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy220: yych = *++YYCURSOR; + if(yych == '-') goto yy221; + if(yych == '/') goto yy217; + goto yy192; +yy221: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy222: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy223: yych = *++YYCURSOR; + if(yych == '/') goto yy217; + goto yy192; +yy224: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'r') goto yy201; + } +yy225: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'i') goto yy201; + } +yy226: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'v') goto yy201; + } +yy227: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'a') goto yy201; + } +yy228: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 't') goto yy201; + } +yy229: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'e') goto yy201; + } +yy230: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != ':') goto yy201; + } +yy231: yych = *++YYCURSOR; +yy232: +#line 128 + { return type_id; } +yy233: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'g') goto yy201; + } +yy234: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'u') goto yy201; + } +yy235: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'r') goto yy201; + } +yy236: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != 'i') goto yy201; + } +yy237: yych = *++YYCURSOR; + if(yych <= '.'){ + if(yych == ',') goto yy204; + if(yych <= '-') goto yy201; + goto yy205; + } else { + if(yych <= '/') goto yy206; + if(yych != ':') goto yy201; + } +yy238: yych = *++YYCURSOR; + if(yych <= '+') goto yy240; + if(yych <= '.') goto yy192; + goto yy240; +yy239: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy240: if(yych <= '9'){ + if(yych <= '-'){ + if(yych <= '+') goto yy192; + if(yych <= ',') goto yy243; + } else { + if(yych <= '.') goto yy244; + if(yych <= '/') goto yy192; + goto yy239; + } + } else { + if(yych <= '^'){ + if(yych <= '@') goto yy192; + if(yych <= 'Z') goto yy239; + goto yy192; + } else { + if(yych == '`') goto yy192; + if(yych <= 'z') goto yy239; + goto yy192; + } + } +yy241: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy242: if(yych <= '@'){ + if(yych <= '-'){ + if(yych <= ',') goto yy192; + goto yy241; + } else { + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy239; + goto yy192; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy239; + if(yych <= '^') goto yy192; + goto yy239; + } else { + if(yych <= '`') goto yy192; + if(yych <= 'z') goto yy239; + goto yy192; + } + } +yy243: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy249; + goto yy192; +yy244: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 'Z'){ + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy245; + if(yych <= '@') goto yy192; + } else { + if(yych <= '_'){ + if(yych <= '^') goto yy192; + } else { + if(yych <= '`') goto yy192; + if(yych >= '{') goto yy192; + } + } +yy245: ++YYCURSOR; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; +yy246: if(yych <= '9'){ + if(yych <= '-'){ + if(yych <= '+') goto yy192; + if(yych <= ',') goto yy243; + } else { + if(yych <= '.') goto yy244; + if(yych <= '/') goto yy192; + goto yy245; + } + } else { + if(yych <= '^'){ + if(yych <= '@') goto yy192; + if(yych <= 'Z') goto yy245; + goto yy192; + } else { + if(yych == '`') goto yy192; + if(yych <= 'z') goto yy245; + goto yy192; + } + } +yy247: ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy248: if(yych <= '@'){ + if(yych <= '-'){ + if(yych <= ',') goto yy192; + goto yy247; + } else { + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy245; + goto yy192; + } + } else { + if(yych <= '_'){ + if(yych <= 'Z') goto yy245; + if(yych <= '^') goto yy192; + goto yy245; + } else { + if(yych <= '`') goto yy192; + if(yych <= 'z') goto yy245; + goto yy192; + } + } +yy249: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy250: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy251: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy252: yych = *++YYCURSOR; + if(yych == '-') goto yy253; + if(yych == ':') goto yy254; + goto yy192; +yy253: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych <= '9') goto yy256; + goto yy192; +yy254: yych = *++YYCURSOR; +yy255: +#line 126 + { return type_id; } +yy256: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy257: yych = *++YYCURSOR; + if(yych == '-') goto yy258; + if(yych == ':') goto yy254; + goto yy192; +yy258: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy259: yych = *++YYCURSOR; + if(yych <= '/') goto yy192; + if(yych >= ':') goto yy192; +yy260: yych = *++YYCURSOR; + if(yych == ':') goto yy254; + goto yy192; +} +#line 158 } diff --git a/ext/syck/rubyext.c b/ext/syck/rubyext.c index 66aa7e4fcd..96627f1199 100644 --- a/ext/syck/rubyext.c +++ b/ext/syck/rubyext.c @@ -12,10 +12,13 @@ #include #include +#define RUBY_DOMAIN "ruby.yaml.org,2002" + static ID s_utc, s_read, s_binmode; +static VALUE str_taguri, str_xprivate; static VALUE sym_model, sym_generic; static VALUE sym_scalar, sym_seq, sym_map; -VALUE cNode; +VALUE cParser, cLoader, cNode, oDefaultLoader; // // my private collection of numerical oddities. @@ -83,6 +86,22 @@ syck_parser_assign_io(parser, port) } } +// +// Get value in hash by key, forcing an empty hash if nil. +// +VALUE +syck_get_hash_aref(hsh, key) + VALUE hsh, key; +{ + VALUE val = rb_hash_aref( hsh, key ); + if ( NIL_P( val ) ) + { + val = rb_hash_new(); + rb_hash_aset(hsh, key, val); + } + return val; +} + // // creating timestamps // @@ -469,9 +488,199 @@ syck_parser_load_documents(argc, argv, self) } // -// YAML::Syck::Node.initialize +// YAML::Syck::Loader.initialize +// +static VALUE +syck_loader_initialize( self ) + VALUE self; +{ + VALUE families; + + rb_iv_set(self, "@families", rb_hash_new() ); + rb_iv_set(self, "@private_types", rb_hash_new() ); + families = rb_iv_get(self, "@families"); + + rb_hash_aset(families, rb_str_new2( YAML_DOMAIN ), rb_hash_new()); + rb_hash_aset(families, rb_str_new2( RUBY_DOMAIN ), rb_hash_new()); + + return self; +} + +// +// Add type family, used by add_*_type methods. +// +VALUE +syck_loader_add_type_family( self, domain, type_re, proc ) + VALUE self, domain, type_re, proc; +{ + VALUE families, domain_types; + + families = rb_iv_get(self, "@families"); + domain_types = syck_get_hash_aref(families, domain); + rb_hash_aset( domain_types, type_re, proc ); +} + +// +// YAML::Syck::Loader.add_domain_type +// +VALUE +syck_loader_add_domain_type( argc, argv, self ) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE domain, type_re, proc, families, ruby_yaml_org, domain_types; + + rb_scan_args(argc, argv, "2&", &domain, &type_re, &proc); + syck_loader_add_type_family( self, domain, type_re, proc ); +} + + +// +// YAML::Syck::Loader.add_builtin_type +// +VALUE +syck_loader_add_builtin_type( argc, argv, self ) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE type_re, proc, families, ruby_yaml_org, domain_types; + + rb_scan_args(argc, argv, "1&", &type_re, &proc); + syck_loader_add_type_family( self, rb_str_new2( YAML_DOMAIN ), type_re, proc ); +} + +// +// YAML::Syck::Loader.add_ruby_type +// +VALUE +syck_loader_add_ruby_type( argc, argv, self ) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE type_re, proc, families, ruby_yaml_org, domain_types; + + rb_scan_args(argc, argv, "1&", &type_re, &proc); + syck_loader_add_type_family( self, rb_str_new2( RUBY_DOMAIN ), type_re, proc ); +} + +// +// YAML::Syck::Loader.add_private_type +// +VALUE +syck_loader_add_private_type( argc, argv, self ) + int argc; + VALUE *argv; + VALUE self; +{ + VALUE type_re, proc, priv_types; + + rb_scan_args(argc, argv, "1&", &type_re, &proc); + + priv_types = rb_iv_get(self, "@private_types"); + rb_hash_aset( priv_types, type_re, proc ); +} + +// +// iterator to search a type hash for a match. // static VALUE +transfer_find_i(entry, col) + VALUE entry, col; +{ + VALUE key = rb_ary_entry( entry, 0 ); + VALUE tid = rb_ary_entry( col, 0 ); + VALUE match = rb_funcall(tid, rb_intern("=~"), 1, key); + if ( ! NIL_P( match ) ) + { + rb_ary_push( col, rb_ary_entry( entry, 1 ) ); + rb_iter_break(); + } + return Qnil; +} + +// +// YAML::Syck::Loader#transfer +// +VALUE +syck_loader_transfer( self, type, val ) + VALUE self, type, val; +{ + char *taguri = NULL; + + // rb_funcall(rb_mKernel, rb_intern("p"), 2, rb_str_new2( "-- TYPE --" ), type); + if (NIL_P(type) || !RSTRING(type)->ptr || RSTRING(type)->len == 0) + { + // + // Empty transfer, detect type + // + if ( TYPE(val) == T_STRING ) + { + taguri = syck_match_implicit( RSTRING(val)->ptr, RSTRING(val)->len ); + taguri = syck_taguri( YAML_DOMAIN, taguri, strlen( taguri ) ); + } + } + else + { + taguri = syck_type_id_to_uri( RSTRING(type)->ptr ); + } + + if ( taguri != NULL ) + { + VALUE scheme, name, type_hash, type_proc; + VALUE type_uri = rb_str_new2( taguri ); + VALUE parts = rb_str_split( type_uri, ":" ); + // rb_funcall(rb_mKernel, rb_intern("p"), 1, parts); + + scheme = rb_ary_shift( parts ); + + if ( rb_str_cmp( scheme, str_xprivate ) == 0 ) + { + name = rb_ary_join( parts, rb_str_new2( ":" ) ); + type_hash = rb_iv_get(self, "@private_types"); + } + else if ( rb_str_cmp( scheme, str_taguri ) == 0 ) + { + VALUE domain = rb_ary_shift( parts ); + name = rb_ary_join( parts, rb_str_new2( ":" ) ); + type_hash = rb_iv_get(self, "@families"); + type_hash = rb_hash_aref(type_hash, domain); + } + else + { + rb_raise(rb_eTypeError, "invalid typing scheme: %s given", + scheme); + } + + if ( rb_obj_is_instance_of( type_hash, rb_cHash ) ) + { + type_proc = rb_hash_aref( type_hash, name ); + if ( NIL_P( type_proc ) ) + { + VALUE col = rb_ary_new(); + rb_ary_push( col, name ); + rb_iterate(rb_each, type_hash, transfer_find_i, col ); + name = rb_ary_shift( col ); + type_proc = rb_ary_shift( col ); + } + // rb_funcall(rb_mKernel, rb_intern("p"), 2, name, type_proc); + } + + if ( rb_obj_is_instance_of( type_proc, rb_cProc ) ) + { + val = rb_funcall(type_proc, rb_intern("call"), 2, type_uri, val); + } + } + + return val; +} + +// +// YAML::Syck::Node.initialize +// +VALUE syck_node_initialize( self, type_id, val ) VALUE self, type_id, val; { @@ -479,7 +688,7 @@ syck_node_initialize( self, type_id, val ) rb_iv_set( self, "@value", val ); } -static VALUE +VALUE syck_node_thash( entry, t ) VALUE entry, t; { @@ -489,7 +698,7 @@ syck_node_thash( entry, t ) rb_hash_aset( t, key, val ); } -static VALUE +VALUE syck_node_ahash( entry, t ) VALUE entry, t; { @@ -500,11 +709,12 @@ syck_node_ahash( entry, t ) // // YAML::Syck::Node.transform // -static VALUE +VALUE syck_node_transform( self ) VALUE self; { VALUE t = Qnil; + VALUE type_id = rb_iv_get( self, "@type_id" ); VALUE val = rb_iv_get( self, "@value" ); if ( rb_obj_is_instance_of( val, rb_cHash ) ) { @@ -520,7 +730,7 @@ syck_node_transform( self ) { t = val; } - return t; + return rb_funcall( oDefaultLoader, rb_intern( "transfer" ), 2, type_id, t ); } // @@ -531,7 +741,6 @@ Init_syck() { VALUE rb_yaml = rb_define_module( "YAML" ); VALUE rb_syck = rb_define_module_under( rb_yaml, "Syck" ); - VALUE cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject ); rb_define_const( rb_syck, "VERSION", rb_str_new2( SYCK_VERSION ) ); // @@ -540,6 +749,8 @@ Init_syck() s_utc = rb_intern("utc"); s_read = rb_intern("read"); s_binmode = rb_intern("binmode"); + str_taguri = rb_str_new2("taguri"); + str_xprivate = rb_str_new2("x-private"); sym_model = ID2SYM(rb_intern("Model")); sym_generic = ID2SYM(rb_intern("Generic")); sym_map = ID2SYM(rb_intern("map")); @@ -547,10 +758,27 @@ Init_syck() sym_seq = ID2SYM(rb_intern("seq")); // + // Define YAML::Syck::Loader class + // + cLoader = rb_define_class_under( rb_syck, "Loader", rb_cObject ); + rb_define_attr( cLoader, "families", 1, 1 ); + rb_define_attr( cLoader, "private_types", 1, 1 ); + rb_define_method( cLoader, "initialize", syck_loader_initialize, 0 ); + rb_define_method( cLoader, "add_domain_type", syck_loader_add_domain_type, -1 ); + rb_define_method( cLoader, "add_builtin_type", syck_loader_add_builtin_type, -1 ); + rb_define_method( cLoader, "add_ruby_type", syck_loader_add_ruby_type, -1 ); + rb_define_method( cLoader, "add_private_type", syck_loader_add_private_type, -1 ); + rb_define_method( cLoader, "transfer", syck_loader_transfer, 2 ); + + oDefaultLoader = rb_funcall( cLoader, rb_intern( "new" ), 0 ); + rb_define_const( rb_syck, "DefaultLoader", oDefaultLoader ); + + // // Define YAML::Syck::Parser class // + cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject ); rb_define_attr( cParser, "options", 1, 1 ); - rb_define_singleton_method(cParser, "new", syck_parser_new, -1); + rb_define_singleton_method( cParser, "new", syck_parser_new, -1 ); rb_define_method(cParser, "initialize", syck_parser_initialize, 1); rb_define_method(cParser, "load", syck_parser_load, -1); rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1); diff --git a/ext/syck/syck.c b/ext/syck/syck.c index feb72e7b50..8e16351692 100644 --- a/ext/syck/syck.c +++ b/ext/syck/syck.c @@ -109,7 +109,7 @@ syck_parser_reset_levels( SyckParser *p ) { p->lvl_idx = 1; p->levels[0].spaces = -1; - p->levels[0].domain = "yaml.org,2002/"; + p->levels[0].domain = ""; // YAML_DOMAIN + "/"; p->levels[0].status = syck_lvl_header; } @@ -166,7 +166,7 @@ syck_add_sym( SyckParser *p, char *data ) p->syms = st_init_numtable(); } id = p->syms->num_entries; - st_insert( p->syms, id, (st_data_t)data ); + st_insert( p->syms, id, data ); return id; } @@ -174,10 +174,10 @@ int syck_lookup_sym( SyckParser *p, SYMID id, char **data ) { if ( p->syms == NULL ) return 0; - return st_lookup( p->syms, id, (st_data_t *)data ); + return st_lookup( p->syms, id, data ); } -int +enum st_retval syck_st_free_nodes( char *key, SyckNode *n, char *arg ) { syck_free_node( n ); @@ -201,7 +201,7 @@ syck_free_parser( SyckParser *p ) // // Free the anchor table // - st_foreach( p->anchors, syck_st_free_nodes, (st_data_t)NULL ); + st_foreach( p->anchors, syck_st_free_nodes, NULL ); st_free_table( p->anchors ); // diff --git a/ext/syck/syck.h b/ext/syck/syck.h index 431c859a66..6fdbea6849 100644 --- a/ext/syck/syck.h +++ b/ext/syck/syck.h @@ -11,6 +11,7 @@ #define SYCK_H #define SYCK_VERSION "0.25" +#define YAML_DOMAIN "yaml.org,2002" #include #ifdef HAVE_ST_H @@ -196,13 +197,15 @@ SYMID syck_hdlr_add_node( SyckParser *, SyckNode * ); SyckNode *syck_hdlr_add_anchor( SyckParser *, char *, SyckNode * ); SyckNode *syck_hdlr_add_alias( SyckParser *, char * ); void syck_add_transfer( char *, SyckNode *, int ); -void syck_xprivate( SyckNode *, char *, int ); -void syck_taguri( SyckNode *, char *, char *, int ); +char *syck_xprivate( char *, int ); +char *syck_taguri( char *, char *, int ); int syck_add_sym( SyckParser *, char * ); int syck_lookup_sym( SyckParser *, SYMID, char ** ); int syck_try_implicit( SyckNode * ); +char *syck_type_id_to_uri( char * ); void syck_fold_format( struct SyckStr *, int, int, int ); void try_tag_implicit( SyckNode *, int ); +char *syck_match_implicit( char *, size_t ); // // API prototypes diff --git a/lib/yaml.rb b/lib/yaml.rb index 3b669d3723..1b2a4ea81f 100644 --- a/lib/yaml.rb +++ b/lib/yaml.rb @@ -10,53 +10,36 @@ module YAML begin require 'syck' - Parser = YAML::Syck::Parser + @@parser = YAML::Syck::Parser + @@loader = YAML::Syck::DefaultLoader rescue LoadError require 'yaml/parser' - Parser = YAML::Parser + @@parser = YAML::Parser + @@loader = YAML::DefaultLoader end require 'yaml/emitter' - require 'yaml/rubytypes' - - # - # Allocate blank object - # - def YAML.object_maker( obj_class, val ) - if Hash === val - name = obj_class.name - o = ::Marshal.load( sprintf( "\004\006o:%c%s\000", name.length + 5, name )) - val.each_pair { |k,v| - o.instance_eval "@#{k} = v" - } - o - else - raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect - end - end - - # - # Input methods - # + require 'yaml/loader' + require 'yaml/stream' # # Load a single document from the current stream # def YAML.load( io ) - yp = YAML::Parser.new.parse( io ) + yp = @@parser.new.load( io ) end # # Parse a single document from the current stream # def YAML.parse( io ) - yp = YAML::Parser.new( :Model => :Generic ).parse( io ) + yp = @@parser.new( :Model => :Generic ).load( io ) end # # Load all documents from the current stream # def YAML.each_document( io, &doc_proc ) - yp = YAML::Parser.new.parse_documents( io, &doc_proc ) + yp = @@parser.new.load_documents( io, &doc_proc ) end # @@ -70,7 +53,7 @@ module YAML # Parse all documents from the current stream # def YAML.each_node( io, &doc_proc ) - yp = YAML::Parser.new( :Model => :Generic ).parse_documents( io, &doc_proc ) + yp = @@parser.new( :Model => :Generic ).load_documents( io, &doc_proc ) end # @@ -84,17 +67,78 @@ module YAML # Load all documents from the current stream # def YAML.load_stream( io ) - yp = YAML::Parser.new + yp = @@parser.new d = nil - yp.parse_documents( io ) { |doc| + yp.load_documents( io ) { |doc| d = YAML::Stream.new( yp.options ) if not d d.add( doc ) } return d end + # + # Add a transfer method to a domain + # + def YAML.add_domain_type( domain, type_re, &transfer_proc ) + @@loader.add_domain_type( domain, type_re, &transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def YAML.add_builtin_type( type_re, &transfer_proc ) + @@loader.add_builtin_type( type_re, &transfer_proc ) + end + + # + # Add a transfer method for a builtin type + # + def YAML.add_ruby_type( type, &transfer_proc ) + @@loader.add_ruby_type( type, &transfer_proc ) + end + + # + # Add a private document type + # + def YAML.add_private_type( type_re, &transfer_proc ) + @@loader.add_private_type( type_re, &transfer_proc ) + end + + # + # Method to extract colon-seperated type and class, returning + # the type and the constant of the class + # + def YAML.read_type_class( type, obj_class ) + type =~ /^([^:]+):(.+)/i + if $2 + type = $1 + $2.split( "::" ).each { |c| + obj_class = obj_class.const_get( c ) + } + end + return [ type, obj_class ] + end + + # + # Allocate blank object + # + def YAML.object_maker( obj_class, val ) + if Hash === val + name = obj_class.name + o = ::Marshal.load( sprintf( "\004\006o:%c%s\000", name.length + 5, name )) + val.each_pair { |k,v| + o.instance_eval "@#{k} = v" + } + o + else + raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect + end + end + end +require 'yaml/rubytypes' + # # ryan: You know how Kernel.p is a really convenient way to dump ruby # structures? The only downside is that it's not as legible as diff --git a/lib/yaml/loader.rb b/lib/yaml/loader.rb new file mode 100644 index 0000000000..eb0709e103 --- /dev/null +++ b/lib/yaml/loader.rb @@ -0,0 +1,14 @@ +# +# YAML::Loader class +# .. type handling .. +# +module YAML + class Loader + TRANSFER_DOMAINS = { + 'yaml.org,2002' => {}, + 'ruby.yaml.org,2002' => {} + } + PRIVATE_TYPES = {} + IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ] + end +end -- cgit v1.2.3