concordia-publishing-house-syck 1.0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +25 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +51 -0
- data/Rakefile +32 -0
- data/ext/syck/bytecode.c +1165 -0
- data/ext/syck/emitter.c +1247 -0
- data/ext/syck/extconf.h +3 -0
- data/ext/syck/extconf.rb +5 -0
- data/ext/syck/gram.c +1894 -0
- data/ext/syck/gram.h +79 -0
- data/ext/syck/handler.c +173 -0
- data/ext/syck/implicit.c +2990 -0
- data/ext/syck/node.c +407 -0
- data/ext/syck/rubyext.c +2328 -0
- data/ext/syck/syck.c +524 -0
- data/ext/syck/syck.h +453 -0
- data/ext/syck/token.c +2724 -0
- data/ext/syck/yaml2byte.c +259 -0
- data/ext/syck/yamlbyte.h +171 -0
- data/lib/syck.rb +448 -0
- data/lib/syck/baseemitter.rb +242 -0
- data/lib/syck/basenode.rb +222 -0
- data/lib/syck/constants.rb +45 -0
- data/lib/syck/encoding.rb +35 -0
- data/lib/syck/error.rb +34 -0
- data/lib/syck/loader.rb +14 -0
- data/lib/syck/rubytypes.rb +450 -0
- data/lib/syck/stream.rb +41 -0
- data/lib/syck/stringio.rb +85 -0
- data/lib/syck/syck.rb +16 -0
- data/lib/syck/tag.rb +95 -0
- data/lib/syck/types.rb +192 -0
- data/lib/syck/yamlnode.rb +54 -0
- data/lib/syck/ypath.rb +54 -0
- data/lib/yaml/engine_manager.rb +71 -0
- data/lib/yaml/syck.rb +14 -0
- data/test/helper.rb +2 -0
- data/test/test_array.rb +13 -0
- data/test/test_boolean.rb +36 -0
- data/test/test_class.rb +11 -0
- data/test/test_exception.rb +45 -0
- data/test/test_hash.rb +24 -0
- data/test/test_null.rb +19 -0
- data/test/test_omap.rb +55 -0
- data/test/test_set.rb +30 -0
- data/test/test_string.rb +44 -0
- data/test/test_struct.rb +32 -0
- data/test/test_symbol.rb +21 -0
- data/test/test_time.rb +23 -0
- data/test/test_yaml.rb +1403 -0
- data/test/test_yaml_properties.rb +63 -0
- metadata +163 -0
@@ -0,0 +1,242 @@
|
|
1
|
+
#
|
2
|
+
# BaseEmitter
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'syck/constants'
|
6
|
+
require 'syck/encoding'
|
7
|
+
require 'syck/error'
|
8
|
+
|
9
|
+
module Syck
|
10
|
+
module BaseEmitter
|
11
|
+
def options( opt = nil )
|
12
|
+
if opt
|
13
|
+
@options[opt] || DEFAULTS[opt]
|
14
|
+
else
|
15
|
+
@options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def options=( opt )
|
20
|
+
@options = opt
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Emit binary data
|
25
|
+
#
|
26
|
+
def binary_base64( value )
|
27
|
+
self << "!binary "
|
28
|
+
self.node_text( [value].pack("m"), '|' )
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Emit plain, normal flowing text
|
33
|
+
#
|
34
|
+
def node_text( value, block = nil )
|
35
|
+
@seq_map = false
|
36
|
+
valx = value.dup
|
37
|
+
unless block
|
38
|
+
block =
|
39
|
+
if options(:UseBlock)
|
40
|
+
'|'
|
41
|
+
elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{ESCAPE_CHAR}/
|
42
|
+
'|'
|
43
|
+
else
|
44
|
+
'>'
|
45
|
+
end
|
46
|
+
indt = $&.to_i if block =~ /\d+/
|
47
|
+
if valx =~ /(\A\n*[ \t#]|^---\s+)/
|
48
|
+
indt = options(:Indent) unless indt.to_i > 0
|
49
|
+
block += indt.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
block +=
|
53
|
+
if valx =~ /\n\Z\n/
|
54
|
+
"+"
|
55
|
+
elsif valx =~ /\Z\n/
|
56
|
+
""
|
57
|
+
else
|
58
|
+
"-"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
block += "\n"
|
62
|
+
if block[0] == ?"
|
63
|
+
esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
|
64
|
+
valx = fold( Syck.escape( valx, esc_skip ) + "\"" ).chomp
|
65
|
+
self << '"' + indent_text( valx, indt, false )
|
66
|
+
else
|
67
|
+
if block[0] == ?>
|
68
|
+
valx = fold( valx )
|
69
|
+
end
|
70
|
+
#p [block, indt]
|
71
|
+
self << block + indent_text( valx, indt )
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Emit a simple, unqouted string
|
77
|
+
#
|
78
|
+
def simple( value )
|
79
|
+
@seq_map = false
|
80
|
+
self << value.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Emit double-quoted string
|
85
|
+
#
|
86
|
+
def double( value )
|
87
|
+
"\"#{Syck.escape( value )}\""
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Emit single-quoted string
|
92
|
+
#
|
93
|
+
def single( value )
|
94
|
+
"'#{value}'"
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Write a text block with the current indent
|
99
|
+
#
|
100
|
+
def indent_text( text, mod, first_line = true )
|
101
|
+
return "" if text.to_s.empty?
|
102
|
+
spacing = indent( mod )
|
103
|
+
text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
|
104
|
+
return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Write a current indent
|
109
|
+
#
|
110
|
+
def indent( mod = nil )
|
111
|
+
#p [ self.id, level, mod, :INDENT ]
|
112
|
+
if level <= 0
|
113
|
+
mod ||= 0
|
114
|
+
else
|
115
|
+
mod ||= options(:Indent)
|
116
|
+
mod += ( level - 1 ) * options(:Indent)
|
117
|
+
end
|
118
|
+
return " " * mod
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Add indent to the buffer
|
123
|
+
#
|
124
|
+
def indent!
|
125
|
+
self << indent
|
126
|
+
end
|
127
|
+
|
128
|
+
#
|
129
|
+
# Folding paragraphs within a column
|
130
|
+
#
|
131
|
+
def fold( value )
|
132
|
+
value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do
|
133
|
+
$1 || $2 + ( $3 || "\n" )
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
#
|
138
|
+
# Quick mapping
|
139
|
+
#
|
140
|
+
def map( type, &e )
|
141
|
+
val = Mapping.new
|
142
|
+
e.call( val )
|
143
|
+
self << "#{type} " if type.length.nonzero?
|
144
|
+
|
145
|
+
#
|
146
|
+
# Empty hashes
|
147
|
+
#
|
148
|
+
if val.length.zero?
|
149
|
+
self << "{}"
|
150
|
+
@seq_map = false
|
151
|
+
else
|
152
|
+
# FIXME
|
153
|
+
# if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
|
154
|
+
# @headless = 1
|
155
|
+
# end
|
156
|
+
|
157
|
+
defkey = @options.delete( :DefaultKey )
|
158
|
+
if defkey
|
159
|
+
seq_map_shortcut
|
160
|
+
self << "= : "
|
161
|
+
defkey.to_yaml( :Emitter => self )
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# Emit the key and value
|
166
|
+
#
|
167
|
+
val.each { |v|
|
168
|
+
seq_map_shortcut
|
169
|
+
if v[0].is_complex_yaml?
|
170
|
+
self << "? "
|
171
|
+
end
|
172
|
+
v[0].to_yaml( :Emitter => self )
|
173
|
+
if v[0].is_complex_yaml?
|
174
|
+
self << "\n"
|
175
|
+
indent!
|
176
|
+
end
|
177
|
+
self << ": "
|
178
|
+
v[1].to_yaml( :Emitter => self )
|
179
|
+
}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def seq_map_shortcut
|
184
|
+
# FIXME: seq_map needs to work with the new anchoring system
|
185
|
+
# if @seq_map
|
186
|
+
# @anchor_extras[@buffer.length - 1] = "\n" + indent
|
187
|
+
# @seq_map = false
|
188
|
+
# else
|
189
|
+
self << "\n"
|
190
|
+
indent!
|
191
|
+
# end
|
192
|
+
end
|
193
|
+
|
194
|
+
#
|
195
|
+
# Quick sequence
|
196
|
+
#
|
197
|
+
def seq( type, &e )
|
198
|
+
@seq_map = false
|
199
|
+
val = Sequence.new
|
200
|
+
e.call( val )
|
201
|
+
self << "#{type} " if type.length.nonzero?
|
202
|
+
|
203
|
+
#
|
204
|
+
# Empty arrays
|
205
|
+
#
|
206
|
+
if val.length.zero?
|
207
|
+
self << "[]"
|
208
|
+
else
|
209
|
+
# FIXME
|
210
|
+
# if @buffer.length == 1 and options(:UseHeader) == false and type.length.zero?
|
211
|
+
# @headless = 1
|
212
|
+
# end
|
213
|
+
|
214
|
+
#
|
215
|
+
# Emit the key and value
|
216
|
+
#
|
217
|
+
val.each { |v|
|
218
|
+
self << "\n"
|
219
|
+
indent!
|
220
|
+
self << "- "
|
221
|
+
@seq_map = true if v.class == Hash
|
222
|
+
v.to_yaml( :Emitter => self )
|
223
|
+
}
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
#
|
229
|
+
# Emitter helper classes
|
230
|
+
#
|
231
|
+
class Mapping < Array
|
232
|
+
def add( k, v )
|
233
|
+
push [k, v]
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
class Sequence < Array
|
238
|
+
def add( v )
|
239
|
+
push v
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#
|
2
|
+
# YAML::BaseNode class
|
3
|
+
#
|
4
|
+
|
5
|
+
module Syck
|
6
|
+
|
7
|
+
#
|
8
|
+
# YAML Generic Model container
|
9
|
+
#
|
10
|
+
module BaseNode
|
11
|
+
|
12
|
+
#
|
13
|
+
# Search for YPath entry and return
|
14
|
+
# qualified nodes.
|
15
|
+
#
|
16
|
+
def select( ypath_str )
|
17
|
+
warn "#{caller[0]}: select is deprecated" if $VERBOSE
|
18
|
+
matches = match_path( ypath_str )
|
19
|
+
|
20
|
+
#
|
21
|
+
# Create a new generic view of the elements selected
|
22
|
+
#
|
23
|
+
if matches
|
24
|
+
result = []
|
25
|
+
matches.each { |m|
|
26
|
+
result.push m.last
|
27
|
+
}
|
28
|
+
Syck.transfer( 'seq', result )
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Search for YPath entry and return
|
34
|
+
# transformed nodes.
|
35
|
+
#
|
36
|
+
def select!( ypath_str )
|
37
|
+
warn "#{caller[0]}: select!() is deprecated" if $VERBOSE
|
38
|
+
matches = match_path( ypath_str )
|
39
|
+
|
40
|
+
#
|
41
|
+
# Create a new generic view of the elements selected
|
42
|
+
#
|
43
|
+
if matches
|
44
|
+
result = []
|
45
|
+
matches.each { |m|
|
46
|
+
result.push m.last.transform
|
47
|
+
}
|
48
|
+
result
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Search for YPath entry and return a list of
|
54
|
+
# qualified paths.
|
55
|
+
#
|
56
|
+
def search( ypath_str )
|
57
|
+
warn "#{caller[0]}: search() is deprecated" if $VERBOSE
|
58
|
+
matches = match_path( ypath_str )
|
59
|
+
|
60
|
+
if matches
|
61
|
+
matches.collect { |m|
|
62
|
+
path = []
|
63
|
+
m.each_index { |i|
|
64
|
+
path.push m[i] if ( i % 2 ).zero?
|
65
|
+
}
|
66
|
+
"/" + path.compact.join( "/" )
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def at( seg )
|
72
|
+
warn "#{caller[0]}: at() is deprecated" if $VERBOSE
|
73
|
+
if Hash === @value
|
74
|
+
self[seg]
|
75
|
+
elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
|
76
|
+
@value[seg.to_i]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# YPath search returning a complete depth array
|
82
|
+
#
|
83
|
+
def match_path( ypath_str )
|
84
|
+
warn "#{caller[0]}: match_path is deprecated" if $VERBOSE
|
85
|
+
require 'syck/ypath'
|
86
|
+
matches = []
|
87
|
+
YPath.each_path( ypath_str ) do |ypath|
|
88
|
+
seg = match_segment( ypath, 0 )
|
89
|
+
matches += seg if seg
|
90
|
+
end
|
91
|
+
matches.uniq
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Search a node for a single YPath segment
|
96
|
+
#
|
97
|
+
def match_segment( ypath, depth )
|
98
|
+
warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE
|
99
|
+
deep_nodes = []
|
100
|
+
seg = ypath.segments[ depth ]
|
101
|
+
if seg == "/"
|
102
|
+
unless String === @value
|
103
|
+
idx = -1
|
104
|
+
@value.collect { |v|
|
105
|
+
idx += 1
|
106
|
+
if Hash === @value
|
107
|
+
match_init = [v[0].transform, v[1]]
|
108
|
+
match_deep = v[1].match_segment( ypath, depth )
|
109
|
+
else
|
110
|
+
match_init = [idx, v]
|
111
|
+
match_deep = v.match_segment( ypath, depth )
|
112
|
+
end
|
113
|
+
if match_deep
|
114
|
+
match_deep.each { |m|
|
115
|
+
deep_nodes.push( match_init + m )
|
116
|
+
}
|
117
|
+
end
|
118
|
+
}
|
119
|
+
end
|
120
|
+
depth += 1
|
121
|
+
seg = ypath.segments[ depth ]
|
122
|
+
end
|
123
|
+
match_nodes =
|
124
|
+
case seg
|
125
|
+
when "."
|
126
|
+
[[nil, self]]
|
127
|
+
when ".."
|
128
|
+
[["..", nil]]
|
129
|
+
when "*"
|
130
|
+
if @value.is_a? Enumerable
|
131
|
+
idx = -1
|
132
|
+
@value.collect { |h|
|
133
|
+
idx += 1
|
134
|
+
if Hash === @value
|
135
|
+
[h[0].transform, h[1]]
|
136
|
+
else
|
137
|
+
[idx, h]
|
138
|
+
end
|
139
|
+
}
|
140
|
+
end
|
141
|
+
else
|
142
|
+
if seg =~ /^"(.*)"$/
|
143
|
+
seg = $1
|
144
|
+
elsif seg =~ /^'(.*)'$/
|
145
|
+
seg = $1
|
146
|
+
end
|
147
|
+
if ( v = at( seg ) )
|
148
|
+
[[ seg, v ]]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
return deep_nodes unless match_nodes
|
152
|
+
pred = ypath.predicates[ depth ]
|
153
|
+
if pred
|
154
|
+
case pred
|
155
|
+
when /^\.=/
|
156
|
+
pred = $' # '
|
157
|
+
match_nodes.reject! { |n|
|
158
|
+
n.last.value != pred
|
159
|
+
}
|
160
|
+
else
|
161
|
+
match_nodes.reject! { |n|
|
162
|
+
n.last.at( pred ).nil?
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
|
167
|
+
|
168
|
+
#puts "DEPTH: #{depth + 1}"
|
169
|
+
deep_nodes = []
|
170
|
+
match_nodes.each { |n|
|
171
|
+
if n[1].is_a? BaseNode
|
172
|
+
match_deep = n[1].match_segment( ypath, depth + 1 )
|
173
|
+
if match_deep
|
174
|
+
match_deep.each { |m|
|
175
|
+
deep_nodes.push( n + m )
|
176
|
+
}
|
177
|
+
end
|
178
|
+
else
|
179
|
+
deep_nodes = []
|
180
|
+
end
|
181
|
+
}
|
182
|
+
deep_nodes = nil if deep_nodes.length == 0
|
183
|
+
deep_nodes
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# We want the node to act like as Hash
|
188
|
+
# if it is.
|
189
|
+
#
|
190
|
+
def []( *key )
|
191
|
+
if Hash === @value
|
192
|
+
v = @value.detect { |k,| k.transform == key.first }
|
193
|
+
v[1] if v
|
194
|
+
elsif Array === @value
|
195
|
+
@value.[]( *key )
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def children
|
200
|
+
if Hash === @value
|
201
|
+
@value.values.collect { |c| c[1] }
|
202
|
+
elsif Array === @value
|
203
|
+
@value
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def children_with_index
|
208
|
+
warn "#{caller[0]}: children_with_index is deprecated, use children" if $VERBOSE
|
209
|
+
if Hash === @value
|
210
|
+
@value.keys.collect { |i| [self[i], i] }
|
211
|
+
elsif Array === @value
|
212
|
+
i = -1; @value.collect { |v| i += 1; [v, i] }
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def emit
|
217
|
+
transform.to_yaml
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|