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.
- data/lib/rbyaml.rb +14 -256
- data/lib/rbyaml.rb.~1.2.~ +383 -0
- data/lib/rbyaml/composer.rb +9 -11
- data/lib/rbyaml/{composer.rb.~1.2.~ → composer.rb.~1.3.~} +28 -25
- data/lib/rbyaml/constants.rb +95 -0
- data/lib/rbyaml/constructor.rb +180 -89
- data/lib/rbyaml/{constructor.rb.~1.2.~ → constructor.rb.~1.9.~} +137 -95
- data/lib/rbyaml/dumper.rb +12 -9
- data/lib/rbyaml/dumper.rb.~1.3.~ +36 -0
- data/lib/rbyaml/emitter.rb +14 -28
- data/lib/rbyaml/{emitter.rb.~1.2.~ → emitter.rb.~1.6.~} +22 -33
- data/lib/rbyaml/error.rb +4 -57
- data/lib/rbyaml/error.rb.~1.2.~ +75 -0
- data/lib/rbyaml/events.rb +8 -14
- data/lib/rbyaml/{events.rb.~1.2.~ → events.rb.~1.4.~} +29 -6
- data/lib/rbyaml/nodes.rb +5 -5
- data/lib/rbyaml/{nodes.rb.~1.2.~ → nodes.rb.~1.3.~} +13 -9
- data/lib/rbyaml/parser.rb +70 -108
- data/lib/rbyaml/parser.rb.~1.4.~ +632 -0
- data/lib/rbyaml/representer.rb +19 -157
- data/lib/rbyaml/representer.rb.old +317 -0
- data/lib/rbyaml/{representer.rb.~1.2.~ → representer.rb.~1.5.~} +60 -26
- data/lib/rbyaml/resolver.rb +6 -6
- data/lib/rbyaml/{resolver.rb.~1.1.~ → resolver.rb.~1.6.~} +20 -20
- data/lib/rbyaml/rubytypes.rb +391 -0
- data/lib/rbyaml/scanner.rb +123 -225
- data/lib/rbyaml/{scanner.rb.~1.2.~ → scanner.rb.~1.5.~} +466 -378
- data/lib/rbyaml/serializer.rb +9 -9
- data/lib/rbyaml/{serializer.rb.~1.2.~ → serializer.rb.~1.4.~} +19 -17
- data/lib/rbyaml/stream.rb +48 -0
- data/lib/rbyaml/tag.rb +72 -0
- data/lib/rbyaml/tokens.rb +22 -16
- data/lib/rbyaml/{tokens.rb.~1.2.~ → tokens.rb.~1.3.~} +44 -4
- data/lib/rbyaml/types.rb +146 -0
- data/lib/rbyaml/util.rb.~1.3.~ +38 -0
- data/lib/rbyaml/yaml.rb +22 -32
- data/lib/rbyaml/{yaml.rb.~1.2.~ → yaml.rb.~1.5.~} +17 -17
- data/test/load_one.rb +6 -0
- data/test/load_one_yaml.rb +6 -0
- data/test/output_events.rb +9 -0
- data/test/test_add_ctor.rb +51 -0
- data/test/test_add_ctor.rb.~1.1.~ +30 -0
- data/test/test_bm.rb +2 -2
- data/test/test_bm.rb.~1.1.~ +28 -0
- data/test/test_gems.rb +10 -0
- data/test/test_one.rb.~1.1.~ +5 -0
- data/test/test_one_syck.rb +5 -0
- data/test/test_rbyaml.rb +63 -32
- data/test/test_rbyaml.rb.~1.6.~ +59 -0
- data/test/{test_rbyaml.rb.~1.2.~ → test_rbyaml_old.rb} +13 -4
- data/test/test_time_events.rb +24 -0
- data/test/test_time_nodes.rb +24 -0
- data/test/test_time_tokens.rb +24 -0
- data/test/yaml/gems_new.yml +147456 -0
- data/test/yaml/test1.rb +8 -0
- data/test/yaml/test10.rb +14 -0
- data/test/yaml/test11.rb +13 -0
- data/test/yaml/test12.rb +9 -0
- data/test/yaml/test13.rb +9 -0
- data/test/yaml/test14.rb +13 -0
- data/test/yaml/test15.rb +12 -0
- data/test/yaml/test16.rb +11 -0
- data/test/yaml/test16.rb.~1.1.~ +11 -0
- data/test/yaml/test17.rb +10 -0
- data/test/yaml/test18.rb +13 -0
- data/test/yaml/test19.rb +9 -0
- data/test/yaml/test19.yml +1 -1
- data/test/yaml/test2.rb +8 -0
- data/test/yaml/test20.rb +11 -0
- data/test/yaml/test20.rb.~1.1.~ +9 -0
- data/test/yaml/test20.yml +1 -1
- data/test/yaml/test3.rb +13 -0
- data/test/yaml/test4.rb +13 -0
- data/test/yaml/test5.rb +8 -0
- data/test/yaml/test6.rb +10 -0
- data/test/yaml/test7.rb +15 -0
- data/test/yaml/test8.rb +15 -0
- data/test/yaml/test9.rb +13 -0
- metadata +61 -16
- data/lib/rbyaml/dumper.rb.~1.2.~ +0 -43
- data/lib/rbyaml/parser.rb.~1.2.~ +0 -494
data/lib/rbyaml/composer.rb
CHANGED
@@ -3,7 +3,7 @@ require 'rbyaml/events'
|
|
3
3
|
require 'rbyaml/nodes'
|
4
4
|
|
5
5
|
module RbYAML
|
6
|
-
class ComposerError <
|
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,
|
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",
|
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.
|
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.
|
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
|
-
|
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.
|
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",
|
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
|
-
|
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
|
-
|
10
|
-
def
|
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
|
-
|
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
|
29
|
-
|
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
|
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
|
55
|
+
@resolver.descend_resolver(parent,index)
|
56
|
+
if @parser.peek_event.__is_scalar
|
54
57
|
node = compose_scalar_node(anchor)
|
55
|
-
elsif
|
58
|
+
elsif @parser.peek_event.__is_sequence_start
|
56
59
|
node = compose_sequence_node(anchor)
|
57
|
-
elsif
|
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
|
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
|
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
|
data/lib/rbyaml/constructor.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'base64'
|
2
|
-
require '
|
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(
|
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 <
|
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
|
-
|
69
|
-
|
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
|
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|
|
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 =
|
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
|
-
|
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
|
-
|
147
|
+
str(node)
|
104
148
|
elsif node.__is_sequence
|
105
|
-
|
149
|
+
seq(node)
|
106
150
|
elsif node.__is_mapping
|
107
|
-
|
151
|
+
map(node)
|
108
152
|
else
|
109
153
|
puts node.tag
|
110
154
|
end
|
111
155
|
end
|
112
156
|
|
113
|
-
def
|
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
|
162
|
+
return str(node.value[key_node])
|
119
163
|
end
|
120
164
|
end
|
121
165
|
end
|
122
|
-
raise ConstructorError.new(nil,
|
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
|
128
|
-
|
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
|
133
|
-
raise ConstructorError.new(nil,
|
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",
|
186
|
+
raise ConstructorError.new("while constructing a mapping","found duplicate merge key") if !merge.nil?
|
139
187
|
if value_node.__is_mapping
|
140
|
-
merge = [
|
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",
|
193
|
+
raise ConstructorError.new("while constructing a mapping","expected a mapping for merging, but found #{subnode.tid}")
|
146
194
|
end
|
147
|
-
merge.unshift(
|
195
|
+
merge.unshift(map(subnode))
|
148
196
|
end
|
149
197
|
else
|
150
|
-
raise ConstructorError.new("while constructing a mapping",
|
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",
|
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
|
-
|
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,
|
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
|
-
@@
|
248
|
+
@@yaml_safe_constructors[tag] = constructor
|
180
249
|
end
|
181
250
|
|
182
251
|
def self.add_multi_constructor(tag_prefix, multi_constructor)
|
183
|
-
@@
|
184
|
-
@@
|
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
|
-
|
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 =
|
273
|
+
value = str(node)
|
207
274
|
BOOL_VALUES[value.downcase]
|
208
275
|
end
|
209
276
|
|
210
277
|
def construct_yaml_int(node)
|
211
|
-
value =
|
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 =
|
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 =
|
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
|
-
|
289
|
-
|
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.
|
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",
|
310
|
-
"expected a mapping of length 1, but found #{subnode.tid}"
|
311
|
-
raise ConstructorError.new("while constructing an ordered map",
|
312
|
-
"expected a single mapping item, but found #{subnode.value.length} items"
|
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(
|
399
|
+
Set.new(map(node).keys)
|
327
400
|
end
|
328
401
|
|
329
402
|
def construct_yaml_str(node)
|
330
|
-
|
403
|
+
val = str(node).to_s
|
404
|
+
val.empty? ? nil : val
|
331
405
|
end
|
332
406
|
|
333
407
|
def construct_yaml_seq(node)
|
334
|
-
|
408
|
+
seq(node)
|
335
409
|
end
|
336
410
|
|
337
411
|
def construct_yaml_map(node)
|
338
|
-
|
412
|
+
map(node)
|
339
413
|
end
|
340
414
|
|
341
415
|
def construct_yaml_object(node, cls)
|
342
|
-
mapping =
|
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,
|
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
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
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 =
|
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
|
-
|
390
|
-
end
|
481
|
+
Constructor.add_multi_constructor("!ruby/object:",:construct_ruby)
|
391
482
|
end
|