rubysl-syck 2.0.1 → 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,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
+