mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/yaml.rb: reworking YAML::Stream to use the new
emitter. * lib/yaml/stream.rb: ditto. * lib/yaml/rubytypes.rb: added Object#yaml_new. * lib/yaml/tag.rb: the tag_subclasses? method now shows up in the class. allow taguri to be set using an accessor. continue support of Object#to_yaml_type. * ext/syck/rubyext.c: new emitter code. yaml_new and yaml_initialize get called, should they be present. consolidated all the diaspora of internal node types into the family below YAML::Syck::Node -- Map, Seq, Scalar -- all of whom are SyckNode structs pointing to Ruby data. moved Object#yaml_new into the node_import and made it the default behavior. the target_class is always called wih yaml_new, prepended a parameter, which is the klass. loaded nodes through GenericResolver show their style. new Resolver#tagurize converts type ids to taguris. * ext/syck/implicit.re: were 'y' and 'n' seriously omitted?? * ext/syck/emitter.c: renovated emitter, walks the tree in advance. consolidated redundant block_styles struct into the scalar_style struct. (this means loaded nodes can now be sent back to emitter and preserve at least its very basic formatting.) * ext/syck/gram.c: headless documents of any kind allowed. * ext/syck/node.c: new syck_replace_str methods and syck_empty_* methods for rewriting node contents, while keeping the ID and other setup info. added syck_seq_assign. * ext/syck/syck.h: reflect block_styles and new node functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9141 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2007d73102
commit
f1827a2faf
20 changed files with 4568 additions and 2765 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Generated by re2c 0.9.3 on Fri Aug 13 11:47:50 2004 */
|
||||
/* Generated by re2c 0.9.3 on Tue Apr 12 20:34:14 2005 */
|
||||
#line 1 "bytecode.re"
|
||||
/*
|
||||
* bytecode.re
|
||||
|
@ -89,7 +89,7 @@ char *get_inline( SyckParser *parser );
|
|||
#define ENSURE_YAML_IOPEN(last_lvl, lvl_type, to_len, reset) \
|
||||
if ( last_lvl->spaces < to_len ) \
|
||||
{ \
|
||||
if ( last_lvl->status == syck_lvl_inline ) \
|
||||
if ( last_lvl->status == syck_lvl_iseq || last_lvl->status == syck_lvl_imap ) \
|
||||
{ \
|
||||
goto Document; \
|
||||
} \
|
||||
|
|
1056
ext/syck/emitter.c
1056
ext/syck/emitter.c
File diff suppressed because it is too large
Load diff
1180
ext/syck/gram.c
1180
ext/syck/gram.c
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,7 @@
|
|||
/* A Bison parser, made from gram.y, by GNU bison 1.75. */
|
||||
/* A Bison parser, made by GNU Bison 1.875d. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -23,9 +23,6 @@
|
|||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
#ifndef BISON_Y_TAB_H
|
||||
# define BISON_Y_TAB_H
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
|
@ -62,20 +59,21 @@
|
|||
|
||||
|
||||
|
||||
#ifndef YYSTYPE
|
||||
#line 33 "gram.y"
|
||||
typedef union {
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 35 "gram.y"
|
||||
typedef union YYSTYPE {
|
||||
SYMID nodeId;
|
||||
SyckNode *nodeData;
|
||||
char *name;
|
||||
} yystype;
|
||||
/* Line 1281 of /usr/local/share/bison/yacc.c. */
|
||||
#line 74 "y.tab.h"
|
||||
# define YYSTYPE yystype
|
||||
} YYSTYPE;
|
||||
/* Line 1285 of yacc.c. */
|
||||
#line 71 "gram.h"
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* not BISON_Y_TAB_H */
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ syck_hdlr_add_node( SyckParser *p, SyckNode *n )
|
|||
SyckNode *
|
||||
syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n )
|
||||
{
|
||||
char *atmp = NULL;
|
||||
SyckNode *ntmp = NULL;
|
||||
|
||||
n->anchor = a;
|
||||
if ( p->bad_anchors != NULL )
|
||||
{
|
||||
|
@ -48,6 +51,13 @@ syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n )
|
|||
{
|
||||
p->anchors = st_init_strtable();
|
||||
}
|
||||
if ( st_lookup( p->anchors, (st_data_t)a, (st_data_t *)&ntmp ) )
|
||||
{
|
||||
if ( ntmp != (void *)1 )
|
||||
{
|
||||
syck_free_node( ntmp );
|
||||
}
|
||||
}
|
||||
st_insert( p->anchors, (st_data_t)a, (st_data_t)n );
|
||||
return n;
|
||||
}
|
||||
|
@ -55,10 +65,19 @@ syck_hdlr_add_anchor( SyckParser *p, char *a, SyckNode *n )
|
|||
void
|
||||
syck_hdlr_remove_anchor( SyckParser *p, char *a )
|
||||
{
|
||||
char *atmp = a;
|
||||
SyckNode *ntmp;
|
||||
if ( p->anchors == NULL )
|
||||
{
|
||||
p->anchors = st_init_strtable();
|
||||
}
|
||||
if ( st_delete( p->anchors, (st_data_t *)&atmp, (st_data_t *)&ntmp ) )
|
||||
{
|
||||
if ( ntmp != (void *)1 )
|
||||
{
|
||||
syck_free_node( ntmp );
|
||||
}
|
||||
}
|
||||
st_insert( p->anchors, (st_data_t)a, (st_data_t)1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by re2c 0.9.3 on Fri Aug 13 11:47:51 2004 */
|
||||
/* Generated by re2c 0.9.3 on Wed Mar 30 08:27:25 2005 */
|
||||
#line 1 "implicit.re"
|
||||
/*
|
||||
* implicit.re
|
||||
|
@ -36,6 +36,7 @@ try_tag_implicit( SyckNode *n, int taguri )
|
|||
tid = "map";
|
||||
break;
|
||||
}
|
||||
if ( n->type_id != NULL ) S_FREE( n->type_id );
|
||||
if ( taguri == 1 )
|
||||
{
|
||||
n->type_id = syck_taguri( YAML_DOMAIN, tid, strlen( tid ) );
|
||||
|
@ -94,7 +95,7 @@ yy2: ++YYCURSOR;
|
|||
if((yych = *YYCURSOR) <= '\000') goto yy6;
|
||||
goto yy3;
|
||||
yy3:
|
||||
#line 122 "implicit.re"
|
||||
#line 123 "implicit.re"
|
||||
{ return "str"; }
|
||||
#line 51 "<stdout>"
|
||||
yy4: yyaccept = 0;
|
||||
|
@ -115,7 +116,7 @@ yy5: yyaccept = 0;
|
|||
yy6: ++YYCURSOR;
|
||||
goto yy7;
|
||||
yy7:
|
||||
#line 84 "implicit.re"
|
||||
#line 85 "implicit.re"
|
||||
{ return "null"; }
|
||||
#line 72 "<stdout>"
|
||||
yy8: yyaccept = 0;
|
||||
|
@ -273,13 +274,13 @@ yy25: YYCURSOR = YYMARKER;
|
|||
yy26: ++YYCURSOR;
|
||||
goto yy27;
|
||||
yy27:
|
||||
#line 120 "implicit.re"
|
||||
#line 121 "implicit.re"
|
||||
{ return "merge"; }
|
||||
#line 230 "<stdout>"
|
||||
yy28: ++YYCURSOR;
|
||||
goto yy29;
|
||||
yy29:
|
||||
#line 118 "implicit.re"
|
||||
#line 119 "implicit.re"
|
||||
{ return "default"; }
|
||||
#line 236 "<stdout>"
|
||||
yy30: yych = *++YYCURSOR;
|
||||
|
@ -320,7 +321,7 @@ yy36: yych = *++YYCURSOR;
|
|||
yy37: ++YYCURSOR;
|
||||
goto yy38;
|
||||
yy38:
|
||||
#line 104 "implicit.re"
|
||||
#line 105 "implicit.re"
|
||||
{ return "float#inf"; }
|
||||
#line 277 "<stdout>"
|
||||
yy39: yych = *++YYCURSOR;
|
||||
|
@ -344,7 +345,7 @@ yy42: yych = *++YYCURSOR;
|
|||
yy43: ++YYCURSOR;
|
||||
goto yy44;
|
||||
yy44:
|
||||
#line 108 "implicit.re"
|
||||
#line 109 "implicit.re"
|
||||
{ return "float#nan"; }
|
||||
#line 301 "<stdout>"
|
||||
yy45: yych = *++YYCURSOR;
|
||||
|
@ -426,7 +427,7 @@ yy51: switch(yych){
|
|||
yy52: ++YYCURSOR;
|
||||
goto yy53;
|
||||
yy53:
|
||||
#line 96 "implicit.re"
|
||||
#line 97 "implicit.re"
|
||||
{ return "int"; }
|
||||
#line 386 "<stdout>"
|
||||
yy54: ++YYCURSOR;
|
||||
|
@ -450,7 +451,7 @@ yy55: switch(yych){
|
|||
yy56: ++YYCURSOR;
|
||||
goto yy57;
|
||||
yy57:
|
||||
#line 98 "implicit.re"
|
||||
#line 99 "implicit.re"
|
||||
{ return "float#fix"; }
|
||||
#line 411 "<stdout>"
|
||||
yy58: ++YYCURSOR;
|
||||
|
@ -500,7 +501,7 @@ yy63: switch(yych){
|
|||
yy64: ++YYCURSOR;
|
||||
goto yy65;
|
||||
yy65:
|
||||
#line 100 "implicit.re"
|
||||
#line 101 "implicit.re"
|
||||
{ return "float#exp"; }
|
||||
#line 463 "<stdout>"
|
||||
yy66: ++YYCURSOR;
|
||||
|
@ -552,13 +553,13 @@ yy69: switch(yych){
|
|||
yy70: ++YYCURSOR;
|
||||
goto yy71;
|
||||
yy71:
|
||||
#line 94 "implicit.re"
|
||||
#line 95 "implicit.re"
|
||||
{ return "int#base60"; }
|
||||
#line 518 "<stdout>"
|
||||
yy72: ++YYCURSOR;
|
||||
goto yy73;
|
||||
yy73:
|
||||
#line 102 "implicit.re"
|
||||
#line 103 "implicit.re"
|
||||
{ return "float#base60"; }
|
||||
#line 524 "<stdout>"
|
||||
yy74: yych = *++YYCURSOR;
|
||||
|
@ -661,7 +662,7 @@ yy81: yych = *++YYCURSOR;
|
|||
yy82: ++YYCURSOR;
|
||||
goto yy83;
|
||||
yy83:
|
||||
#line 110 "implicit.re"
|
||||
#line 111 "implicit.re"
|
||||
{ return "timestamp#ymd"; }
|
||||
#line 627 "<stdout>"
|
||||
yy84: yych = *++YYCURSOR;
|
||||
|
@ -878,7 +879,7 @@ yy104: yych = *++YYCURSOR;
|
|||
yy105: ++YYCURSOR;
|
||||
goto yy106;
|
||||
yy106:
|
||||
#line 114 "implicit.re"
|
||||
#line 115 "implicit.re"
|
||||
{ return "timestamp#spaced"; }
|
||||
#line 847 "<stdout>"
|
||||
yy107: yych = *++YYCURSOR;
|
||||
|
@ -1063,7 +1064,7 @@ yy122: yych = *++YYCURSOR;
|
|||
yy123: ++YYCURSOR;
|
||||
goto yy124;
|
||||
yy124:
|
||||
#line 112 "implicit.re"
|
||||
#line 113 "implicit.re"
|
||||
{ return "timestamp#iso8601"; }
|
||||
#line 1033 "<stdout>"
|
||||
yy125: yych = *++YYCURSOR;
|
||||
|
@ -1301,13 +1302,13 @@ yy146: switch(yych){
|
|||
yy147: ++YYCURSOR;
|
||||
goto yy148;
|
||||
yy148:
|
||||
#line 90 "implicit.re"
|
||||
#line 91 "implicit.re"
|
||||
{ return "int#hex"; }
|
||||
#line 1275 "<stdout>"
|
||||
yy149: ++YYCURSOR;
|
||||
goto yy150;
|
||||
yy150:
|
||||
#line 92 "implicit.re"
|
||||
#line 93 "implicit.re"
|
||||
{ return "int#oct"; }
|
||||
#line 1281 "<stdout>"
|
||||
yy151: ++YYCURSOR;
|
||||
|
@ -1406,7 +1407,7 @@ yy163: yych = *++YYCURSOR;
|
|||
yy164: ++YYCURSOR;
|
||||
goto yy165;
|
||||
yy165:
|
||||
#line 106 "implicit.re"
|
||||
#line 107 "implicit.re"
|
||||
{ return "float#neginf"; }
|
||||
#line 1381 "<stdout>"
|
||||
yy166: yych = *++YYCURSOR;
|
||||
|
@ -1446,7 +1447,7 @@ yy172: yych = *++YYCURSOR;
|
|||
yy173: ++YYCURSOR;
|
||||
goto yy174;
|
||||
yy174:
|
||||
#line 88 "implicit.re"
|
||||
#line 89 "implicit.re"
|
||||
{ return "bool#no"; }
|
||||
#line 1421 "<stdout>"
|
||||
yy175: yych = *++YYCURSOR;
|
||||
|
@ -1490,7 +1491,7 @@ yy182: yych = *++YYCURSOR;
|
|||
yy183: ++YYCURSOR;
|
||||
goto yy184;
|
||||
yy184:
|
||||
#line 86 "implicit.re"
|
||||
#line 87 "implicit.re"
|
||||
{ return "bool#yes"; }
|
||||
#line 1465 "<stdout>"
|
||||
yy185: yych = *++YYCURSOR;
|
||||
|
@ -1577,11 +1578,36 @@ yy201: ++YYCURSOR;
|
|||
default: goto yy25;
|
||||
}
|
||||
}
|
||||
#line 124 "implicit.re"
|
||||
#line 125 "implicit.re"
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Remove ending fragment and compare types */
|
||||
int
|
||||
syck_tagcmp( char *tag1, char *tag2 )
|
||||
{
|
||||
if ( tag1 == tag2 ) return 1;
|
||||
if ( tag1 == NULL || tag2 == NULL ) return 0;
|
||||
else {
|
||||
int i;
|
||||
char *othorpe;
|
||||
char *tmp1 = syck_strndup( tag1, strlen( tag1 ) );
|
||||
char *tmp2 = syck_strndup( tag2, strlen( tag2 ) );
|
||||
othorpe = strstr( tmp1, "#" );
|
||||
if ( othorpe != NULL ) {
|
||||
othorpe[0] = '\0';
|
||||
}
|
||||
othorpe = strstr( tmp2, "#" );
|
||||
if ( othorpe != NULL ) {
|
||||
othorpe[0] = '\0';
|
||||
}
|
||||
i = strcmp( tmp1, tmp2 );
|
||||
S_FREE( tmp1 ); S_FREE( tmp2 );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
syck_type_id_to_uri( char *type_id )
|
||||
{
|
||||
|
@ -1737,7 +1763,7 @@ yy205: yyaccept = 0;
|
|||
default: goto yy206;
|
||||
}
|
||||
yy206:
|
||||
#line 176 "implicit.re"
|
||||
#line 202 "implicit.re"
|
||||
{ return syck_taguri( YAML_DOMAIN, type_id, strlen( type_id ) ); }
|
||||
#line 1700 "<stdout>"
|
||||
yy207: yyaccept = 0;
|
||||
|
@ -1811,7 +1837,7 @@ yy207: yyaccept = 0;
|
|||
yy208: ++YYCURSOR;
|
||||
goto yy209;
|
||||
yy209:
|
||||
#line 150 "implicit.re"
|
||||
#line 176 "implicit.re"
|
||||
{ return syck_xprivate( type_id + 1, strlen( type_id ) - 1 ); }
|
||||
#line 1774 "<stdout>"
|
||||
yy210: yyaccept = 0;
|
||||
|
@ -2107,7 +2133,7 @@ yy217: ++YYCURSOR;
|
|||
yy218: ++YYCURSOR;
|
||||
goto yy219;
|
||||
yy219:
|
||||
#line 152 "implicit.re"
|
||||
#line 178 "implicit.re"
|
||||
{ char *domain = S_ALLOC_N( char, ( YYCURSOR - type_id ) + 15 );
|
||||
char *uri;
|
||||
|
||||
|
@ -2325,7 +2351,7 @@ yy228: yych = *++YYCURSOR;
|
|||
yy229: ++YYCURSOR;
|
||||
goto yy230;
|
||||
yy230:
|
||||
#line 165 "implicit.re"
|
||||
#line 191 "implicit.re"
|
||||
{ char *domain = S_ALLOC_N( char, YYCURSOR - type_id );
|
||||
char *uri;
|
||||
|
||||
|
@ -2454,7 +2480,7 @@ yy243: yych = *++YYCURSOR;
|
|||
yy244: ++YYCURSOR;
|
||||
goto yy245;
|
||||
yy245:
|
||||
#line 148 "implicit.re"
|
||||
#line 174 "implicit.re"
|
||||
{ return type_id; }
|
||||
#line 2422 "<stdout>"
|
||||
yy246: yych = *++YYCURSOR;
|
||||
|
@ -2901,7 +2927,7 @@ yy263: yych = *++YYCURSOR;
|
|||
yy264: ++YYCURSOR;
|
||||
goto yy265;
|
||||
yy265:
|
||||
#line 146 "implicit.re"
|
||||
#line 172 "implicit.re"
|
||||
{ return type_id; }
|
||||
#line 2874 "<stdout>"
|
||||
yy266: yych = *++YYCURSOR;
|
||||
|
@ -2958,8 +2984,7 @@ yy270: ++YYCURSOR;
|
|||
default: goto yy204;
|
||||
}
|
||||
}
|
||||
#line 178 "implicit.re"
|
||||
#line 204 "implicit.re"
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,15 @@ syck_free_node( SyckNode *n )
|
|||
{
|
||||
syck_free_members( n );
|
||||
if ( n->type_id != NULL )
|
||||
{
|
||||
S_FREE( n->type_id );
|
||||
n->type_id = NULL;
|
||||
}
|
||||
if ( n->anchor != NULL )
|
||||
{
|
||||
S_FREE( n->anchor );
|
||||
n->anchor = NULL;
|
||||
}
|
||||
S_FREE( n );
|
||||
}
|
||||
|
||||
|
@ -46,6 +52,7 @@ syck_alloc_map()
|
|||
struct SyckMap *m;
|
||||
|
||||
m = S_ALLOC( struct SyckMap );
|
||||
m->style = map_none;
|
||||
m->idx = 0;
|
||||
m->capa = ALLOC_CT;
|
||||
m->keys = S_ALLOC_N( SYMID, m->capa );
|
||||
|
@ -64,6 +71,7 @@ syck_alloc_seq()
|
|||
struct SyckSeq *s;
|
||||
|
||||
s = S_ALLOC( struct SyckSeq );
|
||||
s->style = seq_none;
|
||||
s->idx = 0;
|
||||
s->capa = ALLOC_CT;
|
||||
s->items = S_ALLOC_N( SYMID, s->capa );
|
||||
|
@ -112,6 +120,28 @@ syck_new_str2( char *str, long len, enum scalar_style style )
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
syck_replace_str( SyckNode *n, char *str, enum scalar_style style )
|
||||
{
|
||||
return syck_replace_str2( n, str, strlen( str ), style );
|
||||
}
|
||||
|
||||
void
|
||||
syck_replace_str2( SyckNode *n, char *str, long len, enum scalar_style style )
|
||||
{
|
||||
if ( n->data.str != NULL )
|
||||
{
|
||||
S_FREE( n->data.str->ptr );
|
||||
n->data.str->ptr = NULL;
|
||||
n->data.str->len = 0;
|
||||
}
|
||||
n->data.str->ptr = S_ALLOC_N( char, len + 1 );
|
||||
n->data.str->len = len;
|
||||
n->data.str->style = style;
|
||||
memcpy( n->data.str->ptr, str, len );
|
||||
n->data.str->ptr[len] = '\0';
|
||||
}
|
||||
|
||||
void
|
||||
syck_str_blow_away_commas( SyckNode *n )
|
||||
{
|
||||
|
@ -148,6 +178,22 @@ syck_new_map( SYMID key, SYMID value )
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
syck_map_empty( SyckNode *n )
|
||||
{
|
||||
struct SyckMap *m;
|
||||
ASSERT( n != NULL );
|
||||
ASSERT( n->data.list != NULL );
|
||||
|
||||
S_FREE( n->data.pairs->keys );
|
||||
S_FREE( n->data.pairs->values );
|
||||
m = n->data.pairs;
|
||||
m->idx = 0;
|
||||
m->capa = ALLOC_CT;
|
||||
m->keys = S_ALLOC_N( SYMID, m->capa );
|
||||
m->values = S_ALLOC_N( SYMID, m->capa );
|
||||
}
|
||||
|
||||
void
|
||||
syck_map_add( SyckNode *map, SYMID key, SYMID value )
|
||||
{
|
||||
|
@ -257,6 +303,20 @@ syck_new_seq( SYMID value )
|
|||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
syck_seq_empty( SyckNode *n )
|
||||
{
|
||||
struct SyckSeq *s;
|
||||
ASSERT( n != NULL );
|
||||
ASSERT( n->data.list != NULL );
|
||||
|
||||
S_FREE( n->data.list->items );
|
||||
s = n->data.list;
|
||||
s->idx = 0;
|
||||
s->capa = ALLOC_CT;
|
||||
s->items = S_ALLOC_N( SYMID, s->capa );
|
||||
}
|
||||
|
||||
void
|
||||
syck_seq_add( SyckNode *arr, SYMID value )
|
||||
{
|
||||
|
@ -285,6 +345,17 @@ syck_seq_count( SyckNode *seq )
|
|||
return seq->data.list->idx;
|
||||
}
|
||||
|
||||
void
|
||||
syck_seq_assign( SyckNode *seq, long idx, SYMID id )
|
||||
{
|
||||
struct SyckSeq *s;
|
||||
|
||||
ASSERT( map != NULL );
|
||||
s = seq->data.list;
|
||||
ASSERT( m != NULL );
|
||||
s->items[idx] = id;
|
||||
}
|
||||
|
||||
SYMID
|
||||
syck_seq_read( SyckNode *seq, long idx )
|
||||
{
|
||||
|
|
2320
ext/syck/rubyext.c
2320
ext/syck/rubyext.c
File diff suppressed because it is too large
Load diff
|
@ -208,15 +208,6 @@ syck_st_free_nodes( char *key, SyckNode *n, char *arg )
|
|||
void
|
||||
syck_st_free( SyckParser *p )
|
||||
{
|
||||
/*
|
||||
* Free the adhoc symbol table
|
||||
*/
|
||||
if ( p->syms != NULL )
|
||||
{
|
||||
st_free_table( p->syms );
|
||||
p->syms = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the anchor tables
|
||||
*/
|
||||
|
@ -238,6 +229,15 @@ syck_st_free( SyckParser *p )
|
|||
void
|
||||
syck_free_parser( SyckParser *p )
|
||||
{
|
||||
/*
|
||||
* Free the adhoc symbol table
|
||||
*/
|
||||
if ( p->syms != NULL )
|
||||
{
|
||||
st_free_table( p->syms );
|
||||
p->syms = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free tables, levels
|
||||
*/
|
||||
|
|
103
ext/syck/syck.h
103
ext/syck/syck.h
|
@ -13,7 +13,7 @@
|
|||
#define SYCK_YAML_MAJOR 1
|
||||
#define SYCK_YAML_MINOR 0
|
||||
|
||||
#define SYCK_VERSION "0.45"
|
||||
#define SYCK_VERSION "0.55"
|
||||
#define YAML_DOMAIN "yaml.org,2002"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -63,12 +63,16 @@ extern "C" {
|
|||
#define BLOCK_FOLD 10
|
||||
#define BLOCK_LIT 20
|
||||
#define BLOCK_PLAIN 30
|
||||
#define NL_CHOMP 130
|
||||
#define NL_KEEP 140
|
||||
#define NL_CHOMP 40
|
||||
#define NL_KEEP 50
|
||||
|
||||
/*
|
||||
* Node definitions
|
||||
*/
|
||||
#ifndef ST_DATA_T_DEFINED
|
||||
typedef long st_data_t;
|
||||
#endif
|
||||
|
||||
#define SYMID unsigned long
|
||||
|
||||
typedef struct _syck_node SyckNode;
|
||||
|
@ -84,12 +88,23 @@ enum map_part {
|
|||
map_value
|
||||
};
|
||||
|
||||
enum map_style {
|
||||
map_none,
|
||||
map_inline
|
||||
};
|
||||
|
||||
enum seq_style {
|
||||
seq_none,
|
||||
seq_inline
|
||||
};
|
||||
|
||||
enum scalar_style {
|
||||
scalar_none,
|
||||
scalar_plain,
|
||||
scalar_1quote,
|
||||
scalar_2quote,
|
||||
scalar_block
|
||||
scalar_fold,
|
||||
scalar_literal,
|
||||
scalar_plain
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -107,6 +122,7 @@ struct _syck_node {
|
|||
union {
|
||||
/* Storage for map data */
|
||||
struct SyckMap {
|
||||
enum map_style style;
|
||||
SYMID *keys;
|
||||
SYMID *values;
|
||||
long capa;
|
||||
|
@ -114,6 +130,7 @@ struct _syck_node {
|
|||
} *pairs;
|
||||
/* Storage for sequence data */
|
||||
struct SyckSeq {
|
||||
enum seq_style style;
|
||||
SYMID *items;
|
||||
long capa;
|
||||
long idx;
|
||||
|
@ -163,9 +180,13 @@ enum syck_level_status {
|
|||
syck_lvl_map,
|
||||
syck_lvl_block,
|
||||
syck_lvl_str,
|
||||
syck_lvl_inline,
|
||||
syck_lvl_iseq,
|
||||
syck_lvl_imap,
|
||||
syck_lvl_end,
|
||||
syck_lvl_pause
|
||||
syck_lvl_pause,
|
||||
syck_lvl_anctag,
|
||||
syck_lvl_mapx,
|
||||
syck_lvl_seqx
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -186,9 +207,16 @@ struct _syck_str {
|
|||
};
|
||||
|
||||
struct _syck_level {
|
||||
/* Indent */
|
||||
int spaces;
|
||||
/* Counts nodes emitted at this level, useful for parsing
|
||||
* keys and pairs in bytecode */
|
||||
int ncount;
|
||||
/* Does node have anchors or tags? */
|
||||
int anctag;
|
||||
/* Domain prefixing at the given level */
|
||||
char *domain;
|
||||
/* Keeps a node status */
|
||||
enum syck_level_status status;
|
||||
};
|
||||
|
||||
|
@ -231,6 +259,7 @@ struct _syck_parser {
|
|||
SyckLevel *levels;
|
||||
int lvl_idx;
|
||||
int lvl_capa;
|
||||
/* Pointer for extension's use */
|
||||
void *bonus;
|
||||
};
|
||||
|
||||
|
@ -241,6 +270,7 @@ typedef struct _syck_emitter SyckEmitter;
|
|||
typedef struct _syck_emitter_node SyckEmitterNode;
|
||||
|
||||
typedef void (*SyckOutputHandler)(SyckEmitter *, char *, long);
|
||||
typedef void (*SyckEmitterHandler)(SyckEmitter *, st_data_t);
|
||||
|
||||
enum doc_stage {
|
||||
doc_open,
|
||||
|
@ -248,20 +278,12 @@ enum doc_stage {
|
|||
doc_processing
|
||||
};
|
||||
|
||||
enum block_styles {
|
||||
block_arbitrary,
|
||||
block_fold,
|
||||
block_literal
|
||||
};
|
||||
|
||||
/*
|
||||
* Emitter struct
|
||||
*/
|
||||
struct _syck_emitter {
|
||||
/* Headerless doc flag */
|
||||
int headless;
|
||||
/* Sequence map shortcut flag */
|
||||
int seq_map;
|
||||
/* Force header? */
|
||||
int use_header;
|
||||
/* Force version? */
|
||||
|
@ -275,7 +297,7 @@ struct _syck_emitter {
|
|||
/* Best width on folded scalars */
|
||||
int best_width;
|
||||
/* Use literal[1] or folded[2] blocks on all text? */
|
||||
enum block_styles block_style;
|
||||
enum scalar_style style;
|
||||
/* Stage of written document */
|
||||
enum doc_stage stage;
|
||||
/* Level counter */
|
||||
|
@ -285,15 +307,21 @@ struct _syck_emitter {
|
|||
/* Object ignore ID */
|
||||
SYMID ignore_id;
|
||||
/* Symbol table for anchors */
|
||||
st_table *markers, *anchors;
|
||||
st_table *markers, *anchors, *anchored;
|
||||
/* Custom buffer size */
|
||||
size_t bufsize;
|
||||
/* Buffer */
|
||||
char *buffer, *marker;
|
||||
/* Absolute position of the buffer */
|
||||
long bufpos;
|
||||
/* Handler for emitter nodes */
|
||||
SyckEmitterHandler emitter_handler;
|
||||
/* Handler for output */
|
||||
SyckOutputHandler handler;
|
||||
SyckOutputHandler output_handler;
|
||||
/* Levels of indentation */
|
||||
SyckLevel *levels;
|
||||
int lvl_idx;
|
||||
int lvl_capa;
|
||||
/* Pointer for extension's use */
|
||||
void *bonus;
|
||||
};
|
||||
|
@ -320,6 +348,7 @@ SyckNode *syck_hdlr_get_anchor( SyckParser *, char * );
|
|||
void syck_add_transfer( char *, SyckNode *, int );
|
||||
char *syck_xprivate( char *, int );
|
||||
char *syck_taguri( char *, char *, int );
|
||||
int syck_tagcmp( char *, char * );
|
||||
int syck_add_sym( SyckParser *, char * );
|
||||
int syck_lookup_sym( SyckParser *, SYMID, char ** );
|
||||
int syck_try_implicit( SyckNode * );
|
||||
|
@ -336,20 +365,38 @@ long syck_io_str_read( char *, SyckIoStr *, long, long );
|
|||
char *syck_base64enc( char *, long );
|
||||
char *syck_base64dec( char *, long );
|
||||
SyckEmitter *syck_new_emitter();
|
||||
SYMID syck_emitter_mark_node( SyckEmitter *, st_data_t );
|
||||
void syck_emitter_ignore_id( SyckEmitter *, SYMID );
|
||||
void syck_emitter_handler( SyckEmitter *, SyckOutputHandler );
|
||||
void syck_output_handler( SyckEmitter *, SyckOutputHandler );
|
||||
void syck_emitter_handler( SyckEmitter *, SyckEmitterHandler );
|
||||
void syck_free_emitter( SyckEmitter * );
|
||||
void syck_emitter_clear( SyckEmitter * );
|
||||
void syck_emitter_simple( SyckEmitter *, char *, long );
|
||||
void syck_emitter_write( SyckEmitter *, char *, long );
|
||||
void syck_emitter_escape( SyckEmitter *, char *, long );
|
||||
void syck_emitter_flush( SyckEmitter *, long );
|
||||
char *syck_emitter_start_obj( SyckEmitter *, SYMID );
|
||||
void syck_emitter_end_obj( SyckEmitter * );
|
||||
void syck_emit( SyckEmitter *, st_data_t );
|
||||
void syck_emit_scalar( SyckEmitter *, char *, enum scalar_style, int, int, char, char *, long );
|
||||
void syck_emit_1quoted( SyckEmitter *, int, char *, long );
|
||||
void syck_emit_2quoted( SyckEmitter *, int, char *, long );
|
||||
void syck_emit_folded( SyckEmitter *, int, char, char *, long );
|
||||
void syck_emit_literal( SyckEmitter *, char, char *, long );
|
||||
void syck_emit_seq( SyckEmitter *, char *, enum seq_style );
|
||||
void syck_emit_item( SyckEmitter *, st_data_t );
|
||||
void syck_emit_map( SyckEmitter *, char *, enum map_style );
|
||||
void syck_emit_end( SyckEmitter * );
|
||||
void syck_emit_tag( SyckEmitter *, char *, char * );
|
||||
void syck_emit_indent( SyckEmitter * );
|
||||
SyckLevel *syck_emitter_current_level( SyckEmitter * );
|
||||
SyckLevel *syck_emitter_parent_level( SyckEmitter * );
|
||||
void syck_emitter_pop_level( SyckEmitter * );
|
||||
void syck_emitter_add_level( SyckEmitter *, int, enum syck_level_status );
|
||||
void syck_emitter_reset_levels( SyckEmitter * );
|
||||
SyckParser *syck_new_parser();
|
||||
void syck_free_parser( SyckParser * );
|
||||
void syck_parser_set_root_on_error( SyckParser *, SYMID );
|
||||
void syck_parser_implicit_typing( SyckParser *, int );
|
||||
void syck_parser_taguri_expansion( SyckParser *, int );
|
||||
int syck_scan_scalar( int, char *, long );
|
||||
void syck_parser_handler( SyckParser *, SyckNodeHandler );
|
||||
void syck_parser_error_handler( SyckParser *, SyckErrorHandler );
|
||||
void syck_parser_bad_anchor_handler( SyckParser *, SyckBadAnchorHandler );
|
||||
|
@ -362,7 +409,6 @@ void syck_parser_pop_level( SyckParser * );
|
|||
void free_any_io( SyckParser * );
|
||||
long syck_parser_read( SyckParser * );
|
||||
long syck_parser_readlen( SyckParser *, long );
|
||||
void syck_parser_init( SyckParser *, int );
|
||||
SYMID syck_parse( SyckParser * );
|
||||
void syck_default_error_handler( SyckParser *, char * );
|
||||
SYMID syck_yaml2byte_handler( SyckParser *, SyckNode * );
|
||||
|
@ -378,30 +424,29 @@ void syck_free_node( SyckNode * );
|
|||
void syck_free_members( SyckNode * );
|
||||
SyckNode *syck_new_str( char *, enum scalar_style );
|
||||
SyckNode *syck_new_str2( char *, long, enum scalar_style );
|
||||
void syck_replace_str( SyckNode *, char *, enum scalar_style );
|
||||
void syck_replace_str2( SyckNode *, char *, long, enum scalar_style );
|
||||
void syck_str_blow_away_commas( SyckNode * );
|
||||
char *syck_str_read( SyckNode * );
|
||||
SyckNode *syck_new_map( SYMID, SYMID );
|
||||
void syck_map_empty( SyckNode * );
|
||||
void syck_map_add( SyckNode *, SYMID, SYMID );
|
||||
SYMID syck_map_read( SyckNode *, enum map_part, long );
|
||||
void syck_map_assign( SyckNode *, enum map_part, long, SYMID );
|
||||
long syck_map_count( SyckNode * );
|
||||
void syck_map_update( SyckNode *, SyckNode * );
|
||||
SyckNode *syck_new_seq( SYMID );
|
||||
void syck_seq_empty( SyckNode * );
|
||||
void syck_seq_add( SyckNode *, SYMID );
|
||||
void syck_seq_assign( SyckNode *, long, SYMID );
|
||||
SYMID syck_seq_read( SyckNode *, long );
|
||||
long syck_seq_count( SyckNode * );
|
||||
|
||||
void apply_seq_in_map( SyckParser *, SyckNode * );
|
||||
|
||||
/*
|
||||
* Lexer prototypes
|
||||
*/
|
||||
void syckerror( char * );
|
||||
|
||||
#ifndef ST_DATA_T_DEFINED
|
||||
typedef long st_data_t;
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
|
1322
ext/syck/token.c
1322
ext/syck/token.c
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* ybext.c
|
||||
* yaml2byte.c
|
||||
*
|
||||
* $Author$
|
||||
* $Date$
|
||||
|
|
119
lib/yaml.rb
119
lib/yaml.rb
|
@ -6,8 +6,10 @@
|
|||
# Author:: why the lucky stiff
|
||||
#
|
||||
|
||||
require 'stringio'
|
||||
require 'yaml/error'
|
||||
require 'yaml/syck'
|
||||
require 'yaml/loader'
|
||||
require 'yaml/tag'
|
||||
require 'yaml/stream'
|
||||
|
||||
# == YAML
|
||||
|
@ -73,7 +75,7 @@ require 'yaml/stream'
|
|||
# ruby_obj == test_obj
|
||||
# # => true
|
||||
#
|
||||
# To register your custom types with the global loader, use +add_domain_type+.
|
||||
# To register your custom types with the global resolver, use +add_domain_type+.
|
||||
#
|
||||
# YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
|
||||
# Widget.new( val )
|
||||
|
@ -81,9 +83,21 @@ require 'yaml/stream'
|
|||
#
|
||||
module YAML
|
||||
|
||||
@@parser = YAML::Syck::Parser
|
||||
@@loader = YAML::Syck::DefaultLoader
|
||||
@@emitter = YAML::Syck::Emitter
|
||||
Resolver = YAML::Syck::Resolver
|
||||
DefaultResolver = YAML::Syck::DefaultResolver
|
||||
DefaultResolver.use_types_at( @@tagged_classes )
|
||||
GenericResolver = YAML::Syck::GenericResolver
|
||||
Parser = YAML::Syck::Parser
|
||||
Emitter = YAML::Syck::Emitter
|
||||
|
||||
# Returns a new default parser
|
||||
def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end
|
||||
# Returns a new generic parser
|
||||
def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end
|
||||
# Returns the default resolver
|
||||
def YAML.resolver; DefaultResolver; end
|
||||
# Returns a new default emitter
|
||||
def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end
|
||||
|
||||
#
|
||||
# Converts _obj_ to YAML and writes the YAML result to _io_.
|
||||
|
@ -99,9 +113,8 @@ module YAML
|
|||
# #=> "--- :locked"
|
||||
#
|
||||
def YAML.dump( obj, io = nil )
|
||||
io ||= ""
|
||||
io << obj.to_yaml
|
||||
io
|
||||
obj.to_yaml( io || io2 = StringIO.new )
|
||||
io || ( io2.rewind; io2.read )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -116,7 +129,7 @@ module YAML
|
|||
# #=> :locked
|
||||
#
|
||||
def YAML.load( io )
|
||||
yp = @@parser.new.load( io )
|
||||
yp = parser.load( io )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -153,13 +166,13 @@ module YAML
|
|||
#
|
||||
# Can also load from a string.
|
||||
#
|
||||
# YAML.load( "--- :locked" )
|
||||
# YAML.parse( "--- :locked" )
|
||||
# #=> #<YAML::Syck::Node:0x82edddc
|
||||
# @type_id="tag:ruby.yaml.org,2002:sym",
|
||||
# @value=":locked", @kind=:scalar>
|
||||
#
|
||||
def YAML.parse( io )
|
||||
yp = @@parser.new( :Model => :Generic ).load( io )
|
||||
yp = generic_parser.load( io )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -200,7 +213,7 @@ module YAML
|
|||
# end
|
||||
#
|
||||
def YAML.each_document( io, &block )
|
||||
yp = @@parser.new.load_documents( io, &block )
|
||||
yp = parser.load_documents( io, &block )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -230,7 +243,7 @@ module YAML
|
|||
# end
|
||||
#
|
||||
def YAML.each_node( io, &doc_proc )
|
||||
yp = @@parser.new( :Model => :Generic ).load_documents( io, &doc_proc )
|
||||
yp = generic_parser.load_documents( io, &doc_proc )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -254,12 +267,11 @@ module YAML
|
|||
# loaded documents.
|
||||
#
|
||||
def YAML.load_stream( io )
|
||||
yp = @@parser.new
|
||||
d = nil
|
||||
yp.load_documents( io ) { |doc|
|
||||
d = YAML::Stream.new( yp.options ) if not d
|
||||
parser.load_documents( io ) do |doc|
|
||||
d = YAML::Stream.new if not d
|
||||
d.add( doc )
|
||||
}
|
||||
end
|
||||
return d
|
||||
end
|
||||
|
||||
|
@ -283,43 +295,50 @@ module YAML
|
|||
#
|
||||
# Add a global handler for a YAML domain type.
|
||||
#
|
||||
def YAML.add_domain_type( domain, type_re, &transfer_proc )
|
||||
@@loader.add_domain_type( domain, type_re, &transfer_proc )
|
||||
def YAML.add_domain_type( domain, type_tag, &transfer_proc )
|
||||
resolver.add_type( "tag:#{ domain }:#{ type_tag }", 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 )
|
||||
def YAML.add_builtin_type( type_tag, &transfer_proc )
|
||||
resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", 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 )
|
||||
resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", 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 )
|
||||
resolver.add_type( "x-private:" + type_re, transfer_proc )
|
||||
end
|
||||
|
||||
#
|
||||
# Detect typing of a string
|
||||
#
|
||||
def YAML.detect_implicit( val )
|
||||
@@loader.detect_implicit( val )
|
||||
resolver.detect_implicit( val )
|
||||
end
|
||||
|
||||
#
|
||||
# Convert a type_id to a taguri
|
||||
#
|
||||
def YAML.tagurize( val )
|
||||
resolver.tagurize( val )
|
||||
end
|
||||
|
||||
#
|
||||
# Apply a transfer method to a Ruby object
|
||||
#
|
||||
def YAML.transfer( type_id, obj )
|
||||
@@loader.transfer( type_id, obj )
|
||||
resolver.transfer( YAML.tagurize( type_id ), obj )
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -358,24 +377,13 @@ module YAML
|
|||
# Allocate an Emitter if needed
|
||||
#
|
||||
def YAML.quick_emit( oid, opts = {}, &e )
|
||||
old_opt = nil
|
||||
if opts[:Emitter].is_a? @@emitter
|
||||
out = opts.delete( :Emitter )
|
||||
old_opt = out.options.dup
|
||||
out.options.update( opts )
|
||||
else
|
||||
out = @@emitter.new( opts )
|
||||
end
|
||||
aidx = out.start_object( oid )
|
||||
if aidx
|
||||
out.simple( "*#{ aidx }" )
|
||||
else
|
||||
e.call( out )
|
||||
end
|
||||
if old_opt.is_a? Hash
|
||||
out.options = old_opt
|
||||
end
|
||||
out.end_object
|
||||
out =
|
||||
if opts.is_a? YAML::Emitter
|
||||
opts
|
||||
else
|
||||
emitter.reset( opts )
|
||||
end
|
||||
out.emit( oid, &e )
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -383,7 +391,7 @@ end
|
|||
require 'yaml/rubytypes'
|
||||
require 'yaml/types'
|
||||
|
||||
module Kernel
|
||||
module Kernel # :nodoc:
|
||||
#
|
||||
# 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
|
||||
|
@ -400,12 +408,25 @@ module Kernel
|
|||
# ryan:: Either way, I certainly will have a pony parade.
|
||||
#
|
||||
|
||||
def y( o, *x )
|
||||
x.unshift o
|
||||
puts( if x.length == 1
|
||||
YAML::dump( *x )
|
||||
# Prints any supplied _objects_ out in YAML. Intended as
|
||||
# a variation on +Kernel::p+.
|
||||
#
|
||||
# S = Struct.new(:name, :state)
|
||||
# s = S['dave', 'TX']
|
||||
# y s
|
||||
#
|
||||
# _produces:_
|
||||
#
|
||||
# --- !ruby/struct:S
|
||||
# name: dave
|
||||
# state: TX
|
||||
#
|
||||
def y( object, *objects )
|
||||
objects.unshift object
|
||||
puts( if objects.length == 1
|
||||
YAML::dump( *objects )
|
||||
else
|
||||
YAML::dump_stream( *x )
|
||||
YAML::dump_stream( *objects )
|
||||
end )
|
||||
end
|
||||
private :y
|
||||
|
|
|
@ -25,7 +25,7 @@ module YAML
|
|||
matches.each { |m|
|
||||
result.push m.last
|
||||
}
|
||||
self.class.new( 'seq', result )
|
||||
YAML.transfer( 'seq', result )
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,5 +29,6 @@ module YAML
|
|||
|
||||
class Error < StandardError; end
|
||||
class ParseError < Error; end
|
||||
class TypeError < StandardError; end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
|
||||
require 'date'
|
||||
|
||||
#
|
||||
# Type conversions
|
||||
#
|
||||
|
||||
class Class
|
||||
def to_yaml( opts = {} )
|
||||
raise TypeError, "can't dump anonymous class %s" % self.class
|
||||
|
@ -11,564 +11,377 @@ class Class
|
|||
end
|
||||
|
||||
class Object
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/object:#{self.class}"
|
||||
end
|
||||
def to_yaml_properties
|
||||
instance_variables.sort
|
||||
end
|
||||
yaml_as "tag:ruby.yaml.org,2002:object"
|
||||
def to_yaml_style; end
|
||||
def to_yaml_properties; instance_variables.sort; end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out.map( self.to_yaml_type ) { |map|
|
||||
to_yaml_properties.each { |m|
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m[1..-1], instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^object/ ) { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, Object )
|
||||
YAML.object_maker( obj_class, val )
|
||||
}
|
||||
|
||||
#
|
||||
# Maps: Hash#to_yaml
|
||||
#
|
||||
class Hash
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml_type
|
||||
if self.class == Hash or self.class == YAML::SpecialHash
|
||||
"!map"
|
||||
yaml_as "tag:ruby.yaml.org,2002:hash"
|
||||
yaml_as "tag:yaml.org,2002:map"
|
||||
def yaml_initialize( tag, val )
|
||||
if Array === val
|
||||
update Hash.[]( *val ) # Convert the map to a sequence
|
||||
elsif Hash === val
|
||||
update val
|
||||
else
|
||||
"!ruby/hash:#{self.class}"
|
||||
raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
opts[:DocType] = self.class if Hash === opts
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
hash_type = to_yaml_type
|
||||
if not out.options(:ExplicitTypes) and hash_type == "!map"
|
||||
hash_type = ""
|
||||
end
|
||||
out.map( hash_type ) { |map|
|
||||
#
|
||||
# Sort the hash
|
||||
#
|
||||
if out.options(:SortKeys)
|
||||
map.concat( self.sort )
|
||||
else
|
||||
map.concat( self.to_a )
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
each do |k, v|
|
||||
map.add( k, v )
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
hash_proc = Proc.new { |type, val|
|
||||
if Array === val
|
||||
val = Hash.[]( *val ) # Convert the map to a sequence
|
||||
elsif Hash === val
|
||||
type, obj_class = YAML.read_type_class( type, Hash )
|
||||
if obj_class != Hash
|
||||
o = obj_class.allocate
|
||||
o.update( val )
|
||||
val = o
|
||||
end
|
||||
else
|
||||
raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
|
||||
end
|
||||
val
|
||||
}
|
||||
YAML.add_ruby_type( /^hash/, &hash_proc )
|
||||
|
||||
module YAML
|
||||
|
||||
#
|
||||
# Ruby-specific collection: !ruby/flexhash
|
||||
#
|
||||
class FlexHash < Array
|
||||
def []( k )
|
||||
self.assoc( k ).to_a[1]
|
||||
end
|
||||
def []=( k, *rest )
|
||||
val, set = rest.reverse
|
||||
if ( tmp = self.assoc( k ) ) and not set
|
||||
tmp[1] = val
|
||||
else
|
||||
self << [ k, val ]
|
||||
end
|
||||
val
|
||||
end
|
||||
def has_key?( k )
|
||||
self.assoc( k ) ? true : false
|
||||
end
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out.seq( "!ruby/flexhash" ) { |seq|
|
||||
self.each { |v|
|
||||
if v[1]
|
||||
seq.add( Hash.[]( *v ) )
|
||||
else
|
||||
seq.add( v[0] )
|
||||
end
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( 'flexhash' ) { |type, val|
|
||||
if Array === val
|
||||
p = FlexHash.new
|
||||
val.each { |v|
|
||||
if Hash === v
|
||||
p.concat( v.to_a ) # Convert the map to a sequence
|
||||
else
|
||||
p << [ v, nil ]
|
||||
end
|
||||
}
|
||||
p
|
||||
else
|
||||
raise YAML::Error, "Invalid !ruby/flexhash: " + val.inspect
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Structs: export as a !map
|
||||
#
|
||||
class Struct
|
||||
def is_complex_yaml?
|
||||
true
|
||||
yaml_as "tag:ruby.yaml.org,2002:struct"
|
||||
def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
|
||||
def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
|
||||
def self.yaml_new( klass, tag, val )
|
||||
if Hash === val
|
||||
struct_type = nil
|
||||
|
||||
#
|
||||
# Use existing Struct if it exists
|
||||
#
|
||||
props = {}
|
||||
val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
|
||||
begin
|
||||
struct_name, struct_type = YAML.read_type_class( tag, Struct )
|
||||
rescue NameError
|
||||
end
|
||||
if not struct_type
|
||||
struct_def = [ tag.split( ':', 4 ).last ]
|
||||
struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
|
||||
end
|
||||
|
||||
#
|
||||
# Set the Struct properties
|
||||
#
|
||||
st = YAML::object_maker( struct_type, {} )
|
||||
st.members.each do |m|
|
||||
st.send( "#{m}=", val[m] )
|
||||
end
|
||||
props.each do |k,v|
|
||||
st.instance_variable_set(k, v)
|
||||
end
|
||||
st
|
||||
else
|
||||
raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
#
|
||||
# Basic struct is passed as a YAML map
|
||||
#
|
||||
struct_name = self.class.name.gsub( "Struct::", "" )
|
||||
out.map( "!ruby/struct:#{struct_name}" ) { |map|
|
||||
self.members.each { |m|
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
self.members.each do |m|
|
||||
map.add( m, self[m] )
|
||||
}
|
||||
self.to_yaml_properties.each { |m|
|
||||
end
|
||||
self.to_yaml_properties.each do |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^struct/ ) { |type, val|
|
||||
if Hash === val
|
||||
struct_type = nil
|
||||
|
||||
#
|
||||
# Use existing Struct if it exists
|
||||
#
|
||||
props = {}
|
||||
val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
|
||||
begin
|
||||
struct_name, struct_type = YAML.read_type_class( type, Struct )
|
||||
rescue NameError
|
||||
end
|
||||
if not struct_type
|
||||
struct_def = [ type.split( ':', 4 ).last ]
|
||||
struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
|
||||
end
|
||||
|
||||
#
|
||||
# Set the Struct properties
|
||||
#
|
||||
st = YAML::object_maker( struct_type, {} )
|
||||
st.members.each { |m|
|
||||
st.send( "#{m}=", val[m] )
|
||||
}
|
||||
props.each { |k,v|
|
||||
st.instance_variable_set(k, v)
|
||||
}
|
||||
st
|
||||
else
|
||||
raise YAML::Error, "Invalid Ruby Struct: " + val.inspect
|
||||
end
|
||||
}
|
||||
|
||||
#
|
||||
# Sequences: Array#to_yaml
|
||||
#
|
||||
class Array
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml_type
|
||||
if self.class == Array
|
||||
"!seq"
|
||||
else
|
||||
"!ruby/array:#{self.class}"
|
||||
end
|
||||
end
|
||||
yaml_as "tag:ruby.yaml.org,2002:array"
|
||||
yaml_as "tag:yaml.org,2002:seq"
|
||||
def yaml_initialize( tag, val ); concat( val.to_a ); end
|
||||
def to_yaml( opts = {} )
|
||||
opts[:DocType] = self.class if Hash === opts
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
array_type = to_yaml_type
|
||||
if not out.options(:ExplicitTypes) and array_type == "!seq"
|
||||
array_type = ""
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.seq( taguri, to_yaml_style ) do |seq|
|
||||
each do |x|
|
||||
seq.add( x )
|
||||
end
|
||||
end
|
||||
|
||||
out.seq( array_type ) { |seq|
|
||||
seq.concat( self )
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
array_proc = Proc.new { |type, val|
|
||||
if Array === val
|
||||
type, obj_class = YAML.read_type_class( type, Array )
|
||||
if obj_class != Array
|
||||
o = obj_class.allocate
|
||||
o.concat( val )
|
||||
val = o
|
||||
end
|
||||
val
|
||||
else
|
||||
val.to_a
|
||||
end
|
||||
}
|
||||
YAML.add_ruby_type( /^array/, &array_proc )
|
||||
|
||||
#
|
||||
# Exception#to_yaml
|
||||
#
|
||||
class Exception
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/exception:#{self.class}"
|
||||
yaml_as "tag:ruby.yaml.org,2002:exception"
|
||||
def Exception.yaml_new( klass, tag, val )
|
||||
o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } )
|
||||
val.each_pair do |k,v|
|
||||
o.instance_variable_set("@#{k}", v)
|
||||
end
|
||||
o
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out.map( self.to_yaml_type ) { |map|
|
||||
map.add( 'message', self.message )
|
||||
to_yaml_properties.each { |m|
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
map.add( 'message', message )
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m[1..-1], instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^exception/ ) { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, Exception )
|
||||
o = YAML.object_maker( obj_class, { 'mesg' => val.delete( 'message' ) } )
|
||||
val.each_pair { |k,v|
|
||||
o.instance_variable_set("@#{k}", v)
|
||||
}
|
||||
o
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# String#to_yaml
|
||||
#
|
||||
class String
|
||||
yaml_as "tag:ruby.yaml.org,2002:string"
|
||||
yaml_as "tag:yaml.org,2002:str"
|
||||
def is_complex_yaml?
|
||||
to_yaml_fold or not to_yaml_properties.empty? or self =~ /\n.+/
|
||||
to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
|
||||
end
|
||||
def is_binary_data?
|
||||
( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 )
|
||||
( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 ) unless empty?
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/string#{ ":#{ self.class }" if self.class != ::String }"
|
||||
end
|
||||
def to_yaml_fold
|
||||
nil
|
||||
def String.yaml_new( klass, tag, val )
|
||||
val = { 'str' => val } if String === val
|
||||
if Hash === val
|
||||
s = klass.allocate
|
||||
# Thank you, NaHi
|
||||
String.instance_method(:initialize).
|
||||
bind(s).
|
||||
call( val.delete( 'str' ) )
|
||||
val.each { |k,v| s.instance_variable_set( k, v ) }
|
||||
s
|
||||
else
|
||||
raise YAML::TypeError, "Invalid String: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
complex = false
|
||||
if self.is_complex_yaml?
|
||||
complex = true
|
||||
elsif opts[:BestWidth].to_i > 0
|
||||
if self.length > opts[:BestWidth] and opts[:UseFold]
|
||||
complex = true
|
||||
YAML::quick_emit( is_complex_yaml? ? object_id : nil, opts ) do |out|
|
||||
if is_binary_data?
|
||||
out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
|
||||
elsif to_yaml_properties.empty?
|
||||
out.scalar( taguri, self, to_yaml_style )
|
||||
else
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
map.add( 'str', "#{self}" )
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
YAML::quick_emit( complex ? self.object_id : nil, opts ) { |out|
|
||||
if complex
|
||||
if not to_yaml_properties.empty?
|
||||
out.map( self.to_yaml_type ) { |map|
|
||||
map.add( 'str', "#{self}" )
|
||||
to_yaml_properties.each { |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
elsif self.is_binary_data?
|
||||
out.binary_base64( self )
|
||||
elsif self =~ /#{YAML::ESCAPE_CHAR}/
|
||||
out.node_text( self, '"' )
|
||||
else
|
||||
out.node_text( self, to_yaml_fold )
|
||||
end
|
||||
else
|
||||
ostr = if out.options(:KeepValue)
|
||||
self
|
||||
elsif empty?
|
||||
"''"
|
||||
elsif self =~ /^[^#{YAML::WORD_CHAR}\/]| \#|#{YAML::ESCAPE_CHAR}|[#{YAML::SPACE_INDICATORS}]( |$)| $|\n|\'/
|
||||
out.node_text( self, '"' ); nil
|
||||
elsif YAML.detect_implicit( self ) != 'str'
|
||||
out.node_text( self, '"' ); nil
|
||||
else
|
||||
self
|
||||
end
|
||||
out.simple( ostr ) unless ostr.nil?
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^string/ ) { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, ::String )
|
||||
if Hash === val
|
||||
s = YAML::object_maker( obj_class, {} )
|
||||
# Thank you, NaHi
|
||||
String.instance_method(:initialize).
|
||||
bind(s).
|
||||
call( val.delete( 'str' ) )
|
||||
val.each { |k,v| s.instance_variable_set( k, v ) }
|
||||
s
|
||||
else
|
||||
raise YAML::Error, "Invalid String: " + val.inspect
|
||||
end
|
||||
}
|
||||
|
||||
#
|
||||
# Symbol#to_yaml
|
||||
#
|
||||
class Symbol
|
||||
def is_complex_yaml?
|
||||
false
|
||||
yaml_as "tag:ruby.yaml.org,2002:symbol"
|
||||
yaml_as "tag:ruby.yaml.org,2002:sym"
|
||||
# yaml_implicit /^:/, :yaml_new
|
||||
def Symbol.yaml_new( klass, tag, val )
|
||||
if String === val
|
||||
val.intern
|
||||
else
|
||||
raise YAML::TypeError, "Invalid Symbol: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( nil, opts ) { |out|
|
||||
out << ":"
|
||||
self.id2name.to_yaml( :Emitter => out )
|
||||
}
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
out.scalar( taguri, self.id2name, :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
symbol_proc = Proc.new { |type, val|
|
||||
if String === val
|
||||
val = YAML::load( "--- #{val}") if val =~ /^["'].*['"]$/
|
||||
val.intern
|
||||
else
|
||||
raise YAML::Error, "Invalid Symbol: " + val.inspect
|
||||
end
|
||||
}
|
||||
YAML.add_ruby_type( 'symbol', &symbol_proc )
|
||||
YAML.add_ruby_type( 'sym', &symbol_proc )
|
||||
|
||||
#
|
||||
# Range#to_yaml
|
||||
# TODO: Rework the Range as a sequence (simpler)
|
||||
#
|
||||
class Range
|
||||
def is_complex_yaml?
|
||||
true
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/range#{ if self.class != ::Range; ":#{ self.class }"; end }"
|
||||
yaml_as "tag:ruby.yaml.org,2002:range"
|
||||
def Range.yaml_new( klass, tag, val )
|
||||
inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
|
||||
opts = {}
|
||||
if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
|
||||
r1, rdots, r2 = $1, $2, $3
|
||||
opts = {
|
||||
'begin' => YAML.load( "--- #{r1}" ),
|
||||
'end' => YAML.load( "--- #{r2}" ),
|
||||
'excl' => rdots.length == 3
|
||||
}
|
||||
val = {}
|
||||
elsif Hash === val
|
||||
opts['begin'] = val.delete('begin')
|
||||
opts['end'] = val.delete('end')
|
||||
opts['excl'] = val.delete('excl')
|
||||
end
|
||||
if Hash === opts
|
||||
r = YAML::object_maker( klass, {} )
|
||||
# Thank you, NaHi
|
||||
Range.instance_method(:initialize).
|
||||
bind(r).
|
||||
call( opts['begin'], opts['end'], opts['excl'] )
|
||||
val.each { |k,v| r.instance_variable_set( k, v ) }
|
||||
r
|
||||
else
|
||||
raise YAML::TypeError, "Invalid Range: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
|
||||
self.end.is_complex_yaml? or self.end.respond_to? :to_str or
|
||||
not to_yaml_properties.empty?
|
||||
out.map( to_yaml_type ) { |map|
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
# if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
|
||||
# self.end.is_complex_yaml? or self.end.respond_to? :to_str or
|
||||
# not to_yaml_properties.empty?
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
map.add( 'begin', self.begin )
|
||||
map.add( 'end', self.end )
|
||||
map.add( 'excl', self.exclude_end? )
|
||||
to_yaml_properties.each { |m|
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
else
|
||||
out << "#{ to_yaml_type } '"
|
||||
self.begin.to_yaml(:Emitter => out)
|
||||
out << ( self.exclude_end? ? "..." : ".." )
|
||||
self.end.to_yaml(:Emitter => out)
|
||||
out << "'"
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
# else
|
||||
# out.scalar( taguri ) do |sc|
|
||||
# sc.embed( self.begin )
|
||||
# sc.concat( self.exclude_end? ? "..." : ".." )
|
||||
# sc.embed( self.end )
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^range/ ) { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, ::Range )
|
||||
inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
|
||||
opts = {}
|
||||
if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
|
||||
r1, rdots, r2 = $1, $2, $3
|
||||
opts = {
|
||||
'begin' => YAML.load( "--- #{r1}" ),
|
||||
'end' => YAML.load( "--- #{r2}" ),
|
||||
'excl' => rdots.length == 3
|
||||
}
|
||||
val = {}
|
||||
elsif Hash === val
|
||||
opts['begin'] = val.delete('begin')
|
||||
opts['end'] = val.delete('end')
|
||||
opts['excl'] = val.delete('excl')
|
||||
end
|
||||
if Hash === opts
|
||||
r = YAML::object_maker( obj_class, {} )
|
||||
# Thank you, NaHi
|
||||
Range.instance_method(:initialize).
|
||||
bind(r).
|
||||
call( opts['begin'], opts['end'], opts['excl'] )
|
||||
val.each { |k,v| r.instance_variable_set( k, v ) }
|
||||
r
|
||||
else
|
||||
raise YAML::Error, "Invalid Range: " + val.inspect
|
||||
end
|
||||
}
|
||||
|
||||
#
|
||||
# Make an Regexp
|
||||
#
|
||||
class Regexp
|
||||
def is_complex_yaml?
|
||||
self.class != Regexp or not to_yaml_properties.empty?
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/regexp#{ if self.class != ::Regexp; ":#{ self.class }"; end }"
|
||||
yaml_as "tag:ruby.yaml.org,2002:regexp"
|
||||
def Regexp.yaml_new( klass, tag, val )
|
||||
if String === val and val =~ /^\/(.*)\/([mix]*)$/
|
||||
val = { 'regexp' => $1, 'mods' => $2 }
|
||||
end
|
||||
if Hash === val
|
||||
mods = nil
|
||||
unless val['mods'].to_s.empty?
|
||||
mods = 0x00
|
||||
mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
|
||||
mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
|
||||
mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
|
||||
end
|
||||
val.delete( 'mods' )
|
||||
r = YAML::object_maker( klass, {} )
|
||||
Regexp.instance_method(:initialize).
|
||||
bind(r).
|
||||
call( val.delete( 'regexp' ), mods )
|
||||
val.each { |k,v| r.instance_variable_set( k, v ) }
|
||||
r
|
||||
else
|
||||
raise YAML::TypeError, "Invalid Regular expression: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( nil, opts ) { |out|
|
||||
if self.is_complex_yaml?
|
||||
out.map( self.to_yaml_type ) { |map|
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
if to_yaml_properties.empty?
|
||||
out.scalar( taguri, self.inspect, :plain )
|
||||
else
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
src = self.inspect
|
||||
if src =~ /\A\/(.*)\/([a-z]*)\Z/
|
||||
map.add( 'regexp', $1 )
|
||||
map.add( 'mods', $2 )
|
||||
else
|
||||
raise YAML::Error, "Invalid Regular expression: " + src
|
||||
raise YAML::TypeError, "Invalid Regular expression: " + src
|
||||
end
|
||||
to_yaml_properties.each { |m|
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
else
|
||||
out << "#{ to_yaml_type } "
|
||||
self.inspect.to_yaml( :Emitter => out )
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
regexp_proc = Proc.new { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, ::Regexp )
|
||||
if String === val and val =~ /^\/(.*)\/([mix]*)$/
|
||||
val = { 'regexp' => $1, 'mods' => $2 }
|
||||
end
|
||||
if Hash === val
|
||||
mods = nil
|
||||
unless val['mods'].to_s.empty?
|
||||
mods = 0x00
|
||||
mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
|
||||
mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
|
||||
mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
|
||||
end
|
||||
val.delete( 'mods' )
|
||||
r = YAML::object_maker( obj_class, {} )
|
||||
Regexp.instance_method(:initialize).
|
||||
bind(r).
|
||||
call( val.delete( 'regexp' ), mods )
|
||||
val.each { |k,v| r.instance_variable_set( k, v ) }
|
||||
r
|
||||
else
|
||||
raise YAML::Error, "Invalid Regular expression: " + val.inspect
|
||||
end
|
||||
}
|
||||
YAML.add_domain_type( "perl.yaml.org,2002", /^regexp/, ®exp_proc )
|
||||
YAML.add_ruby_type( /^regexp/, ®exp_proc )
|
||||
|
||||
#
|
||||
# Emit a Time object as an ISO 8601 timestamp
|
||||
#
|
||||
class Time
|
||||
def is_complex_yaml?
|
||||
self.class != Time or not to_yaml_properties.empty?
|
||||
end
|
||||
def to_yaml_type
|
||||
"!ruby/time#{ if self.class != ::Time; ":#{ self.class }"; end }"
|
||||
yaml_as "tag:ruby.yaml.org,2002:time"
|
||||
yaml_as "tag:yaml.org,2002:timestamp"
|
||||
def Time.yaml_new( klass, tag, val )
|
||||
if Hash === val
|
||||
t = val.delete( 'at' )
|
||||
val.each { |k,v| t.instance_variable_set( k, v ) }
|
||||
t
|
||||
else
|
||||
raise YAML::TypeError, "Invalid Time: " + val.inspect
|
||||
end
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( nil, opts ) { |out|
|
||||
if self.is_complex_yaml?
|
||||
out.map( self.to_yaml_type ) { |map|
|
||||
map.add( 'at', ::Time.at( self ) )
|
||||
to_yaml_properties.each { |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
}
|
||||
}
|
||||
else
|
||||
tz = "Z"
|
||||
# from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
|
||||
unless self.utc?
|
||||
utc_same_instant = self.dup.utc
|
||||
utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
|
||||
difference_to_utc = utc_same_writing - utc_same_instant
|
||||
if (difference_to_utc < 0)
|
||||
difference_sign = '-'
|
||||
absolute_difference = -difference_to_utc
|
||||
else
|
||||
difference_sign = '+'
|
||||
absolute_difference = difference_to_utc
|
||||
end
|
||||
difference_minutes = (absolute_difference/60).round
|
||||
tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
tz = "Z"
|
||||
# from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
|
||||
unless self.utc?
|
||||
utc_same_instant = self.dup.utc
|
||||
utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
|
||||
difference_to_utc = utc_same_writing - utc_same_instant
|
||||
if (difference_to_utc < 0)
|
||||
difference_sign = '-'
|
||||
absolute_difference = -difference_to_utc
|
||||
else
|
||||
difference_sign = '+'
|
||||
absolute_difference = difference_to_utc
|
||||
end
|
||||
standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
|
||||
standard += ".%06d" % [usec] if usec.nonzero?
|
||||
standard += " %s" % [tz]
|
||||
standard.to_yaml( :Emitter => out, :KeepValue => true )
|
||||
difference_minutes = (absolute_difference/60).round
|
||||
tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
|
||||
end
|
||||
}
|
||||
standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
|
||||
standard += ".%06d" % [usec] if usec.nonzero?
|
||||
standard += " %s" % [tz]
|
||||
if to_yaml_properties.empty?
|
||||
out.scalar( taguri, standard, :plain )
|
||||
else
|
||||
out.map( taguri, to_yaml_style ) do |map|
|
||||
map.add( 'at', standard )
|
||||
to_yaml_properties.each do |m|
|
||||
map.add( m, instance_variable_get( m ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_ruby_type( /^time/ ) { |type, val|
|
||||
type, obj_class = YAML.read_type_class( type, ::Time )
|
||||
if Hash === val
|
||||
t = obj_class.at( val.delete( 'at' ) )
|
||||
val.each { |k,v| t.instance_variable_set( k, v ) }
|
||||
t
|
||||
else
|
||||
raise YAML::Error, "Invalid Time: " + val.inspect
|
||||
end
|
||||
}
|
||||
|
||||
#
|
||||
# Emit a Date object as a simple implicit
|
||||
#
|
||||
class Date
|
||||
def is_complex_yaml?
|
||||
false
|
||||
end
|
||||
yaml_as "tag:yaml.org,2002:timestamp#ymd"
|
||||
def to_yaml( opts = {} )
|
||||
opts[:KeepValue] = true
|
||||
self.to_s.to_yaml( opts )
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -576,50 +389,51 @@ end
|
|||
# Send Integer, Booleans, NilClass to String
|
||||
#
|
||||
class Numeric
|
||||
def is_complex_yaml?
|
||||
false
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
str = self.to_s
|
||||
if str == "Infinity"
|
||||
str = ".Inf"
|
||||
elsif str == "-Infinity"
|
||||
str = "-.Inf"
|
||||
elsif str == "NaN"
|
||||
str = ".NaN"
|
||||
end
|
||||
opts[:KeepValue] = true
|
||||
str.to_yaml( opts )
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
str = self.to_s
|
||||
if str == "Infinity"
|
||||
str = ".Inf"
|
||||
elsif str == "-Infinity"
|
||||
str = "-.Inf"
|
||||
elsif str == "NaN"
|
||||
str = ".NaN"
|
||||
end
|
||||
out.scalar( taguri, str, :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
class Fixnum
|
||||
yaml_as "tag:yaml.org,2002:int"
|
||||
end
|
||||
class Float
|
||||
yaml_as "tag:yaml.org,2002:float"
|
||||
end
|
||||
|
||||
class TrueClass
|
||||
def is_complex_yaml?
|
||||
false
|
||||
end
|
||||
yaml_as "tag:yaml.org,2002:bool#yes"
|
||||
def to_yaml( opts = {} )
|
||||
opts[:KeepValue] = true
|
||||
"true".to_yaml( opts )
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
out.scalar( taguri, "true", :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class FalseClass
|
||||
def is_complex_yaml?
|
||||
false
|
||||
end
|
||||
yaml_as "tag:yaml.org,2002:bool#no"
|
||||
def to_yaml( opts = {} )
|
||||
opts[:KeepValue] = true
|
||||
"false".to_yaml( opts )
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
out.scalar( taguri, "false", :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class NilClass
|
||||
def is_complex_yaml?
|
||||
false
|
||||
end
|
||||
yaml_as "tag:yaml.org,2002:null"
|
||||
def to_yaml( opts = {} )
|
||||
opts[:KeepValue] = true
|
||||
"".to_yaml( opts )
|
||||
YAML::quick_emit( nil, opts ) do |out|
|
||||
out.scalar( taguri, "", :plain )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -24,19 +24,15 @@ module YAML
|
|||
@documents[ doc_num ] = doc
|
||||
end
|
||||
|
||||
def emit
|
||||
opts = @options.dup
|
||||
opts[:UseHeader] = true if @documents.length > 1
|
||||
ct = 0
|
||||
out = YAML::Syck::Emitter.new( opts )
|
||||
def emit( io = nil )
|
||||
# opts = @options.dup
|
||||
# opts[:UseHeader] = true if @documents.length > 1
|
||||
out = YAML.emitter
|
||||
out.reset( io || io2 = StringIO.new )
|
||||
@documents.each { |v|
|
||||
if ct > 0
|
||||
out << "\n--- "
|
||||
end
|
||||
v.to_yaml( :Emitter => out )
|
||||
ct += 1
|
||||
v.to_yaml( out )
|
||||
}
|
||||
out.end_object
|
||||
io || ( io2.rewind; io2.read )
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#
|
||||
require 'syck'
|
||||
require 'yaml/basenode'
|
||||
require 'yaml/baseemitter'
|
||||
|
||||
module YAML
|
||||
module Syck
|
||||
|
@ -16,12 +15,5 @@ module YAML
|
|||
include YAML::BaseNode
|
||||
end
|
||||
|
||||
#
|
||||
# Mixin BaseEmitter functionality
|
||||
#
|
||||
class Emitter
|
||||
include YAML::BaseEmitter
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
86
lib/yaml/tag.rb
Normal file
86
lib/yaml/tag.rb
Normal file
|
@ -0,0 +1,86 @@
|
|||
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
|
||||
# $Id$
|
||||
#
|
||||
# = yaml/tag.rb: methods for associating a taguri to a class.
|
||||
#
|
||||
# Author:: why the lucky stiff
|
||||
#
|
||||
module YAML
|
||||
# A dictionary of taguris which map to
|
||||
# Ruby classes.
|
||||
@@tagged_classes = {}
|
||||
|
||||
#
|
||||
# Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
|
||||
# to classes when loading YAML. Taguris are of the form:
|
||||
#
|
||||
# tag:authorityName,date:specific
|
||||
#
|
||||
# The +authorityName+ is a domain name or email address. The +date+ is the date the type
|
||||
# was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
|
||||
# the type being added.
|
||||
#
|
||||
# For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
|
||||
# +date+. The +specific+ is simply the name of the type:
|
||||
#
|
||||
# tag:yaml.org,2002:int
|
||||
# tag:yaml.org,2002:float
|
||||
# tag:yaml.org,2002:timestamp
|
||||
#
|
||||
# The domain must be owned by you on the +date+ declared. If you don't own any domains on the
|
||||
# date you declare the type, you can simply use an e-mail address.
|
||||
#
|
||||
# tag:why@ruby-lang.org,2004:notes/personal
|
||||
#
|
||||
def YAML.tag_class( tag, cls )
|
||||
if @@tagged_classes.has_key? tag
|
||||
warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
|
||||
end
|
||||
@@tagged_classes[tag] = cls
|
||||
end
|
||||
|
||||
# Returns the complete dictionary of taguris, paired with classes. The key for
|
||||
# the dictionary is the full taguri. The value for each key is the class constant
|
||||
# associated to that taguri.
|
||||
#
|
||||
# YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
|
||||
#
|
||||
def YAML.tagged_classes
|
||||
@@tagged_classes
|
||||
end
|
||||
end
|
||||
|
||||
class Module # :nodoc: all
|
||||
# Adds a taguri _tag_ to a class, used when dumping or loading the class
|
||||
# in YAML. See YAML::tag_class for detailed information on typing and
|
||||
# taguris.
|
||||
def yaml_as( tag, sc = true )
|
||||
class_eval <<-"end;"
|
||||
attr_accessor :taguri
|
||||
def taguri
|
||||
if respond_to? :to_yaml_type
|
||||
YAML::tagurize( to_yaml_type[1..-1] )
|
||||
else
|
||||
return @taguri if @taguri
|
||||
tag = #{ tag.dump }
|
||||
if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag]
|
||||
tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
|
||||
end
|
||||
tag
|
||||
end
|
||||
end
|
||||
def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
|
||||
end;
|
||||
YAML::tag_class tag, self
|
||||
end
|
||||
# Transforms the subclass name into a name suitable for display
|
||||
# in a subclassed tag.
|
||||
def yaml_tag_class_name
|
||||
self.name
|
||||
end
|
||||
# Transforms the subclass name found in the tag into a Ruby
|
||||
# constant name.
|
||||
def yaml_tag_read_class( name )
|
||||
name
|
||||
end
|
||||
end
|
|
@ -8,15 +8,14 @@ module YAML
|
|||
# Default private type
|
||||
#
|
||||
class PrivateType
|
||||
def self.tag_subclasses?; false; end
|
||||
attr_accessor :type_id, :value
|
||||
def initialize( type, val )
|
||||
@type_id = type; @value = val
|
||||
@value.taguri = "x-private:#{ @type_id }"
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out << " !!#{@type_id}"
|
||||
value.to_yaml( :Emitter => out )
|
||||
}
|
||||
@value.to_yaml( opts )
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -24,29 +23,37 @@ module YAML
|
|||
# Default domain type
|
||||
#
|
||||
class DomainType
|
||||
def self.tag_subclasses?; false; end
|
||||
attr_accessor :domain, :type_id, :value
|
||||
def initialize( domain, type, val )
|
||||
@domain = domain; @type_id = type; @value = val
|
||||
@value.taguri = "tag:#{ @domain }:#{ @type_id }"
|
||||
end
|
||||
def to_yaml_type
|
||||
dom = @domain.dup
|
||||
if dom =~ /\.yaml\.org,2002$/
|
||||
dom = $`
|
||||
end
|
||||
"#{dom}/#{@type_id}"
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out << " !#{to_yaml_type} "
|
||||
value.to_yaml( :Emitter => out )
|
||||
}
|
||||
@value.to_yaml( opts )
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Unresolved objects
|
||||
#
|
||||
class Object
|
||||
def self.tag_subclasses?; false; end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( object_id, opts ) do |out|
|
||||
out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map|
|
||||
@ivars.each do |k,v|
|
||||
map.add( k, v )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# YAML Hash class to support comments and defaults
|
||||
#
|
||||
class SpecialHash < Object::Hash
|
||||
class SpecialHash < ::Hash
|
||||
attr_accessor :default
|
||||
def inspect
|
||||
self.default.to_s
|
||||
|
@ -69,12 +76,27 @@ module YAML
|
|||
#
|
||||
# Builtin collection: !omap
|
||||
#
|
||||
class Omap < Array
|
||||
class Omap < ::Array
|
||||
yaml_as "tag:yaml.org,2002:omap"
|
||||
def yaml_initialize( tag, val )
|
||||
if Array === val
|
||||
val.each do |v|
|
||||
if Hash === v
|
||||
concat( v.to_a ) # Convert the map to a sequence
|
||||
else
|
||||
raise YAML::Error, "Invalid !omap entry: " + val.inspect
|
||||
end
|
||||
end
|
||||
else
|
||||
raise YAML::Error, "Invalid !omap: " + val.inspect
|
||||
end
|
||||
self
|
||||
end
|
||||
def self.[]( *vals )
|
||||
o = Omap.new
|
||||
0.step( vals.length - 1, 2 ) { |i|
|
||||
0.step( vals.length - 1, 2 ) do |i|
|
||||
o[vals[i]] = vals[i+1]
|
||||
}
|
||||
end
|
||||
o
|
||||
end
|
||||
def []( k )
|
||||
|
@ -96,36 +118,35 @@ module YAML
|
|||
true
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out.seq( "!omap" ) { |seq|
|
||||
self.each { |v|
|
||||
YAML::quick_emit( self.object_id, opts ) do |out|
|
||||
out.seq( taguri, to_yaml_style ) do |seq|
|
||||
self.each do |v|
|
||||
seq.add( Hash[ *v ] )
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_builtin_type( "omap" ) { |type, val|
|
||||
if Array === val
|
||||
p = Omap.new
|
||||
val.each { |v|
|
||||
if Hash === v
|
||||
p.concat( v.to_a ) # Convert the map to a sequence
|
||||
else
|
||||
raise YAML::Error, "Invalid !omap entry: " + val.inspect
|
||||
end
|
||||
}
|
||||
else
|
||||
raise YAML::Error, "Invalid !omap: " + val.inspect
|
||||
end
|
||||
p
|
||||
}
|
||||
|
||||
#
|
||||
# Builtin collection: !pairs
|
||||
#
|
||||
class Pairs < Array
|
||||
class Pairs < ::Array
|
||||
yaml_as "tag:yaml.org,2002:pairs"
|
||||
def yaml_initialize( tag, val )
|
||||
if Array === val
|
||||
val.each do |v|
|
||||
if Hash === v
|
||||
concat( v.to_a ) # Convert the map to a sequence
|
||||
else
|
||||
raise YAML::Error, "Invalid !pairs entry: " + val.inspect
|
||||
end
|
||||
end
|
||||
else
|
||||
raise YAML::Error, "Invalid !pairs: " + val.inspect
|
||||
end
|
||||
self
|
||||
end
|
||||
def self.[]( *vals )
|
||||
p = Pairs.new
|
||||
0.step( vals.length - 1, 2 ) { |i|
|
||||
|
@ -147,50 +168,20 @@ module YAML
|
|||
true
|
||||
end
|
||||
def to_yaml( opts = {} )
|
||||
YAML::quick_emit( self.object_id, opts ) { |out|
|
||||
out.seq( "!pairs" ) { |seq|
|
||||
self.each { |v|
|
||||
YAML::quick_emit( self.object_id, opts ) do |out|
|
||||
out.seq( taguri, to_yaml_style ) do |seq|
|
||||
self.each do |v|
|
||||
seq.add( Hash[ *v ] )
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
YAML.add_builtin_type( "pairs" ) { |type, val|
|
||||
if Array === val
|
||||
p = Pairs.new
|
||||
val.each { |v|
|
||||
if Hash === v
|
||||
p.concat( v.to_a ) # Convert the map to a sequence
|
||||
else
|
||||
raise YAML::Error, "Invalid !pairs entry: " + val.inspect
|
||||
end
|
||||
}
|
||||
else
|
||||
raise YAML::Error, "Invalid !pairs: " + val.inspect
|
||||
end
|
||||
p
|
||||
}
|
||||
|
||||
#
|
||||
# Builtin collection: !set
|
||||
#
|
||||
class Set < Hash
|
||||
def to_yaml_type
|
||||
"!set"
|
||||
end
|
||||
class Set < ::Hash
|
||||
yaml_as "tag:yaml.org,2002:set"
|
||||
end
|
||||
|
||||
YAML.add_builtin_type( 'set' ) { |type, val|
|
||||
if Array === val
|
||||
val = Set[ *val ]
|
||||
elsif Hash === val
|
||||
Set[ val ]
|
||||
else
|
||||
raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
|
||||
end
|
||||
val
|
||||
}
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue