RbYAML 0.0.2 → 0.1.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/README +1 -1
- data/lib/rbyaml/composer.rb +28 -25
- data/lib/rbyaml/composer.rb.~1.2.~ +109 -0
- data/lib/rbyaml/constructor.rb +94 -84
- data/lib/rbyaml/constructor.rb.~1.2.~ +381 -0
- data/lib/rbyaml/dumper.rb +10 -17
- data/lib/rbyaml/dumper.rb.~1.2.~ +43 -0
- data/lib/rbyaml/emitter.rb +13 -26
- data/lib/rbyaml/emitter.rb.~1.2.~ +1116 -0
- data/lib/rbyaml/error.rb +15 -21
- data/lib/rbyaml/events.rb +29 -5
- data/lib/rbyaml/events.rb.~1.2.~ +93 -0
- data/lib/rbyaml/loader.rb +11 -23
- data/lib/rbyaml/loader.rb.~1.2.~ +52 -0
- data/lib/rbyaml/nodes.rb +13 -9
- data/lib/rbyaml/nodes.rb.~1.2.~ +52 -0
- data/lib/rbyaml/parser.rb +481 -343
- data/lib/rbyaml/parser.rb.old +531 -0
- data/lib/rbyaml/parser.rb.~1.2.~ +494 -0
- data/lib/rbyaml/reader.rb.~1.1.1.1.~ +127 -0
- data/lib/rbyaml/representer.rb +26 -17
- data/lib/rbyaml/representer.rb.~1.2.~ +239 -0
- data/lib/rbyaml/resolver.rb +15 -15
- data/lib/rbyaml/resolver.rb.~1.1.~ +163 -0
- data/lib/rbyaml/scanner.rb +457 -366
- data/lib/rbyaml/scanner.rb.~1.2.~ +1259 -0
- data/lib/rbyaml/serializer.rb +19 -17
- data/lib/rbyaml/serializer.rb.~1.2.~ +115 -0
- data/lib/rbyaml/tokens.rb +44 -4
- data/lib/rbyaml/tokens.rb.~1.2.~ +164 -0
- data/lib/rbyaml/util.rb +28 -0
- data/lib/rbyaml/yaml.rb +12 -12
- data/lib/rbyaml/yaml.rb.~1.2.~ +136 -0
- data/test/test_bm.rb +28 -0
- data/test/test_bm_syck.rb +28 -0
- data/test/test_invoke.rb +31 -0
- data/test/test_one.rb +5 -0
- data/test/test_profile.rb +32 -0
- data/test/test_rbyaml.rb +2 -1
- data/test/test_rbyaml.rb.~1.2.~ +31 -0
- data/test/test_time.rb +13 -8
- data/test/test_time.rb.~1.1.~ +29 -0
- data/test/yamlx.rb +3563 -0
- metadata +27 -2
data/test/yamlx.rb
ADDED
@@ -0,0 +1,3563 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by racc 1.4.3
|
4
|
+
# from racc grammer file "src/yaml.y.rb".
|
5
|
+
#
|
6
|
+
#
|
7
|
+
# src/yaml.rb: generated by racc (runtime embedded)
|
8
|
+
#
|
9
|
+
|
10
|
+
###### racc/parser.rb
|
11
|
+
|
12
|
+
unless $".index 'racc/parser.rb'
|
13
|
+
$".push 'racc/parser.rb'
|
14
|
+
|
15
|
+
self.class.module_eval <<'..end /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb modeval..id4449eb2054', '/usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb', 1
|
16
|
+
#
|
17
|
+
# parser.rb
|
18
|
+
#
|
19
|
+
# Copyright (c) 1999-2002 Minero Aoki <aamine@loveruby.net>
|
20
|
+
#
|
21
|
+
# This program is free software.
|
22
|
+
# You can distribute/modify this program under the same terms of ruby.
|
23
|
+
#
|
24
|
+
# As a special exception, when this code is copied by Racc
|
25
|
+
# into a Racc output file, you may use that output file
|
26
|
+
# without restriction.
|
27
|
+
#
|
28
|
+
#
|
29
|
+
|
30
|
+
unless defined? NotImplementedError
|
31
|
+
NotImplementedError = NotImplementError
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
module Racc
|
36
|
+
class ParseError < StandardError; end
|
37
|
+
end
|
38
|
+
unless defined? ::ParseError
|
39
|
+
ParseError = Racc::ParseError
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
module Racc
|
44
|
+
|
45
|
+
unless defined? Racc_No_Extentions
|
46
|
+
Racc_No_Extentions = false
|
47
|
+
end
|
48
|
+
|
49
|
+
class Parser
|
50
|
+
|
51
|
+
# revisions have been hardcoded to avoid branch/merge issues
|
52
|
+
Racc_Runtime_Version = '1.4.3'
|
53
|
+
Racc_Runtime_Revision = '1.1'.split(/\s+/)[1]
|
54
|
+
|
55
|
+
Racc_Runtime_Core_Version_R = '1.4.3'
|
56
|
+
Racc_Runtime_Core_Revision_R = '1.1'.split(/\s+/)[1]
|
57
|
+
begin
|
58
|
+
require 'racc/cparse'
|
59
|
+
# Racc_Runtime_Core_Version_C = (defined in extention)
|
60
|
+
Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split(/\s+/)[2]
|
61
|
+
unless new.respond_to?(:_racc_do_parse_c, true)
|
62
|
+
raise LoadError, 'old cparse.so'
|
63
|
+
end
|
64
|
+
if Racc_No_Extentions
|
65
|
+
raise LoadError, 'selecting ruby version of racc runtime core'
|
66
|
+
end
|
67
|
+
|
68
|
+
Racc_Main_Parsing_Routine = :_racc_do_parse_c
|
69
|
+
Racc_YY_Parse_Method = :_racc_yyparse_c
|
70
|
+
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
|
71
|
+
Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
|
72
|
+
Racc_Runtime_Type = 'c'
|
73
|
+
rescue LoadError
|
74
|
+
Racc_Main_Parsing_Routine = :_racc_do_parse_rb
|
75
|
+
Racc_YY_Parse_Method = :_racc_yyparse_rb
|
76
|
+
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
|
77
|
+
Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
|
78
|
+
Racc_Runtime_Type = 'ruby'
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.racc_runtime_type
|
82
|
+
Racc_Runtime_Type
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def _racc_setup
|
88
|
+
@yydebug = false unless self.class::Racc_debug_parser
|
89
|
+
@yydebug = false unless defined? @yydebug
|
90
|
+
if @yydebug
|
91
|
+
@racc_debug_out = $stderr unless defined? @racc_debug_out
|
92
|
+
@racc_debug_out ||= $stderr
|
93
|
+
end
|
94
|
+
arg = self.class::Racc_arg
|
95
|
+
arg[13] = true if arg.size < 14
|
96
|
+
arg
|
97
|
+
end
|
98
|
+
|
99
|
+
def _racc_init_sysvars
|
100
|
+
@racc_state = [0]
|
101
|
+
@racc_tstack = []
|
102
|
+
@racc_vstack = []
|
103
|
+
|
104
|
+
@racc_t = nil
|
105
|
+
@racc_val = nil
|
106
|
+
|
107
|
+
@racc_read_next = true
|
108
|
+
|
109
|
+
@racc_user_yyerror = false
|
110
|
+
@racc_error_status = 0
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
###
|
115
|
+
### do_parse
|
116
|
+
###
|
117
|
+
|
118
|
+
def do_parse
|
119
|
+
__send__ Racc_Main_Parsing_Routine, _racc_setup(), false
|
120
|
+
end
|
121
|
+
|
122
|
+
def next_token
|
123
|
+
raise NotImplementedError, "#{self.class}\#next_token is not defined"
|
124
|
+
end
|
125
|
+
|
126
|
+
def _racc_do_parse_rb( arg, in_debug )
|
127
|
+
action_table, action_check, action_default, action_pointer,
|
128
|
+
goto_table, goto_check, goto_default, goto_pointer,
|
129
|
+
nt_base, reduce_table, token_table, shift_n,
|
130
|
+
reduce_n, use_result, * = arg
|
131
|
+
|
132
|
+
_racc_init_sysvars()
|
133
|
+
tok = act = i = nil
|
134
|
+
nerr = 0
|
135
|
+
|
136
|
+
catch(:racc_end_parse) {
|
137
|
+
while true
|
138
|
+
if i = action_pointer[@racc_state[-1]]
|
139
|
+
if @racc_read_next
|
140
|
+
if @racc_t != 0 # not EOF
|
141
|
+
tok, @racc_val = next_token()
|
142
|
+
unless tok # EOF
|
143
|
+
@racc_t = 0
|
144
|
+
else
|
145
|
+
@racc_t = (token_table[tok] or 1) # error token
|
146
|
+
end
|
147
|
+
racc_read_token(@racc_t, tok, @racc_val) if @yydebug
|
148
|
+
@racc_read_next = false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
i += @racc_t
|
152
|
+
if i >= 0 and
|
153
|
+
act = action_table[i] and
|
154
|
+
action_check[i] == @racc_state[-1]
|
155
|
+
;
|
156
|
+
else
|
157
|
+
act = action_default[@racc_state[-1]]
|
158
|
+
end
|
159
|
+
else
|
160
|
+
act = action_default[@racc_state[-1]]
|
161
|
+
end
|
162
|
+
while act = _racc_evalact(act, arg)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
###
|
170
|
+
### yyparse
|
171
|
+
###
|
172
|
+
|
173
|
+
def yyparse( recv, mid )
|
174
|
+
__send__ Racc_YY_Parse_Method, recv, mid, _racc_setup(), true
|
175
|
+
end
|
176
|
+
|
177
|
+
def _racc_yyparse_rb( recv, mid, arg, c_debug )
|
178
|
+
action_table, action_check, action_default, action_pointer,
|
179
|
+
goto_table, goto_check, goto_default, goto_pointer,
|
180
|
+
nt_base, reduce_table, token_table, shift_n,
|
181
|
+
reduce_n, use_result, * = arg
|
182
|
+
|
183
|
+
_racc_init_sysvars
|
184
|
+
tok = nil
|
185
|
+
act = nil
|
186
|
+
i = nil
|
187
|
+
nerr = 0
|
188
|
+
|
189
|
+
|
190
|
+
catch(:racc_end_parse) {
|
191
|
+
until i = action_pointer[@racc_state[-1]]
|
192
|
+
while act = _racc_evalact(action_default[@racc_state[-1]], arg)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
recv.__send__(mid) do |tok, val|
|
197
|
+
# $stderr.puts "rd: tok=#{tok}, val=#{val}"
|
198
|
+
unless tok
|
199
|
+
@racc_t = 0
|
200
|
+
else
|
201
|
+
@racc_t = (token_table[tok] or 1) # error token
|
202
|
+
end
|
203
|
+
@racc_val = val
|
204
|
+
@racc_read_next = false
|
205
|
+
|
206
|
+
i += @racc_t
|
207
|
+
if i >= 0 and
|
208
|
+
act = action_table[i] and
|
209
|
+
action_check[i] == @racc_state[-1]
|
210
|
+
;
|
211
|
+
# $stderr.puts "01: act=#{act}"
|
212
|
+
else
|
213
|
+
act = action_default[@racc_state[-1]]
|
214
|
+
# $stderr.puts "02: act=#{act}"
|
215
|
+
# $stderr.puts "curstate=#{@racc_state[-1]}"
|
216
|
+
end
|
217
|
+
|
218
|
+
while act = _racc_evalact(act, arg)
|
219
|
+
end
|
220
|
+
|
221
|
+
while not (i = action_pointer[@racc_state[-1]]) or
|
222
|
+
not @racc_read_next or
|
223
|
+
@racc_t == 0 # $
|
224
|
+
if i and i += @racc_t and
|
225
|
+
i >= 0 and
|
226
|
+
act = action_table[i] and
|
227
|
+
action_check[i] == @racc_state[-1]
|
228
|
+
;
|
229
|
+
# $stderr.puts "03: act=#{act}"
|
230
|
+
else
|
231
|
+
# $stderr.puts "04: act=#{act}"
|
232
|
+
act = action_default[@racc_state[-1]]
|
233
|
+
end
|
234
|
+
|
235
|
+
while act = _racc_evalact(act, arg)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
}
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
###
|
244
|
+
### common
|
245
|
+
###
|
246
|
+
|
247
|
+
def _racc_evalact( act, arg )
|
248
|
+
# $stderr.puts "ea: act=#{act}"
|
249
|
+
action_table, action_check, action_default, action_pointer,
|
250
|
+
goto_table, goto_check, goto_default, goto_pointer,
|
251
|
+
nt_base, reduce_table, token_table, shift_n,
|
252
|
+
reduce_n, use_result, * = arg
|
253
|
+
nerr = 0 # tmp
|
254
|
+
|
255
|
+
if act > 0 and act < shift_n
|
256
|
+
#
|
257
|
+
# shift
|
258
|
+
#
|
259
|
+
|
260
|
+
if @racc_error_status > 0
|
261
|
+
@racc_error_status -= 1 unless @racc_t == 1 # error token
|
262
|
+
end
|
263
|
+
|
264
|
+
@racc_vstack.push @racc_val
|
265
|
+
@racc_state.push act
|
266
|
+
@racc_read_next = true
|
267
|
+
|
268
|
+
if @yydebug
|
269
|
+
@racc_tstack.push @racc_t
|
270
|
+
racc_shift @racc_t, @racc_tstack, @racc_vstack
|
271
|
+
end
|
272
|
+
|
273
|
+
elsif act < 0 and act > -reduce_n
|
274
|
+
#
|
275
|
+
# reduce
|
276
|
+
#
|
277
|
+
|
278
|
+
code = catch(:racc_jump) {
|
279
|
+
@racc_state.push _racc_do_reduce(arg, act)
|
280
|
+
false
|
281
|
+
}
|
282
|
+
if code
|
283
|
+
case code
|
284
|
+
when 1 # yyerror
|
285
|
+
@racc_user_yyerror = true # user_yyerror
|
286
|
+
return -reduce_n
|
287
|
+
when 2 # yyaccept
|
288
|
+
return shift_n
|
289
|
+
else
|
290
|
+
raise RuntimeError, '[Racc Bug] unknown jump code'
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
elsif act == shift_n
|
295
|
+
#
|
296
|
+
# accept
|
297
|
+
#
|
298
|
+
|
299
|
+
racc_accept if @yydebug
|
300
|
+
throw :racc_end_parse, @racc_vstack[0]
|
301
|
+
|
302
|
+
elsif act == -reduce_n
|
303
|
+
#
|
304
|
+
# error
|
305
|
+
#
|
306
|
+
|
307
|
+
case @racc_error_status
|
308
|
+
when 0
|
309
|
+
unless arg[21] # user_yyerror
|
310
|
+
nerr += 1
|
311
|
+
on_error @racc_t, @racc_val, @racc_vstack
|
312
|
+
end
|
313
|
+
when 3
|
314
|
+
if @racc_t == 0 # is $
|
315
|
+
throw :racc_end_parse, nil
|
316
|
+
end
|
317
|
+
@racc_read_next = true
|
318
|
+
end
|
319
|
+
@racc_user_yyerror = false
|
320
|
+
@racc_error_status = 3
|
321
|
+
|
322
|
+
while true
|
323
|
+
if i = action_pointer[@racc_state[-1]]
|
324
|
+
i += 1 # error token
|
325
|
+
if i >= 0 and
|
326
|
+
(act = action_table[i]) and
|
327
|
+
action_check[i] == @racc_state[-1]
|
328
|
+
break
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
throw :racc_end_parse, nil if @racc_state.size < 2
|
333
|
+
@racc_state.pop
|
334
|
+
@racc_vstack.pop
|
335
|
+
if @yydebug
|
336
|
+
@racc_tstack.pop
|
337
|
+
racc_e_pop @racc_state, @racc_tstack, @racc_vstack
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
return act
|
342
|
+
|
343
|
+
else
|
344
|
+
raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}"
|
345
|
+
end
|
346
|
+
|
347
|
+
racc_next_state(@racc_state[-1], @racc_state) if @yydebug
|
348
|
+
|
349
|
+
nil
|
350
|
+
end
|
351
|
+
|
352
|
+
def _racc_do_reduce( arg, act )
|
353
|
+
action_table, action_check, action_default, action_pointer,
|
354
|
+
goto_table, goto_check, goto_default, goto_pointer,
|
355
|
+
nt_base, reduce_table, token_table, shift_n,
|
356
|
+
reduce_n, use_result, * = arg
|
357
|
+
state = @racc_state
|
358
|
+
vstack = @racc_vstack
|
359
|
+
tstack = @racc_tstack
|
360
|
+
|
361
|
+
i = act * -3
|
362
|
+
len = reduce_table[i]
|
363
|
+
reduce_to = reduce_table[i+1]
|
364
|
+
method_id = reduce_table[i+2]
|
365
|
+
void_array = []
|
366
|
+
|
367
|
+
tmp_t = tstack[-len, len] if @yydebug
|
368
|
+
tmp_v = vstack[-len, len]
|
369
|
+
tstack[-len, len] = void_array if @yydebug
|
370
|
+
vstack[-len, len] = void_array
|
371
|
+
state[-len, len] = void_array
|
372
|
+
|
373
|
+
# tstack must be updated AFTER method call
|
374
|
+
if use_result
|
375
|
+
vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
|
376
|
+
else
|
377
|
+
vstack.push __send__(method_id, tmp_v, vstack)
|
378
|
+
end
|
379
|
+
tstack.push reduce_to
|
380
|
+
|
381
|
+
racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
|
382
|
+
|
383
|
+
k1 = reduce_to - nt_base
|
384
|
+
if i = goto_pointer[k1]
|
385
|
+
i += state[-1]
|
386
|
+
if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
|
387
|
+
return curstate
|
388
|
+
end
|
389
|
+
end
|
390
|
+
goto_default[k1]
|
391
|
+
end
|
392
|
+
|
393
|
+
def on_error( t, val, vstack )
|
394
|
+
raise ParseError, sprintf("\nparse error on value %s (%s)",
|
395
|
+
val.inspect, token_to_str(t) || '?')
|
396
|
+
end
|
397
|
+
|
398
|
+
def yyerror
|
399
|
+
throw :racc_jump, 1
|
400
|
+
end
|
401
|
+
|
402
|
+
def yyaccept
|
403
|
+
throw :racc_jump, 2
|
404
|
+
end
|
405
|
+
|
406
|
+
def yyerrok
|
407
|
+
@racc_error_status = 0
|
408
|
+
end
|
409
|
+
|
410
|
+
|
411
|
+
# for debugging output
|
412
|
+
|
413
|
+
def racc_read_token( t, tok, val )
|
414
|
+
@racc_debug_out.print 'read '
|
415
|
+
@racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
|
416
|
+
@racc_debug_out.puts val.inspect
|
417
|
+
@racc_debug_out.puts
|
418
|
+
end
|
419
|
+
|
420
|
+
def racc_shift( tok, tstack, vstack )
|
421
|
+
@racc_debug_out.puts "shift #{racc_token2str tok}"
|
422
|
+
racc_print_stacks tstack, vstack
|
423
|
+
@racc_debug_out.puts
|
424
|
+
end
|
425
|
+
|
426
|
+
def racc_reduce( toks, sim, tstack, vstack )
|
427
|
+
out = @racc_debug_out
|
428
|
+
out.print 'reduce '
|
429
|
+
if toks.empty?
|
430
|
+
out.print ' <none>'
|
431
|
+
else
|
432
|
+
toks.each {|t| out.print ' ', racc_token2str(t) }
|
433
|
+
end
|
434
|
+
out.puts " --> #{racc_token2str(sim)}"
|
435
|
+
|
436
|
+
racc_print_stacks tstack, vstack
|
437
|
+
@racc_debug_out.puts
|
438
|
+
end
|
439
|
+
|
440
|
+
def racc_accept
|
441
|
+
@racc_debug_out.puts 'accept'
|
442
|
+
@racc_debug_out.puts
|
443
|
+
end
|
444
|
+
|
445
|
+
def racc_e_pop( state, tstack, vstack )
|
446
|
+
@racc_debug_out.puts 'error recovering mode: pop token'
|
447
|
+
racc_print_states state
|
448
|
+
racc_print_stacks tstack, vstack
|
449
|
+
@racc_debug_out.puts
|
450
|
+
end
|
451
|
+
|
452
|
+
def racc_next_state( curstate, state )
|
453
|
+
@racc_debug_out.puts "goto #{curstate}"
|
454
|
+
racc_print_states state
|
455
|
+
@racc_debug_out.puts
|
456
|
+
end
|
457
|
+
|
458
|
+
def racc_print_stacks( t, v )
|
459
|
+
out = @racc_debug_out
|
460
|
+
out.print ' ['
|
461
|
+
t.each_index do |i|
|
462
|
+
out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
|
463
|
+
end
|
464
|
+
out.puts ' ]'
|
465
|
+
end
|
466
|
+
|
467
|
+
def racc_print_states( s )
|
468
|
+
out = @racc_debug_out
|
469
|
+
out.print ' ['
|
470
|
+
s.each {|st| out.print ' ', st }
|
471
|
+
out.puts ' ]'
|
472
|
+
end
|
473
|
+
|
474
|
+
def racc_token2str( tok )
|
475
|
+
self.class::Racc_token_to_s_table[tok] or
|
476
|
+
raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string"
|
477
|
+
end
|
478
|
+
|
479
|
+
def token_to_str( t )
|
480
|
+
self.class::Racc_token_to_s_table[t]
|
481
|
+
end
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
|
+
end
|
486
|
+
..end /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb modeval..id4449eb2054
|
487
|
+
end # end of racc/parser.rb
|
488
|
+
|
489
|
+
|
490
|
+
self.class.module_eval <<'..end src/emitter.rb modeval..iddd2784be19', 'src/emitter.rb', 1
|
491
|
+
# vim:sw=4:ts=4
|
492
|
+
#
|
493
|
+
# YAML for Ruby:
|
494
|
+
# - Thanks to Brian Ingerson for YAML.pm
|
495
|
+
#
|
496
|
+
# Docs in YAML (see /doc/)
|
497
|
+
#
|
498
|
+
require 'pstore'
|
499
|
+
require 'parsedate'
|
500
|
+
require 'date'
|
501
|
+
|
502
|
+
begin
|
503
|
+
require 'stringio'
|
504
|
+
rescue LoadError
|
505
|
+
# StringIO based on code by MoonWolf
|
506
|
+
class StringIO
|
507
|
+
def initialize(string="")
|
508
|
+
@string=string
|
509
|
+
@pos=0
|
510
|
+
@eof=(string.size==0)
|
511
|
+
end
|
512
|
+
def pos
|
513
|
+
@pos
|
514
|
+
end
|
515
|
+
def eof
|
516
|
+
@eof
|
517
|
+
end
|
518
|
+
alias eof? eof
|
519
|
+
def readline(rs=$/)
|
520
|
+
if @eof
|
521
|
+
raise EOFError
|
522
|
+
else
|
523
|
+
if p = @string[@pos..-1]=~rs
|
524
|
+
line = @string[@pos,p+1]
|
525
|
+
else
|
526
|
+
line = @string[@pos..-1]
|
527
|
+
end
|
528
|
+
@pos+=line.size
|
529
|
+
@eof =true if @pos==@string.size
|
530
|
+
$_ = line
|
531
|
+
end
|
532
|
+
end
|
533
|
+
def rewind
|
534
|
+
seek(0,0)
|
535
|
+
end
|
536
|
+
def seek(offset,whence)
|
537
|
+
case whence
|
538
|
+
when 0
|
539
|
+
@pos=offset
|
540
|
+
when 1
|
541
|
+
@pos+=offset
|
542
|
+
when 2
|
543
|
+
@pos=@string.size+offset
|
544
|
+
end
|
545
|
+
@eof=(@pos>=@string.size)
|
546
|
+
0
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
end
|
551
|
+
|
552
|
+
|
553
|
+
module YAML
|
554
|
+
|
555
|
+
#
|
556
|
+
# Constants
|
557
|
+
#
|
558
|
+
VERSION = '0.49'
|
559
|
+
SUPPORTED_YAML_VERSIONS = ['1.0']
|
560
|
+
|
561
|
+
#
|
562
|
+
# Parser tokens
|
563
|
+
#
|
564
|
+
WORD_CHAR = 'A-Za-z0-9'
|
565
|
+
PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
|
566
|
+
NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
|
567
|
+
ESCAPE_CHAR = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f]'
|
568
|
+
INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
|
569
|
+
SPACE_INDICATORS = '-#:,?'
|
570
|
+
RESTRICTED_INDICATORS = '#:,}]'
|
571
|
+
DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
|
572
|
+
DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
|
573
|
+
ESCAPES = %w{\z \x01 \x02 \x03 \x04 \x05 \x06 \a
|
574
|
+
\x08 \t \n \v \f \r \x0e \x0f
|
575
|
+
\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
|
576
|
+
\x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
|
577
|
+
}
|
578
|
+
UNESCAPES = {
|
579
|
+
'z' => "\x00", 'a' => "\x07", 'b' => "\x08", 't' => "\x09",
|
580
|
+
'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
|
581
|
+
'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
|
582
|
+
}
|
583
|
+
|
584
|
+
#
|
585
|
+
# Encodings ( $-K to ICONV )
|
586
|
+
#
|
587
|
+
CHARSETS = {
|
588
|
+
'NONE' => 'LATIN1',
|
589
|
+
'ASCII' => 'US-ASCII',
|
590
|
+
'UTF-8' => 'UTF-8',
|
591
|
+
'EUC' => 'EUC-JP',
|
592
|
+
'SJIS' => 'SHIFT-JIS'
|
593
|
+
}
|
594
|
+
|
595
|
+
#
|
596
|
+
# Error messages
|
597
|
+
#
|
598
|
+
ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
|
599
|
+
ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
|
600
|
+
ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
|
601
|
+
ERROR_MANY_EXPLICIT = "More than one explicit transfer"
|
602
|
+
ERROR_MANY_IMPLICIT = "More than one implicit request"
|
603
|
+
ERROR_NO_ANCHOR = "No anchor for alias '%s'"
|
604
|
+
ERROR_BAD_ANCHOR = "Invalid anchor: %s"
|
605
|
+
ERROR_MANY_ANCHOR = "More than one anchor"
|
606
|
+
ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
|
607
|
+
ERROR_BAD_ALIAS = "Invalid alias: %s"
|
608
|
+
ERROR_MANY_ALIAS = "More than one alias"
|
609
|
+
ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
|
610
|
+
ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
|
611
|
+
ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
|
612
|
+
|
613
|
+
#
|
614
|
+
# Default settings
|
615
|
+
#
|
616
|
+
DEFAULTS = {
|
617
|
+
:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
|
618
|
+
:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
|
619
|
+
:WidthType => 'absolute', :BestWidth => 80,
|
620
|
+
:UseBlock => false, :UseFold => false, :Encoding => :None
|
621
|
+
}
|
622
|
+
TRANSFER_DOMAINS = {
|
623
|
+
'yaml.org,2002' => {},
|
624
|
+
'ruby.yaml.org,2002' => {}
|
625
|
+
}
|
626
|
+
PRIVATE_TYPES = {}
|
627
|
+
IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
|
628
|
+
|
629
|
+
def YAML.object_maker( obj_class, val )
|
630
|
+
if Hash === val
|
631
|
+
o = obj_class.new_without_initialize
|
632
|
+
val.each_pair { |k,v|
|
633
|
+
o.instance_eval "@#{k} = v"
|
634
|
+
}
|
635
|
+
o
|
636
|
+
else
|
637
|
+
raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
#
|
642
|
+
# YAML documents can be in UTF-8, UTF-16 or UTF-32
|
643
|
+
# So let's read and write in Unicode
|
644
|
+
#
|
645
|
+
@@unicode = false
|
646
|
+
begin
|
647
|
+
require 'iconv'
|
648
|
+
DEFAULTS[:Encoding] = :Utf8
|
649
|
+
rescue LoadError
|
650
|
+
end
|
651
|
+
|
652
|
+
def YAML.unicode; @@unicode; end
|
653
|
+
def YAML.unicode=( bool ); @@unicode = bool; end
|
654
|
+
|
655
|
+
#
|
656
|
+
# YAML Error class
|
657
|
+
#
|
658
|
+
class Error < StandardError; end
|
659
|
+
class ParseError < Error; end
|
660
|
+
|
661
|
+
#
|
662
|
+
# YAML Generic Model container
|
663
|
+
#
|
664
|
+
class YamlNode
|
665
|
+
attr_accessor :kind, :type_id, :value, :anchor
|
666
|
+
def initialize( t, v )
|
667
|
+
@type_id = t
|
668
|
+
if Hash === v
|
669
|
+
@kind = 'map'
|
670
|
+
@value = {}
|
671
|
+
v.each { |k,v|
|
672
|
+
@value[ k.transform ] = [ k, v ]
|
673
|
+
}
|
674
|
+
elsif Array === v
|
675
|
+
@kind = 'seq'
|
676
|
+
@value = v
|
677
|
+
elsif String === v
|
678
|
+
@kind = 'scalar'
|
679
|
+
@value = v
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
#
|
684
|
+
# Search for YPath entry and return
|
685
|
+
# qualified nodes.
|
686
|
+
#
|
687
|
+
def select( ypath_str )
|
688
|
+
matches = match_path( ypath_str )
|
689
|
+
|
690
|
+
#
|
691
|
+
# Create a new generic view of the elements selected
|
692
|
+
#
|
693
|
+
if matches
|
694
|
+
result = []
|
695
|
+
matches.each { |m|
|
696
|
+
result.push m.last
|
697
|
+
}
|
698
|
+
YamlNode.new( 'seq', result )
|
699
|
+
end
|
700
|
+
end
|
701
|
+
|
702
|
+
#
|
703
|
+
# Search for YPath entry and return a list of
|
704
|
+
# qualified paths.
|
705
|
+
#
|
706
|
+
def search( ypath_str )
|
707
|
+
matches = match_path( ypath_str )
|
708
|
+
|
709
|
+
if matches
|
710
|
+
matches.collect { |m|
|
711
|
+
path = []
|
712
|
+
m.each_index { |i|
|
713
|
+
path.push m[i] if ( i % 2 ).zero?
|
714
|
+
}
|
715
|
+
"/" + path.compact.join( "/" )
|
716
|
+
}
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
720
|
+
def at( seg )
|
721
|
+
if Hash === @value and @value.has_key?( seg )
|
722
|
+
@value[seg][1]
|
723
|
+
elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
|
724
|
+
@value[seg.to_i]
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
#
|
729
|
+
# YPath search returning a complete depth array
|
730
|
+
#
|
731
|
+
def match_path( ypath_str )
|
732
|
+
depth = 0
|
733
|
+
matches = []
|
734
|
+
YPath.each_path( ypath_str ) do |ypath|
|
735
|
+
seg = match_segment( ypath, 0 )
|
736
|
+
matches += seg if seg
|
737
|
+
end
|
738
|
+
matches.uniq
|
739
|
+
end
|
740
|
+
|
741
|
+
#
|
742
|
+
# Search a node for a single YPath segment
|
743
|
+
#
|
744
|
+
def match_segment( ypath, depth )
|
745
|
+
deep_nodes = []
|
746
|
+
seg = ypath.segments[ depth ]
|
747
|
+
if seg == "/"
|
748
|
+
unless String === @value
|
749
|
+
idx = -1
|
750
|
+
@value.collect { |v|
|
751
|
+
idx += 1
|
752
|
+
if Hash === @value
|
753
|
+
match_init = [v[0], v[1][1]]
|
754
|
+
match_deep = v[1][1].match_segment( ypath, depth )
|
755
|
+
else
|
756
|
+
match_init = [idx, v]
|
757
|
+
match_deep = v.match_segment( ypath, depth )
|
758
|
+
end
|
759
|
+
if match_deep
|
760
|
+
match_deep.each { |m|
|
761
|
+
deep_nodes.push( match_init + m )
|
762
|
+
}
|
763
|
+
end
|
764
|
+
}
|
765
|
+
end
|
766
|
+
depth += 1
|
767
|
+
seg = ypath.segments[ depth ]
|
768
|
+
end
|
769
|
+
match_nodes =
|
770
|
+
case seg
|
771
|
+
when "."
|
772
|
+
[[nil, self]]
|
773
|
+
when ".."
|
774
|
+
[["..", nil]]
|
775
|
+
when "*"
|
776
|
+
unless String === @value
|
777
|
+
idx = -1
|
778
|
+
@value.collect { |h|
|
779
|
+
idx += 1
|
780
|
+
if Hash === @value
|
781
|
+
[h[0], h[1][1]]
|
782
|
+
else
|
783
|
+
[idx, h]
|
784
|
+
end
|
785
|
+
}
|
786
|
+
end
|
787
|
+
else
|
788
|
+
if seg =~ /^"(.*)"$/
|
789
|
+
seg = $1
|
790
|
+
elsif seg =~ /^'(.*)'$/
|
791
|
+
seg = $1
|
792
|
+
end
|
793
|
+
if ( v = at( seg ) )
|
794
|
+
[[ seg, v ]]
|
795
|
+
end
|
796
|
+
end
|
797
|
+
return deep_nodes unless match_nodes
|
798
|
+
pred = ypath.predicates[ depth ]
|
799
|
+
if pred
|
800
|
+
case pred
|
801
|
+
when /^\.=/
|
802
|
+
pred = $'
|
803
|
+
match_nodes.reject! { |n|
|
804
|
+
n.last.value != pred
|
805
|
+
}
|
806
|
+
else
|
807
|
+
match_nodes.reject! { |n|
|
808
|
+
n.last.at( pred ).nil?
|
809
|
+
}
|
810
|
+
end
|
811
|
+
end
|
812
|
+
return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
|
813
|
+
|
814
|
+
#puts "DEPTH: #{depth + 1}"
|
815
|
+
deep_nodes = []
|
816
|
+
match_nodes.each { |n|
|
817
|
+
if n[1].is_a? YamlNode
|
818
|
+
match_deep = n[1].match_segment( ypath, depth + 1 )
|
819
|
+
if match_deep
|
820
|
+
match_deep.each { |m|
|
821
|
+
deep_nodes.push( n + m )
|
822
|
+
}
|
823
|
+
end
|
824
|
+
else
|
825
|
+
deep_nodes = []
|
826
|
+
end
|
827
|
+
}
|
828
|
+
deep_nodes = nil if deep_nodes.length == 0
|
829
|
+
deep_nodes
|
830
|
+
end
|
831
|
+
|
832
|
+
#
|
833
|
+
# Transform this node fully into a native type
|
834
|
+
#
|
835
|
+
def transform
|
836
|
+
t = nil
|
837
|
+
if @value.is_a? Hash
|
838
|
+
t = {}
|
839
|
+
@value.each { |k,v|
|
840
|
+
t[ k ] = v[1].transform
|
841
|
+
}
|
842
|
+
elsif @value.is_a? Array
|
843
|
+
t = []
|
844
|
+
@value.each { |v|
|
845
|
+
t.push v.transform
|
846
|
+
}
|
847
|
+
else
|
848
|
+
t = @value
|
849
|
+
end
|
850
|
+
YAML.transfer_method( @type_id, t )
|
851
|
+
end
|
852
|
+
|
853
|
+
#
|
854
|
+
# We want the node to act like as Hash
|
855
|
+
# if it is.
|
856
|
+
#
|
857
|
+
def []( *k )
|
858
|
+
if Hash === @value
|
859
|
+
v = @value.[]( *k )
|
860
|
+
v[1] if v
|
861
|
+
elsif Array === @value
|
862
|
+
@value.[]( *k )
|
863
|
+
end
|
864
|
+
end
|
865
|
+
|
866
|
+
def children
|
867
|
+
if Hash === @value
|
868
|
+
@value.values.collect { |c| c[1] }
|
869
|
+
elsif Array === @value
|
870
|
+
@value
|
871
|
+
end
|
872
|
+
end
|
873
|
+
|
874
|
+
def children_with_index
|
875
|
+
if Hash === @value
|
876
|
+
@value.keys.collect { |i| [self[i], i] }
|
877
|
+
elsif Array === @value
|
878
|
+
i = -1; @value.collect { |v| i += 1; [v, i] }
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
def emit
|
883
|
+
transform.to_yaml
|
884
|
+
end
|
885
|
+
end
|
886
|
+
|
887
|
+
class YPath
|
888
|
+
attr_accessor :segments, :predicates, :flags
|
889
|
+
def initialize( str )
|
890
|
+
@segments = []
|
891
|
+
@predicates = []
|
892
|
+
@flags = nil
|
893
|
+
while str =~ /^\/?(\/|[^\/[]+)(?:\[([^\]]+)\])?/
|
894
|
+
@segments.push $1
|
895
|
+
@predicates.push $2
|
896
|
+
str = $'
|
897
|
+
end
|
898
|
+
unless str.to_s.empty?
|
899
|
+
@segments += str.split( "/" )
|
900
|
+
end
|
901
|
+
if @segments.length == 0
|
902
|
+
@segments.push "."
|
903
|
+
end
|
904
|
+
end
|
905
|
+
def YPath.each_path( str )
|
906
|
+
#
|
907
|
+
# Find choices
|
908
|
+
#
|
909
|
+
paths = []
|
910
|
+
str = "(#{ str })"
|
911
|
+
while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" )
|
912
|
+
paths.push $1.split( '|' )
|
913
|
+
end
|
914
|
+
|
915
|
+
#
|
916
|
+
# Construct all possible paths
|
917
|
+
#
|
918
|
+
all = [ str ]
|
919
|
+
( paths.length - 1 ).downto( 0 ) do |i|
|
920
|
+
all = all.collect do |a|
|
921
|
+
paths[i].collect do |p|
|
922
|
+
a.gsub( /\n#{ i }\n/, p )
|
923
|
+
end
|
924
|
+
end.flatten.uniq
|
925
|
+
end
|
926
|
+
all.collect do |path|
|
927
|
+
yield YPath.new( path )
|
928
|
+
end
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
#
|
933
|
+
# Class method for creating streams
|
934
|
+
#
|
935
|
+
def YAML.make_stream( io )
|
936
|
+
if String === io
|
937
|
+
io = StringIO.new( io )
|
938
|
+
#elsif not IO === io
|
939
|
+
# raise YAML::Error, "YAML stream must be an IO or String object."
|
940
|
+
# cnutter: This test was removed because GzipFile does not < IO in Ruby 1.8
|
941
|
+
end
|
942
|
+
if YAML::unicode
|
943
|
+
def io.readline
|
944
|
+
YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding )
|
945
|
+
end
|
946
|
+
def io.check_unicode
|
947
|
+
@utf_encoding = YAML.sniff_encoding( read( 4 ) )
|
948
|
+
@ln_sep = YAML.enc_separator( @utf_encoding )
|
949
|
+
seek( -4, IO::SEEK_CUR )
|
950
|
+
end
|
951
|
+
def io.utf_encoding
|
952
|
+
@utf_encoding
|
953
|
+
end
|
954
|
+
io.check_unicode
|
955
|
+
else
|
956
|
+
def io.utf_encoding
|
957
|
+
:None
|
958
|
+
end
|
959
|
+
end
|
960
|
+
io
|
961
|
+
end
|
962
|
+
|
963
|
+
#
|
964
|
+
# Unicode conversion
|
965
|
+
#
|
966
|
+
def YAML.utf_to_internal( str, from_enc )
|
967
|
+
return unless str
|
968
|
+
to_enc = CHARSETS[$-K]
|
969
|
+
case from_enc
|
970
|
+
when :Utf32
|
971
|
+
Iconv.iconv( to_enc, 'UTF-32', str )[0]
|
972
|
+
when :Utf16
|
973
|
+
Iconv.iconv( to_enc, 'UTF-16', str )[0]
|
974
|
+
when :Utf8
|
975
|
+
Iconv.iconv( to_enc, 'UTF-8', str )[0]
|
976
|
+
when :None
|
977
|
+
str
|
978
|
+
else
|
979
|
+
raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % from_enc.inspect
|
980
|
+
end
|
981
|
+
end
|
982
|
+
|
983
|
+
def YAML.internal_to_utf( str, to_enc )
|
984
|
+
return unless str
|
985
|
+
from_enc = CHARSETS[$-K]
|
986
|
+
case to_enc
|
987
|
+
when :Utf32
|
988
|
+
Iconv.iconv( 'UTF-32', from_enc, str )[0]
|
989
|
+
when :Utf16
|
990
|
+
Iconv.iconv( 'UTF-16', from_enc, str )[0]
|
991
|
+
when :Utf8
|
992
|
+
Iconv.iconv( 'UTF-8', from_enc, str )[0]
|
993
|
+
when :None
|
994
|
+
str
|
995
|
+
else
|
996
|
+
raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % to_enc.inspect
|
997
|
+
end
|
998
|
+
end
|
999
|
+
|
1000
|
+
def YAML.sniff_encoding( str )
|
1001
|
+
unless YAML::unicode
|
1002
|
+
:None
|
1003
|
+
else
|
1004
|
+
case str
|
1005
|
+
when /^\x00\x00\xFE\xFF/ # UTF-32
|
1006
|
+
:Utf32
|
1007
|
+
when /^\xFE\xFF/ # UTF-32BE
|
1008
|
+
:Utf16
|
1009
|
+
else
|
1010
|
+
:Utf8
|
1011
|
+
end
|
1012
|
+
end
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
def YAML.enc_separator( enc )
|
1016
|
+
case enc
|
1017
|
+
when :Utf32
|
1018
|
+
"\000\000\000\n"
|
1019
|
+
when :Utf16
|
1020
|
+
"\000\n"
|
1021
|
+
when :Utf8
|
1022
|
+
"\n"
|
1023
|
+
when :None
|
1024
|
+
"\n"
|
1025
|
+
else
|
1026
|
+
raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % enc.inspect
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
#
|
1031
|
+
# Output methods
|
1032
|
+
#
|
1033
|
+
|
1034
|
+
#
|
1035
|
+
# Emit a set of values
|
1036
|
+
#
|
1037
|
+
class Emitter
|
1038
|
+
attr_accessor :options
|
1039
|
+
def initialize( opts )
|
1040
|
+
opts = {} if opts.class != Hash
|
1041
|
+
@options = YAML::DEFAULTS.dup.update( opts )
|
1042
|
+
@headless = 0
|
1043
|
+
@seq_map = false
|
1044
|
+
@anchors = {}
|
1045
|
+
@anchor_extras = {}
|
1046
|
+
@active_anchors = []
|
1047
|
+
@level = -1
|
1048
|
+
self.clear
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
def clear
|
1052
|
+
@buffer = []
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
#
|
1056
|
+
# Version string
|
1057
|
+
#
|
1058
|
+
def version_s
|
1059
|
+
" %YAML:#{@options[:Version]}" if @options[:UseVersion]
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
#
|
1063
|
+
# Header
|
1064
|
+
#
|
1065
|
+
def header
|
1066
|
+
if @headless.nonzero?
|
1067
|
+
""
|
1068
|
+
else
|
1069
|
+
"---#{version_s} "
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
#
|
1074
|
+
# Emit binary data
|
1075
|
+
#
|
1076
|
+
def binary_base64( value )
|
1077
|
+
self << "!binary "
|
1078
|
+
self.node_text( [value].pack("m"), '|' )
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
#
|
1082
|
+
# Emit plain, normal flowing text
|
1083
|
+
#
|
1084
|
+
def node_text( value, block = '>' )
|
1085
|
+
valx = value.dup
|
1086
|
+
if @options[:UseBlock]
|
1087
|
+
block = '|'
|
1088
|
+
elsif not @options[:UseFold] and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
|
1089
|
+
block = '|'
|
1090
|
+
end
|
1091
|
+
str = block.dup
|
1092
|
+
if valx =~ /\n\Z\n/
|
1093
|
+
str << "+"
|
1094
|
+
elsif valx =~ /\Z\n/
|
1095
|
+
else
|
1096
|
+
str << "-"
|
1097
|
+
end
|
1098
|
+
if valx =~ /#{YAML::ESCAPE_CHAR}/
|
1099
|
+
valx = YAML::escape( valx )
|
1100
|
+
end
|
1101
|
+
if valx =~ /\A[ \t#]/
|
1102
|
+
str << @options[:Indent].to_s
|
1103
|
+
end
|
1104
|
+
if block == '>'
|
1105
|
+
valx = fold( valx )
|
1106
|
+
end
|
1107
|
+
self << str + indent_text( valx ) + "\n"
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
#
|
1111
|
+
# Emit a simple, unqouted string
|
1112
|
+
#
|
1113
|
+
def simple( value )
|
1114
|
+
self << value.to_s
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
#
|
1118
|
+
# Emit double-quoted string
|
1119
|
+
#
|
1120
|
+
def double( value )
|
1121
|
+
"\"#{YAML.escape( value )}\""
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
#
|
1125
|
+
# Emit single-quoted string
|
1126
|
+
#
|
1127
|
+
def single( value )
|
1128
|
+
"'#{value}'"
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
#
|
1132
|
+
# Write a text block with the current indent
|
1133
|
+
#
|
1134
|
+
def indent_text( text )
|
1135
|
+
return "" if text.to_s.empty?
|
1136
|
+
spacing = " " * ( @level * @options[:Indent] )
|
1137
|
+
return "\n" + text.gsub( /^([^\n])/, "#{spacing}\\1" )
|
1138
|
+
end
|
1139
|
+
|
1140
|
+
#
|
1141
|
+
# Write a current indent
|
1142
|
+
#
|
1143
|
+
def indent
|
1144
|
+
#p [ self.id, @level, :INDENT ]
|
1145
|
+
return " " * ( @level * @options[:Indent] )
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
#
|
1149
|
+
# Add indent to the buffer
|
1150
|
+
#
|
1151
|
+
def indent!
|
1152
|
+
self << indent
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
#
|
1156
|
+
# Folding paragraphs within a column
|
1157
|
+
#
|
1158
|
+
def fold( value )
|
1159
|
+
value.gsub!( /\A\n+/, '' )
|
1160
|
+
folded = $&.to_s
|
1161
|
+
width = (0..@options[:BestWidth])
|
1162
|
+
while not value.empty?
|
1163
|
+
last = value.index( /(\n+)/ )
|
1164
|
+
chop_s = false
|
1165
|
+
if width.include?( last )
|
1166
|
+
last += $1.length - 1
|
1167
|
+
elsif width.include?( value.length )
|
1168
|
+
last = value.length
|
1169
|
+
else
|
1170
|
+
last = value.rindex( /[ \t]/, @options[:BestWidth] )
|
1171
|
+
chop_s = true
|
1172
|
+
end
|
1173
|
+
folded += value.slice!( 0, width.include?( last ) ? last + 1 : @options[:BestWidth] )
|
1174
|
+
folded.chop! if chop_s
|
1175
|
+
folded += "\n" unless value.empty?
|
1176
|
+
end
|
1177
|
+
folded
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
#
|
1181
|
+
# Quick mapping
|
1182
|
+
#
|
1183
|
+
def map( type, &e )
|
1184
|
+
val = Mapping.new
|
1185
|
+
e.call( val )
|
1186
|
+
self << "#{type} " if type.length.nonzero?
|
1187
|
+
|
1188
|
+
#
|
1189
|
+
# Empty hashes
|
1190
|
+
#
|
1191
|
+
if val.length.zero?
|
1192
|
+
self << "{}"
|
1193
|
+
else
|
1194
|
+
if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero?
|
1195
|
+
@headless = 1
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
defkey = @options.delete( :DefaultKey )
|
1199
|
+
if defkey
|
1200
|
+
seq_map_shortcut
|
1201
|
+
self << "= : "
|
1202
|
+
defkey.to_yaml( :Emitter => self )
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
#
|
1206
|
+
# Emit the key and value
|
1207
|
+
#
|
1208
|
+
val.each { |v|
|
1209
|
+
seq_map_shortcut
|
1210
|
+
if v[0].is_complex_yaml?
|
1211
|
+
self << "? "
|
1212
|
+
end
|
1213
|
+
v[0].to_yaml( :Emitter => self )
|
1214
|
+
if v[0].is_complex_yaml?
|
1215
|
+
self << "\n"
|
1216
|
+
indent!
|
1217
|
+
end
|
1218
|
+
self << ": "
|
1219
|
+
v[1].to_yaml( :Emitter => self )
|
1220
|
+
}
|
1221
|
+
end
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
def seq_map_shortcut
|
1225
|
+
if @seq_map
|
1226
|
+
@anchor_extras[@buffer.length - 1] = "\n" + indent
|
1227
|
+
@seq_map = false
|
1228
|
+
else
|
1229
|
+
self << "\n"
|
1230
|
+
indent!
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
#
|
1235
|
+
# Quick sequence
|
1236
|
+
#
|
1237
|
+
def seq( type, &e )
|
1238
|
+
val = Sequence.new
|
1239
|
+
e.call( val )
|
1240
|
+
self << "#{type} " if type.length.nonzero?
|
1241
|
+
|
1242
|
+
#
|
1243
|
+
# Empty arrays
|
1244
|
+
#
|
1245
|
+
if val.length.zero?
|
1246
|
+
self << "[]"
|
1247
|
+
else
|
1248
|
+
if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero?
|
1249
|
+
@headless = 1
|
1250
|
+
end
|
1251
|
+
#
|
1252
|
+
# Emit the key and value
|
1253
|
+
#
|
1254
|
+
val.each { |v|
|
1255
|
+
self << "\n"
|
1256
|
+
indent!
|
1257
|
+
self << "- "
|
1258
|
+
@seq_map = true if v.class == Hash
|
1259
|
+
v.to_yaml( :Emitter => self )
|
1260
|
+
}
|
1261
|
+
end
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
#
|
1265
|
+
# Concatenate to the buffer
|
1266
|
+
#
|
1267
|
+
def <<( str )
|
1268
|
+
#p [ self.id, @level, str ]
|
1269
|
+
@buffer.last << str
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
#
|
1273
|
+
# Monitor objects and allow references
|
1274
|
+
#
|
1275
|
+
def start_object( oid )
|
1276
|
+
@level += 1
|
1277
|
+
@buffer.push( "" )
|
1278
|
+
#p [ self.id, @level, :OPEN ]
|
1279
|
+
idx = nil
|
1280
|
+
if oid
|
1281
|
+
if @anchors.has_key?( oid )
|
1282
|
+
idx = @active_anchors.index( oid )
|
1283
|
+
unless idx
|
1284
|
+
idx = @active_anchors.length
|
1285
|
+
af_str = "&#{@options[:AnchorFormat]} " % [ idx + 1 ]
|
1286
|
+
af_str += @anchor_extras[ @anchors[ oid ] ].to_s
|
1287
|
+
@buffer[ @anchors[ oid ] ][0,0] = af_str
|
1288
|
+
@headless = 0 if @anchors[ oid ].zero?
|
1289
|
+
end
|
1290
|
+
idx += 1
|
1291
|
+
@active_anchors.push( oid )
|
1292
|
+
else
|
1293
|
+
@anchors[ oid ] = @buffer.length - 1
|
1294
|
+
end
|
1295
|
+
end
|
1296
|
+
return idx
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
#
|
1300
|
+
# Output method
|
1301
|
+
#
|
1302
|
+
def end_object
|
1303
|
+
@level -= 1
|
1304
|
+
@buffer.push( "" )
|
1305
|
+
#p [ self.id, @level, :END ]
|
1306
|
+
if @level < 0
|
1307
|
+
YAML.internal_to_utf( header + @buffer.to_s[@headless..-1], @options[:Encoding] )
|
1308
|
+
end
|
1309
|
+
end
|
1310
|
+
end
|
1311
|
+
|
1312
|
+
#
|
1313
|
+
# Emitter helper classes
|
1314
|
+
#
|
1315
|
+
class Mapping < Array
|
1316
|
+
def add( k, v )
|
1317
|
+
push [k, v]
|
1318
|
+
end
|
1319
|
+
end
|
1320
|
+
|
1321
|
+
class Sequence < Array
|
1322
|
+
def add( v )
|
1323
|
+
push v
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
#
|
1328
|
+
# Input methods
|
1329
|
+
#
|
1330
|
+
|
1331
|
+
#
|
1332
|
+
# Load a single document from the current stream
|
1333
|
+
#
|
1334
|
+
def YAML.load( io )
|
1335
|
+
yp = YAML::Parser.new.parse( io )
|
1336
|
+
end
|
1337
|
+
|
1338
|
+
#
|
1339
|
+
# Parse a single document from the current stream
|
1340
|
+
#
|
1341
|
+
def YAML.parse( io )
|
1342
|
+
yp = YAML::Parser.new( :Model => :Generic ).parse( io )
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
#
|
1346
|
+
# Load all documents from the current stream
|
1347
|
+
#
|
1348
|
+
def YAML.each_document( io, &doc_proc )
|
1349
|
+
yp = YAML::Parser.new.parse_documents( io, &doc_proc )
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
#
|
1353
|
+
# Identical to each_document
|
1354
|
+
#
|
1355
|
+
def YAML.load_documents( io, &doc_proc )
|
1356
|
+
YAML.each_document( io, &doc_proc )
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
#
|
1360
|
+
# Parse all documents from the current stream
|
1361
|
+
#
|
1362
|
+
def YAML.each_node( io, &doc_proc )
|
1363
|
+
yp = YAML::Parser.new( :Model => :Generic ).parse_documents( io, &doc_proc )
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
#
|
1367
|
+
# Parse all documents from the current stream
|
1368
|
+
#
|
1369
|
+
def YAML.parse_documents( io, &doc_proc )
|
1370
|
+
YAML.each_node( io, &doc_proc )
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
#
|
1374
|
+
# Load all documents from the current stream
|
1375
|
+
#
|
1376
|
+
def YAML.load_stream( io )
|
1377
|
+
yp = YAML::Parser.new
|
1378
|
+
d = nil
|
1379
|
+
yp.parse_documents( io ) { |doc|
|
1380
|
+
d = YAML::Stream.new( yp.options ) if not d
|
1381
|
+
d.add( doc )
|
1382
|
+
}
|
1383
|
+
return d
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
#
|
1387
|
+
# Racc parser will go here
|
1388
|
+
#
|
1389
|
+
# class Parser; def initialize; raise YAML::Error, "No parser available"; end; end
|
1390
|
+
|
1391
|
+
#
|
1392
|
+
# Add a transfer method to a domain
|
1393
|
+
#
|
1394
|
+
def YAML.add_domain_type( domain, type_re, &transfer_proc )
|
1395
|
+
type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
|
1396
|
+
if not YAML::TRANSFER_DOMAINS.has_key?( domain )
|
1397
|
+
YAML::TRANSFER_DOMAINS[ domain ] = {}
|
1398
|
+
end
|
1399
|
+
YAML::TRANSFER_DOMAINS[ domain ][ type_re ] = transfer_proc
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
#
|
1403
|
+
# Add a transfer method for a builtin type
|
1404
|
+
#
|
1405
|
+
def YAML.add_builtin_type( type_re, &transfer_proc )
|
1406
|
+
type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
|
1407
|
+
YAML::TRANSFER_DOMAINS[ 'yaml.org,2002' ][ type_re ] = transfer_proc
|
1408
|
+
end
|
1409
|
+
|
1410
|
+
#
|
1411
|
+
# Add a transfer method for a builtin type
|
1412
|
+
#
|
1413
|
+
def YAML.add_ruby_type( type, &transfer_proc )
|
1414
|
+
type_re = /^#{Regexp::quote( type.to_s )}(?::.+)?$/i
|
1415
|
+
YAML::TRANSFER_DOMAINS[ 'ruby.yaml.org,2002' ][ type_re ] = transfer_proc
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
#
|
1419
|
+
# Add a private document type
|
1420
|
+
#
|
1421
|
+
def YAML.add_private_type( type_re, &transfer_proc )
|
1422
|
+
type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
|
1423
|
+
YAML::PRIVATE_TYPES[ type_re ] = transfer_proc
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
#
|
1427
|
+
# Method to extract colon-seperated type and class, returning
|
1428
|
+
# the type and the constant of the class
|
1429
|
+
#
|
1430
|
+
def YAML.read_type_class( type, obj_class )
|
1431
|
+
type =~ /^([^:]+):(.+)/i
|
1432
|
+
if $2
|
1433
|
+
type = $1
|
1434
|
+
$2.split( "::" ).each { |c|
|
1435
|
+
obj_class = obj_class.const_get( c )
|
1436
|
+
}
|
1437
|
+
end
|
1438
|
+
return [ type, obj_class ]
|
1439
|
+
end
|
1440
|
+
|
1441
|
+
#
|
1442
|
+
# Default private type
|
1443
|
+
#
|
1444
|
+
class PrivateType
|
1445
|
+
attr_accessor :type_id, :value
|
1446
|
+
def initialize( type, val )
|
1447
|
+
@type_id = type; @value = val
|
1448
|
+
end
|
1449
|
+
def to_yaml( opts = {} )
|
1450
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1451
|
+
out << " !!#{@type_id}"
|
1452
|
+
value.to_yaml( :Emitter => out )
|
1453
|
+
}
|
1454
|
+
end
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
#
|
1458
|
+
# Default domain type
|
1459
|
+
#
|
1460
|
+
class DomainType
|
1461
|
+
attr_accessor :domain, :type_id, :value
|
1462
|
+
def initialize( domain, type, val )
|
1463
|
+
@domain = domain; @type_id = type; @value = val
|
1464
|
+
end
|
1465
|
+
def to_yaml_type
|
1466
|
+
dom = @domain.dup
|
1467
|
+
if dom =~ /\.yaml\.org,2002$/
|
1468
|
+
dom = $`
|
1469
|
+
end
|
1470
|
+
"#{dom}/#{@type_id}"
|
1471
|
+
end
|
1472
|
+
def to_yaml( opts = {} )
|
1473
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1474
|
+
out << " !#{to_yaml_type} "
|
1475
|
+
value.to_yaml( :Emitter => out )
|
1476
|
+
}
|
1477
|
+
end
|
1478
|
+
end
|
1479
|
+
|
1480
|
+
#
|
1481
|
+
# Utility functions
|
1482
|
+
#
|
1483
|
+
|
1484
|
+
#
|
1485
|
+
# Handle all transfer methods
|
1486
|
+
# http://www.yaml.org/spec/#syntax-trans
|
1487
|
+
#
|
1488
|
+
def YAML.transfer_method( type, val )
|
1489
|
+
domain = "yaml.org,2002"
|
1490
|
+
|
1491
|
+
#
|
1492
|
+
# Figure out the domain
|
1493
|
+
#
|
1494
|
+
if type =~ /^(\w+)\/(.+)$/
|
1495
|
+
domain = "#{$1}.yaml.org,2002"; type = $2
|
1496
|
+
elsif type =~ /^(#{DNS_NAME_RE},\d{4}(?:-\d{2}){0,2})\/(.+)$/
|
1497
|
+
domain = $1; type = $2
|
1498
|
+
end
|
1499
|
+
|
1500
|
+
#
|
1501
|
+
# Route the data, transfer it
|
1502
|
+
#
|
1503
|
+
begin
|
1504
|
+
r = nil
|
1505
|
+
if type == ""
|
1506
|
+
YAML.try_implicit( val )
|
1507
|
+
elsif type =~ /^!(.*)/
|
1508
|
+
type = $1
|
1509
|
+
if YAML::PRIVATE_TYPES.keys.detect { |r| type =~ r }
|
1510
|
+
YAML::PRIVATE_TYPES[r].call( type, val )
|
1511
|
+
else
|
1512
|
+
YAML::PrivateType.new( type, val )
|
1513
|
+
end
|
1514
|
+
else
|
1515
|
+
type = YAML.escape( type )
|
1516
|
+
if YAML::TRANSFER_DOMAINS.has_key?( domain ) and
|
1517
|
+
YAML::TRANSFER_DOMAINS[domain].keys.detect { |r| type =~ r }
|
1518
|
+
YAML::TRANSFER_DOMAINS[domain][r].call( type, val )
|
1519
|
+
else
|
1520
|
+
YAML::DomainType.new( domain, type, val )
|
1521
|
+
end
|
1522
|
+
end
|
1523
|
+
end
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
#
|
1527
|
+
# Try a string against all implicit YAML types
|
1528
|
+
# http://www.yaml.org/spec/#trans
|
1529
|
+
#
|
1530
|
+
def YAML.detect_implicit( str )
|
1531
|
+
r = nil
|
1532
|
+
YAML::IMPLICIT_TYPES.each { |type|
|
1533
|
+
if YAML::TRANSFER_DOMAINS['yaml.org,2002'].keys.detect { |r| type =~ r }
|
1534
|
+
val = YAML::TRANSFER_DOMAINS['yaml.org,2002'][r].call( :Implicit, str )
|
1535
|
+
return type unless Symbol === val and val == :InvalidType
|
1536
|
+
end
|
1537
|
+
}
|
1538
|
+
return 'str'
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
#
|
1542
|
+
# Uses the implicit if found
|
1543
|
+
#
|
1544
|
+
def YAML.try_implicit( str )
|
1545
|
+
type = YAML.detect_implicit( str )
|
1546
|
+
YAML.transfer_method( type, str )
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
#
|
1550
|
+
# Make a time with the time zone
|
1551
|
+
#
|
1552
|
+
def YAML.mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
|
1553
|
+
usec = usec.to_s.to_f * 1000000
|
1554
|
+
val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
|
1555
|
+
if zone != "Z"
|
1556
|
+
hour = zone[0,3].to_i * 3600
|
1557
|
+
min = zone[3,2].to_i * 60
|
1558
|
+
ofs = (hour + min)
|
1559
|
+
val = Time.at( val.to_f - ofs )
|
1560
|
+
end
|
1561
|
+
return val
|
1562
|
+
end
|
1563
|
+
|
1564
|
+
#
|
1565
|
+
# Retrieve plain scalar regexp
|
1566
|
+
#
|
1567
|
+
def YAML.plain_re( allow = '' )
|
1568
|
+
space_set = ''
|
1569
|
+
restrict_set = RESTRICTED_INDICATORS.delete( allow )
|
1570
|
+
restrict_set.split( // ).each { |ind|
|
1571
|
+
if ind == "#"
|
1572
|
+
space_set << "[^#\\s]#+|#+[^#\\s]|"
|
1573
|
+
elsif SPACE_INDICATORS.include?( ind )
|
1574
|
+
ind = Regexp::quote( ind )
|
1575
|
+
space_set << "#{ind}+[^#{ind}\\s]|"
|
1576
|
+
end
|
1577
|
+
}
|
1578
|
+
/\A([^#{NOT_PLAIN_CHAR}#{Regexp::quote(INDICATOR_CHAR)}](?:#{space_set}[^#{NOT_PLAIN_CHAR}#{Regexp::quote(restrict_set)}])*)/
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
#
|
1582
|
+
# Escape the string, condensing common escapes
|
1583
|
+
#
|
1584
|
+
def YAML.escape( value )
|
1585
|
+
value.gsub( /\\/, "\\\\\\" ).gsub( /"/, "\\\"" ).gsub( /([\x00-\x1f])/ ) { |x| ESCAPES[ x.unpack("C")[0] ] }
|
1586
|
+
end
|
1587
|
+
|
1588
|
+
#
|
1589
|
+
# Unescape the condenses escapes
|
1590
|
+
#
|
1591
|
+
def YAML.unescape( value )
|
1592
|
+
value.gsub( /\\(?:([nevbr\\fartz])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { |x|
|
1593
|
+
if $3
|
1594
|
+
["#$3".hex ].pack('U*')
|
1595
|
+
elsif $2
|
1596
|
+
[$2].pack( "H2" )
|
1597
|
+
else
|
1598
|
+
UNESCAPES[$1]
|
1599
|
+
end
|
1600
|
+
}
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
#
|
1604
|
+
# YAML::Stream -- for emitting many documents
|
1605
|
+
#
|
1606
|
+
class Stream
|
1607
|
+
|
1608
|
+
attr_accessor :documents, :options
|
1609
|
+
|
1610
|
+
def initialize( opts = {} )
|
1611
|
+
@options = opts
|
1612
|
+
@documents = []
|
1613
|
+
end
|
1614
|
+
|
1615
|
+
def []( i )
|
1616
|
+
@documents[ i ]
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
def add( doc )
|
1620
|
+
@documents << doc
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
def edit( doc_num, doc )
|
1624
|
+
@documents[ doc_num ] = doc
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
def emit
|
1628
|
+
opts = @options.dup
|
1629
|
+
opts[:UseHeader] = true if @documents.length > 1
|
1630
|
+
ct = 0
|
1631
|
+
out = Emitter.new( opts )
|
1632
|
+
@documents.each { |v|
|
1633
|
+
if ct > 0
|
1634
|
+
out << "\n--- "
|
1635
|
+
end
|
1636
|
+
v.to_yaml( :Emitter => out )
|
1637
|
+
ct += 1
|
1638
|
+
}
|
1639
|
+
out.end_object
|
1640
|
+
end
|
1641
|
+
|
1642
|
+
end
|
1643
|
+
|
1644
|
+
#
|
1645
|
+
# Allocate an Emitter if needed
|
1646
|
+
#
|
1647
|
+
def YAML.quick_emit( oid, opts = {}, &e )
|
1648
|
+
old_opt = nil
|
1649
|
+
if opts[:Emitter].is_a? YAML::Emitter
|
1650
|
+
out = opts.delete( :Emitter )
|
1651
|
+
old_opt = out.options.dup
|
1652
|
+
out.options.update( opts )
|
1653
|
+
else
|
1654
|
+
out = YAML::Emitter.new( opts )
|
1655
|
+
end
|
1656
|
+
aidx = out.start_object( oid )
|
1657
|
+
if aidx
|
1658
|
+
out.simple( "*#{out.options[:AnchorFormat]} " % [ aidx ] )
|
1659
|
+
else
|
1660
|
+
e.call( out )
|
1661
|
+
end
|
1662
|
+
if old_opt.is_a? Hash
|
1663
|
+
out.options = old_opt
|
1664
|
+
end
|
1665
|
+
out.end_object
|
1666
|
+
end
|
1667
|
+
|
1668
|
+
#
|
1669
|
+
# YAML::Store -- Pstore replacement
|
1670
|
+
#
|
1671
|
+
class Store < PStore
|
1672
|
+
#
|
1673
|
+
# Constructor
|
1674
|
+
#
|
1675
|
+
def initialize( *o )
|
1676
|
+
@opt = YAML::DEFAULTS.dup
|
1677
|
+
if String === o.first
|
1678
|
+
super(o.pop)
|
1679
|
+
end
|
1680
|
+
if o.last.is_a? Hash
|
1681
|
+
@opt.update(o.pop)
|
1682
|
+
end
|
1683
|
+
end
|
1684
|
+
|
1685
|
+
#
|
1686
|
+
# Override Pstore#transaction
|
1687
|
+
#
|
1688
|
+
def transaction
|
1689
|
+
raise YAML::Error, "nested transaction" if @transaction
|
1690
|
+
raise YAML::Error, "no filename for transaction" unless @filename
|
1691
|
+
begin
|
1692
|
+
@transaction = true
|
1693
|
+
value = nil
|
1694
|
+
backup = @filename+"~"
|
1695
|
+
if File::exist?(@filename)
|
1696
|
+
file = File::open(@filename, "rb+")
|
1697
|
+
orig = true
|
1698
|
+
else
|
1699
|
+
@table = {}
|
1700
|
+
file = File::open(@filename, "wb+")
|
1701
|
+
file.write( @table.to_yaml( @opt ) )
|
1702
|
+
end
|
1703
|
+
file.flock(File::LOCK_EX)
|
1704
|
+
if orig
|
1705
|
+
File::copy @filename, backup
|
1706
|
+
@table = YAML::load( file )
|
1707
|
+
end
|
1708
|
+
begin
|
1709
|
+
catch(:pstore_abort_transaction) do
|
1710
|
+
value = yield(self)
|
1711
|
+
end
|
1712
|
+
rescue Exception
|
1713
|
+
@abort = true
|
1714
|
+
raise
|
1715
|
+
ensure
|
1716
|
+
unless @abort
|
1717
|
+
begin
|
1718
|
+
file.rewind
|
1719
|
+
file.write( @table.to_yaml( @opt ) )
|
1720
|
+
file.truncate(file.pos)
|
1721
|
+
rescue
|
1722
|
+
File::rename backup, @filename if File::exist?(backup)
|
1723
|
+
raise
|
1724
|
+
end
|
1725
|
+
end
|
1726
|
+
@abort = false
|
1727
|
+
end
|
1728
|
+
ensure
|
1729
|
+
@table = nil
|
1730
|
+
@transaction = false
|
1731
|
+
file.close if file
|
1732
|
+
end
|
1733
|
+
value
|
1734
|
+
end
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
#
|
1738
|
+
# YAML Hash class to support comments and defaults
|
1739
|
+
#
|
1740
|
+
class SpecialHash < Hash
|
1741
|
+
attr_accessor :default
|
1742
|
+
def inspect
|
1743
|
+
self.default.to_s
|
1744
|
+
end
|
1745
|
+
def to_s
|
1746
|
+
self.default.to_s
|
1747
|
+
end
|
1748
|
+
def update( h )
|
1749
|
+
if YAML::SpecialHash === h
|
1750
|
+
@default = h.default if h.default
|
1751
|
+
end
|
1752
|
+
super( h )
|
1753
|
+
end
|
1754
|
+
def to_yaml( opts = {} )
|
1755
|
+
opts[:DefaultKey] = self.default
|
1756
|
+
super( opts )
|
1757
|
+
end
|
1758
|
+
end
|
1759
|
+
|
1760
|
+
#
|
1761
|
+
# Builtin collection: !omap
|
1762
|
+
#
|
1763
|
+
class Omap < Array
|
1764
|
+
def self.[]( *vals )
|
1765
|
+
o = Omap.new
|
1766
|
+
0.step( vals.length - 1, 2 ) { |i|
|
1767
|
+
o[vals[i]] = vals[i+1]
|
1768
|
+
}
|
1769
|
+
o
|
1770
|
+
end
|
1771
|
+
def []( k )
|
1772
|
+
self.assoc( k ).to_a[1]
|
1773
|
+
end
|
1774
|
+
def []=( k, *rest )
|
1775
|
+
val, set = rest.reverse
|
1776
|
+
if ( tmp = self.assoc( k ) ) and not set
|
1777
|
+
tmp[1] = val
|
1778
|
+
else
|
1779
|
+
self << [ k, val ]
|
1780
|
+
end
|
1781
|
+
val
|
1782
|
+
end
|
1783
|
+
def has_key?( k )
|
1784
|
+
self.assoc( k ) ? true : false
|
1785
|
+
end
|
1786
|
+
def is_complex_yaml?
|
1787
|
+
true
|
1788
|
+
end
|
1789
|
+
def to_yaml( opts = {} )
|
1790
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1791
|
+
out.seq( "!omap" ) { |seq|
|
1792
|
+
self.each { |v|
|
1793
|
+
seq.add( Hash[ *v ] )
|
1794
|
+
}
|
1795
|
+
}
|
1796
|
+
}
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
YAML.add_builtin_type( "omap" ) { |type, val|
|
1801
|
+
if Array === val
|
1802
|
+
p = Omap.new
|
1803
|
+
val.each { |v|
|
1804
|
+
if Hash === v
|
1805
|
+
p.concat( v.to_a ) # Convert the map to a sequence
|
1806
|
+
else
|
1807
|
+
raise YAML::Error, "Invalid !omap entry: " + val.inspect
|
1808
|
+
end
|
1809
|
+
}
|
1810
|
+
else
|
1811
|
+
raise YAML::Error, "Invalid !omap: " + val.inspect
|
1812
|
+
end
|
1813
|
+
p
|
1814
|
+
}
|
1815
|
+
|
1816
|
+
#
|
1817
|
+
# Builtin collection: !pairs
|
1818
|
+
#
|
1819
|
+
class Pairs < Array
|
1820
|
+
def self.[]( *vals )
|
1821
|
+
p = Pairs.new
|
1822
|
+
0.step( vals.length - 1, 2 ) { |i|
|
1823
|
+
p[vals[i]] = vals[i+1]
|
1824
|
+
}
|
1825
|
+
p
|
1826
|
+
end
|
1827
|
+
def []( k )
|
1828
|
+
self.assoc( k ).to_a
|
1829
|
+
end
|
1830
|
+
def []=( k, val )
|
1831
|
+
self << [ k, val ]
|
1832
|
+
val
|
1833
|
+
end
|
1834
|
+
def has_key?( k )
|
1835
|
+
self.assoc( k ) ? true : false
|
1836
|
+
end
|
1837
|
+
def is_complex_yaml?
|
1838
|
+
true
|
1839
|
+
end
|
1840
|
+
def to_yaml( opts = {} )
|
1841
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1842
|
+
out.seq( "!pairs" ) { |seq|
|
1843
|
+
self.each { |v|
|
1844
|
+
seq.add( Hash[ *v ] )
|
1845
|
+
}
|
1846
|
+
}
|
1847
|
+
}
|
1848
|
+
end
|
1849
|
+
end
|
1850
|
+
|
1851
|
+
YAML.add_builtin_type( "pairs" ) { |type, val|
|
1852
|
+
if Array === val
|
1853
|
+
p = Pairs.new
|
1854
|
+
val.each { |v|
|
1855
|
+
if Hash === v
|
1856
|
+
p.concat( v.to_a ) # Convert the map to a sequence
|
1857
|
+
else
|
1858
|
+
raise YAML::Error, "Invalid !pairs entry: " + val.inspect
|
1859
|
+
end
|
1860
|
+
}
|
1861
|
+
else
|
1862
|
+
raise YAML::Error, "Invalid !pairs: " + val.inspect
|
1863
|
+
end
|
1864
|
+
p
|
1865
|
+
}
|
1866
|
+
|
1867
|
+
#
|
1868
|
+
# Builtin collection: !set
|
1869
|
+
#
|
1870
|
+
class Set < Hash
|
1871
|
+
def to_yaml_type
|
1872
|
+
"!set"
|
1873
|
+
end
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
YAML.add_builtin_type( 'set' ) { |type, val|
|
1877
|
+
if Array === val
|
1878
|
+
val = Set[ *val ]
|
1879
|
+
elsif Hash === val
|
1880
|
+
Set[ val ]
|
1881
|
+
else
|
1882
|
+
raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
|
1883
|
+
end
|
1884
|
+
val
|
1885
|
+
}
|
1886
|
+
|
1887
|
+
#
|
1888
|
+
# Ruby-specific collection: !ruby/flexhash
|
1889
|
+
#
|
1890
|
+
class FlexHash < Array
|
1891
|
+
def []( k )
|
1892
|
+
self.assoc( k ).to_a[1]
|
1893
|
+
end
|
1894
|
+
def []=( k, *rest )
|
1895
|
+
val, set = rest.reverse
|
1896
|
+
if ( tmp = self.assoc( k ) ) and not set
|
1897
|
+
tmp[1] = val
|
1898
|
+
else
|
1899
|
+
self << [ k, val ]
|
1900
|
+
end
|
1901
|
+
val
|
1902
|
+
end
|
1903
|
+
def has_key?( k )
|
1904
|
+
self.assoc( k ) ? true : false
|
1905
|
+
end
|
1906
|
+
def is_complex_yaml?
|
1907
|
+
true
|
1908
|
+
end
|
1909
|
+
def to_yaml( opts = {} )
|
1910
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1911
|
+
out.seq( "!ruby/flexhash" ) { |seq|
|
1912
|
+
self.each { |v|
|
1913
|
+
if v[1]
|
1914
|
+
seq.add( Hash.[]( *v ) )
|
1915
|
+
else
|
1916
|
+
seq.add( v[0] )
|
1917
|
+
end
|
1918
|
+
}
|
1919
|
+
}
|
1920
|
+
}
|
1921
|
+
end
|
1922
|
+
end
|
1923
|
+
|
1924
|
+
YAML.add_ruby_type( :flexhash ) { |type, val|
|
1925
|
+
if Array === val
|
1926
|
+
p = FlexHash.new
|
1927
|
+
val.each { |v|
|
1928
|
+
if Hash === v
|
1929
|
+
p.concat( v.to_a ) # Convert the map to a sequence
|
1930
|
+
else
|
1931
|
+
p << [ v, nil ]
|
1932
|
+
end
|
1933
|
+
}
|
1934
|
+
p
|
1935
|
+
else
|
1936
|
+
raise YAML::Error, "Invalid !ruby/flexhash: " + val.inspect
|
1937
|
+
end
|
1938
|
+
}
|
1939
|
+
|
1940
|
+
end
|
1941
|
+
|
1942
|
+
#
|
1943
|
+
# Type conversions
|
1944
|
+
#
|
1945
|
+
class Object
|
1946
|
+
def is_complex_yaml?
|
1947
|
+
true
|
1948
|
+
end
|
1949
|
+
def to_yaml_type
|
1950
|
+
"!ruby/object:#{self.class}"
|
1951
|
+
end
|
1952
|
+
def to_yaml_properties
|
1953
|
+
instance_variables.sort
|
1954
|
+
end
|
1955
|
+
def to_yaml( opts = {} )
|
1956
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
1957
|
+
out.map( self.to_yaml_type ) { |map|
|
1958
|
+
to_yaml_properties.each { |m|
|
1959
|
+
map.add( m[1..-1], instance_eval( m ) )
|
1960
|
+
}
|
1961
|
+
}
|
1962
|
+
}
|
1963
|
+
end
|
1964
|
+
end
|
1965
|
+
|
1966
|
+
class Class
|
1967
|
+
def new_without_initialize( *args )
|
1968
|
+
self.class_eval %{
|
1969
|
+
alias :old_initialize_with_args :initialize
|
1970
|
+
def initialize( *args ); end
|
1971
|
+
}
|
1972
|
+
begin
|
1973
|
+
result = self.new( *args )
|
1974
|
+
ensure
|
1975
|
+
self.class_eval %{
|
1976
|
+
alias :initialize :old_initialize_with_args
|
1977
|
+
}
|
1978
|
+
end
|
1979
|
+
result
|
1980
|
+
end
|
1981
|
+
end
|
1982
|
+
|
1983
|
+
YAML.add_ruby_type( Object ) { |type, val|
|
1984
|
+
type, obj_class = YAML.read_type_class( type, Object )
|
1985
|
+
YAML.object_maker( obj_class, val )
|
1986
|
+
}
|
1987
|
+
|
1988
|
+
#
|
1989
|
+
# Maps: Hash#to_yaml
|
1990
|
+
#
|
1991
|
+
class Hash
|
1992
|
+
def is_complex_yaml?
|
1993
|
+
true
|
1994
|
+
end
|
1995
|
+
def to_yaml_type
|
1996
|
+
if self.class == Hash or self.class == YAML::SpecialHash
|
1997
|
+
"!map"
|
1998
|
+
else
|
1999
|
+
"!ruby/hash:#{self.class}"
|
2000
|
+
end
|
2001
|
+
end
|
2002
|
+
def to_yaml( opts = {} )
|
2003
|
+
opts[:DocType] = self.class if Hash === opts
|
2004
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
2005
|
+
hash_type = to_yaml_type
|
2006
|
+
if not out.options[:ExplicitTypes] and hash_type == "!map"
|
2007
|
+
hash_type = ""
|
2008
|
+
end
|
2009
|
+
out.map( hash_type ) { |map|
|
2010
|
+
#
|
2011
|
+
# Sort the hash
|
2012
|
+
#
|
2013
|
+
if out.options[:SortKeys]
|
2014
|
+
map.concat( self.sort )
|
2015
|
+
else
|
2016
|
+
map.concat( self.to_a )
|
2017
|
+
end
|
2018
|
+
}
|
2019
|
+
}
|
2020
|
+
end
|
2021
|
+
end
|
2022
|
+
|
2023
|
+
hash_proc = Proc.new { |type, val|
|
2024
|
+
if Array === val
|
2025
|
+
val = Hash.[]( *val ) # Convert the map to a sequence
|
2026
|
+
elsif Hash === val
|
2027
|
+
type, obj_class = YAML.read_type_class( type, Hash )
|
2028
|
+
if obj_class != Hash
|
2029
|
+
o = obj_class.new
|
2030
|
+
o.update( val )
|
2031
|
+
val = o
|
2032
|
+
end
|
2033
|
+
else
|
2034
|
+
raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
|
2035
|
+
end
|
2036
|
+
val
|
2037
|
+
}
|
2038
|
+
YAML.add_builtin_type( /^map/, &hash_proc )
|
2039
|
+
YAML.add_ruby_type( Hash, &hash_proc )
|
2040
|
+
|
2041
|
+
#
|
2042
|
+
# Structs: export as a !map
|
2043
|
+
#
|
2044
|
+
class Struct
|
2045
|
+
def is_complex_yaml?
|
2046
|
+
true
|
2047
|
+
end
|
2048
|
+
def to_yaml( opts = {} )
|
2049
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
2050
|
+
#
|
2051
|
+
# Basic struct is passed as a YAML map
|
2052
|
+
#
|
2053
|
+
struct_name = self.class.name.gsub( "Struct:", "" )
|
2054
|
+
out.map( "!ruby/struct#{struct_name}" ) { |map|
|
2055
|
+
self.members.each { |m|
|
2056
|
+
map.add( m, self[m] )
|
2057
|
+
}
|
2058
|
+
}
|
2059
|
+
}
|
2060
|
+
end
|
2061
|
+
end
|
2062
|
+
|
2063
|
+
YAML.add_ruby_type( Struct ) { |type, val|
|
2064
|
+
type =~ /^struct:(\w+)/
|
2065
|
+
if Hash === val
|
2066
|
+
type = $1
|
2067
|
+
struct_type = nil
|
2068
|
+
struct_def = []
|
2069
|
+
struct_name = ""
|
2070
|
+
if $1.to_s.length > 1
|
2071
|
+
struct_name = $1[0..$1.length]
|
2072
|
+
struct_def << struct_name
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
#
|
2076
|
+
# Use existing Struct if it exists
|
2077
|
+
#
|
2078
|
+
begin
|
2079
|
+
struct_type = Struct.const_get( struct_name )
|
2080
|
+
rescue NameError
|
2081
|
+
end
|
2082
|
+
if not struct_type
|
2083
|
+
struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
#
|
2087
|
+
# Set the Struct properties
|
2088
|
+
#
|
2089
|
+
st = struct_type.new
|
2090
|
+
st.members.each { |m|
|
2091
|
+
st.send( "#{m}=", val[m] )
|
2092
|
+
}
|
2093
|
+
st
|
2094
|
+
else
|
2095
|
+
raise YAML::Error, "Invalid Ruby Struct: " + val.inspect
|
2096
|
+
end
|
2097
|
+
}
|
2098
|
+
|
2099
|
+
#
|
2100
|
+
# Sequences: Array#to_yaml
|
2101
|
+
#
|
2102
|
+
class Array
|
2103
|
+
def is_complex_yaml?
|
2104
|
+
true
|
2105
|
+
end
|
2106
|
+
def to_yaml_type
|
2107
|
+
if self.class == Array
|
2108
|
+
"!seq"
|
2109
|
+
else
|
2110
|
+
"!ruby/array:#{self.class}"
|
2111
|
+
end
|
2112
|
+
end
|
2113
|
+
def to_yaml( opts = {} )
|
2114
|
+
opts[:DocType] = self.class if Hash === opts
|
2115
|
+
YAML::quick_emit( self.id, opts ) { |out|
|
2116
|
+
array_type = to_yaml_type
|
2117
|
+
if not out.options[:ExplicitTypes] and array_type == "!seq"
|
2118
|
+
array_type = ""
|
2119
|
+
end
|
2120
|
+
|
2121
|
+
out.seq( array_type ) { |seq|
|
2122
|
+
seq.concat( self )
|
2123
|
+
}
|
2124
|
+
}
|
2125
|
+
end
|
2126
|
+
end
|
2127
|
+
|
2128
|
+
array_proc = Proc.new { |type, val|
|
2129
|
+
if Array === val
|
2130
|
+
type, obj_class = YAML.read_type_class( type, Array )
|
2131
|
+
if obj_class != Array
|
2132
|
+
o = obj_class.new
|
2133
|
+
o.concat( val )
|
2134
|
+
val = o
|
2135
|
+
end
|
2136
|
+
val
|
2137
|
+
else
|
2138
|
+
val.to_a
|
2139
|
+
end
|
2140
|
+
}
|
2141
|
+
YAML.add_builtin_type( /^seq/, &array_proc )
|
2142
|
+
YAML.add_ruby_type( Array, &array_proc )
|
2143
|
+
|
2144
|
+
#
|
2145
|
+
# String#to_yaml
|
2146
|
+
#
|
2147
|
+
class String
|
2148
|
+
def is_complex_yaml?
|
2149
|
+
( self =~ /\n.+/ ? true : false )
|
2150
|
+
end
|
2151
|
+
def is_binary_data?
|
2152
|
+
( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 )
|
2153
|
+
end
|
2154
|
+
def to_yaml( opts = {} )
|
2155
|
+
complex = false
|
2156
|
+
if self.is_complex_yaml?
|
2157
|
+
complex = true
|
2158
|
+
elsif opts[:BestWidth].to_i > 0
|
2159
|
+
if self.length > opts[:BestWidth] and opts[:UseFold]
|
2160
|
+
complex = true
|
2161
|
+
end
|
2162
|
+
end
|
2163
|
+
YAML::quick_emit( complex ? self.id : nil, opts ) { |out|
|
2164
|
+
if complex
|
2165
|
+
if self.is_binary_data?
|
2166
|
+
out.binary_base64( self )
|
2167
|
+
else
|
2168
|
+
out.node_text( self )
|
2169
|
+
end
|
2170
|
+
else
|
2171
|
+
ostr = if out.options[:KeepValue]
|
2172
|
+
self
|
2173
|
+
elsif empty?
|
2174
|
+
"''"
|
2175
|
+
elsif YAML.detect_implicit( self ) != 'str'
|
2176
|
+
"\"#{YAML.escape( self )}\""
|
2177
|
+
elsif self =~ /#{YAML::ESCAPE_CHAR}|[#{YAML::SPACE_INDICATORS}] |\n|\'/
|
2178
|
+
"\"#{YAML.escape( self )}\""
|
2179
|
+
elsif self =~ /^[^#{YAML::WORD_CHAR}]/
|
2180
|
+
"\"#{YAML.escape( self )}\""
|
2181
|
+
else
|
2182
|
+
self
|
2183
|
+
end
|
2184
|
+
out.simple( ostr )
|
2185
|
+
end
|
2186
|
+
}
|
2187
|
+
end
|
2188
|
+
end
|
2189
|
+
|
2190
|
+
YAML.add_builtin_type( 'str' ) { |type,val| val.to_s }
|
2191
|
+
YAML.add_builtin_type( 'binary' ) { |type,val|
|
2192
|
+
enctype = "m"
|
2193
|
+
if String === val
|
2194
|
+
val.gsub( /\s+/, '' ).unpack( enctype )[0]
|
2195
|
+
else
|
2196
|
+
raise YAML::Error, "Binary data must be represented by a string: " + val.inspect
|
2197
|
+
end
|
2198
|
+
}
|
2199
|
+
|
2200
|
+
#
|
2201
|
+
# Symbol#to_yaml
|
2202
|
+
#
|
2203
|
+
class Symbol
|
2204
|
+
def is_complex_yaml?
|
2205
|
+
false
|
2206
|
+
end
|
2207
|
+
def to_yaml( opts = {} )
|
2208
|
+
YAML::quick_emit( nil, opts ) { |out|
|
2209
|
+
out << "!ruby/sym "
|
2210
|
+
self.id2name.to_yaml( :Emitter => out )
|
2211
|
+
}
|
2212
|
+
end
|
2213
|
+
end
|
2214
|
+
|
2215
|
+
symbol_proc = Proc.new { |type, val|
|
2216
|
+
if String === val
|
2217
|
+
val.intern
|
2218
|
+
else
|
2219
|
+
raise YAML::Error, "Invalid Symbol: " + val.inspect
|
2220
|
+
end
|
2221
|
+
}
|
2222
|
+
YAML.add_ruby_type( Symbol, &symbol_proc )
|
2223
|
+
YAML.add_ruby_type( :sym, &symbol_proc )
|
2224
|
+
|
2225
|
+
#
|
2226
|
+
# Range#to_yaml
|
2227
|
+
#
|
2228
|
+
class Range
|
2229
|
+
def is_complex_yaml?
|
2230
|
+
false
|
2231
|
+
end
|
2232
|
+
def to_yaml( opts = {} )
|
2233
|
+
YAML::quick_emit( nil, opts ) { |out|
|
2234
|
+
out << "!ruby/range "
|
2235
|
+
self.inspect.to_yaml( :Emitter => out )
|
2236
|
+
}
|
2237
|
+
end
|
2238
|
+
end
|
2239
|
+
|
2240
|
+
YAML.add_ruby_type( Range ) { |type, val|
|
2241
|
+
if String === val and val =~ /^(.*[^.])(\.{2,3})([^.].*)$/
|
2242
|
+
r1, rdots, r2 = $1, $2, $3
|
2243
|
+
Range.new( YAML.try_implicit( r1 ), YAML.try_implicit( r2 ), rdots.length == 3 )
|
2244
|
+
elsif Hash === val
|
2245
|
+
Range.new( val['begin'], val['end'], val['exclude_end?'] )
|
2246
|
+
else
|
2247
|
+
raise YAML::Error, "Invalid Range: " + val.inspect
|
2248
|
+
end
|
2249
|
+
}
|
2250
|
+
|
2251
|
+
#
|
2252
|
+
# Make an RegExp
|
2253
|
+
#
|
2254
|
+
class Regexp
|
2255
|
+
def is_complex_yaml?
|
2256
|
+
false
|
2257
|
+
end
|
2258
|
+
def to_yaml( opts = {} )
|
2259
|
+
YAML::quick_emit( nil, opts ) { |out|
|
2260
|
+
out << "!ruby/regexp "
|
2261
|
+
self.inspect.to_yaml( :Emitter => out )
|
2262
|
+
}
|
2263
|
+
end
|
2264
|
+
end
|
2265
|
+
|
2266
|
+
regexp_proc = Proc.new { |type, val|
|
2267
|
+
if String === val and val =~ /^\/(.*)\/([mix]*)$/
|
2268
|
+
val = { 'REGEXP' => $1, 'MODIFIERS' => $2 }
|
2269
|
+
end
|
2270
|
+
if Hash === val
|
2271
|
+
mods = nil
|
2272
|
+
unless val['MODIFIERS'].to_s.empty?
|
2273
|
+
mods = 0x00
|
2274
|
+
if val['MODIFIERS'].include?( 'x' )
|
2275
|
+
mods |= Regexp::EXTENDED
|
2276
|
+
elsif val['MODIFIERS'].include?( 'i' )
|
2277
|
+
mods |= Regexp::IGNORECASE
|
2278
|
+
elsif val['MODIFIERS'].include?( 'm' )
|
2279
|
+
mods |= Regexp::POSIXLINE
|
2280
|
+
end
|
2281
|
+
end
|
2282
|
+
Regexp::compile( val['REGEXP'], mods )
|
2283
|
+
else
|
2284
|
+
raise YAML::Error, "Invalid Regular expression: " + val.inspect
|
2285
|
+
end
|
2286
|
+
}
|
2287
|
+
YAML.add_domain_type( "perl.yaml.org,2002", /^regexp/, ®exp_proc )
|
2288
|
+
YAML.add_ruby_type( Regexp, ®exp_proc )
|
2289
|
+
|
2290
|
+
#
|
2291
|
+
# Emit a Time object as an ISO 8601 timestamp
|
2292
|
+
#
|
2293
|
+
class Time
|
2294
|
+
def is_complex_yaml?
|
2295
|
+
false
|
2296
|
+
end
|
2297
|
+
def to_yaml( opts = {} )
|
2298
|
+
YAML::quick_emit( nil, opts ) { |out|
|
2299
|
+
tz = "Z"
|
2300
|
+
# from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
|
2301
|
+
unless self.utc?
|
2302
|
+
utc_same_instant = self.dup.utc
|
2303
|
+
utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
|
2304
|
+
difference_to_utc = utc_same_writing - utc_same_instant
|
2305
|
+
if (difference_to_utc < 0)
|
2306
|
+
difference_sign = '-'
|
2307
|
+
absolute_difference = -difference_to_utc
|
2308
|
+
else
|
2309
|
+
difference_sign = '+'
|
2310
|
+
absolute_difference = difference_to_utc
|
2311
|
+
end
|
2312
|
+
difference_minutes = (absolute_difference/60).round
|
2313
|
+
tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
|
2314
|
+
end
|
2315
|
+
( self.strftime( "%Y-%m-%d %H:%M:%S." ) +
|
2316
|
+
"%06d %s" % [usec, tz] ).
|
2317
|
+
to_yaml( :Emitter => out, :KeepValue => true )
|
2318
|
+
}
|
2319
|
+
end
|
2320
|
+
end
|
2321
|
+
|
2322
|
+
YAML.add_builtin_type( 'time' ) { |type, val|
|
2323
|
+
if val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})[Tt](\d{2})\:(\d{2})\:(\d{2})(\.\d{1,2})?(Z|[-+][0-9][0-9](?:\:[0-9][0-9])?)\Z/
|
2324
|
+
YAML.mktime( *$~.to_a[1,8] )
|
2325
|
+
elsif val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})[ \t]+(\d{2})\:(\d{2})\:(\d{2})(\.\d+)?[ \t]+(Z|[-+][0-9][0-9](?:\:[0-9][0-9])?)\Z/
|
2326
|
+
YAML.mktime( *$~.to_a[1,8] )
|
2327
|
+
elsif val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})[ \t]+(\d{2})\:(\d{2})\:(\d{2})(\.\d{1,2})?\Z/
|
2328
|
+
YAML.mktime( *$~.to_a[1,7] )
|
2329
|
+
elsif val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})\Z/
|
2330
|
+
Date.new($1.to_i, $2.to_i, $3.to_i)
|
2331
|
+
elsif type == :Implicit
|
2332
|
+
:InvalidType
|
2333
|
+
else
|
2334
|
+
raise YAML::TypeError, "Invalid !time string: " + val.inspect
|
2335
|
+
end
|
2336
|
+
}
|
2337
|
+
|
2338
|
+
#
|
2339
|
+
# Emit a Date object as a simple implicit
|
2340
|
+
#
|
2341
|
+
class Date
|
2342
|
+
def is_complex_yaml?
|
2343
|
+
false
|
2344
|
+
end
|
2345
|
+
def to_yaml( opts = {} )
|
2346
|
+
opts[:KeepValue] = true
|
2347
|
+
self.to_s.to_yaml( opts )
|
2348
|
+
end
|
2349
|
+
end
|
2350
|
+
|
2351
|
+
#
|
2352
|
+
# Send Integer, Booleans, NilClass to String
|
2353
|
+
#
|
2354
|
+
class Numeric
|
2355
|
+
def is_complex_yaml?
|
2356
|
+
false
|
2357
|
+
end
|
2358
|
+
def to_yaml( opts = {} )
|
2359
|
+
str = self.to_s
|
2360
|
+
if str == "Infinity"
|
2361
|
+
str = ".Inf"
|
2362
|
+
elsif str == "-Infinity"
|
2363
|
+
str = "-.Inf"
|
2364
|
+
elsif str == "NaN"
|
2365
|
+
str = ".NaN"
|
2366
|
+
end
|
2367
|
+
opts[:KeepValue] = true
|
2368
|
+
str.to_yaml( opts )
|
2369
|
+
end
|
2370
|
+
end
|
2371
|
+
|
2372
|
+
YAML.add_builtin_type( 'float' ) { |type, val|
|
2373
|
+
if val =~ /\A[-+]?[\d][\d,]*\.[\d,]*[eE][-+][0-9]+\Z/ # Float (exponential)
|
2374
|
+
$&.tr( ',', '' ).to_f
|
2375
|
+
elsif val =~ /\A[-+]?[\d][\d,]*\.[\d,]*\Z/ # Float (fixed)
|
2376
|
+
$&.tr( ',', '' ).to_f
|
2377
|
+
elsif val =~ /\A([-+]?)\.(inf|Inf|INF)\Z/ # Float (english)
|
2378
|
+
( $1 == "-" ? -1.0/0.0 : 1.0/0.0 )
|
2379
|
+
elsif val =~ /\A\.(nan|NaN|NAN)\Z/
|
2380
|
+
0.0/0.0
|
2381
|
+
elsif type == :Implicit
|
2382
|
+
:InvalidType
|
2383
|
+
else
|
2384
|
+
val.to_f
|
2385
|
+
end
|
2386
|
+
}
|
2387
|
+
|
2388
|
+
YAML.add_builtin_type( 'int' ) { |type, val|
|
2389
|
+
if val =~ /\A[-+]?0[0-7,]+\Z/ # Integer (octal)
|
2390
|
+
$&.oct
|
2391
|
+
elsif val =~ /\A[-+]?0x[0-9a-fA-F,]+\Z/ # Integer (hex)
|
2392
|
+
$&.hex
|
2393
|
+
elsif val =~ /\A[-+]?\d[\d,]*\Z/ # Integer (canonical)
|
2394
|
+
$&.tr( ',', '' ).to_i
|
2395
|
+
elsif val =~ /\A([-+]?)(\d[\d,]*(?::[0-5]?[0-9])+)\Z/
|
2396
|
+
sign = ( $1 == '-' ? -1 : 1 )
|
2397
|
+
digits = $2.split( /:/ ).collect { |x| x.to_i }
|
2398
|
+
val = 0; digits.each { |x| val = ( val * 60 ) + x }; val *= sign
|
2399
|
+
elsif type == :Implicit
|
2400
|
+
:InvalidType
|
2401
|
+
else
|
2402
|
+
val.to_i
|
2403
|
+
end
|
2404
|
+
}
|
2405
|
+
|
2406
|
+
class TrueClass
|
2407
|
+
def is_complex_yaml?
|
2408
|
+
false
|
2409
|
+
end
|
2410
|
+
def to_yaml( opts = {} )
|
2411
|
+
opts[:KeepValue] = true
|
2412
|
+
"true".to_yaml( opts )
|
2413
|
+
end
|
2414
|
+
end
|
2415
|
+
|
2416
|
+
class FalseClass
|
2417
|
+
def is_complex_yaml?
|
2418
|
+
false
|
2419
|
+
end
|
2420
|
+
def to_yaml( opts = {} )
|
2421
|
+
opts[:KeepValue] = true
|
2422
|
+
"false".to_yaml( opts )
|
2423
|
+
end
|
2424
|
+
end
|
2425
|
+
|
2426
|
+
YAML.add_builtin_type( 'bool' ) { |type, val|
|
2427
|
+
if val =~ /\A(\+|true|True|TRUE|yes|Yes|YES|on|On|ON)\Z/
|
2428
|
+
true
|
2429
|
+
elsif val =~ /\A(\-|false|False|FALSE|no|No|NO|off|Off|OFF)\Z/
|
2430
|
+
false
|
2431
|
+
elsif type == :Implicit
|
2432
|
+
:InvalidType
|
2433
|
+
else
|
2434
|
+
raise YAML::TypeError, "Invalid !bool string: " + val.inspect
|
2435
|
+
end
|
2436
|
+
}
|
2437
|
+
|
2438
|
+
class NilClass
|
2439
|
+
def is_complex_yaml?
|
2440
|
+
false
|
2441
|
+
end
|
2442
|
+
def to_yaml( opts = {} )
|
2443
|
+
opts[:KeepValue] = true
|
2444
|
+
"".to_yaml( opts )
|
2445
|
+
end
|
2446
|
+
end
|
2447
|
+
|
2448
|
+
YAML.add_builtin_type( 'null' ) { |type, val|
|
2449
|
+
if val =~ /\A(\~|null|Null|NULL)\Z/
|
2450
|
+
nil
|
2451
|
+
elsif val.empty?
|
2452
|
+
nil
|
2453
|
+
elsif type == :Implicit
|
2454
|
+
:InvalidType
|
2455
|
+
else
|
2456
|
+
raise YAML::TypeError, "Invalid !null string: " + val.inspect
|
2457
|
+
end
|
2458
|
+
}
|
2459
|
+
|
2460
|
+
#
|
2461
|
+
# ryan: You know how Kernel.p is a really convenient way to dump ruby
|
2462
|
+
# structures? The only downside is that it's not as legible as
|
2463
|
+
# YAML.
|
2464
|
+
#
|
2465
|
+
# _why: (listening)
|
2466
|
+
#
|
2467
|
+
# ryan: I know you don't want to urinate all over your users' namespaces.
|
2468
|
+
# But, on the other hand, convenience of dumping for debugging is,
|
2469
|
+
# IMO, a big YAML use case.
|
2470
|
+
#
|
2471
|
+
# _why: Go nuts! Have a pony parade!
|
2472
|
+
#
|
2473
|
+
# ryan: Either way, I certainly will have a pony parade.
|
2474
|
+
#
|
2475
|
+
module Kernel
|
2476
|
+
def y( x )
|
2477
|
+
puts x.to_yaml
|
2478
|
+
end
|
2479
|
+
end
|
2480
|
+
|
2481
|
+
#
|
2482
|
+
# Example of using YAML to replace PStore
|
2483
|
+
#
|
2484
|
+
if __FILE__ == $0
|
2485
|
+
y = YAML::Store.new( "/tmp/yaml.store.1", :Indent => 2,
|
2486
|
+
:UseHeader => true, :UseVersion => true )
|
2487
|
+
y.transaction do
|
2488
|
+
y['names'] = ['Steve', 'Jonathan', 'Tom']
|
2489
|
+
y['hello'] = {'hi' => 'hello', 'yes' => 'YES!!' }
|
2490
|
+
end
|
2491
|
+
end
|
2492
|
+
|
2493
|
+
#
|
2494
|
+
# Example of using YAML::Stream
|
2495
|
+
#
|
2496
|
+
# a = "File ID"
|
2497
|
+
# y = YAML::Stream.new( :Indent => 2, :UseVersion => 0 )
|
2498
|
+
# y.add( {'hi2' => 'hello', 'map' => {'good' => 'two'}, 'time' => Time.now, 'try' => /^po(.*)$/, 'bye' => 'goodbye' } )
|
2499
|
+
# y.add( {'po' => nil, 'oper' => 90 } )
|
2500
|
+
# y.add( {'hi' => 'wow!', 'bye' => 'wow!'} )
|
2501
|
+
# y.add( {['Red Socks','Boston'] => ['One', 'Two', 'Three']} )
|
2502
|
+
# y.add( [true, false, false] ) # This should use aliases
|
2503
|
+
# puts y.emit
|
2504
|
+
|
2505
|
+
#
|
2506
|
+
# Example of loading a YAML document
|
2507
|
+
#
|
2508
|
+
# obj = YAML::load( "/tmp/yaml.store.1" )
|
2509
|
+
|
2510
|
+
#
|
2511
|
+
# Examples of using #to_yaml
|
2512
|
+
#
|
2513
|
+
# puts [1, 2, 3, nil, 'hello', "Glow all!", 'hi', Time.now, /^po(.*)/im ].to_yaml( :UseBlock => true )
|
2514
|
+
# puts Hash['hi', 'hello', 'time', Time.now, 'try', /^po(.*)$/, 'bye', 'goodbye' ].to_yaml
|
2515
|
+
# puts [
|
2516
|
+
# {'hi' => 'hello', 'time' => Time.now, 'try' => /^po(.*)$/, 'bye' => 'goodbye' },
|
2517
|
+
# {'po' => nil, 'oper' => 90 },
|
2518
|
+
# {'hi' => 'wow!', 'bye' => 'wow!'} ].to_yaml
|
2519
|
+
|
2520
|
+
|
2521
|
+
..end src/emitter.rb modeval..iddd2784be19
|
2522
|
+
|
2523
|
+
module YAML
|
2524
|
+
|
2525
|
+
class Parser < Racc::Parser
|
2526
|
+
|
2527
|
+
module_eval <<'..end src/yaml.y.rb modeval..idae682a68eb', 'src/yaml.y.rb', 140
|
2528
|
+
|
2529
|
+
attr_accessor :finished, :directives, :options
|
2530
|
+
|
2531
|
+
#
|
2532
|
+
# Reset the directives, EOF flag
|
2533
|
+
#
|
2534
|
+
def initialize( opts = {} )
|
2535
|
+
@directives = { 'YAML' => '1.0', 'TAB' => 'NONE' }
|
2536
|
+
@options = YAML::DEFAULTS.dup.update( opts )
|
2537
|
+
@finished = false
|
2538
|
+
@plain_sets = {
|
2539
|
+
:AllowInline => YAML.plain_re( ',}]' ),
|
2540
|
+
:AllowMapping => YAML.plain_re( ':' ),
|
2541
|
+
:AllowNone => YAML.plain_re
|
2542
|
+
}
|
2543
|
+
end
|
2544
|
+
|
2545
|
+
#
|
2546
|
+
# Iterator for parsing many documents
|
2547
|
+
#
|
2548
|
+
def parse_documents( io, &doc_proc )
|
2549
|
+
@stream = YAML.make_stream( io )
|
2550
|
+
@lineno = 0
|
2551
|
+
@charno = 0
|
2552
|
+
@leftovers = nil
|
2553
|
+
@options[:Encoding] = @stream.utf_encoding
|
2554
|
+
while true
|
2555
|
+
o = _parse
|
2556
|
+
doc_proc.call( o )
|
2557
|
+
break if @finished
|
2558
|
+
end
|
2559
|
+
end
|
2560
|
+
|
2561
|
+
#
|
2562
|
+
# Basic single document parsing
|
2563
|
+
#
|
2564
|
+
def parse( io )
|
2565
|
+
@stream = YAML.make_stream( io )
|
2566
|
+
@lineno = 0
|
2567
|
+
@charno = 0
|
2568
|
+
@leftovers = nil
|
2569
|
+
@options[:Encoding] = @stream.utf_encoding
|
2570
|
+
_parse
|
2571
|
+
end
|
2572
|
+
|
2573
|
+
#
|
2574
|
+
# Common tokenizer and parser
|
2575
|
+
#
|
2576
|
+
def _parse
|
2577
|
+
|
2578
|
+
#
|
2579
|
+
# Parser instance variables
|
2580
|
+
#
|
2581
|
+
@anchor = {}
|
2582
|
+
@lvl = [ Level.new( -1, :Implicit, "" ) ]
|
2583
|
+
@separator = nil
|
2584
|
+
@last_tokens = []
|
2585
|
+
@plain_set = @plain_sets[ :AllowInline ]
|
2586
|
+
|
2587
|
+
reset_indent
|
2588
|
+
reset_tokens
|
2589
|
+
|
2590
|
+
# Tokenizer
|
2591
|
+
do_tokenize
|
2592
|
+
|
2593
|
+
@finished = true if eof? and @leftovers.nil?
|
2594
|
+
return nil if @q.length.zero?
|
2595
|
+
|
2596
|
+
add_end_indent -1
|
2597
|
+
close_tokens
|
2598
|
+
|
2599
|
+
# @q.each { |tok|
|
2600
|
+
# p [ tok.sym, tok.data ]
|
2601
|
+
# }
|
2602
|
+
|
2603
|
+
# Parser
|
2604
|
+
begin
|
2605
|
+
do_parse
|
2606
|
+
rescue Racc::ParseError => rpe
|
2607
|
+
token = @last_tokens.last
|
2608
|
+
raise YAML::ParseError, "Parse error at line #{token.lineno}, char #{token.charno}: [#{token.sym}, #{token.data}]"
|
2609
|
+
end
|
2610
|
+
end
|
2611
|
+
|
2612
|
+
def do_tokenize
|
2613
|
+
until eof? and @leftovers.nil? do
|
2614
|
+
if @leftovers
|
2615
|
+
yline = @leftovers
|
2616
|
+
@leftovers = nil
|
2617
|
+
else
|
2618
|
+
# ENEBO: readline returns nil instead of "". I wonder if this is a ruby behavioral change thing
|
2619
|
+
yline = readline
|
2620
|
+
yline.chomp! if yline
|
2621
|
+
end
|
2622
|
+
handle_indent( yline )
|
2623
|
+
until !yline || yline.empty? do
|
2624
|
+
handle_content( yline )
|
2625
|
+
if [ :End, :Pause ].include?( @lvl.last.status )
|
2626
|
+
@leftovers = yline
|
2627
|
+
return
|
2628
|
+
end
|
2629
|
+
end
|
2630
|
+
end
|
2631
|
+
end
|
2632
|
+
|
2633
|
+
def handle_indent( yline )
|
2634
|
+
if ( indt_match = @lvl.last.indent_re.match( yline ) )
|
2635
|
+
@indent_raw << "\n" + indt_match[0]
|
2636
|
+
case indt_match[2]
|
2637
|
+
when /^#/
|
2638
|
+
yline.replace ""
|
2639
|
+
when /^-/
|
2640
|
+
@indent << "\n" + yline.slice!( 0, indt_match[1].length ) + " "
|
2641
|
+
@charno += indt_match[1].length
|
2642
|
+
else
|
2643
|
+
@indent << "\n" + yline.slice!( 0, indt_match[0].length )
|
2644
|
+
@charno += indt_match[0].length
|
2645
|
+
end
|
2646
|
+
end
|
2647
|
+
end
|
2648
|
+
|
2649
|
+
def handle_content( yline )
|
2650
|
+
if @charno == 1
|
2651
|
+
case yline
|
2652
|
+
when /\A---( |$)/
|
2653
|
+
if @q.length.zero?
|
2654
|
+
reset_indent
|
2655
|
+
@lvl.last.status = :Header
|
2656
|
+
@charno += $&.length
|
2657
|
+
yline.replace $'
|
2658
|
+
else
|
2659
|
+
@lvl.last.status = :End
|
2660
|
+
end
|
2661
|
+
return
|
2662
|
+
when /\A\.\.\.( |$)/
|
2663
|
+
@lvl.last.status = :Pause
|
2664
|
+
@charno += $&.length
|
2665
|
+
yline.replace $'
|
2666
|
+
return
|
2667
|
+
end
|
2668
|
+
elsif @lvl.last.status == :Header
|
2669
|
+
if yline =~ /\A%(\w+):(\S+)/
|
2670
|
+
@directives[$1] = $2
|
2671
|
+
case $1
|
2672
|
+
when "YAML"
|
2673
|
+
@options[:Version] = $2
|
2674
|
+
@options[:UseVersion] = true
|
2675
|
+
end
|
2676
|
+
len = $&.length
|
2677
|
+
yline.slice!( 0, len )
|
2678
|
+
@charno += len
|
2679
|
+
return
|
2680
|
+
else
|
2681
|
+
@lvl.last.status = :Implicit
|
2682
|
+
end
|
2683
|
+
end
|
2684
|
+
if @lvl.last.status != :Block or @q.last.sym == :FSTART
|
2685
|
+
case yline
|
2686
|
+
when /\A#/
|
2687
|
+
# Throwaway comments
|
2688
|
+
yline.replace ""
|
2689
|
+
return
|
2690
|
+
when /\A +/
|
2691
|
+
# Throwaway space
|
2692
|
+
len = $&.length
|
2693
|
+
yline.slice!( 0, len )
|
2694
|
+
@charno += len
|
2695
|
+
return
|
2696
|
+
end
|
2697
|
+
end
|
2698
|
+
apply_indent
|
2699
|
+
if @lvl.last.status == :Block
|
2700
|
+
add_token :FOLD, yline
|
2701
|
+
yline.replace ""
|
2702
|
+
return
|
2703
|
+
end
|
2704
|
+
len = 0
|
2705
|
+
case yline
|
2706
|
+
when /\A[#{ Regexp::quote( SPACE_INDICATORS ) }]( |$)/
|
2707
|
+
# Space indicators
|
2708
|
+
len = $&.length
|
2709
|
+
c = yline[ 0, 1 ]
|
2710
|
+
if @lvl.last.status == :Inline
|
2711
|
+
if c == ':'
|
2712
|
+
@plain_set = @plain_sets[ :AllowMapping ]
|
2713
|
+
elsif c == ','
|
2714
|
+
@plain_set = @plain_sets[ :AllowNone ]
|
2715
|
+
end
|
2716
|
+
else
|
2717
|
+
if c == ':'
|
2718
|
+
@plain_set = @plain_sets[ :AllowInline ]
|
2719
|
+
elsif c == '-'
|
2720
|
+
handle_seq_shortcuts
|
2721
|
+
if @q[-1] and [ :INDENT, :IOPEN, :IEND ].include?( @q[-1] )
|
2722
|
+
@lvl.last.spaces = @charno + 1
|
2723
|
+
@q.last.data = @charno + 1
|
2724
|
+
end
|
2725
|
+
end
|
2726
|
+
end
|
2727
|
+
add_token c, c
|
2728
|
+
when /\A([>|])([-+\d]*)/
|
2729
|
+
len = $&.length
|
2730
|
+
fold = $&
|
2731
|
+
fold_type = $1
|
2732
|
+
@lvl.push Level.new( @lvl.last.spaces + 1, :Block, fold_type == "|" ? :Literal : :Folded )
|
2733
|
+
@q.push Token.new( :IOPEN, @lvl.last.spaces, @lineno, 1 )
|
2734
|
+
add_token :FSTART, fold
|
2735
|
+
when /\A([{\[])/
|
2736
|
+
len = $&.length
|
2737
|
+
tok = $&
|
2738
|
+
@lvl.push Level.new( @lvl.last.spaces + 2, :Inline, @lvl.last.domain )
|
2739
|
+
@plain_set = @plain_sets[ :AllowNone ]
|
2740
|
+
add_token tok, tok
|
2741
|
+
when /\A([}\]])/
|
2742
|
+
len = $&.length
|
2743
|
+
tok = $&
|
2744
|
+
@lvl.pop
|
2745
|
+
@plain_set = @plain_sets[ :AllowInline ]
|
2746
|
+
add_token tok, tok
|
2747
|
+
when /\A&(\w+)/
|
2748
|
+
len = $&.length
|
2749
|
+
add_token :ANCHOR, $1
|
2750
|
+
when /\A\*(\w+)/
|
2751
|
+
len = $&.length
|
2752
|
+
add_token :ALIAS, $1
|
2753
|
+
when /\A!(\S*)/
|
2754
|
+
len = $&.length
|
2755
|
+
ttype = $1
|
2756
|
+
if ttype =~ /(.*)\^(.+)/
|
2757
|
+
if $1.length > 0
|
2758
|
+
@lvl.last.domain = $1
|
2759
|
+
ttype = $1 + $2
|
2760
|
+
else
|
2761
|
+
ttype = @lvl.last.domain + $2
|
2762
|
+
end
|
2763
|
+
end
|
2764
|
+
add_token :TRANSFER, ttype
|
2765
|
+
when /\A"((?:\\\"|[^\n"])*)/
|
2766
|
+
handle_seq_shortcuts
|
2767
|
+
len = $&.length
|
2768
|
+
yline.slice!( 0, len )
|
2769
|
+
@charno += len
|
2770
|
+
qstr = $1.to_s
|
2771
|
+
qstr_indt = "+"
|
2772
|
+
while yline[0,1] != '"'
|
2773
|
+
if qstr[-1,1] == "\\"
|
2774
|
+
qstr = qstr.chop!
|
2775
|
+
else
|
2776
|
+
qstr << " "
|
2777
|
+
end
|
2778
|
+
yline = readline
|
2779
|
+
yline =~ /\A(\s#{qstr_indt})((?:\\\"|[^\n"])*)/
|
2780
|
+
len = $&.to_s.length
|
2781
|
+
yline.slice!( 0, len )
|
2782
|
+
@charno += len
|
2783
|
+
qstr << $2.to_s
|
2784
|
+
end
|
2785
|
+
len = 1
|
2786
|
+
add_token :WORD, YAML.unescape(qstr.gsub( /\\"/, '"' ))
|
2787
|
+
when /\A'((?:''|[^\n'])*)/
|
2788
|
+
handle_seq_shortcuts
|
2789
|
+
len = $&.length
|
2790
|
+
yline.slice!( 0, len )
|
2791
|
+
@charno += len
|
2792
|
+
qstr = $1.to_s
|
2793
|
+
qstr_indt = "+"
|
2794
|
+
nl_mode = false
|
2795
|
+
while yline[0,1] != "'"
|
2796
|
+
qstr << " " if qstr[-1,1] != "\n"
|
2797
|
+
yline = readline
|
2798
|
+
yline =~ /\A(\s#{qstr_indt})((?:''|[^\n'])*)/
|
2799
|
+
qstr_indt = "{0,#{$1.length}}" if qstr_indt == "+"
|
2800
|
+
inner_str = $2.to_s.strip
|
2801
|
+
if inner_str == ""
|
2802
|
+
qstr = ( nl_mode ? qstr : qstr[0..-2] ) + "\n"
|
2803
|
+
nl_mode = true
|
2804
|
+
else
|
2805
|
+
qstr << $2
|
2806
|
+
nl_mode = false
|
2807
|
+
end
|
2808
|
+
len = $&.to_s.length
|
2809
|
+
yline.slice!( 0, len )
|
2810
|
+
@charno += len
|
2811
|
+
end
|
2812
|
+
len = 1
|
2813
|
+
add_token :WORD, qstr.gsub( "''", "'" )
|
2814
|
+
when @plain_set
|
2815
|
+
handle_seq_shortcuts
|
2816
|
+
len = $&.length
|
2817
|
+
match = $&.strip
|
2818
|
+
if @q.last and @q.last.sym == :PLAIN
|
2819
|
+
@q.last.data += " " if @q.last.data !~ /\Z\n/
|
2820
|
+
@q.last.data += match
|
2821
|
+
else
|
2822
|
+
add_token :PLAIN, match
|
2823
|
+
end
|
2824
|
+
else
|
2825
|
+
handle_seq_shortcuts
|
2826
|
+
len = 1
|
2827
|
+
c = yline[ 0, 1 ]
|
2828
|
+
add_token c, c
|
2829
|
+
end
|
2830
|
+
yline.slice!( 0, len )
|
2831
|
+
@charno += len
|
2832
|
+
end
|
2833
|
+
|
2834
|
+
def handle_seq_shortcuts
|
2835
|
+
if @q[-1] and @q[-1].sym == '-' and @q[-2] and [:IOPEN, :INDENT, :IEND].include?( @q[-2].sym )
|
2836
|
+
# Check the current level and indent to match the dash
|
2837
|
+
@lvl.last.spaces = @q[-1].charno
|
2838
|
+
@q[-2].data = @q[-1].charno
|
2839
|
+
# Add open indent after the dash
|
2840
|
+
@lvl.push Level.new( @charno - 1, @lvl.last.status, @lvl.last.domain )
|
2841
|
+
@q.push Token.new( :IOPEN, @charno - 1, @lineno, @charno )
|
2842
|
+
end
|
2843
|
+
end
|
2844
|
+
|
2845
|
+
#
|
2846
|
+
# Level descent class added 2002 Dec 31
|
2847
|
+
# The levels of indentation are tracked using this class.
|
2848
|
+
# Each level has an indentation space count, a status field
|
2849
|
+
# indicating what sort of data is contained at this depth,
|
2850
|
+
# and the domain anchored at this depth.
|
2851
|
+
#
|
2852
|
+
class Level
|
2853
|
+
attr_accessor :spaces, :status, :domain
|
2854
|
+
def initialize( ct, s, d )
|
2855
|
+
@spaces, @status, @domain = ct, s, d
|
2856
|
+
end
|
2857
|
+
def indent_re
|
2858
|
+
if @status == :Block
|
2859
|
+
if @spaces > 0
|
2860
|
+
/\A( {0,#{ @spaces - 1 }})(#[^\n]+|-( +(?!:)|$)| *)?/
|
2861
|
+
else
|
2862
|
+
/\A( *)(#[^\n]+)?/
|
2863
|
+
end
|
2864
|
+
else
|
2865
|
+
/\A( *)(#[^\n]+|-( +(?!:)|$))?/
|
2866
|
+
end
|
2867
|
+
end
|
2868
|
+
end
|
2869
|
+
|
2870
|
+
#
|
2871
|
+
# Token class added 2002 Dec 26.
|
2872
|
+
# Thanks to this class, we can now track line numbers
|
2873
|
+
# and store accessory data to our tokens. This should
|
2874
|
+
# eventually assist our emitter in reforming a document
|
2875
|
+
# in its original form.
|
2876
|
+
#
|
2877
|
+
class Token
|
2878
|
+
attr_accessor :sym, :data, :lineno, :charno
|
2879
|
+
def initialize( s, d, ln, cn )
|
2880
|
+
@sym, @data, @lineno, @charno = s, d, ln, cn
|
2881
|
+
end
|
2882
|
+
end
|
2883
|
+
|
2884
|
+
#
|
2885
|
+
# Token stack ops
|
2886
|
+
#
|
2887
|
+
def reset_indent
|
2888
|
+
@indent, @indent_raw = "", ""
|
2889
|
+
end
|
2890
|
+
|
2891
|
+
def reset_tokens
|
2892
|
+
@q = []
|
2893
|
+
end
|
2894
|
+
|
2895
|
+
def add_token( sym, data )
|
2896
|
+
if sym == :FOLD
|
2897
|
+
if @q.last.sym != :FOLD
|
2898
|
+
raise YAML::Error, "Improper fold!!"
|
2899
|
+
end
|
2900
|
+
if @q.last.data =~ / \Z/
|
2901
|
+
@lvl.last.domain = :FoldIndt if @lvl.last.domain == :Folded
|
2902
|
+
elsif @lvl.last.domain == :Folded
|
2903
|
+
@q.last.data.gsub!( /\n\Z\n/, "\n" ) unless @q.last.data.gsub!( /(.)\Z\n/, '\1 ' )
|
2904
|
+
elsif @lvl.last.domain == :FoldIndt
|
2905
|
+
@lvl.last.domain = :Folded
|
2906
|
+
end
|
2907
|
+
@q.last.data += data
|
2908
|
+
else
|
2909
|
+
@q.push Token.new( sym, data, @lineno, @charno )
|
2910
|
+
end
|
2911
|
+
end
|
2912
|
+
|
2913
|
+
def apply_indent
|
2914
|
+
# Turn indent into a token
|
2915
|
+
unless @indent.empty?
|
2916
|
+
indt_len = /^ *\Z/.match( @indent )[0].length
|
2917
|
+
if @lvl.last.status == :Block and @q.last.sym == :FOLD
|
2918
|
+
add_fold_indent
|
2919
|
+
end
|
2920
|
+
if @lvl.last.spaces > indt_len
|
2921
|
+
add_end_indent indt_len
|
2922
|
+
end
|
2923
|
+
if @lvl.last.status == :Block
|
2924
|
+
fold_txt = ""
|
2925
|
+
if @q.last.sym == :FSTART
|
2926
|
+
if @q.last.data =~ /(\d+)/
|
2927
|
+
if @lvl.last.spaces > 0
|
2928
|
+
@lvl.last.spaces -= 1
|
2929
|
+
end
|
2930
|
+
indt_len = $1.to_i + @lvl.last.spaces
|
2931
|
+
end
|
2932
|
+
@lvl.last.spaces = indt_len
|
2933
|
+
@q.push Token.new( :FOLD, fold_txt, @lineno, 1 )
|
2934
|
+
@indent.slice!( 0, 1 )
|
2935
|
+
add_fold_indent
|
2936
|
+
end
|
2937
|
+
else
|
2938
|
+
indt_type = :INDENT
|
2939
|
+
if @lvl.last.spaces < indt_len
|
2940
|
+
indt_type = :IOPEN
|
2941
|
+
end
|
2942
|
+
if @q.last and @q.last.sym == :PLAIN and ( indt_type == :IOPEN or
|
2943
|
+
( @lvl.last.spaces == indt_len and @q[-2] and @q[-2].sym == :IOPEN ) )
|
2944
|
+
unless @q.last.data.empty?
|
2945
|
+
@q.last.data += @indent_raw.gsub( /^ +/, '' ).gsub( /\n(\n*)/, '\1' )
|
2946
|
+
end
|
2947
|
+
elsif @lvl.last.status != :Inline
|
2948
|
+
@plain_set = @plain_sets[ :AllowInline ]
|
2949
|
+
if indt_type == :IOPEN
|
2950
|
+
@lvl.push Level.new( indt_len, @lvl.last.status, @lvl.last.domain )
|
2951
|
+
end
|
2952
|
+
@q.push Token.new( indt_type, indt_len, @lineno, 1 )
|
2953
|
+
end
|
2954
|
+
end
|
2955
|
+
reset_indent
|
2956
|
+
end
|
2957
|
+
end
|
2958
|
+
|
2959
|
+
def close_tokens
|
2960
|
+
@q.push Token.new( false, '$', @lineno, @charno )
|
2961
|
+
end
|
2962
|
+
|
2963
|
+
def pop_token
|
2964
|
+
@q.pop
|
2965
|
+
end
|
2966
|
+
|
2967
|
+
def push_token( tok )
|
2968
|
+
@q.push tok
|
2969
|
+
end
|
2970
|
+
|
2971
|
+
#
|
2972
|
+
# Used by Racc
|
2973
|
+
# The @last_token stored for error_reporting
|
2974
|
+
#
|
2975
|
+
def next_token
|
2976
|
+
@last_tokens.push @q.first
|
2977
|
+
if @last_tokens.length > 5
|
2978
|
+
@last_tokens.shift
|
2979
|
+
end
|
2980
|
+
tok = @q.shift
|
2981
|
+
[ tok.sym, tok.data ]
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
def add_end_indent( indt_len )
|
2985
|
+
while @lvl.last.spaces > indt_len
|
2986
|
+
@q.push Token.new( :IEND, @lvl.pop.spaces, @lineno, 1 )
|
2987
|
+
end
|
2988
|
+
end
|
2989
|
+
|
2990
|
+
#
|
2991
|
+
# Keep line number count
|
2992
|
+
#
|
2993
|
+
def readline
|
2994
|
+
@lineno += 1
|
2995
|
+
@charno = 1
|
2996
|
+
begin
|
2997
|
+
@stream.readline
|
2998
|
+
rescue IOError
|
2999
|
+
end
|
3000
|
+
end
|
3001
|
+
|
3002
|
+
def eof?; @stream.eof?; end
|
3003
|
+
|
3004
|
+
#
|
3005
|
+
# Handle Hash special keys
|
3006
|
+
#
|
3007
|
+
def hash_update( h, item )
|
3008
|
+
if item.class == Array
|
3009
|
+
# if h.class != YAML::SpecialHash
|
3010
|
+
# h = YAML::SpecialHash.new.update( h )
|
3011
|
+
# end
|
3012
|
+
if item[0] == :MERGE
|
3013
|
+
if Hash === item[1]
|
3014
|
+
h.update( item[1] )
|
3015
|
+
elsif Array === item[1]
|
3016
|
+
item[1].flatten.reverse.each { |hmerge|
|
3017
|
+
h.update( hmerge )
|
3018
|
+
}
|
3019
|
+
end
|
3020
|
+
elsif item[0] == :DEFAULT
|
3021
|
+
h.default = item[1]
|
3022
|
+
# elsif item[0] == :COMMENT
|
3023
|
+
# h.comment = item[1]
|
3024
|
+
end
|
3025
|
+
elsif item.class == YAML::SpecialHash
|
3026
|
+
h = item.update( h )
|
3027
|
+
elsif item.is_a? Hash
|
3028
|
+
h.update( item )
|
3029
|
+
else
|
3030
|
+
raise YAML::Error, "Invalid update to Hash with item: " + item.inspect
|
3031
|
+
end
|
3032
|
+
return h
|
3033
|
+
end
|
3034
|
+
|
3035
|
+
def attach_transfer( meth, val )
|
3036
|
+
meth = YAML.unescape( meth )
|
3037
|
+
if @options[:Model] == :Generic
|
3038
|
+
val.type_id = meth
|
3039
|
+
val
|
3040
|
+
else
|
3041
|
+
YAML.transfer_method( meth, val )
|
3042
|
+
end
|
3043
|
+
end
|
3044
|
+
|
3045
|
+
#
|
3046
|
+
# Add a new node
|
3047
|
+
#
|
3048
|
+
def new_node( type_id, val )
|
3049
|
+
if @options[:Model] == :Generic
|
3050
|
+
val = YamlNode.new( type_id, val )
|
3051
|
+
end
|
3052
|
+
val
|
3053
|
+
end
|
3054
|
+
|
3055
|
+
#
|
3056
|
+
# Take block text and format based on the block def characters
|
3057
|
+
#
|
3058
|
+
def process_block( fold_type, fold_text )
|
3059
|
+
fold_text.chomp! if fold_type.include?( '|' )
|
3060
|
+
if fold_type.include?( '+' )
|
3061
|
+
fold_text << "\n"
|
3062
|
+
else
|
3063
|
+
fold_text.chomp!( '' )
|
3064
|
+
if fold_type.include?( '-' )
|
3065
|
+
fold_text.chomp!
|
3066
|
+
else
|
3067
|
+
fold_text << "\n"
|
3068
|
+
end
|
3069
|
+
end
|
3070
|
+
return fold_text
|
3071
|
+
end
|
3072
|
+
|
3073
|
+
def add_fold_indent
|
3074
|
+
if @lvl.last.spaces > 0
|
3075
|
+
@indent.gsub!( /^ {0,#{ @lvl.last.spaces }}/, '' )
|
3076
|
+
end
|
3077
|
+
@q.last.data += @indent
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
def process_plain( p )
|
3081
|
+
if @options[:Model] == :Generic
|
3082
|
+
new_node( YAML.detect_implicit( p ), p )
|
3083
|
+
else
|
3084
|
+
YAML.try_implicit( p )
|
3085
|
+
end
|
3086
|
+
end
|
3087
|
+
..end src/yaml.y.rb modeval..idae682a68eb
|
3088
|
+
|
3089
|
+
##### racc 1.4.3 generates ###
|
3090
|
+
|
3091
|
+
racc_reduce_table = [
|
3092
|
+
0, 0, :racc_error,
|
3093
|
+
1, 22, :_reduce_none,
|
3094
|
+
1, 22, :_reduce_none,
|
3095
|
+
2, 22, :_reduce_3,
|
3096
|
+
1, 22, :_reduce_4,
|
3097
|
+
1, 25, :_reduce_none,
|
3098
|
+
0, 25, :_reduce_6,
|
3099
|
+
2, 23, :_reduce_7,
|
3100
|
+
1, 23, :_reduce_8,
|
3101
|
+
1, 23, :_reduce_9,
|
3102
|
+
3, 23, :_reduce_10,
|
3103
|
+
2, 24, :_reduce_11,
|
3104
|
+
1, 24, :_reduce_none,
|
3105
|
+
1, 24, :_reduce_none,
|
3106
|
+
1, 24, :_reduce_none,
|
3107
|
+
3, 24, :_reduce_15,
|
3108
|
+
1, 24, :_reduce_none,
|
3109
|
+
1, 24, :_reduce_none,
|
3110
|
+
3, 24, :_reduce_18,
|
3111
|
+
4, 26, :_reduce_19,
|
3112
|
+
3, 26, :_reduce_20,
|
3113
|
+
3, 27, :_reduce_21,
|
3114
|
+
2, 32, :_reduce_22,
|
3115
|
+
1, 31, :_reduce_23,
|
3116
|
+
3, 31, :_reduce_24,
|
3117
|
+
3, 28, :_reduce_25,
|
3118
|
+
2, 28, :_reduce_26,
|
3119
|
+
1, 33, :_reduce_27,
|
3120
|
+
2, 33, :_reduce_28,
|
3121
|
+
3, 33, :_reduce_29,
|
3122
|
+
3, 29, :_reduce_30,
|
3123
|
+
3, 35, :_reduce_31,
|
3124
|
+
3, 35, :_reduce_32,
|
3125
|
+
1, 36, :_reduce_none,
|
3126
|
+
5, 36, :_reduce_34,
|
3127
|
+
1, 34, :_reduce_35,
|
3128
|
+
3, 34, :_reduce_36,
|
3129
|
+
3, 30, :_reduce_37,
|
3130
|
+
2, 30, :_reduce_38,
|
3131
|
+
1, 37, :_reduce_39,
|
3132
|
+
3, 37, :_reduce_40 ]
|
3133
|
+
|
3134
|
+
racc_reduce_n = 41
|
3135
|
+
|
3136
|
+
racc_shift_n = 74
|
3137
|
+
|
3138
|
+
racc_action_table = [
|
3139
|
+
4, 6, 8, 10, 12, 14, 59, 60, 52, 61,
|
3140
|
+
58, 3, 30, 10, 12, 34, 51, 15, 4, 6,
|
3141
|
+
8, 10, 12, 14, 68, 31, 44, 45, 42, 3,
|
3142
|
+
30, 10, 12, 34, 43, 15, 4, 6, 8, 10,
|
3143
|
+
12, 14, 50, 31, 33, 62, 49, 3, 20, 21,
|
3144
|
+
63, 54, 17, 15, 4, 6, 8, 10, 12, 14,
|
3145
|
+
30, 10, 12, 34, 57, 3, 30, 10, 12, 34,
|
3146
|
+
52, 15, 4, 6, 8, 10, 12, 14, 25, 31,
|
3147
|
+
70, 53, 72, 3, 30, 10, 12, 34, 51, 15,
|
3148
|
+
4, 6, 8, 10, 12, 14, nil, nil, nil, nil,
|
3149
|
+
nil, 3, nil, nil, nil, nil, nil, 15, 4, 6,
|
3150
|
+
8, 10, 12, 14, nil, nil, nil, nil, nil, 3,
|
3151
|
+
nil, nil, nil, nil, nil, 15, 4, 6, 8, 10,
|
3152
|
+
12, 14, nil, nil, nil, nil, nil, 3, nil, nil,
|
3153
|
+
nil, nil, nil, 15, 4, 6, 8, 10, 12, 14,
|
3154
|
+
nil, nil, nil, nil, nil, 3, nil, nil, nil, nil,
|
3155
|
+
nil, 15, 4, 6, 8, 10, 12, 14, 8, 10,
|
3156
|
+
12, 14, nil, 3, nil, nil, nil, 3, nil, 15,
|
3157
|
+
nil, nil, nil, 15, 30, 10, 12, 34, nil, 37,
|
3158
|
+
nil, 25, nil, 3, nil, nil, nil, 31, 33, 15 ]
|
3159
|
+
|
3160
|
+
racc_action_check = [
|
3161
|
+
0, 0, 0, 0, 0, 0, 36, 37, 27, 37,
|
3162
|
+
36, 0, 15, 15, 15, 15, 27, 0, 53, 53,
|
3163
|
+
53, 53, 53, 53, 55, 15, 19, 19, 15, 53,
|
3164
|
+
49, 49, 49, 49, 17, 53, 3, 3, 3, 3,
|
3165
|
+
3, 3, 26, 49, 49, 41, 26, 3, 3, 3,
|
3166
|
+
41, 32, 1, 3, 4, 4, 4, 4, 4, 4,
|
3167
|
+
30, 30, 30, 30, 35, 4, 62, 62, 62, 62,
|
3168
|
+
56, 4, 51, 51, 51, 51, 51, 51, 58, 62,
|
3169
|
+
61, 31, 68, 51, 34, 34, 34, 34, 39, 51,
|
3170
|
+
45, 45, 45, 45, 45, 45, nil, nil, nil, nil,
|
3171
|
+
nil, 45, nil, nil, nil, nil, nil, 45, 21, 21,
|
3172
|
+
21, 21, 21, 21, nil, nil, nil, nil, nil, 21,
|
3173
|
+
nil, nil, nil, nil, nil, 21, 33, 33, 33, 33,
|
3174
|
+
33, 33, nil, nil, nil, nil, nil, 33, nil, nil,
|
3175
|
+
nil, nil, nil, 33, 25, 25, 25, 25, 25, 25,
|
3176
|
+
nil, nil, nil, nil, nil, 25, nil, nil, nil, nil,
|
3177
|
+
nil, 25, 72, 72, 72, 72, 72, 72, 8, 8,
|
3178
|
+
8, 8, nil, 72, nil, nil, nil, 8, nil, 72,
|
3179
|
+
nil, nil, nil, 8, 14, 14, 14, 14, nil, 14,
|
3180
|
+
nil, 14, nil, 14, nil, nil, nil, 14, 14, 14 ]
|
3181
|
+
|
3182
|
+
racc_action_pointer = [
|
3183
|
+
-2, 52, nil, 34, 52, nil, nil, nil, 164, nil,
|
3184
|
+
nil, nil, nil, nil, 180, 8, nil, 34, nil, 12,
|
3185
|
+
nil, 106, nil, nil, nil, 142, 34, 0, nil, nil,
|
3186
|
+
56, 65, 43, 124, 80, 56, -2, -1, nil, 72,
|
3187
|
+
nil, 30, nil, nil, nil, 88, nil, nil, nil, 26,
|
3188
|
+
nil, 70, nil, 16, nil, 12, 62, nil, 67, nil,
|
3189
|
+
nil, 72, 62, nil, nil, nil, nil, nil, 66, nil,
|
3190
|
+
nil, nil, 160, nil ]
|
3191
|
+
|
3192
|
+
racc_action_default = [
|
3193
|
+
-41, -41, -1, -41, -41, -2, -4, -12, -41, -13,
|
3194
|
+
-8, -14, -9, -16, -41, -41, -17, -41, -27, -41,
|
3195
|
+
-26, -6, -3, -7, -11, -6, -41, -41, -33, -35,
|
3196
|
+
-41, -41, -41, -41, -41, -41, -41, -41, -23, -41,
|
3197
|
+
-39, -41, -38, 74, -25, -6, -5, -28, -22, -41,
|
3198
|
+
-30, -6, -10, -6, -15, -41, -41, -18, -41, -21,
|
3199
|
+
-20, -41, -41, -37, -29, -36, -31, -32, -41, -24,
|
3200
|
+
-19, -40, -6, -34 ]
|
3201
|
+
|
3202
|
+
racc_goto_table = [
|
3203
|
+
23, 47, 40, 38, 29, 48, 27, 39, 36, 1,
|
3204
|
+
35, 19, 18, 22, 26, 32, 24, 41, nil, nil,
|
3205
|
+
nil, nil, 23, nil, nil, 64, 56, nil, nil, nil,
|
3206
|
+
nil, 66, nil, 67, nil, nil, nil, nil, nil, 65,
|
3207
|
+
nil, 39, 55, nil, nil, nil, nil, 69, nil, 71,
|
3208
|
+
nil, nil, 73, nil, 39 ]
|
3209
|
+
|
3210
|
+
racc_goto_check = [
|
3211
|
+
2, 4, 14, 11, 15, 4, 2, 2, 10, 1,
|
3212
|
+
9, 12, 1, 1, 13, 7, 3, 16, nil, nil,
|
3213
|
+
nil, nil, 2, nil, nil, 4, 2, nil, nil, nil,
|
3214
|
+
nil, 4, nil, 4, nil, nil, nil, nil, nil, 15,
|
3215
|
+
nil, 2, 1, nil, nil, nil, nil, 11, nil, 14,
|
3216
|
+
nil, nil, 4, nil, 2 ]
|
3217
|
+
|
3218
|
+
racc_goto_pointer = [
|
3219
|
+
nil, 9, -8, 8, -20, nil, nil, 1, nil, -4,
|
3220
|
+
-6, -11, 8, 0, -13, -10, 2 ]
|
3221
|
+
|
3222
|
+
racc_goto_default = [
|
3223
|
+
nil, 46, 2, 5, nil, 7, 9, 11, 13, 16,
|
3224
|
+
nil, nil, nil, nil, 28, nil, nil ]
|
3225
|
+
|
3226
|
+
racc_token_table = {
|
3227
|
+
false => 0,
|
3228
|
+
Object.new => 1,
|
3229
|
+
:ANCHOR => 2,
|
3230
|
+
:ALIAS => 3,
|
3231
|
+
:TRANSFER => 4,
|
3232
|
+
:WORD => 5,
|
3233
|
+
:PLAIN => 6,
|
3234
|
+
:IOPEN => 7,
|
3235
|
+
:IEND => 8,
|
3236
|
+
:FSTART => 9,
|
3237
|
+
:FOLD => 10,
|
3238
|
+
"-" => 11,
|
3239
|
+
:INDENT => 12,
|
3240
|
+
"[" => 13,
|
3241
|
+
"]" => 14,
|
3242
|
+
"," => 15,
|
3243
|
+
":" => 16,
|
3244
|
+
"=" => 17,
|
3245
|
+
"?" => 18,
|
3246
|
+
"{" => 19,
|
3247
|
+
"}" => 20 }
|
3248
|
+
|
3249
|
+
racc_use_result_var = true
|
3250
|
+
|
3251
|
+
racc_nt_base = 21
|
3252
|
+
|
3253
|
+
Racc_arg = [
|
3254
|
+
racc_action_table,
|
3255
|
+
racc_action_check,
|
3256
|
+
racc_action_default,
|
3257
|
+
racc_action_pointer,
|
3258
|
+
racc_goto_table,
|
3259
|
+
racc_goto_check,
|
3260
|
+
racc_goto_default,
|
3261
|
+
racc_goto_pointer,
|
3262
|
+
racc_nt_base,
|
3263
|
+
racc_reduce_table,
|
3264
|
+
racc_token_table,
|
3265
|
+
racc_shift_n,
|
3266
|
+
racc_reduce_n,
|
3267
|
+
racc_use_result_var ]
|
3268
|
+
|
3269
|
+
Racc_token_to_s_table = [
|
3270
|
+
'$end',
|
3271
|
+
'error',
|
3272
|
+
'ANCHOR',
|
3273
|
+
'ALIAS',
|
3274
|
+
'TRANSFER',
|
3275
|
+
'WORD',
|
3276
|
+
'PLAIN',
|
3277
|
+
'IOPEN',
|
3278
|
+
'IEND',
|
3279
|
+
'FSTART',
|
3280
|
+
'FOLD',
|
3281
|
+
'"-"',
|
3282
|
+
'INDENT',
|
3283
|
+
'"["',
|
3284
|
+
'"]"',
|
3285
|
+
'","',
|
3286
|
+
'":"',
|
3287
|
+
'"="',
|
3288
|
+
'"?"',
|
3289
|
+
'"{"',
|
3290
|
+
'"}"',
|
3291
|
+
'$start',
|
3292
|
+
'atom',
|
3293
|
+
'word_rep',
|
3294
|
+
'struct_rep',
|
3295
|
+
'atom_or_empty',
|
3296
|
+
'scalar_block',
|
3297
|
+
'implicit_seq',
|
3298
|
+
'inline_seq',
|
3299
|
+
'implicit_map',
|
3300
|
+
'inline_map',
|
3301
|
+
'in_implicit_seq',
|
3302
|
+
'basic_seq',
|
3303
|
+
'in_inline_seq',
|
3304
|
+
'in_implicit_map',
|
3305
|
+
'basic_mapping',
|
3306
|
+
'complex_mapping',
|
3307
|
+
'in_inline_map']
|
3308
|
+
|
3309
|
+
Racc_debug_parser = false
|
3310
|
+
|
3311
|
+
##### racc system variables end #####
|
3312
|
+
|
3313
|
+
# reduce 0 omitted
|
3314
|
+
|
3315
|
+
# reduce 1 omitted
|
3316
|
+
|
3317
|
+
# reduce 2 omitted
|
3318
|
+
|
3319
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 17
|
3320
|
+
def _reduce_3( val, _values, result )
|
3321
|
+
if @options[:Model] == :Generic
|
3322
|
+
val[1].anchor = val[0]
|
3323
|
+
end
|
3324
|
+
result = @anchor[ val[0] ] = val[1]
|
3325
|
+
result
|
3326
|
+
end
|
3327
|
+
.,.,
|
3328
|
+
|
3329
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 22
|
3330
|
+
def _reduce_4( val, _values, result )
|
3331
|
+
result = @anchor[ val[0] ]
|
3332
|
+
result
|
3333
|
+
end
|
3334
|
+
.,.,
|
3335
|
+
|
3336
|
+
# reduce 5 omitted
|
3337
|
+
|
3338
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 25
|
3339
|
+
def _reduce_6( val, _values, result )
|
3340
|
+
result = new_node( 'null', nil )
|
3341
|
+
result
|
3342
|
+
end
|
3343
|
+
.,.,
|
3344
|
+
|
3345
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 32
|
3346
|
+
def _reduce_7( val, _values, result )
|
3347
|
+
result = attach_transfer( val[0], val[1] )
|
3348
|
+
result
|
3349
|
+
end
|
3350
|
+
.,.,
|
3351
|
+
|
3352
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 33
|
3353
|
+
def _reduce_8( val, _values, result )
|
3354
|
+
result = new_node( 'str', val[0] )
|
3355
|
+
result
|
3356
|
+
end
|
3357
|
+
.,.,
|
3358
|
+
|
3359
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 34
|
3360
|
+
def _reduce_9( val, _values, result )
|
3361
|
+
result = process_plain( val[0] )
|
3362
|
+
result
|
3363
|
+
end
|
3364
|
+
.,.,
|
3365
|
+
|
3366
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 35
|
3367
|
+
def _reduce_10( val, _values, result )
|
3368
|
+
result = val[1]
|
3369
|
+
result
|
3370
|
+
end
|
3371
|
+
.,.,
|
3372
|
+
|
3373
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 41
|
3374
|
+
def _reduce_11( val, _values, result )
|
3375
|
+
result = attach_transfer( val[0], val[1] )
|
3376
|
+
result
|
3377
|
+
end
|
3378
|
+
.,.,
|
3379
|
+
|
3380
|
+
# reduce 12 omitted
|
3381
|
+
|
3382
|
+
# reduce 13 omitted
|
3383
|
+
|
3384
|
+
# reduce 14 omitted
|
3385
|
+
|
3386
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 45
|
3387
|
+
def _reduce_15( val, _values, result )
|
3388
|
+
result = val[1]
|
3389
|
+
result
|
3390
|
+
end
|
3391
|
+
.,.,
|
3392
|
+
|
3393
|
+
# reduce 16 omitted
|
3394
|
+
|
3395
|
+
# reduce 17 omitted
|
3396
|
+
|
3397
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 48
|
3398
|
+
def _reduce_18( val, _values, result )
|
3399
|
+
result = val[1]
|
3400
|
+
result
|
3401
|
+
end
|
3402
|
+
.,.,
|
3403
|
+
|
3404
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 56
|
3405
|
+
def _reduce_19( val, _values, result )
|
3406
|
+
result = new_node( 'str', process_block( val[1], val[2] ) )
|
3407
|
+
result
|
3408
|
+
end
|
3409
|
+
.,.,
|
3410
|
+
|
3411
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 60
|
3412
|
+
def _reduce_20( val, _values, result )
|
3413
|
+
result = new_node( 'str', '' )
|
3414
|
+
result
|
3415
|
+
end
|
3416
|
+
.,.,
|
3417
|
+
|
3418
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 66
|
3419
|
+
def _reduce_21( val, _values, result )
|
3420
|
+
result = new_node( 'seq', val[1] )
|
3421
|
+
result
|
3422
|
+
end
|
3423
|
+
.,.,
|
3424
|
+
|
3425
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 68
|
3426
|
+
def _reduce_22( val, _values, result )
|
3427
|
+
result = val[1]
|
3428
|
+
result
|
3429
|
+
end
|
3430
|
+
.,.,
|
3431
|
+
|
3432
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 70
|
3433
|
+
def _reduce_23( val, _values, result )
|
3434
|
+
result = val
|
3435
|
+
result
|
3436
|
+
end
|
3437
|
+
.,.,
|
3438
|
+
|
3439
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 73
|
3440
|
+
def _reduce_24( val, _values, result )
|
3441
|
+
result.push val[2]
|
3442
|
+
result
|
3443
|
+
end
|
3444
|
+
.,.,
|
3445
|
+
|
3446
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 79
|
3447
|
+
def _reduce_25( val, _values, result )
|
3448
|
+
result = new_node( 'seq', val[1] )
|
3449
|
+
result
|
3450
|
+
end
|
3451
|
+
.,.,
|
3452
|
+
|
3453
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 80
|
3454
|
+
def _reduce_26( val, _values, result )
|
3455
|
+
result = new_node( 'seq', [] )
|
3456
|
+
result
|
3457
|
+
end
|
3458
|
+
.,.,
|
3459
|
+
|
3460
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 82
|
3461
|
+
def _reduce_27( val, _values, result )
|
3462
|
+
result = val
|
3463
|
+
result
|
3464
|
+
end
|
3465
|
+
.,.,
|
3466
|
+
|
3467
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 83
|
3468
|
+
def _reduce_28( val, _values, result )
|
3469
|
+
result = [ result = new_node( 'null', nil ), val[1] ]
|
3470
|
+
result
|
3471
|
+
end
|
3472
|
+
.,.,
|
3473
|
+
|
3474
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 84
|
3475
|
+
def _reduce_29( val, _values, result )
|
3476
|
+
result.push val[2]
|
3477
|
+
result
|
3478
|
+
end
|
3479
|
+
.,.,
|
3480
|
+
|
3481
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 89
|
3482
|
+
def _reduce_30( val, _values, result )
|
3483
|
+
result = new_node( 'map', val[1] )
|
3484
|
+
result
|
3485
|
+
end
|
3486
|
+
.,.,
|
3487
|
+
|
3488
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 93
|
3489
|
+
def _reduce_31( val, _values, result )
|
3490
|
+
if val[0] == '<<'
|
3491
|
+
result = [ :MERGE, val[2] ]
|
3492
|
+
else
|
3493
|
+
result = { val[0] => val[2] }
|
3494
|
+
end
|
3495
|
+
result
|
3496
|
+
end
|
3497
|
+
.,.,
|
3498
|
+
|
3499
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 101
|
3500
|
+
def _reduce_32( val, _values, result )
|
3501
|
+
result = [ :DEFAULT, val[2] ]
|
3502
|
+
result
|
3503
|
+
end
|
3504
|
+
.,.,
|
3505
|
+
|
3506
|
+
# reduce 33 omitted
|
3507
|
+
|
3508
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 107
|
3509
|
+
def _reduce_34( val, _values, result )
|
3510
|
+
result = { val[1] => val[4] }
|
3511
|
+
result
|
3512
|
+
end
|
3513
|
+
.,.,
|
3514
|
+
|
3515
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 112
|
3516
|
+
def _reduce_35( val, _values, result )
|
3517
|
+
result = hash_update( {}, val[0] )
|
3518
|
+
result
|
3519
|
+
end
|
3520
|
+
.,.,
|
3521
|
+
|
3522
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 116
|
3523
|
+
def _reduce_36( val, _values, result )
|
3524
|
+
result = hash_update( val[0], val[2] )
|
3525
|
+
result
|
3526
|
+
end
|
3527
|
+
.,.,
|
3528
|
+
|
3529
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 122
|
3530
|
+
def _reduce_37( val, _values, result )
|
3531
|
+
result = new_node( 'map', val[1] )
|
3532
|
+
result
|
3533
|
+
end
|
3534
|
+
.,.,
|
3535
|
+
|
3536
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 123
|
3537
|
+
def _reduce_38( val, _values, result )
|
3538
|
+
result = new_node( 'map', Hash.new )
|
3539
|
+
result
|
3540
|
+
end
|
3541
|
+
.,.,
|
3542
|
+
|
3543
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 127
|
3544
|
+
def _reduce_39( val, _values, result )
|
3545
|
+
result = hash_update( {}, val[0] )
|
3546
|
+
result
|
3547
|
+
end
|
3548
|
+
.,.,
|
3549
|
+
|
3550
|
+
module_eval <<'.,.,', 'src/yaml.y.rb', 131
|
3551
|
+
def _reduce_40( val, _values, result )
|
3552
|
+
result = hash_update( val[0], val[2] )
|
3553
|
+
result
|
3554
|
+
end
|
3555
|
+
.,.,
|
3556
|
+
|
3557
|
+
def _reduce_none( val, _values, result )
|
3558
|
+
result
|
3559
|
+
end
|
3560
|
+
|
3561
|
+
end # class Parser
|
3562
|
+
|
3563
|
+
end # module YAML
|