syck 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest.erb +8 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +6 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +51 -0
- data/Rakefile +32 -0
- data/ext/syck/bytecode.c +1165 -0
- data/ext/syck/emitter.c +1247 -0
- data/ext/syck/extconf.h +3 -0
- data/ext/syck/extconf.rb +5 -0
- data/ext/syck/gram.c +1894 -0
- data/ext/syck/gram.h +79 -0
- data/ext/syck/handler.c +173 -0
- data/ext/syck/implicit.c +2990 -0
- data/ext/syck/node.c +407 -0
- data/ext/syck/rubyext.c +2328 -0
- data/ext/syck/syck.c +524 -0
- data/ext/syck/syck.h +453 -0
- data/ext/syck/token.c +2724 -0
- data/ext/syck/yaml2byte.c +259 -0
- data/ext/syck/yamlbyte.h +171 -0
- data/lib/syck.bundle +0 -0
- data/lib/syck.rb +447 -0
- data/lib/syck/baseemitter.rb +242 -0
- data/lib/syck/basenode.rb +222 -0
- data/lib/syck/constants.rb +45 -0
- data/lib/syck/encoding.rb +35 -0
- data/lib/syck/error.rb +34 -0
- data/lib/syck/loader.rb +14 -0
- data/lib/syck/rubytypes.rb +450 -0
- data/lib/syck/stream.rb +41 -0
- data/lib/syck/stringio.rb +85 -0
- data/lib/syck/syck.rb +16 -0
- data/lib/syck/tag.rb +95 -0
- data/lib/syck/types.rb +192 -0
- data/lib/syck/yamlnode.rb +54 -0
- data/lib/syck/ypath.rb +54 -0
- data/lib/yaml/syck.rb +14 -0
- data/test/helper.rb +2 -0
- data/test/test_array.rb +13 -0
- data/test/test_boolean.rb +36 -0
- data/test/test_class.rb +11 -0
- data/test/test_exception.rb +45 -0
- data/test/test_hash.rb +24 -0
- data/test/test_null.rb +19 -0
- data/test/test_omap.rb +55 -0
- data/test/test_set.rb +30 -0
- data/test/test_string.rb +44 -0
- data/test/test_struct.rb +32 -0
- data/test/test_symbol.rb +21 -0
- data/test/test_time.rb +23 -0
- data/test/test_yaml.rb +1403 -0
- data/test/test_yaml_properties.rb +63 -0
- metadata +187 -0
data/lib/syck/stream.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Syck
|
2
|
+
|
3
|
+
#
|
4
|
+
# YAML::Stream -- for emitting many documents
|
5
|
+
#
|
6
|
+
class Stream
|
7
|
+
|
8
|
+
attr_accessor :documents, :options
|
9
|
+
|
10
|
+
def initialize( opts = {} )
|
11
|
+
@options = opts
|
12
|
+
@documents = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def []( i )
|
16
|
+
@documents[ i ]
|
17
|
+
end
|
18
|
+
|
19
|
+
def add( doc )
|
20
|
+
@documents << doc
|
21
|
+
end
|
22
|
+
|
23
|
+
def edit( doc_num, doc )
|
24
|
+
warn "#{caller[0]}: edit is deprecated" if $VERBOSE
|
25
|
+
@documents[ doc_num ] = doc
|
26
|
+
end
|
27
|
+
|
28
|
+
def emit( io = nil )
|
29
|
+
# opts = @options.dup
|
30
|
+
# opts[:UseHeader] = true if @documents.length > 1
|
31
|
+
out = Syck.emitter
|
32
|
+
out.reset( io || io2 = StringIO.new )
|
33
|
+
@documents.each { |v|
|
34
|
+
v.to_yaml( out )
|
35
|
+
}
|
36
|
+
io || ( io2.rewind; io2.read )
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
warn "#{caller[0]}: yaml/stringio is deprecated" if $VERBOSE
|
2
|
+
|
3
|
+
#
|
4
|
+
# Limited StringIO if no core lib is available
|
5
|
+
#
|
6
|
+
begin
|
7
|
+
require 'stringio'
|
8
|
+
rescue LoadError
|
9
|
+
# StringIO based on code by MoonWolf
|
10
|
+
class StringIO
|
11
|
+
def initialize(string="")
|
12
|
+
@string=string
|
13
|
+
@pos=0
|
14
|
+
@eof=(string.size==0)
|
15
|
+
end
|
16
|
+
def pos
|
17
|
+
@pos
|
18
|
+
end
|
19
|
+
def eof
|
20
|
+
@eof
|
21
|
+
end
|
22
|
+
alias eof? eof
|
23
|
+
def readline(rs=$/)
|
24
|
+
if @eof
|
25
|
+
raise EOFError
|
26
|
+
else
|
27
|
+
if p = @string[@pos..-1]=~rs
|
28
|
+
line = @string[@pos,p+1]
|
29
|
+
else
|
30
|
+
line = @string[@pos..-1]
|
31
|
+
end
|
32
|
+
@pos+=line.size
|
33
|
+
@eof =true if @pos==@string.size
|
34
|
+
$_ = line
|
35
|
+
end
|
36
|
+
end
|
37
|
+
def rewind
|
38
|
+
seek(0,0)
|
39
|
+
end
|
40
|
+
def seek(offset,whence)
|
41
|
+
case whence
|
42
|
+
when 0
|
43
|
+
@pos=offset
|
44
|
+
when 1
|
45
|
+
@pos+=offset
|
46
|
+
when 2
|
47
|
+
@pos=@string.size+offset
|
48
|
+
end
|
49
|
+
@eof=(@pos>=@string.size)
|
50
|
+
0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Class method for creating streams
|
56
|
+
#
|
57
|
+
def Syck.make_stream( io )
|
58
|
+
if String === io
|
59
|
+
io = StringIO.new( io )
|
60
|
+
elsif not IO === io
|
61
|
+
raise Syck::Error, "YAML stream must be an IO or String object."
|
62
|
+
end
|
63
|
+
if Syck::unicode
|
64
|
+
def io.readline
|
65
|
+
Syck.utf_to_internal( readline( @ln_sep ), @utf_encoding )
|
66
|
+
end
|
67
|
+
def io.check_unicode
|
68
|
+
@utf_encoding = Syck.sniff_encoding( read( 4 ) )
|
69
|
+
@ln_sep = Syck.enc_separator( @utf_encoding )
|
70
|
+
seek( -4, IO::SEEK_CUR )
|
71
|
+
end
|
72
|
+
def io.utf_encoding
|
73
|
+
@utf_encoding
|
74
|
+
end
|
75
|
+
io.check_unicode
|
76
|
+
else
|
77
|
+
def io.utf_encoding
|
78
|
+
:None
|
79
|
+
end
|
80
|
+
end
|
81
|
+
io
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
data/lib/syck/syck.rb
ADDED
data/lib/syck/tag.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
|
2
|
+
# $Id$
|
3
|
+
#
|
4
|
+
# = yaml/tag.rb: methods for associating a taguri to a class.
|
5
|
+
#
|
6
|
+
# Author:: why the lucky stiff
|
7
|
+
#
|
8
|
+
module Syck
|
9
|
+
# A dictionary of taguris which map to
|
10
|
+
# Ruby classes.
|
11
|
+
@@tagged_classes = {}
|
12
|
+
|
13
|
+
#
|
14
|
+
# Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
|
15
|
+
# to classes when loading YAML. Taguris are of the form:
|
16
|
+
#
|
17
|
+
# tag:authorityName,date:specific
|
18
|
+
#
|
19
|
+
# The +authorityName+ is a domain name or email address. The +date+ is the date the type
|
20
|
+
# was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
|
21
|
+
# the type being added.
|
22
|
+
#
|
23
|
+
# For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
|
24
|
+
# +date+. The +specific+ is simply the name of the type:
|
25
|
+
#
|
26
|
+
# tag:yaml.org,2002:int
|
27
|
+
# tag:yaml.org,2002:float
|
28
|
+
# tag:yaml.org,2002:timestamp
|
29
|
+
#
|
30
|
+
# The domain must be owned by you on the +date+ declared. If you don't own any domains on the
|
31
|
+
# date you declare the type, you can simply use an e-mail address.
|
32
|
+
#
|
33
|
+
# tag:why@ruby-lang.org,2004:notes/personal
|
34
|
+
#
|
35
|
+
def self.tag_class( tag, cls )
|
36
|
+
if @@tagged_classes.has_key? tag
|
37
|
+
warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
|
38
|
+
end
|
39
|
+
@@tagged_classes[tag] = cls
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the complete dictionary of taguris, paired with classes. The key for
|
43
|
+
# the dictionary is the full taguri. The value for each key is the class constant
|
44
|
+
# associated to that taguri.
|
45
|
+
#
|
46
|
+
# YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
|
47
|
+
#
|
48
|
+
def self.tagged_classes
|
49
|
+
@@tagged_classes
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Module
|
54
|
+
# :stopdoc:
|
55
|
+
|
56
|
+
# Adds a taguri _tag_ to a class, used when dumping or loading the class
|
57
|
+
# in YAML. See YAML::tag_class for detailed information on typing and
|
58
|
+
# taguris.
|
59
|
+
def syck_yaml_as( tag, sc = true )
|
60
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
61
|
+
class_eval <<-"END", __FILE__, __LINE__+1
|
62
|
+
attr_writer :taguri
|
63
|
+
def taguri
|
64
|
+
if respond_to? :to_yaml_type
|
65
|
+
Syck.tagurize( to_yaml_type[1..-1] )
|
66
|
+
else
|
67
|
+
return @taguri if defined?(@taguri) and @taguri
|
68
|
+
tag = #{ tag.dump }
|
69
|
+
if self.class.yaml_tag_subclasses? and self.class != Syck.tagged_classes[tag]
|
70
|
+
tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
|
71
|
+
end
|
72
|
+
tag
|
73
|
+
end
|
74
|
+
end
|
75
|
+
def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
|
76
|
+
END
|
77
|
+
Syck.tag_class tag, self
|
78
|
+
ensure
|
79
|
+
$VERBOSE = verbose
|
80
|
+
end
|
81
|
+
remove_method :yaml_as rescue nil
|
82
|
+
alias :yaml_as :syck_yaml_as
|
83
|
+
|
84
|
+
# Transforms the subclass name into a name suitable for display
|
85
|
+
# in a subclassed tag.
|
86
|
+
def yaml_tag_class_name
|
87
|
+
self.name
|
88
|
+
end
|
89
|
+
# Transforms the subclass name found in the tag into a Ruby
|
90
|
+
# constant name.
|
91
|
+
def yaml_tag_read_class( name )
|
92
|
+
name
|
93
|
+
end
|
94
|
+
# :startdoc:
|
95
|
+
end
|
data/lib/syck/types.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4
|
2
|
+
#
|
3
|
+
# Classes required by the full core typeset
|
4
|
+
#
|
5
|
+
|
6
|
+
module Syck
|
7
|
+
|
8
|
+
#
|
9
|
+
# Default private type
|
10
|
+
#
|
11
|
+
class PrivateType
|
12
|
+
def self.tag_subclasses?; false; end
|
13
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
14
|
+
def initialize( type, val )
|
15
|
+
@type_id = type; @value = val
|
16
|
+
@value.taguri = "x-private:#{ @type_id }"
|
17
|
+
end
|
18
|
+
def to_yaml( opts = {} )
|
19
|
+
@value.to_yaml( opts )
|
20
|
+
end
|
21
|
+
ensure
|
22
|
+
$VERBOSE = verbose
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Default domain type
|
27
|
+
#
|
28
|
+
class DomainType
|
29
|
+
def self.tag_subclasses?; false; end
|
30
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
31
|
+
def initialize( domain, type, val )
|
32
|
+
@domain = domain; @type_id = type; @value = val
|
33
|
+
@value.taguri = "tag:#{ @domain }:#{ @type_id }"
|
34
|
+
end
|
35
|
+
def to_yaml( opts = {} )
|
36
|
+
@value.to_yaml( opts )
|
37
|
+
end
|
38
|
+
ensure
|
39
|
+
$VERBOSE = verbose
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Unresolved objects
|
44
|
+
#
|
45
|
+
class Object
|
46
|
+
def self.tag_subclasses?; false; end
|
47
|
+
def to_yaml( opts = {} )
|
48
|
+
::Syck.quick_emit( self, opts ) do |out|
|
49
|
+
out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map|
|
50
|
+
@ivars.each do |k,v|
|
51
|
+
map.add( k, v )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# YAML Hash class to support comments and defaults
|
60
|
+
#
|
61
|
+
class SpecialHash < ::Hash
|
62
|
+
attr_accessor :default
|
63
|
+
def inspect
|
64
|
+
self.default.to_s
|
65
|
+
end
|
66
|
+
def to_s
|
67
|
+
self.default.to_s
|
68
|
+
end
|
69
|
+
def update( h )
|
70
|
+
if ::Syck::SpecialHash === h
|
71
|
+
@default = h.default if h.default
|
72
|
+
end
|
73
|
+
super( h )
|
74
|
+
end
|
75
|
+
def to_yaml( opts = {} )
|
76
|
+
opts[:DefaultKey] = self.default
|
77
|
+
super( opts )
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Builtin collection: !omap
|
83
|
+
#
|
84
|
+
class Omap < ::Array
|
85
|
+
yaml_as "tag:yaml.org,2002:omap"
|
86
|
+
def yaml_initialize( tag, val )
|
87
|
+
if Array === val
|
88
|
+
val.each do |v|
|
89
|
+
if Hash === v
|
90
|
+
concat( v.to_a ) # Convert the map to a sequence
|
91
|
+
else
|
92
|
+
raise ::Syck::Error, "Invalid !omap entry: " + val.inspect
|
93
|
+
end
|
94
|
+
end
|
95
|
+
else
|
96
|
+
raise ::Syck::Error, "Invalid !omap: " + val.inspect
|
97
|
+
end
|
98
|
+
self
|
99
|
+
end
|
100
|
+
def self.[]( *vals )
|
101
|
+
o = Omap.new
|
102
|
+
0.step( vals.length - 1, 2 ) do |i|
|
103
|
+
o[vals[i]] = vals[i+1]
|
104
|
+
end
|
105
|
+
o
|
106
|
+
end
|
107
|
+
def []( k )
|
108
|
+
self.assoc( k ).to_a[1]
|
109
|
+
end
|
110
|
+
def []=( k, *rest )
|
111
|
+
val, set = rest.reverse
|
112
|
+
if ( tmp = self.assoc( k ) ) and not set
|
113
|
+
tmp[1] = val
|
114
|
+
else
|
115
|
+
self << [ k, val ]
|
116
|
+
end
|
117
|
+
val
|
118
|
+
end
|
119
|
+
def has_key?( k )
|
120
|
+
self.assoc( k ) ? true : false
|
121
|
+
end
|
122
|
+
def is_complex_yaml?
|
123
|
+
true
|
124
|
+
end
|
125
|
+
def to_yaml( opts = {} )
|
126
|
+
::Syck.quick_emit( self, opts ) do |out|
|
127
|
+
out.seq( taguri, to_yaml_style ) do |seq|
|
128
|
+
self.each do |v|
|
129
|
+
seq.add( Hash[ *v ] )
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Builtin collection: !pairs
|
138
|
+
#
|
139
|
+
class Pairs < ::Array
|
140
|
+
yaml_as "tag:yaml.org,2002:pairs"
|
141
|
+
def yaml_initialize( tag, val )
|
142
|
+
if Array === val
|
143
|
+
val.each do |v|
|
144
|
+
if Hash === v
|
145
|
+
concat( v.to_a ) # Convert the map to a sequence
|
146
|
+
else
|
147
|
+
raise ::Syck::Error, "Invalid !pairs entry: " + val.inspect
|
148
|
+
end
|
149
|
+
end
|
150
|
+
else
|
151
|
+
raise ::Syck::Error, "Invalid !pairs: " + val.inspect
|
152
|
+
end
|
153
|
+
self
|
154
|
+
end
|
155
|
+
def self.[]( *vals )
|
156
|
+
p = Pairs.new
|
157
|
+
0.step( vals.length - 1, 2 ) { |i|
|
158
|
+
p[vals[i]] = vals[i+1]
|
159
|
+
}
|
160
|
+
p
|
161
|
+
end
|
162
|
+
def []( k )
|
163
|
+
self.assoc( k ).to_a
|
164
|
+
end
|
165
|
+
def []=( k, val )
|
166
|
+
self << [ k, val ]
|
167
|
+
val
|
168
|
+
end
|
169
|
+
def has_key?( k )
|
170
|
+
self.assoc( k ) ? true : false
|
171
|
+
end
|
172
|
+
def is_complex_yaml?
|
173
|
+
true
|
174
|
+
end
|
175
|
+
def to_yaml( opts = {} )
|
176
|
+
::Syck.quick_emit( self, opts ) do |out|
|
177
|
+
out.seq( taguri, to_yaml_style ) do |seq|
|
178
|
+
self.each do |v|
|
179
|
+
seq.add( Hash[ *v ] )
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# Builtin collection: !set
|
188
|
+
#
|
189
|
+
class Set < ::Hash
|
190
|
+
yaml_as "tag:yaml.org,2002:set"
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# YAML::YamlNode class
|
3
|
+
#
|
4
|
+
require 'syck/basenode'
|
5
|
+
|
6
|
+
module Syck
|
7
|
+
|
8
|
+
#
|
9
|
+
# YAML Generic Model container
|
10
|
+
#
|
11
|
+
class YamlNode
|
12
|
+
include BaseNode
|
13
|
+
attr_accessor :kind, :type_id, :value, :anchor
|
14
|
+
def initialize(t, v)
|
15
|
+
@type_id = t
|
16
|
+
if Hash === v
|
17
|
+
@kind = 'map'
|
18
|
+
@value = {}
|
19
|
+
v.each {|key,val|
|
20
|
+
@value[key.transform] = [key, val]
|
21
|
+
}
|
22
|
+
elsif Array === v
|
23
|
+
@kind = 'seq'
|
24
|
+
@value = v
|
25
|
+
elsif String === v
|
26
|
+
@kind = 'scalar'
|
27
|
+
@value = v
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Transform this node fully into a native type
|
33
|
+
#
|
34
|
+
def transform
|
35
|
+
t = nil
|
36
|
+
if @value.is_a? Hash
|
37
|
+
t = {}
|
38
|
+
@value.each { |k,v|
|
39
|
+
t[ k ] = v[1].transform
|
40
|
+
}
|
41
|
+
elsif @value.is_a? Array
|
42
|
+
t = []
|
43
|
+
@value.each { |v|
|
44
|
+
t.push v.transform
|
45
|
+
}
|
46
|
+
else
|
47
|
+
t = @value
|
48
|
+
end
|
49
|
+
Syck.transfer_method( @type_id, t )
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|