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.
Files changed (54) hide show
  1. data/.autotest.erb +8 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +6 -0
  4. data/Manifest.txt +52 -0
  5. data/README.rdoc +51 -0
  6. data/Rakefile +32 -0
  7. data/ext/syck/bytecode.c +1165 -0
  8. data/ext/syck/emitter.c +1247 -0
  9. data/ext/syck/extconf.h +3 -0
  10. data/ext/syck/extconf.rb +5 -0
  11. data/ext/syck/gram.c +1894 -0
  12. data/ext/syck/gram.h +79 -0
  13. data/ext/syck/handler.c +173 -0
  14. data/ext/syck/implicit.c +2990 -0
  15. data/ext/syck/node.c +407 -0
  16. data/ext/syck/rubyext.c +2328 -0
  17. data/ext/syck/syck.c +524 -0
  18. data/ext/syck/syck.h +453 -0
  19. data/ext/syck/token.c +2724 -0
  20. data/ext/syck/yaml2byte.c +259 -0
  21. data/ext/syck/yamlbyte.h +171 -0
  22. data/lib/syck.bundle +0 -0
  23. data/lib/syck.rb +447 -0
  24. data/lib/syck/baseemitter.rb +242 -0
  25. data/lib/syck/basenode.rb +222 -0
  26. data/lib/syck/constants.rb +45 -0
  27. data/lib/syck/encoding.rb +35 -0
  28. data/lib/syck/error.rb +34 -0
  29. data/lib/syck/loader.rb +14 -0
  30. data/lib/syck/rubytypes.rb +450 -0
  31. data/lib/syck/stream.rb +41 -0
  32. data/lib/syck/stringio.rb +85 -0
  33. data/lib/syck/syck.rb +16 -0
  34. data/lib/syck/tag.rb +95 -0
  35. data/lib/syck/types.rb +192 -0
  36. data/lib/syck/yamlnode.rb +54 -0
  37. data/lib/syck/ypath.rb +54 -0
  38. data/lib/yaml/syck.rb +14 -0
  39. data/test/helper.rb +2 -0
  40. data/test/test_array.rb +13 -0
  41. data/test/test_boolean.rb +36 -0
  42. data/test/test_class.rb +11 -0
  43. data/test/test_exception.rb +45 -0
  44. data/test/test_hash.rb +24 -0
  45. data/test/test_null.rb +19 -0
  46. data/test/test_omap.rb +55 -0
  47. data/test/test_set.rb +30 -0
  48. data/test/test_string.rb +44 -0
  49. data/test/test_struct.rb +32 -0
  50. data/test/test_symbol.rb +21 -0
  51. data/test/test_time.rb +23 -0
  52. data/test/test_yaml.rb +1403 -0
  53. data/test/test_yaml_properties.rb +63 -0
  54. metadata +187 -0
@@ -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
+
@@ -0,0 +1,16 @@
1
+ #
2
+ # YAML::Syck module
3
+ # .. glues syck and yaml.rb together ..
4
+ #
5
+ require 'syck/basenode'
6
+
7
+ module Syck
8
+
9
+ #
10
+ # Mixin BaseNode functionality
11
+ #
12
+ class Node
13
+ include Syck::BaseNode
14
+ end
15
+
16
+ end
@@ -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
@@ -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