RbYAML 0.1.0 → 0.2.0

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.
Files changed (81) hide show
  1. data/lib/rbyaml.rb +14 -256
  2. data/lib/rbyaml.rb.~1.2.~ +383 -0
  3. data/lib/rbyaml/composer.rb +9 -11
  4. data/lib/rbyaml/{composer.rb.~1.2.~ → composer.rb.~1.3.~} +28 -25
  5. data/lib/rbyaml/constants.rb +95 -0
  6. data/lib/rbyaml/constructor.rb +180 -89
  7. data/lib/rbyaml/{constructor.rb.~1.2.~ → constructor.rb.~1.9.~} +137 -95
  8. data/lib/rbyaml/dumper.rb +12 -9
  9. data/lib/rbyaml/dumper.rb.~1.3.~ +36 -0
  10. data/lib/rbyaml/emitter.rb +14 -28
  11. data/lib/rbyaml/{emitter.rb.~1.2.~ → emitter.rb.~1.6.~} +22 -33
  12. data/lib/rbyaml/error.rb +4 -57
  13. data/lib/rbyaml/error.rb.~1.2.~ +75 -0
  14. data/lib/rbyaml/events.rb +8 -14
  15. data/lib/rbyaml/{events.rb.~1.2.~ → events.rb.~1.4.~} +29 -6
  16. data/lib/rbyaml/nodes.rb +5 -5
  17. data/lib/rbyaml/{nodes.rb.~1.2.~ → nodes.rb.~1.3.~} +13 -9
  18. data/lib/rbyaml/parser.rb +70 -108
  19. data/lib/rbyaml/parser.rb.~1.4.~ +632 -0
  20. data/lib/rbyaml/representer.rb +19 -157
  21. data/lib/rbyaml/representer.rb.old +317 -0
  22. data/lib/rbyaml/{representer.rb.~1.2.~ → representer.rb.~1.5.~} +60 -26
  23. data/lib/rbyaml/resolver.rb +6 -6
  24. data/lib/rbyaml/{resolver.rb.~1.1.~ → resolver.rb.~1.6.~} +20 -20
  25. data/lib/rbyaml/rubytypes.rb +391 -0
  26. data/lib/rbyaml/scanner.rb +123 -225
  27. data/lib/rbyaml/{scanner.rb.~1.2.~ → scanner.rb.~1.5.~} +466 -378
  28. data/lib/rbyaml/serializer.rb +9 -9
  29. data/lib/rbyaml/{serializer.rb.~1.2.~ → serializer.rb.~1.4.~} +19 -17
  30. data/lib/rbyaml/stream.rb +48 -0
  31. data/lib/rbyaml/tag.rb +72 -0
  32. data/lib/rbyaml/tokens.rb +22 -16
  33. data/lib/rbyaml/{tokens.rb.~1.2.~ → tokens.rb.~1.3.~} +44 -4
  34. data/lib/rbyaml/types.rb +146 -0
  35. data/lib/rbyaml/util.rb.~1.3.~ +38 -0
  36. data/lib/rbyaml/yaml.rb +22 -32
  37. data/lib/rbyaml/{yaml.rb.~1.2.~ → yaml.rb.~1.5.~} +17 -17
  38. data/test/load_one.rb +6 -0
  39. data/test/load_one_yaml.rb +6 -0
  40. data/test/output_events.rb +9 -0
  41. data/test/test_add_ctor.rb +51 -0
  42. data/test/test_add_ctor.rb.~1.1.~ +30 -0
  43. data/test/test_bm.rb +2 -2
  44. data/test/test_bm.rb.~1.1.~ +28 -0
  45. data/test/test_gems.rb +10 -0
  46. data/test/test_one.rb.~1.1.~ +5 -0
  47. data/test/test_one_syck.rb +5 -0
  48. data/test/test_rbyaml.rb +63 -32
  49. data/test/test_rbyaml.rb.~1.6.~ +59 -0
  50. data/test/{test_rbyaml.rb.~1.2.~ → test_rbyaml_old.rb} +13 -4
  51. data/test/test_time_events.rb +24 -0
  52. data/test/test_time_nodes.rb +24 -0
  53. data/test/test_time_tokens.rb +24 -0
  54. data/test/yaml/gems_new.yml +147456 -0
  55. data/test/yaml/test1.rb +8 -0
  56. data/test/yaml/test10.rb +14 -0
  57. data/test/yaml/test11.rb +13 -0
  58. data/test/yaml/test12.rb +9 -0
  59. data/test/yaml/test13.rb +9 -0
  60. data/test/yaml/test14.rb +13 -0
  61. data/test/yaml/test15.rb +12 -0
  62. data/test/yaml/test16.rb +11 -0
  63. data/test/yaml/test16.rb.~1.1.~ +11 -0
  64. data/test/yaml/test17.rb +10 -0
  65. data/test/yaml/test18.rb +13 -0
  66. data/test/yaml/test19.rb +9 -0
  67. data/test/yaml/test19.yml +1 -1
  68. data/test/yaml/test2.rb +8 -0
  69. data/test/yaml/test20.rb +11 -0
  70. data/test/yaml/test20.rb.~1.1.~ +9 -0
  71. data/test/yaml/test20.yml +1 -1
  72. data/test/yaml/test3.rb +13 -0
  73. data/test/yaml/test4.rb +13 -0
  74. data/test/yaml/test5.rb +8 -0
  75. data/test/yaml/test6.rb +10 -0
  76. data/test/yaml/test7.rb +15 -0
  77. data/test/yaml/test8.rb +15 -0
  78. data/test/yaml/test9.rb +13 -0
  79. metadata +61 -16
  80. data/lib/rbyaml/dumper.rb.~1.2.~ +0 -43
  81. data/lib/rbyaml/parser.rb.~1.2.~ +0 -494
