rubysl-syck 2.0.1 → 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,466 @@
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 = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } )
126
+ val.each_pair do |k,v|
127
+ o.instance_variable_set("@#{k}", v)
128
+ end
129
+ o
130
+ end
131
+ def to_yaml( opts = {} )
132
+ return super unless YAML::ENGINE.syck?
133
+ YAML::quick_emit( self, opts ) do |out|
134
+ out.map( taguri, to_yaml_style ) do |map|
135
+ map.add( 'message', message )
136
+ to_yaml_properties.each do |m|
137
+ map.add( m[1..-1], instance_variable_get( m ) )
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ class String
145
+ yaml_as "tag:ruby.yaml.org,2002:string"
146
+ yaml_as "tag:yaml.org,2002:binary"
147
+ yaml_as "tag:yaml.org,2002:str"
148
+ def is_complex_yaml?
149
+ to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
150
+ end
151
+ def is_binary_data?
152
+ self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty?
153
+ end
154
+ def String.yaml_new( klass, tag, val )
155
+ val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
156
+ val = { 'str' => val } if String === val
157
+ if Hash === val
158
+ s = klass.allocate
159
+ # Thank you, NaHi
160
+ String.instance_method(:initialize).
161
+ bind(s).
162
+ call( val.delete( 'str' ) )
163
+ val.each { |k,v| s.instance_variable_set( k, v ) }
164
+ s
165
+ else
166
+ raise YAML::TypeError, "Invalid String: " + val.inspect
167
+ end
168
+ end
169
+ def to_yaml( opts = {} )
170
+ return super unless YAML::ENGINE.syck?
171
+ YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
172
+ if is_binary_data?
173
+ out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
174
+ elsif to_yaml_properties.empty?
175
+ out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
176
+ else
177
+ out.map( taguri, to_yaml_style ) do |map|
178
+ map.add( 'str', "#{self}" )
179
+ to_yaml_properties.each do |m|
180
+ map.add( m, instance_variable_get( m ) )
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ class Symbol
189
+ yaml_as "tag:ruby.yaml.org,2002:symbol"
190
+ yaml_as "tag:ruby.yaml.org,2002:sym"
191
+ def Symbol.yaml_new( klass, tag, val )
192
+ if String === val
193
+ val = YAML::load( val ) if val =~ /\A(["']).*\1\z/
194
+ val.intern
195
+ else
196
+ raise YAML::TypeError, "Invalid Symbol: " + val.inspect
197
+ end
198
+ end
199
+ def to_yaml( opts = {} )
200
+ return super unless YAML::ENGINE.syck?
201
+ YAML::quick_emit( nil, opts ) do |out|
202
+ out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
203
+ end
204
+ end
205
+ end
206
+
207
+ class Range
208
+ yaml_as "tag:ruby.yaml.org,2002:range"
209
+ def Range.yaml_new( klass, tag, val )
210
+ inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
211
+ opts = {}
212
+ if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
213
+ r1, rdots, r2 = $1, $2, $3
214
+ opts = {
215
+ 'begin' => YAML.load( "--- #{r1}" ),
216
+ 'end' => YAML.load( "--- #{r2}" ),
217
+ 'excl' => rdots.length == 3
218
+ }
219
+ val = {}
220
+ elsif Hash === val
221
+ opts['begin'] = val.delete('begin')
222
+ opts['end'] = val.delete('end')
223
+ opts['excl'] = val.delete('excl')
224
+ end
225
+ if Hash === opts
226
+ r = YAML::object_maker( klass, {} )
227
+ # Thank you, NaHi
228
+ Range.instance_method(:initialize).
229
+ bind(r).
230
+ call( opts['begin'], opts['end'], opts['excl'] )
231
+ val.each { |k,v| r.instance_variable_set( k, v ) }
232
+ r
233
+ else
234
+ raise YAML::TypeError, "Invalid Range: " + val.inspect
235
+ end
236
+ end
237
+ def to_yaml( opts = {} )
238
+ return super unless YAML::ENGINE.syck?
239
+ YAML::quick_emit( self, opts ) do |out|
240
+ # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
241
+ # self.end.is_complex_yaml? or self.end.respond_to? :to_str or
242
+ # not to_yaml_properties.empty?
243
+ out.map( taguri, to_yaml_style ) do |map|
244
+ map.add( 'begin', self.begin )
245
+ map.add( 'end', self.end )
246
+ map.add( 'excl', self.exclude_end? )
247
+ to_yaml_properties.each do |m|
248
+ map.add( m, instance_variable_get( m ) )
249
+ end
250
+ end
251
+ # else
252
+ # out.scalar( taguri ) do |sc|
253
+ # sc.embed( self.begin )
254
+ # sc.concat( self.exclude_end? ? "..." : ".." )
255
+ # sc.embed( self.end )
256
+ # end
257
+ # end
258
+ end
259
+ end
260
+ end
261
+
262
+ class Regexp
263
+ yaml_as "tag:ruby.yaml.org,2002:regexp"
264
+ def Regexp.yaml_new( klass, tag, val )
265
+ if String === val and val =~ /^\/(.*)\/([mixn]*)$/
266
+ val = { 'regexp' => $1, 'mods' => $2 }
267
+ end
268
+ if Hash === val
269
+ mods = nil
270
+ unless val['mods'].to_s.empty?
271
+ mods = 0x00
272
+ mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
273
+ mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
274
+ mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
275
+ mods |= Regexp::NOENCODING if val['mods'].include?( 'n' )
276
+ end
277
+ val.delete( 'mods' )
278
+ r = YAML::object_maker( klass, {} )
279
+ Regexp.instance_method(:initialize).
280
+ bind(r).
281
+ call( val.delete( 'regexp' ), mods )
282
+ val.each { |k,v| r.instance_variable_set( k, v ) }
283
+ r
284
+ else
285
+ raise YAML::TypeError, "Invalid Regular expression: " + val.inspect
286
+ end
287
+ end
288
+ def to_yaml( opts = {} )
289
+ return super unless YAML::ENGINE.syck?
290
+ YAML::quick_emit( nil, opts ) do |out|
291
+ if to_yaml_properties.empty?
292
+ out.scalar( taguri, self.inspect, :plain )
293
+ else
294
+ out.map( taguri, to_yaml_style ) do |map|
295
+ src = self.inspect
296
+ if src =~ /\A\/(.*)\/([a-z]*)\Z/
297
+ map.add( 'regexp', $1 )
298
+ map.add( 'mods', $2 )
299
+ else
300
+ raise YAML::TypeError, "Invalid Regular expression: " + src
301
+ end
302
+ to_yaml_properties.each do |m|
303
+ map.add( m, instance_variable_get( m ) )
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
310
+
311
+ class Time
312
+ yaml_as "tag:ruby.yaml.org,2002:time"
313
+ yaml_as "tag:yaml.org,2002:timestamp"
314
+ def Time.yaml_new( klass, tag, val )
315
+ if Hash === val
316
+ t = val.delete( 'at' )
317
+ val.each { |k,v| t.instance_variable_set( k, v ) }
318
+ t
319
+ else
320
+ raise YAML::TypeError, "Invalid Time: " + val.inspect
321
+ end
322
+ end
323
+ def to_yaml( opts = {} )
324
+ return super unless YAML::ENGINE.syck?
325
+ YAML::quick_emit( self, opts ) do |out|
326
+ tz = "Z"
327
+ # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
328
+ unless self.utc?
329
+ utc_same_instant = self.dup.utc
330
+ utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
331
+ difference_to_utc = utc_same_writing - utc_same_instant
332
+ if (difference_to_utc < 0)
333
+ difference_sign = '-'
334
+ absolute_difference = -difference_to_utc
335
+ else
336
+ difference_sign = '+'
337
+ absolute_difference = difference_to_utc
338
+ end
339
+ difference_minutes = (absolute_difference/60).round
340
+ tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
341
+ end
342
+ standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
343
+ standard += ".%06d" % [usec] if usec.nonzero?
344
+ standard += " %s" % [tz]
345
+ if to_yaml_properties.empty?
346
+ out.scalar( taguri, standard, :plain )
347
+ else
348
+ out.map( taguri, to_yaml_style ) do |map|
349
+ map.add( 'at', standard )
350
+ to_yaml_properties.each do |m|
351
+ map.add( m, instance_variable_get( m ) )
352
+ end
353
+ end
354
+ end
355
+ end
356
+ end
357
+ end
358
+
359
+ class Date
360
+ yaml_as "tag:yaml.org,2002:timestamp#ymd"
361
+ def to_yaml( opts = {} )
362
+ return super unless YAML::ENGINE.syck?
363
+ YAML::quick_emit( self, opts ) do |out|
364
+ out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
365
+ end
366
+ end
367
+ end
368
+
369
+ class Integer
370
+ yaml_as "tag:yaml.org,2002:int"
371
+ def to_yaml( opts = {} )
372
+ return super unless YAML::ENGINE.syck?
373
+ YAML::quick_emit( nil, opts ) do |out|
374
+ out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
375
+ end
376
+ end
377
+ end
378
+
379
+ class Float
380
+ yaml_as "tag:yaml.org,2002:float"
381
+ def to_yaml( opts = {} )
382
+ return super unless YAML::ENGINE.syck?
383
+ YAML::quick_emit( nil, opts ) do |out|
384
+ str = self.to_s
385
+ if str == "Infinity"
386
+ str = ".Inf"
387
+ elsif str == "-Infinity"
388
+ str = "-.Inf"
389
+ elsif str == "NaN"
390
+ str = ".NaN"
391
+ end
392
+ out.scalar( "tag:yaml.org,2002:float", str, :plain )
393
+ end
394
+ end
395
+ end
396
+
397
+ class Rational
398
+ yaml_as "tag:ruby.yaml.org,2002:object:Rational"
399
+ def Rational.yaml_new( klass, tag, val )
400
+ if val.is_a? String
401
+ Rational( val )
402
+ else
403
+ Rational( val['numerator'], val['denominator'] )
404
+ end
405
+ end
406
+ def to_yaml( opts = {} )
407
+ return super unless YAML::ENGINE.syck?
408
+ YAML::quick_emit( self, opts ) do |out|
409
+ out.map( taguri, nil ) do |map|
410
+ map.add( 'denominator', denominator )
411
+ map.add( 'numerator', numerator )
412
+ end
413
+ end
414
+ end
415
+ end
416
+
417
+ class Complex
418
+ yaml_as "tag:ruby.yaml.org,2002:object:Complex"
419
+ def Complex.yaml_new( klass, tag, val )
420
+ if val.is_a? String
421
+ Complex( val )
422
+ else
423
+ Complex( val['real'], val['image'] )
424
+ end
425
+ end
426
+ def to_yaml( opts = {} )
427
+ return super unless YAML::ENGINE.syck?
428
+ YAML::quick_emit( self, opts ) do |out|
429
+ out.map( taguri, nil ) do |map|
430
+ map.add( 'image', imaginary )
431
+ map.add( 'real', real )
432
+ end
433
+ end
434
+ end
435
+ end
436
+
437
+ class TrueClass
438
+ yaml_as "tag:yaml.org,2002:bool#yes"
439
+ def to_yaml( opts = {} )
440
+ return super unless YAML::ENGINE.syck?
441
+ YAML::quick_emit( nil, opts ) do |out|
442
+ out.scalar( taguri, "true", :plain )
443
+ end
444
+ end
445
+ end
446
+
447
+ class FalseClass
448
+ yaml_as "tag:yaml.org,2002:bool#no"
449
+ def to_yaml( opts = {} )
450
+ return super unless YAML::ENGINE.syck?
451
+ YAML::quick_emit( nil, opts ) do |out|
452
+ out.scalar( taguri, "false", :plain )
453
+ end
454
+ end
455
+ end
456
+
457
+ class NilClass
458
+ yaml_as "tag:yaml.org,2002:null"
459
+ def to_yaml( opts = {} )
460
+ return super unless YAML::ENGINE.syck?
461
+ YAML::quick_emit( nil, opts ) do |out|
462
+ out.scalar( taguri, "", :plain )
463
+ end
464
+ end
465
+ end
466
+