rubysl-yaml 2.0.0 → 2.0.2

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.
@@ -0,0 +1,45 @@
1
+ #
2
+ # Constants used throughout the library
3
+ #
4
+ module Syck
5
+
6
+ #
7
+ # Constants
8
+ #
9
+ VERSION = '0.60'
10
+ SUPPORTED_YAML_VERSIONS = ['1.0']
11
+
12
+ #
13
+ # Parser tokens
14
+ #
15
+ WORD_CHAR = 'A-Za-z0-9'
16
+ PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
17
+ NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
18
+ ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]'
19
+ INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
20
+ SPACE_INDICATORS = '-#:,?'
21
+ RESTRICTED_INDICATORS = '#:,}]'
22
+ DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
23
+ DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
24
+ ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a
25
+ \x08 \t \n \v \f \r \x0e \x0f
26
+ \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
27
+ \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
28
+ }
29
+ UNESCAPES = {
30
+ 'a' => "\x07", 'b' => "\x08", 't' => "\x09",
31
+ 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
32
+ 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
33
+ }
34
+
35
+ #
36
+ # Default settings
37
+ #
38
+ DEFAULTS = {
39
+ :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
40
+ :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
41
+ :WidthType => 'absolute', :BestWidth => 80,
42
+ :UseBlock => false, :UseFold => false, :Encoding => :None
43
+ }
44
+
45
+ end
@@ -0,0 +1,35 @@
1
+ #
2
+ # Handle Unicode-to-Internal conversion
3
+ #
4
+
5
+ module Syck
6
+
7
+ #
8
+ # Escape the string, condensing common escapes
9
+ #
10
+ def self.escape( value, skip = "" )
11
+ warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE
12
+ value.gsub( /\\/, "\\\\\\" ).
13
+ gsub( /"/, "\\\"" ).
14
+ gsub( /([\x00-\x1f])/ ) do
15
+ skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
16
+ end
17
+ end
18
+
19
+ #
20
+ # Unescape the condenses escapes
21
+ #
22
+ def self.unescape( value )
23
+ warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE
24
+ value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
25
+ if $3
26
+ ["#$3".hex ].pack('U*')
27
+ elsif $2
28
+ [$2].pack( "H2" )
29
+ else
30
+ UNESCAPES[$1]
31
+ end
32
+ }
33
+ end
34
+
35
+ end
data/lib/syck/error.rb ADDED
@@ -0,0 +1,34 @@
1
+ #
2
+ # Error messages and exception class
3
+ #
4
+
5
+ module Syck
6
+
7
+ #
8
+ # Error messages
9
+ #
10
+
11
+ ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
12
+ ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
13
+ ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
14
+ ERROR_MANY_EXPLICIT = "More than one explicit transfer"
15
+ ERROR_MANY_IMPLICIT = "More than one implicit request"
16
+ ERROR_NO_ANCHOR = "No anchor for alias '%s'"
17
+ ERROR_BAD_ANCHOR = "Invalid anchor: %s"
18
+ ERROR_MANY_ANCHOR = "More than one anchor"
19
+ ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
20
+ ERROR_BAD_ALIAS = "Invalid alias: %s"
21
+ ERROR_MANY_ALIAS = "More than one alias"
22
+ ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
23
+ ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
24
+ ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
25
+
26
+ #
27
+ # YAML Error classes
28
+ #
29
+
30
+ class Error < StandardError; end
31
+ class ParseError < Error; end
32
+ class TypeError < StandardError; end
33
+
34
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # YAML::Loader class
3
+ # .. type handling ..
4
+ #
5
+ module Syck
6
+ class Loader
7
+ TRANSFER_DOMAINS = {
8
+ 'yaml.org,2002' => {},
9
+ 'ruby.yaml.org,2002' => {}
10
+ }
11
+ PRIVATE_TYPES = {}
12
+ IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
13
+ end
14
+ end
@@ -0,0 +1,467 @@
1
+ # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
2
+ require 'date'
3
+
4
+ class Class
5
+ def to_yaml( opts = {} )
6
+ raise TypeError, "can't dump anonymous class %s" % self.class
7
+ end
8
+ end
9
+
10
+ class Object
11
+ yaml_as "tag:ruby.yaml.org,2002:object"
12
+ def to_yaml_style; end
13
+ undef to_yaml_properties rescue nil
14
+ def to_yaml_properties; instance_variables.sort; end
15
+ def to_yaml( opts = {} )
16
+ YAML::quick_emit( self, opts ) do |out|
17
+ out.map( taguri, to_yaml_style ) do |map|
18
+ to_yaml_properties.each do |m|
19
+ map.add( m[1..-1], instance_variable_get( m ) )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ alias :syck_to_yaml :to_yaml
25
+ end
26
+
27
+ class Hash
28
+ yaml_as "tag:ruby.yaml.org,2002:hash"
29
+ yaml_as "tag:yaml.org,2002:map"
30
+ def yaml_initialize( tag, val )
31
+ if Array === val
32
+ update Hash.[]( *val ) # Convert the map to a sequence
33
+ elsif Hash === val
34
+ update val
35
+ else
36
+ raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
37
+ end
38
+ end
39
+ def to_yaml( opts = {} )
40
+ return super unless YAML::ENGINE.syck?
41
+ YAML::quick_emit( self, opts ) do |out|
42
+ out.map( taguri, to_yaml_style ) do |map|
43
+ each do |k, v|
44
+ map.add( k, v )
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ class Struct
52
+ yaml_as "tag:ruby.yaml.org,2002:struct"
53
+ def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
54
+ def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
55
+ def self.yaml_new( klass, tag, val )
56
+ if Hash === val
57
+ struct_type = nil
58
+
59
+ #
60
+ # Use existing Struct if it exists
61
+ #
62
+ props = {}
63
+ val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
64
+ begin
65
+ struct_type = YAML.read_type_class( tag, Struct ).last
66
+ rescue NameError
67
+ end
68
+ if not struct_type
69
+ struct_def = [ tag.split( ':', 4 ).last ]
70
+ struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
71
+ end
72
+
73
+ #
74
+ # Set the Struct properties
75
+ #
76
+ st = YAML::object_maker( struct_type, {} )
77
+ st.members.each do |m|
78
+ st.send( "#{m}=", val[m.to_s] )
79
+ end
80
+ props.each do |k,v|
81
+ st.instance_variable_set(k, v)
82
+ end
83
+ st
84
+ else
85
+ raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect
86
+ end
87
+ end
88
+ def to_yaml( opts = {} )
89
+ return super unless YAML::ENGINE.syck?
90
+ YAML::quick_emit( self, opts ) do |out|
91
+ #
92
+ # Basic struct is passed as a YAML map
93
+ #
94
+ out.map( taguri, to_yaml_style ) do |map|
95
+ self.members.each do |m|
96
+ map.add( m.to_s, self[m.to_s] )
97
+ end
98
+ self.to_yaml_properties.each do |m|
99
+ map.add( m, instance_variable_get( m ) )
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ class Array
107
+ yaml_as "tag:ruby.yaml.org,2002:array"
108
+ yaml_as "tag:yaml.org,2002:seq"
109
+ def yaml_initialize( tag, val ); concat( val.to_a ); end
110
+ def to_yaml( opts = {} )
111
+ return super unless YAML::ENGINE.syck?
112
+ YAML::quick_emit( self, opts ) do |out|
113
+ out.seq( taguri, to_yaml_style ) do |seq|
114
+ each do |x|
115
+ seq.add( x )
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ class Exception
123
+ yaml_as "tag:ruby.yaml.org,2002:exception"
124
+ def Exception.yaml_new( klass, tag, val )
125
+ o = klass.allocate
126
+ Exception.instance_method(:initialize).bind(o).call(val.delete('message'))
127
+ val.each_pair do |k,v|
128
+ o.instance_variable_set("@#{k}", v)
129
+ end
130
+ o
131
+ end
132
+ def to_yaml( opts = {} )
133
+ return super unless YAML::ENGINE.syck?
134
+ YAML::quick_emit( self, opts ) do |out|
135
+ out.map( taguri, to_yaml_style ) do |map|
136
+ map.add( 'message', message )
137
+ to_yaml_properties.each do |m|
138
+ map.add( m[1..-1], instance_variable_get( m ) )
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ class String
146
+ yaml_as "tag:ruby.yaml.org,2002:string"
147
+ yaml_as "tag:yaml.org,2002:binary"
148
+ yaml_as "tag:yaml.org,2002:str"
149
+ def is_complex_yaml?
150
+ to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
151
+ end
152
+ def is_binary_data?
153
+ self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty?
154
+ end
155
+ def String.yaml_new( klass, tag, val )
156
+ val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
157
+ val = { 'str' => val } if String === val
158
+ if Hash === val
159
+ s = klass.allocate
160
+ # Thank you, NaHi
161
+ String.instance_method(:initialize).
162
+ bind(s).
163
+ call( val.delete( 'str' ) )
164
+ val.each { |k,v| s.instance_variable_set( k, v ) }
165
+ s
166
+ else
167
+ raise YAML::TypeError, "Invalid String: " + val.inspect
168
+ end
169
+ end
170
+ def to_yaml( opts = {} )
171
+ return super unless YAML::ENGINE.syck?
172
+ YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
173
+ if is_binary_data?
174
+ out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
175
+ elsif to_yaml_properties.empty?
176
+ out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
177
+ else
178
+ out.map( taguri, to_yaml_style ) do |map|
179
+ map.add( 'str', "#{self}" )
180
+ to_yaml_properties.each do |m|
181
+ map.add( m, instance_variable_get( m ) )
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ class Symbol
190
+ yaml_as "tag:ruby.yaml.org,2002:symbol"
191
+ yaml_as "tag:ruby.yaml.org,2002:sym"
192
+ def Symbol.yaml_new( klass, tag, val )
193
+ if String === val
194
+ val = YAML::load( val ) if val =~ /\A(["']).*\1\z/
195
+ val.intern
196
+ else
197
+ raise YAML::TypeError, "Invalid Symbol: " + val.inspect
198
+ end
199
+ end
200
+ def to_yaml( opts = {} )
201
+ return super unless YAML::ENGINE.syck?
202
+ YAML::quick_emit( nil, opts ) do |out|
203
+ out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
204
+ end
205
+ end
206
+ end
207
+
208
+ class Range
209
+ yaml_as "tag:ruby.yaml.org,2002:range"
210
+ def Range.yaml_new( klass, tag, val )
211
+ inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
212
+ opts = {}
213
+ if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
214
+ r1, rdots, r2 = $1, $2, $3
215
+ opts = {
216
+ 'begin' => YAML.load( "--- #{r1}" ),
217
+ 'end' => YAML.load( "--- #{r2}" ),
218
+ 'excl' => rdots.length == 3
219
+ }
220
+ val = {}
221
+ elsif Hash === val
222
+ opts['begin'] = val.delete('begin')
223
+ opts['end'] = val.delete('end')
224
+ opts['excl'] = val.delete('excl')
225
+ end
226
+ if Hash === opts
227
+ r = YAML::object_maker( klass, {} )
228
+ # Thank you, NaHi
229
+ Range.instance_method(:initialize).
230
+ bind(r).
231
+ call( opts['begin'], opts['end'], opts['excl'] )
232
+ val.each { |k,v| r.instance_variable_set( k, v ) }
233
+ r
234
+ else
235
+ raise YAML::TypeError, "Invalid Range: " + val.inspect
236
+ end
237
+ end
238
+ def to_yaml( opts = {} )
239
+ return super unless YAML::ENGINE.syck?
240
+ YAML::quick_emit( self, opts ) do |out|
241
+ # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
242
+ # self.end.is_complex_yaml? or self.end.respond_to? :to_str or
243
+ # not to_yaml_properties.empty?
244
+ out.map( taguri, to_yaml_style ) do |map|
245
+ map.add( 'begin', self.begin )
246
+ map.add( 'end', self.end )
247
+ map.add( 'excl', self.exclude_end? )
248
+ to_yaml_properties.each do |m|
249
+ map.add( m, instance_variable_get( m ) )
250
+ end
251
+ end
252
+ # else
253
+ # out.scalar( taguri ) do |sc|
254
+ # sc.embed( self.begin )
255
+ # sc.concat( self.exclude_end? ? "..." : ".." )
256
+ # sc.embed( self.end )
257
+ # end
258
+ # end
259
+ end
260
+ end
261
+ end
262
+
263
+ class Regexp
264
+ yaml_as "tag:ruby.yaml.org,2002:regexp"
265
+ def Regexp.yaml_new( klass, tag, val )
266
+ if String === val and val =~ /^\/(.*)\/([mixn]*)$/
267
+ val = { 'regexp' => $1, 'mods' => $2 }
268
+ end
269
+ if Hash === val
270
+ mods = nil
271
+ unless val['mods'].to_s.empty?
272
+ mods = 0x00
273
+ mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
274
+ mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
275
+ mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
276
+ mods |= Regexp::NOENCODING if val['mods'].include?( 'n' )
277
+ end
278
+ val.delete( 'mods' )
279
+ r = YAML::object_maker( klass, {} )
280
+ Regexp.instance_method(:initialize).
281
+ bind(r).
282
+ call( val.delete( 'regexp' ), mods )
283
+ val.each { |k,v| r.instance_variable_set( k, v ) }
284
+ r
285
+ else
286
+ raise YAML::TypeError, "Invalid Regular expression: " + val.inspect
287
+ end
288
+ end
289
+ def to_yaml( opts = {} )
290
+ return super unless YAML::ENGINE.syck?
291
+ YAML::quick_emit( nil, opts ) do |out|
292
+ if to_yaml_properties.empty?
293
+ out.scalar( taguri, self.inspect, :plain )
294
+ else
295
+ out.map( taguri, to_yaml_style ) do |map|
296
+ src = self.inspect
297
+ if src =~ /\A\/(.*)\/([a-z]*)\Z/
298
+ map.add( 'regexp', $1 )
299
+ map.add( 'mods', $2 )
300
+ else
301
+ raise YAML::TypeError, "Invalid Regular expression: " + src
302
+ end
303
+ to_yaml_properties.each do |m|
304
+ map.add( m, instance_variable_get( m ) )
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ class Time
313
+ yaml_as "tag:ruby.yaml.org,2002:time"
314
+ yaml_as "tag:yaml.org,2002:timestamp"
315
+ def Time.yaml_new( klass, tag, val )
316
+ if Hash === val
317
+ t = val.delete( 'at' )
318
+ val.each { |k,v| t.instance_variable_set( k, v ) }
319
+ t
320
+ else
321
+ raise YAML::TypeError, "Invalid Time: " + val.inspect
322
+ end
323
+ end
324
+ def to_yaml( opts = {} )
325
+ return super unless YAML::ENGINE.syck?
326
+ YAML::quick_emit( self, opts ) do |out|
327
+ tz = "Z"
328
+ # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
329
+ unless self.utc?
330
+ utc_same_instant = self.dup.utc
331
+ utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
332
+ difference_to_utc = utc_same_writing - utc_same_instant
333
+ if (difference_to_utc < 0)
334
+ difference_sign = '-'
335
+ absolute_difference = -difference_to_utc
336
+ else
337
+ difference_sign = '+'
338
+ absolute_difference = difference_to_utc
339
+ end
340
+ difference_minutes = (absolute_difference/60).round
341
+ tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
342
+ end
343
+ standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
344
+ standard += ".%06d" % [usec] if usec.nonzero?
345
+ standard += " %s" % [tz]
346
+ if to_yaml_properties.empty?
347
+ out.scalar( taguri, standard, :plain )
348
+ else
349
+ out.map( taguri, to_yaml_style ) do |map|
350
+ map.add( 'at', standard )
351
+ to_yaml_properties.each do |m|
352
+ map.add( m, instance_variable_get( m ) )
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
359
+
360
+ class Date
361
+ yaml_as "tag:yaml.org,2002:timestamp#ymd"
362
+ def to_yaml( opts = {} )
363
+ return super unless YAML::ENGINE.syck?
364
+ YAML::quick_emit( self, opts ) do |out|
365
+ out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
366
+ end
367
+ end
368
+ end
369
+
370
+ class Integer
371
+ yaml_as "tag:yaml.org,2002:int"
372
+ def to_yaml( opts = {} )
373
+ return super unless YAML::ENGINE.syck?
374
+ YAML::quick_emit( nil, opts ) do |out|
375
+ out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
376
+ end
377
+ end
378
+ end
379
+
380
+ class Float
381
+ yaml_as "tag:yaml.org,2002:float"
382
+ def to_yaml( opts = {} )
383
+ return super unless YAML::ENGINE.syck?
384
+ YAML::quick_emit( nil, opts ) do |out|
385
+ str = self.to_s
386
+ if str == "Infinity"
387
+ str = ".Inf"
388
+ elsif str == "-Infinity"
389
+ str = "-.Inf"
390
+ elsif str == "NaN"
391
+ str = ".NaN"
392
+ end
393
+ out.scalar( "tag:yaml.org,2002:float", str, :plain )
394
+ end
395
+ end
396
+ end
397
+
398
+ class Rational
399
+ yaml_as "tag:ruby.yaml.org,2002:object:Rational"
400
+ def Rational.yaml_new( klass, tag, val )
401
+ if val.is_a? String
402
+ Rational( val )
403
+ else
404
+ Rational( val['numerator'], val['denominator'] )
405
+ end
406
+ end
407
+ def to_yaml( opts = {} )
408
+ return super unless YAML::ENGINE.syck?
409
+ YAML::quick_emit( self, opts ) do |out|
410
+ out.map( taguri, nil ) do |map|
411
+ map.add( 'denominator', denominator )
412
+ map.add( 'numerator', numerator )
413
+ end
414
+ end
415
+ end
416
+ end
417
+
418
+ class Complex
419
+ yaml_as "tag:ruby.yaml.org,2002:object:Complex"
420
+ def Complex.yaml_new( klass, tag, val )
421
+ if val.is_a? String
422
+ Complex( val )
423
+ else
424
+ Complex( val['real'], val['image'] )
425
+ end
426
+ end
427
+ def to_yaml( opts = {} )
428
+ return super unless YAML::ENGINE.syck?
429
+ YAML::quick_emit( self, opts ) do |out|
430
+ out.map( taguri, nil ) do |map|
431
+ map.add( 'image', imaginary )
432
+ map.add( 'real', real )
433
+ end
434
+ end
435
+ end
436
+ end
437
+
438
+ class TrueClass
439
+ yaml_as "tag:yaml.org,2002:bool#yes"
440
+ def to_yaml( opts = {} )
441
+ return super unless YAML::ENGINE.syck?
442
+ YAML::quick_emit( nil, opts ) do |out|
443
+ out.scalar( taguri, "true", :plain )
444
+ end
445
+ end
446
+ end
447
+
448
+ class FalseClass
449
+ yaml_as "tag:yaml.org,2002:bool#no"
450
+ def to_yaml( opts = {} )
451
+ return super unless YAML::ENGINE.syck?
452
+ YAML::quick_emit( nil, opts ) do |out|
453
+ out.scalar( taguri, "false", :plain )
454
+ end
455
+ end
456
+ end
457
+
458
+ class NilClass
459
+ yaml_as "tag:yaml.org,2002:null"
460
+ def to_yaml( opts = {} )
461
+ return super unless YAML::ENGINE.syck?
462
+ YAML::quick_emit( nil, opts ) do |out|
463
+ out.scalar( taguri, "", :plain )
464
+ end
465
+ end
466
+ end
467
+