@@ -3,7 +3,7 @@ require 'rbyaml/events'
3
3
  require 'rbyaml/nodes'
4
4
 
5
5
  module RbYAML
6
- class ComposerError < MarkedYAMLError
6
+ class ComposerError < YAMLError
7
7
  end
8
8
 
9
9
  class Composer
@@ -42,14 +42,14 @@ module RbYAML
42
42
  if @parser.peek_event.__is_alias
43
43
  event = @parser.get_event
44
44
  anchor = event.anchor
45
- raise ComposerError.new(nil, nil, "found undefined alias #{anchor}", event.start_mark) if !@anchors.include?(anchor)
45
+ raise ComposerError.new(nil, "found undefined alias #{anchor}") if !@anchors.include?(anchor)
46
46
  return @anchors[anchor]
47
47
  end
48
48
  event = @parser.peek_event
49
49
  anchor = event.anchor
50
50
  if !anchor.nil?
51
51
  if @anchors.include?(anchor)
52
- raise ComposerError.new("found duplicate anchor #{anchor}; first occurence", @anchors[anchor].start_mark,"second occurence", event.start_mark)
52
+ raise ComposerError.new("found duplicate anchor #{anchor}; first occurence","second occurence")
53
53
  end
54
54
  end
55
55
  @resolver.descend_resolver(parent,index)
@@ -68,7 +68,7 @@ module RbYAML
68
68
  event = @parser.get_event
69
69
  tag = event.tag
70
70
  tag = @resolver.resolve(ScalarNode,event.value,event.implicit) if tag.nil? || tag == "!"
71
- node = ScalarNode.new(tag, event.value,event.start_mark, event.end_mark, event.style)
71
+ node = ScalarNode.new(tag, event.value,event.style)
72
72
  @anchors[anchor] = node if !anchor.nil?
73
73
  node
74
74
  end
@@ -77,15 +77,14 @@ module RbYAML
77
77
  start_event = @parser.get_event
78
78
  tag = start_event.tag
79
79
  tag = @resolver.resolve(SequenceNode,nil,start_event.implicit) if tag.nil? || tag == "!"
80
- node = SequenceNode.new(tag,[],start_event.start_mark,nil,start_event.flow_style)
80
+ node = SequenceNode.new(tag,[],start_event.flow_style)
81
81
  @anchors[anchor] = node if !anchor.nil?
82
82
  index = 0
83
83
  while !@parser.peek_event.__is_sequence_end
84
84
  node.value << compose_node(node,index)
85
85
  index += 1
86
86
  end
87
- end_event = @parser.get_event
88
- node.end_mark = end_event.end_mark
87
+ @parser.get_event
89
88
  node
90
89
  end
91
90
 
@@ -93,19 +92,18 @@ module RbYAML
93
92
  start_event = @parser.get_event
94
93
  tag = start_event.tag
95
94
  tag = @resolver.resolve(MappingNode,nil,start_event.implicit) if tag.nil? || tag == "!"
96
- node = MappingNode.new(tag, {},start_event.start_mark,nil,start_event.flow_style)
95
+ node = MappingNode.new(tag, {},start_event.flow_style)
97
96
  @anchors[anchor] = node if !anchor.nil?
98
97
  while !@parser.peek_event.__is_mapping_end
99
98
  key_event = @parser.peek_event
100
99
  item_key = compose_node(node,nil)
101
100
  if node.value.include?(item_key)
102
- raise ComposerError.new("while composing a mapping", start_event.start_mark,"found duplicate key", key_event.start_mark)
101
+ raise ComposerError.new("while composing a mapping","found duplicate key")
103
102
  end
104
103
  item_value = compose_node(node,item_key)
105
104
  node.value[item_key] = item_value
106
105
  end
107
- end_event = @parser.get_event
108
- node.end_mark = end_event.end_mark
106
+ @parser.get_event
109
107
  node
110
108
  end
111
109
  end
@@ -6,13 +6,15 @@ module RbYAML
6
6
  class ComposerError < MarkedYAMLError
7
7
  end
8
8
 
9
- module Composer
10
- def initialize_composer
9
+ class Composer
10
+ def initialize(parser,resolver)
11
+ @parser = parser
12
+ @resolver = resolver
11
13
  @anchors = {}
12
14
  end
13
15
 
14
16
  def check_node
15
- !check_event(StreamEndEvent)
17
+ !@parser.peek_event.__is_stream_end
16
18
  end
17
19
 
18
20
  def get_node
@@ -25,75 +27,76 @@ module RbYAML
25
27
 
26
28
  def compose_document
27
29
  # Drop the STREAM-START event.
