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.
Files changed (44) hide show
  1. data/README +1 -1
  2. data/lib/rbyaml/composer.rb +28 -25
  3. data/lib/rbyaml/composer.rb.~1.2.~ +109 -0
  4. data/lib/rbyaml/constructor.rb +94 -84
  5. data/lib/rbyaml/constructor.rb.~1.2.~ +381 -0
  6. data/lib/rbyaml/dumper.rb +10 -17
  7. data/lib/rbyaml/dumper.rb.~1.2.~ +43 -0
  8. data/lib/rbyaml/emitter.rb +13 -26
  9. data/lib/rbyaml/emitter.rb.~1.2.~ +1116 -0
  10. data/lib/rbyaml/error.rb +15 -21
  11. data/lib/rbyaml/events.rb +29 -5
  12. data/lib/rbyaml/events.rb.~1.2.~ +93 -0
  13. data/lib/rbyaml/loader.rb +11 -23
  14. data/lib/rbyaml/loader.rb.~1.2.~ +52 -0
  15. data/lib/rbyaml/nodes.rb +13 -9
  16. data/lib/rbyaml/nodes.rb.~1.2.~ +52 -0
  17. data/lib/rbyaml/parser.rb +481 -343
  18. data/lib/rbyaml/parser.rb.old +531 -0
  19. data/lib/rbyaml/parser.rb.~1.2.~ +494 -0
  20. data/lib/rbyaml/reader.rb.~1.1.1.1.~ +127 -0
  21. data/lib/rbyaml/representer.rb +26 -17
  22. data/lib/rbyaml/representer.rb.~1.2.~ +239 -0
  23. data/lib/rbyaml/resolver.rb +15 -15
  24. data/lib/rbyaml/resolver.rb.~1.1.~ +163 -0
  25. data/lib/rbyaml/scanner.rb +457 -366
  26. data/lib/rbyaml/scanner.rb.~1.2.~ +1259 -0
  27. data/lib/rbyaml/serializer.rb +19 -17
  28. data/lib/rbyaml/serializer.rb.~1.2.~ +115 -0
  29. data/lib/rbyaml/tokens.rb +44 -4
  30. data/lib/rbyaml/tokens.rb.~1.2.~ +164 -0
  31. data/lib/rbyaml/util.rb +28 -0
  32. data/lib/rbyaml/yaml.rb +12 -12
  33. data/lib/rbyaml/yaml.rb.~1.2.~ +136 -0
  34. data/test/test_bm.rb +28 -0
  35. data/test/test_bm_syck.rb +28 -0
  36. data/test/test_invoke.rb +31 -0
  37. data/test/test_one.rb +5 -0
  38. data/test/test_profile.rb +32 -0
  39. data/test/test_rbyaml.rb +2 -1
  40. data/test/test_rbyaml.rb.~1.2.~ +31 -0
  41. data/test/test_time.rb +13 -8
  42. data/test/test_time.rb.~1.1.~ +29 -0
  43. data/test/yamlx.rb +3563 -0
  44. metadata +27 -2
@@ -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/, &regexp_proc )
2288
+ YAML.add_ruby_type( Regexp, &regexp_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