syck 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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