28
- get_event if check_event(StreamStartEvent)
29
- get_event
30
+ @parser.get_event if @parser.peek_event.__is_stream_start
31
+ # Drop the DOCUMENT-START event.
32
+ @parser.get_event
30
33
  # Compose the root node.
31
34
  node = compose_node(nil,nil)
32
35
  # Drop the DOCUMENT-END event.
33
- get_event
36
+ @parser.get_event
34
37
  @anchors = {}
35
38
  node
36
39
  end
37
40
 
38
41
  def compose_node(parent,index)
39
- if check_event(AliasEvent)
40
- event = get_event
42
+ if @parser.peek_event.__is_alias
43
+ event = @parser.get_event
41
44
  anchor = event.anchor
42
45
  raise ComposerError.new(nil, nil, "found undefined alias #{anchor}", event.start_mark) if !@anchors.include?(anchor)
43
46
  return @anchors[anchor]
44
47
  end
45
- event = peek_event
48
+ event = @parser.peek_event
46
49
  anchor = event.anchor
47
50
  if !anchor.nil?
48
51
  if @anchors.include?(anchor)
49
52
  raise ComposerError.new("found duplicate anchor #{anchor}; first occurence", @anchors[anchor].start_mark,"second occurence", event.start_mark)
50
53
  end
51
54
  end
52
- descend_resolver(parent,index)
53
- if check_event(ScalarEvent)
55
+ @resolver.descend_resolver(parent,index)
56
+ if @parser.peek_event.__is_scalar
54
57
  node = compose_scalar_node(anchor)
55
- elsif check_event(SequenceStartEvent)
58
+ elsif @parser.peek_event.__is_sequence_start
56
59
  node = compose_sequence_node(anchor)
57
- elsif check_event(MappingStartEvent)
60
+ elsif @parser.peek_event.__is_mapping_start
58
61
  node = compose_mapping_node(anchor)
59
62
  end
60
- ascend_resolver
63
+ @resolver.ascend_resolver
61
64
  node
62
65
  end
63
66
 
64
67
  def compose_scalar_node(anchor)
65
- event = get_event
68
+ event = @parser.get_event
66
69
  tag = event.tag
67
- tag = resolve(ScalarNode,event.value,event.implicit) if tag.nil? || tag == "!"
70
+ tag = @resolver.resolve(ScalarNode,event.value,event.implicit) if tag.nil? || tag == "!"
68
71
  node = ScalarNode.new(tag, event.value,event.start_mark, event.end_mark, event.style)
69
72
  @anchors[anchor] = node if !anchor.nil?
70
73
  node
71
74
  end
72
75
 
73
76
  def compose_sequence_node(anchor)
74
- start_event = get_event
77
+ start_event = @parser.get_event
75
78
  tag = start_event.tag
76
- tag = resolve(SequenceNode,nil,start_event.implicit) if tag.nil? || tag == "!"
79
+ tag = @resolver.resolve(SequenceNode,nil,start_event.implicit) if tag.nil? || tag == "!"
77
80
  node = SequenceNode.new(tag,[],start_event.start_mark,nil,start_event.flow_style)
78
81
  @anchors[anchor] = node if !anchor.nil?
79
82
  index = 0
80
- while !check_event(SequenceEndEvent)
83
+ while !@parser.peek_event.__is_sequence_end
81
84
  node.value << compose_node(node,index)
82
85
  index += 1
83
86
  end
84
- end_event = get_event
87
+ end_event = @parser.get_event
85
88
  node.end_mark = end_event.end_mark
86
89
  node
87
90
  end
88
91
 
89
92
  def compose_mapping_node(anchor)
90
- start_event = get_event
93
+ start_event = @parser.get_event
91
94
  tag = start_event.tag
92
- tag = resolve(MappingNode,nil,start_event.implicit) if tag.nil? || tag == "!"
95
+ tag = @resolver.resolve(MappingNode,nil,start_event.implicit) if tag.nil? || tag == "!"
93
96
  node = MappingNode.new(tag, {},start_event.start_mark,nil,start_event.flow_style)
94
97
  @anchors[anchor] = node if !anchor.nil?
95
- while !check_event(MappingEndEvent)
96
- key_event = peek_event
98
+ while !@parser.peek_event.__is_mapping_end
99
+ key_event = @parser.peek_event
97
100
  item_key = compose_node(node,nil)
98
101
  if node.value.include?(item_key)
99
102
  raise ComposerError.new("while composing a mapping", start_event.start_mark,"found duplicate key", key_event.start_mark)
@@ -101,7 +104,7 @@ module RbYAML
101
104
  item_value = compose_node(node,item_key)
102
105
  node.value[item_key] = item_value
103
106
  end
104
- end_event = get_event
107
+ end_event = @parser.get_event
105
108
  node.end_mark = end_event.end_mark
106
109
  node
107
110
  end
