rubysl-yaml 2.0.0 → 2.0.2

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