@@ -0,0 +1,95 @@
1
+ require 'rbyaml/emitter'
2
+ require 'rbyaml/serializer'
3
+ require 'rbyaml/representer'
4
+ require 'rbyaml/resolver'
5
+
6
+ module RbYAML
7
+ #
8
+ # Constants
9
+ #
10
+ VERSION = '0.20'
11
+ SUPPORTED_YAML_VERSIONS = ['1.0','1.1']
12
+
13
+ LINE_BR_REG = /[\n\x85]|(?:\r[^\n])/
14
+ NON_PRINTABLE_RE = /[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\xFF]/
15
+
16
+ ENDING = /^---[\0 \t\r\n\x85]$/
17
+ START = /^\.\.\.[\0 \t\r\n\x85]$/
18
+ NULL_OR_OTHER = "\0 \t\r\n\x85"
19
+ # BEG = /^([^\0 \t\r\n\x85\-?:,\[\]{}#&*!|>'"%@`]|([\-?:][^\0 \t\r\n\x85]))/ #Since current SYCK handles this one wrong, we have to allow backtick right now.
20
+ BEG = /^([^\0 \t\r\n\x85\-?:,\[\]{}#&*!|>'"%@]|([\-?:][^\0 \t\r\n\x85]))/
21
+ NULL_OR_LINEBR = "\0\r\n\x85"
22
+ ALPHA_REG = /[-0-9A-Za-z_]/
23
+ NULL_BL_LINEBR = "\0 \r\n\x85"
24
+ NULL_BL_T_LINEBR = NULL_OR_OTHER
25
+ NON_ALPHA = /[^-0-9A-Za-z_]/
26
+ NON_ALPHA_OR_NUM = "\0 \t\r\n\x85?:,]}%@`"
27
+ NULL_T_BL_LINEBR = NULL_OR_OTHER
28
+ BLANK_T = " \t"
29
+ PLUS_MIN = /[+-]/
30
+ BLANK_OR_LINEBR = " \r\n\x85"
31
+ FULL_LINEBR = "\r\n\x85"
32
+ UNESCAPES = {
33
+ "0" => "\0",
34
+ "a" => "\x07",
35
+ "b" => "\x08",
36
+ "t" => "\x09",
37
+ "\t" => "\x09",
38
+ "n" => "\x0A",
39
+ "v" => "\x0B",
40
+ "f" => "\x0C",
41
+ "r" => "\x0D",
42
+ "e" => "\x1B",
43
+ " " => "\x20",
44
+ '"' => '"',
45
+ "\\" => "\\",
46
+ "N" => "\x85",
47
+ "_" => "\xA0"
48
+ }
49
+
50
+ ESCAPE_CODES = {
51
+ 'x' => 2
52
+ }
53
+
54
+
55
+ ESCAPE_REPLACEMENTS = {
56
+ ?\0 => "0",
57
+ ?\x07 => "a",
58
+ ?\x08 => "b",
59
+ ?\x09 => "t",
60
+ ?\x0A => "n",
61
+ ?\x0B => "v",
62
+ ?\x0C => "f",
63
+ ?\x0D => "r",
64
+ ?\x1B => "e",
65
+ ?" => "\"",
66
+ ?\\ => "\\",
67
+ ?\x85 => "N",
68
+ ?\xA0 => "_"
69
+ }
70
+
71
+ SPACES_AND_STUFF = "'\"\\\0 \t\r\n\x85"
72
+ DOUBLE_ESC = "\"\\"
73
+ NOT_HEXA = /[^0-9A-Fa-f]/
74
+ R_flowzero = /[\0 \t\r\n\x85]|(:[\0 \t\r\n\x28])/
75
+ R_flownonzero = /[\0 \t\r\n\x85\[\]{},:?]/
76
+ S4 = "\0 \t\r\n\x28[]{}"
77
+ END_OR_START = /^(---|\.\.\.)[\0 \t\r\n\x85]$/
78
+ STRANGE_CHR = /[\]\[\-';\/?:@&=+$,.!~*()%\w]/
79
+ HEXA_REG = /[0-9A-Fa-f]/
80
+
81
+ #
82
+ # Default settings
83
+ #
84
+ DEFAULTS = {
85
+ :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.1',
86
+ :ExplicitStart => true, :ExplicitEnd => false,
87
+ :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
88
+ :Canonical => false,
89
+ :WidthType => 'absolute', :BestWidth => 80,
90
+ :UseBlock => false, :UseFold => false, :Encoding => :None,
91
+ :UsePlain => false, :UseSingle => false, :UseDouble => false,
92
+ :Emitter => RbYAML::Emitter, :Serializer => RbYAML::Serializer,
93
+ :Representer => RbYAML::Representer, :Resolver => RbYAML::Resolver
94
+ }
95
+ end
@@ -1,5 +1,7 @@
1
1
  require 'base64'
2
- require 'set'
2
+ require 'date'
3
+
4
+ require 'rbyaml/util'
3
5
 
4
6
  require 'rbyaml/error'
5
7
  require 'rbyaml/nodes'
@@ -13,7 +15,7 @@ end
13
15
 
14
16
  class Proc
15
17
  def __call(obj,*args)
16
- call(*args)
18
+ call(obj,*args)
17
19
  end
18
20
  end
19
21
 
@@ -25,7 +27,7 @@ end
25
27
 
26
28
 
27
29
  module RbYAML
28
- class ConstructorError < MarkedYAMLError
30
+ class ConstructorError < YAMLError
29
31
  end
30
32
 
31
33
  class BaseConstructor
@@ -33,6 +35,31 @@ module RbYAML
33
35
  @@yaml_multi_constructors = {}
34
36
  @@yaml_multi_regexps = {}
35
37
 
38
+ def get_yaml_constructor(key)
39
+ @@yaml_constructors[key]
40
+ end
41
+
42
+ def get_yaml_multi_constructor(key)
43
+ @@yaml_multi_constructors[key]
44
+ end
45
+
46
+ def get_yaml_multi_regexp(key)
47
+ @@yaml_multi_regexps[key]
48
+ end
49
+
50
+ def get_yaml_multi_regexps
51
+ @@yaml_multi_regexps
52
+ end
53
+
54
+ def self.add_constructor(tag, constructor)
55
+ @@yaml_constructors[tag] = constructor
56
+ end
57
+
58
+ def self.add_multi_constructor(tag_prefix, multi_constructor)
59
+ @@yaml_multi_constructors[tag_prefix] = multi_constructor
60
+ @@yaml_multi_regexps[tag_prefix] = Regexp.new("^"+Regexp.escape(tag_prefix))
61
+ end
62
+
36
63
  def initialize(composer)
37
64
  @composer = composer
38
65
  @constructed_objects = {}
@@ -62,107 +89,127 @@ module RbYAML
62
89
  @recursive_objects = {}
63
90
  data
64
91
  end
92
+
93
+ class RecursiveProxy
94
+ attr_writer :value
95
+ def method_missing(*args)
96
+ @value.send(*args)
97
+ end
98
+ def class
99
+ @value.class
100
+ end
101
+ def to_s
102
+ @value.to_s
103
+ end
104
+ end
65
105
 
66
106
  def construct_object(node)
67
107
  return @constructed_objects[node] if @constructed_objects.include?(node)
68
- raise ConstructorError.new(nil,nil,"found recursive nod",node.start_mark) if @recursive_objects.include?(node)
69
- @recursive_objects[node] = nil
70
- constructor = @@yaml_constructors[node.tag]
108
+ @constructed_objects[node] = RecursiveProxy.new
109
+ constructor = get_yaml_constructor(node.tag)
71
110
  if !constructor
72
111
  ruby_cls = RbYAML::tagged_classes[node.tag]
73
112
  if ruby_cls && (ruby_cls.method_defined?(:yaml_initialize) || ruby_cls.respond_to?(:yaml_new))
74
- constructor = lambda { |node| send(:construct_ruby_object,ruby_cls,node) }
113
+ constructor = lambda { |obj,node| send(:construct_ruby_object,ruby_cls,node) }
75
114
  else
76
115
  through = true
77
- for tag_prefix,reg in @@yaml_multi_regexps
116
+ for tag_prefix,reg in get_yaml_multi_regexps
78
117
  if reg =~ node.tag
79
118
  tag_suffix = node.tag[tag_prefix.length..-1]
80
- constructor = lambda { |node| @@yaml_multi_constructors[tag_prefix].__call(self,tag_suffix, node) }
119
+ constructor = lambda { |obj, node| get_yaml_multi_constructor(tag_prefix).__call(self,tag_suffix, node) }
81
120
  through = false
82
121
  break
83
122
  end
84
123
  end
85
124
  if through
86
- ctor = @@yaml_multi_constructors[nil] || @@yaml_constructors[nil]
125
+ ctor = get_yaml_multi_constructor(nil)
87
126
  if ctor
88
- constructor = lambda { |node| ctor.__call(self,node.tag,node) }
127
+ constructor = lambda { |obj, node| ctor.__call(self,node.tag,node) }
89
128
  else
90
- constructor = lambda { |node| construct_primitive(node) }
129
+ ctor = get_yaml_constructor(nil)
130
+ if ctor
131
+ constructor = lambda { |obj, node| ctor.__call(self,node)}
132
+ else
133
+ constructor = lambda { |obj, node| construct_primitive(node) }
134
+ end
91
135
  end
92
136
  end
93
137
  end
94
138
  end
95
139
  data = constructor.__call(self,node)
140
+ @constructed_objects[node].value = data
96
141
  @constructed_objects[node] = data
97
- @recursive_objects.delete(node)
98
142
  data
99
143
  end
100
144
 
101
145
  def construct_primitive(node)
102
146
  if node.__is_scalar
103
- construct_scalar(node)
147
+ str(node)
104
148
  elsif node.__is_sequence
105
- construct_sequence(node)
149
+ seq(node)
106
150
  elsif node.__is_mapping
107
- construct_mapping(node)
151
+ map(node)
108
152
  else
109
153
  puts node.tag
110
154
  end
111
155
  end
112
156
 
113
- def construct_scalar(node)
157
+ def str(node)
114
158
  if !node.__is_scalar
115
159
  if node.__is_mapping
116
160
  for key_node in node.value.keys
117
161
  if key_node.tag == "tag:yaml.org,2002:value"
118
- return construct_scalar(node.value[key_node])
162
+ return str(node.value[key_node])
119
163
  end
120
164
  end
121
165
  end
122
- raise ConstructorError.new(nil, nil,"expected a scalar node, but found #{node.tid}",node.start_mark)
166
+ raise ConstructorError.new(nil,"expected a scalar node, but found #{node.tid}")
123
167
  end
124
168
  node.value
125
169
  end
126
170
 
127
- def construct_sequence(node)
128
- raise ConstructorError.new(nil,nil,"expected a sequence node, but found #{node.tid}",node.start_mark) if !node.__is_sequence
171
+ def construct_private_type(node)
172
+ PrivateType.new(node.tag,node.value)
173
+ end
174
+
175
+ def seq(node)
176
+ raise ConstructorError.new(nil,"expected a sequence node, but found #{node.tid}") if !node.__is_sequence
129
177
  node.value.map {|child| construct_object(child) }
130
178
  end
131
179
 
132
- def construct_mapping(node)
133
- raise ConstructorError.new(nil,nil,"expected a mapping node, but found #{node.tid}",node.start_mark) if !node.__is_mapping
180
+ def map(node)
181
+ raise ConstructorError.new(nil,"expected a mapping node, but found #{node.tid}") if !node.__is_mapping
134
182
  mapping = {}
135
183
  merge = nil
136
184
  for key_node,value_node in node.value
137
185
  if key_node.tag == "tag:yaml.org,2002:merge"
138
- raise ConstructorError.new("while constructing a mapping", node.start_mark,"found duplicate merge key", key_node.start_mark) if !merge.nil?
186
+ raise ConstructorError.new("while constructing a mapping","found duplicate merge key") if !merge.nil?
139
187
  if value_node.__is_mapping
140
- merge = [construct_mapping(value_node)]
188
+ merge = [map(value_node)]
141
189
  elsif value_node.__is_sequence
142
190
  merge = []
143
191
  for subnode in value_node.value
144
192
  if !subnode.__is_mapping
145
- raise ConstructorError.new("while constructing a mapping",node.start_mark,"expected a mapping for merging, but found #{subnode.tid}", subnode.start_mark)
193
+ raise ConstructorError.new("while constructing a mapping","expected a mapping for merging, but found #{subnode.tid}")
146
194
  end
147
- merge.unshift(construct_mapping(subnode))
195
+ merge.unshift(map(subnode))
148
196
  end
149
197
  else
150
- raise ConstructorError.new("while constructing a mapping", node.start_mark,"expected a mapping or list of mappings for merging, but found #{value_node.tid}", value_node.start_mark)
198
+ raise ConstructorError.new("while constructing a mapping","expected a mapping or list of mappings for merging, but found #{value_node.tid}")
151
199
  end
152
200
  elsif key_node.tag == "tag:yaml.org,2002:value"
153
- raise ConstructorError.new("while construction a mapping", node.start_mark,"found duplicate value key", key_node.start_mark) if mapping.include?("=")
201
+ raise ConstructorError.new("while construction a mapping","found duplicate value key") if mapping.include?("=")
154
202
  value = construct_object(value_node)
155
203
  mapping["="] = value
156
204
  else
157
205
  key = construct_object(key_node)
158
- # raise ConstructorError.new("while constructing a mapping", node.start_mark,"found duplicate key", key_node.start_mark) if mapping.include?(key)
206
+ value = construct_object(value_node)
207
+ mapping[key] = value
159
208
  end
160
- value = construct_object(value_node)
161
- mapping[key] = value
162
209
  end
163
210
  if !merge.nil?
164
211
  merge << mapping
165
- mapping = {}
212
+ mapping = { }
166
213
  for submapping in merge
167
214
  mapping.merge!(submapping)
168
215
  end
@@ -171,29 +218,49 @@ module RbYAML
171
218
  end
172
219
 
173
220
  def construct_pairs(node)
174
- raise ConstructorError.new(nil,nil,"expected a mapping node, but found #{node.tid}",node.start_mark) if !node.__is_mapping
221
+ raise ConstructorError.new(nil,"expected a mapping node, but found #{node.tid}") if !node.__is_mapping
175
222
  node.value.collect {|key_node,value_node| [construct_object(key_node), construct_object(value_node)] }
176
223
  end
224
+ end
177
225
 
226
+ class SafeConstructor < BaseConstructor
227
+ @@yaml_safe_constructors = {}
228
+ @@yaml_safe_multi_constructors = {}
229
+ @@yaml_safe_multi_regexps = {}
230
+
231
+ def get_yaml_constructor(key)
232
+ @@yaml_safe_constructors[key] || super(key)
233
+ end
234
+
235
+ def get_yaml_multi_constructor(key)
236
+ @@yaml_safe_multi_constructors[key] || super(key)
237
+ end
238
+
239
+ def get_yaml_multi_regexp(key)
240
+ @@yaml_safe_multi_regexps[key] || super(key)
241
+ end
242
+
243
+ def get_yaml_multi_regexps
244
+ super.update(@@yaml_safe_multi_regexps)
245
+ end
246
+
178
247
  def self.add_constructor(tag, constructor)
179
- @@yaml_constructors[tag] = constructor
248
+ @@yaml_safe_constructors[tag] = constructor
180
249
  end
181
250
 
182
251
  def self.add_multi_constructor(tag_prefix, multi_constructor)
183
- @@yaml_multi_constructors[tag_prefix] = multi_constructor
184
- @@yaml_multi_regexps[tag_prefix] = Regexp.new("^"+Regexp.escape(tag_prefix))
252
+ @@yaml_safe_multi_constructors[tag_prefix] = multi_constructor
253
+ @@yaml_safe_multi_regexps[tag_prefix] = Regexp.new("^"+Regexp.escape(tag_prefix))
185
254
  end
186
- end
187
255
 
188
- class SafeConstructor < BaseConstructor
189
256
  def construct_yaml_null(node)
190
- construct_scalar(node)
257
+ str(node)
191
258
  nil
192
259
  end
193
260
 
194
261
  BOOL_VALUES = {
195
- "y" => true,
196
- "n" => false,
262
+ # "y" => true,
263
+ # "n" => false,
197
264
  "yes" => true,
198
265
  "no" => false,
199
266
  "true" => true,
@@ -203,12 +270,12 @@ module RbYAML
203
270
  }
204
271
 
205
272
  def construct_yaml_bool(node)
206
- value = construct_scalar(node)
273
+ value = str(node)
207
274
  BOOL_VALUES[value.downcase]
208
275
  end
209
276
 
210
277
  def construct_yaml_int(node)
211
- value = construct_scalar(node).to_s
278
+ value = str(node).to_s
212
279
  value = value.gsub(/_/, '')
213
280
  sign = +1
214
281
  first = value[0]
@@ -249,7 +316,7 @@ module RbYAML
249
316
  NAN_VALUE = 0.0/0.0
250
317
 
251
318
  def construct_yaml_float(node)
252
- value = construct_scalar(node).to_s
319
+ value = str(node).to_s
253
320
  value = value.gsub(/_/, '')
254
321
  sign = +1
255
322
  first = value[0]
@@ -278,15 +345,22 @@ module RbYAML
278
345
  end
279
346
 
280
347
  def construct_yaml_binary(node)
281
- value = construct_scalar(node)
282
- Base64.decode64(value.to_s)
348
+ value = str(node)
349
+ Base64.decode64(value.split(/[\n\x85]|(?:\r[^\n])/).to_s)
283
350
  end
284
351
 
285
352
  TIMESTAMP_REGEXP = /^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:(?:[Tt]|[ \t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\.([0-9]*))?(?:[ \t]*(?:Z|([-+][0-9][0-9]?)(?::([0-9][0-9])?)?))?)?$/
353
+
354
+ YMD_REGEXP = /^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)$/
286
355
 
287
356
  def construct_yaml_timestamp(node)
288
- value = construct_scalar(node)
289
- match = TIMESTAMP_REGEXP.match(node.value)
357
+ if (match = YMD_REGEXP.match(node.value))
358
+ values = match.captures.map {|val| val.to_i}
359
+ return Date.new(values[0],values[1],values[2])
360
+ end
361
+ unless (match = TIMESTAMP_REGEXP.match(node.value))
362
+ return construct_private_type(node)
363
+ end
290
364
  values = match.captures.map {|val| val.to_i}
291
365
  fraction = values[6]
292
366
  if fraction != 0
@@ -302,14 +376,13 @@ module RbYAML
302
376
  def construct_yaml_omap(node)
303
377
  # Note: we do not check for duplicate keys, because its too
304
378
  # CPU-expensive.
305
- raise ConstructorError.new("while constructing an ordered map", node.start_mark,
306
- "expected a sequence, but found #{node.tid}", node.start_mark) if !node.__is_sequence
379
+ raise ConstructorError.new("while constructing an ordered map","expected a sequence, but found #{node.tid}") if !node.__is_sequence
307
380
  omap = []
308
381
  for subnode in node.value
309
- raise ConstructorError.new("while constructing an ordered map", node.start_mark,
310
- "expected a mapping of length 1, but found #{subnode.tid}",subnode.start_mark) if !subnode.__is_mapping
311
- raise ConstructorError.new("while constructing an ordered map", node.start_mark,
312
- "expected a single mapping item, but found #{subnode.value.length} items",subnode.start_mark) if subnode.value.length != 1
382
+ raise ConstructorError.new("while constructing an ordered map",
383
+ "expected a mapping of length 1, but found #{subnode.tid}") if !subnode.__is_mapping
384
+ raise ConstructorError.new("while constructing an ordered map",
385
+ "expected a single mapping item, but found #{subnode.value.length} items") if subnode.value.length != 1
313
386
  key_node = subnode.value.keys[0]
314
387
  key = construct_object(key_node)
315
388
  value = construct_object(subnode.value[key_node])
@@ -323,69 +396,87 @@ module RbYAML
323
396
  end
324
397
 
325
398
  def construct_yaml_set(node)
326
- Set.new(construct_mapping(node).keys)
399
+ Set.new(map(node).keys)
327
400
  end
328
401
 
329
402
  def construct_yaml_str(node)
330
- construct_scalar(node).to_s
403
+ val = str(node).to_s
404
+ val.empty? ? nil : val
331
405
  end
332
406
 
333
407
  def construct_yaml_seq(node)
334
- construct_sequence(node)
408
+ seq(node)
335
409
  end
336
410
 
337
411
  def construct_yaml_map(node)
338
- construct_mapping(node)
412
+ map(node)
339
413
  end
340
414
 
341
415
  def construct_yaml_object(node, cls)
342
- mapping = construct_mapping(node)
416
+ mapping = map(node)
343
417
  data = cls.new
344
418
  mapping.each {|key,val| data.instance_variable_set("@#{key}",val)}
345
419
  data
346
420
  end
347
421
 
348
422
  def construct_undefined(node)
349
- raise ConstructorError.new(nil,nil,"could not determine a constructor for the tag #{node.tag}",node.start_mark)
423
+ raise ConstructorError.new(nil,"could not determine a constructor for the tag #{node.tag}")
350
424
  end
425
+ end
426
+
427
+ SafeConstructor.add_constructor('tag:yaml.org,2002:null',:construct_yaml_null)
428
+ SafeConstructor.add_constructor('tag:yaml.org,2002:bool',:construct_yaml_bool)
429
+ SafeConstructor.add_constructor('tag:yaml.org,2002:int',:construct_yaml_int)
430
+ SafeConstructor.add_constructor('tag:yaml.org,2002:float',:construct_yaml_float)
431
+ SafeConstructor.add_constructor('tag:yaml.org,2002:binary',:construct_yaml_binary)
432
+ SafeConstructor.add_constructor('tag:yaml.org,2002:timestamp',:construct_yaml_timestamp)
433
+ SafeConstructor.add_constructor('tag:yaml.org,2002:omap',:construct_yaml_omap)
434
+ SafeConstructor.add_constructor('tag:yaml.org,2002:pairs',:construct_yaml_pairs)
435
+ SafeConstructor.add_constructor('tag:yaml.org,2002:set',:construct_yaml_set)
436
+ SafeConstructor.add_constructor('tag:yaml.org,2002:str',:construct_yaml_str)
437
+ SafeConstructor.add_constructor('tag:yaml.org,2002:seq',:construct_yaml_seq)
438
+ SafeConstructor.add_constructor('tag:yaml.org,2002:map',:construct_yaml_map)
439
+ SafeConstructor.add_constructor(nil,:construct_private_type)
351
440
 
352
- def construct_ruby_object(cls,node)
353
- val = construct_primitive(node)
354
- if cls.respond_to?(:yaml_new)
355
- obj = cls.yaml_new(cls,node.tag,val)
356
- else
357
- obj = cls.allocate
358
- obj.yaml_initialize(node.tag,val)
359
- end
360
- obj
441
+ class Constructor < SafeConstructor
442
+ @@yaml_main_constructors = {}
443
+ @@yaml_main_multi_constructors = {}
444
+ @@yaml_main_multi_regexps = {}
445
+
446
+ def get_yaml_constructor(key)
447
+ @@yaml_main_constructors[key] || super(key)
448
+ end
449
+
450
+ def get_yaml_multi_constructor(key)
451
+ @@yaml_main_multi_constructors[key] || super(key)
452
+ end
453
+
454
+ def get_yaml_multi_regexp(key)
455
+ @@yaml_main_multi_regexps[key] || super(key)
456
+ end
457
+
458
+ def get_yaml_multi_regexps
459
+ super.update(@@yaml_main_multi_regexps)
460
+ end
461
+
462
+ def self.add_constructor(tag, constructor)
463
+ @@yaml_main_constructors[tag] = constructor
464
+ end
465
+
466
+ def self.add_multi_constructor(tag_prefix, multi_constructor)
467
+ @@yaml_main_multi_constructors[tag_prefix] = multi_constructor
468
+ @@yaml_main_multi_regexps[tag_prefix] = Regexp.new("^"+Regexp.escape(tag_prefix))
361
469
  end
362
470
 
363
471
  def construct_ruby(tag,node)
364
472
  obj_class = Object
365
473
  tag.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tag
366
474
  o = obj_class.allocate
367
- mapping = construct_mapping(node)
475
+ mapping = map(node)
368
476
  mapping.each {|key,val| o.instance_variable_set("@#{key}",val)}
369
477
  o
370
478
  end
371
479
  end
372
-
373
- SafeConstructor::add_constructor('tag:yaml.org,2002:null',:construct_yaml_null)
374
- BaseConstructor::add_constructor('tag:yaml.org,2002:bool',:construct_yaml_bool)
375
- BaseConstructor::add_constructor('tag:yaml.org,2002:int',:construct_yaml_int)
376
- BaseConstructor::add_constructor('tag:yaml.org,2002:float',:construct_yaml_float)
377
- BaseConstructor::add_constructor('tag:yaml.org,2002:binary',:construct_yaml_binary)
378
- BaseConstructor::add_constructor('tag:yaml.org,2002:timestamp',:construct_yaml_timestamp)
379
- BaseConstructor::add_constructor('tag:yaml.org,2002:omap',:construct_yaml_omap)
380
- BaseConstructor::add_constructor('tag:yaml.org,2002:pairs',:construct_yaml_pairs)
381
- BaseConstructor::add_constructor('tag:yaml.org,2002:set',:construct_yaml_set)
382
- BaseConstructor::add_constructor('tag:yaml.org,2002:str',:construct_yaml_str)
383
- BaseConstructor::add_constructor('tag:yaml.org,2002:seq',:construct_yaml_seq)
384
- BaseConstructor::add_constructor('tag:yaml.org,2002:map',:construct_yaml_map)
385
- BaseConstructor::add_constructor(nil,:construct_undefined)
386
-
387
- BaseConstructor::add_multi_constructor("!ruby/object:",:construct_ruby)
388
480
 
389
- class Constructor < SafeConstructor
390
- end
481
+ Constructor.add_multi_constructor("!ruby/object:",:construct_ruby)
391
482
  end