diff --git a/.classpath b/.classpath
index 7fca1fe2fe3..41f95a585c7 100644
--- a/.classpath
+++ b/.classpath
@@ -6,5 +6,6 @@
+
diff --git a/docs/jvyaml/CREDITS b/docs/jvyaml/CREDITS
new file mode 100644
index 00000000000..f9e8f87a4a2
--- /dev/null
+++ b/docs/jvyaml/CREDITS
@@ -0,0 +1,4 @@
+Credits
+-------
+
+Kirill Simonov - for writing the original Python code.
diff --git a/docs/jvyaml/LICENSE b/docs/jvyaml/LICENSE
new file mode 100644
index 00000000000..0a588b5f6a5
--- /dev/null
+++ b/docs/jvyaml/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2006 Ola Bini
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/docs/jvyaml/README b/docs/jvyaml/README
new file mode 100644
index 00000000000..90a96100a91
--- /dev/null
+++ b/docs/jvyaml/README
@@ -0,0 +1,31 @@
+= RbYAML - A pure Ruby YAML 1.1 loader and dumper
+
+Project Contact: Ola Bini
+
+The code is based mostly on the Python code written by Kirill Simonov for PyYAML3000.
+
+RbYAML is a project originating in the JRuby project (http://jruby.sourceforge.net), to create a pure Ruby
+YAML parser for use in JRuby and SYCK cannot be used in this case.
+Since the effort of writing a new one from scratch seemed like a major undertaking it seemed easier to
+port an existing one.
+
+The current functionality is more or less 1.1-compliant. What's missing is the Unicode-support. The idea
+is to have the interface resemble SYCK as much as possible, but this is still work in progress, since some
+of the major architectural choices are quite different.
+
+== Use
+
+Just require 'rbyaml' and use it as you would use YAML, but in module RbYAML instead:
+
+ require 'rbyaml'
+
+ RbYAML.load("--- \n- A\n- b\n- c\n") ----> ["A","b","c"]
+ "foo".to_yaml ----> "foo\n"
+
+== More information
+
+Visit http://rbyaml.rubyforge.org for more information and updated versions
+
+== License
+
+RbYAML is distributed with a MIT license, which can be found in the file LICENSE.
diff --git a/docs/rbyaml/LICENSE b/docs/rbyaml/LICENSE
new file mode 100644
index 00000000000..0a588b5f6a5
--- /dev/null
+++ b/docs/rbyaml/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2006 Ola Bini
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/docs/rbyaml/README b/docs/rbyaml/README
new file mode 100644
index 00000000000..90a96100a91
--- /dev/null
+++ b/docs/rbyaml/README
@@ -0,0 +1,31 @@
+= RbYAML - A pure Ruby YAML 1.1 loader and dumper
+
+Project Contact: Ola Bini
+
+The code is based mostly on the Python code written by Kirill Simonov for PyYAML3000.
+
+RbYAML is a project originating in the JRuby project (http://jruby.sourceforge.net), to create a pure Ruby
+YAML parser for use in JRuby and SYCK cannot be used in this case.
+Since the effort of writing a new one from scratch seemed like a major undertaking it seemed easier to
+port an existing one.
+
+The current functionality is more or less 1.1-compliant. What's missing is the Unicode-support. The idea
+is to have the interface resemble SYCK as much as possible, but this is still work in progress, since some
+of the major architectural choices are quite different.
+
+== Use
+
+Just require 'rbyaml' and use it as you would use YAML, but in module RbYAML instead:
+
+ require 'rbyaml'
+
+ RbYAML.load("--- \n- A\n- b\n- c\n") ----> ["A","b","c"]
+ "foo".to_yaml ----> "foo\n"
+
+== More information
+
+Visit http://rbyaml.rubyforge.org for more information and updated versions
+
+== License
+
+RbYAML is distributed with a MIT license, which can be found in the file LICENSE.
diff --git a/lib/jvyaml.jar b/lib/jvyaml.jar
new file mode 100644
index 00000000000..1cade989414
Binary files /dev/null and b/lib/jvyaml.jar differ
diff --git a/src/builtin/yaml.rb b/src/builtin/yaml.rb
index 94332cebf06..ee929c17a65 100644
--- a/src/builtin/yaml.rb
+++ b/src/builtin/yaml.rb
@@ -1,3563 +1,36 @@
-#
-# DO NOT MODIFY!!!!
-# This file is automatically generated by racc 1.4.3
-# from racc grammer file "src/yaml.y.rb".
-#
-#
-# src/yaml.rb: generated by racc (runtime embedded)
-#
-###### racc/parser.rb
+require 'rbyaml'
+require 'java'
-unless $".index 'racc/parser.rb'
-$".push 'racc/parser.rb'
-
-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
-#
-# parser.rb
-#
-# Copyright (c) 1999-2002 Minero Aoki
-#
-# This program is free software.
-# You can distribute/modify this program under the same terms of ruby.
-#
-# As a special exception, when this code is copied by Racc
-# into a Racc output file, you may use that output file
-# without restriction.
-#
-#
-
-unless defined? NotImplementedError
- NotImplementedError = NotImplementError
-end
-
-
-module Racc
- class ParseError < StandardError; end
-end
-unless defined? ::ParseError
- ParseError = Racc::ParseError
-end
-
-
-module Racc
-
- unless defined? Racc_No_Extentions
- Racc_No_Extentions = false
- end
-
- class Parser
-
- # revisions have been hardcoded to avoid branch/merge issues
- Racc_Runtime_Version = '1.4.3'
- Racc_Runtime_Revision = '1.1'.split(/\s+/)[1]
-
- Racc_Runtime_Core_Version_R = '1.4.3'
- Racc_Runtime_Core_Revision_R = '1.1'.split(/\s+/)[1]
- begin
- require 'racc/cparse'
- # Racc_Runtime_Core_Version_C = (defined in extention)
- Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split(/\s+/)[2]
- unless new.respond_to?(:_racc_do_parse_c, true)
- raise LoadError, 'old cparse.so'
- end
- if Racc_No_Extentions
- raise LoadError, 'selecting ruby version of racc runtime core'
- end
-
- Racc_Main_Parsing_Routine = :_racc_do_parse_c
- Racc_YY_Parse_Method = :_racc_yyparse_c
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
- Racc_Runtime_Type = 'c'
- rescue LoadError
- Racc_Main_Parsing_Routine = :_racc_do_parse_rb
- Racc_YY_Parse_Method = :_racc_yyparse_rb
- Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
- Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
- Racc_Runtime_Type = 'ruby'
- end
-
- def self.racc_runtime_type
- Racc_Runtime_Type
- end
-
- private
-
- def _racc_setup
- @yydebug = false unless self.class::Racc_debug_parser
- @yydebug = false unless defined? @yydebug
- if @yydebug
- @racc_debug_out = $stderr unless defined? @racc_debug_out
- @racc_debug_out ||= $stderr
- end
- arg = self.class::Racc_arg
- arg[13] = true if arg.size < 14
- arg
- end
-
- def _racc_init_sysvars
- @racc_state = [0]
- @racc_tstack = []
- @racc_vstack = []
-
- @racc_t = nil
- @racc_val = nil
-
- @racc_read_next = true
-
- @racc_user_yyerror = false
- @racc_error_status = 0
- end
-
-
- ###
- ### do_parse
- ###
-
- def do_parse
- __send__ Racc_Main_Parsing_Routine, _racc_setup(), false
- end
-
- def next_token
- raise NotImplementedError, "#{self.class}\#next_token is not defined"
- end
-
- def _racc_do_parse_rb( arg, in_debug )
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
-
- _racc_init_sysvars()
- tok = act = i = nil
- nerr = 0
-
- catch(:racc_end_parse) {
- while true
- if i = action_pointer[@racc_state[-1]]
- if @racc_read_next
- if @racc_t != 0 # not EOF
- tok, @racc_val = next_token()
- unless tok # EOF
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- racc_read_token(@racc_t, tok, @racc_val) if @yydebug
- @racc_read_next = false
- end
- end
- i += @racc_t
- if i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- ;
- else
- act = action_default[@racc_state[-1]]
- end
- else
- act = action_default[@racc_state[-1]]
- end
- while act = _racc_evalact(act, arg)
- end
- end
- }
- end
-
-
- ###
- ### yyparse
- ###
-
- def yyparse( recv, mid )
- __send__ Racc_YY_Parse_Method, recv, mid, _racc_setup(), true
- end
-
- def _racc_yyparse_rb( recv, mid, arg, c_debug )
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
-
- _racc_init_sysvars
- tok = nil
- act = nil
- i = nil
- nerr = 0
-
-
- catch(:racc_end_parse) {
- until i = action_pointer[@racc_state[-1]]
- while act = _racc_evalact(action_default[@racc_state[-1]], arg)
- end
- end
-
- recv.__send__(mid) do |tok, val|
-# $stderr.puts "rd: tok=#{tok}, val=#{val}"
- unless tok
- @racc_t = 0
- else
- @racc_t = (token_table[tok] or 1) # error token
- end
- @racc_val = val
- @racc_read_next = false
-
- i += @racc_t
- if i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- ;
-# $stderr.puts "01: act=#{act}"
- else
- act = action_default[@racc_state[-1]]
-# $stderr.puts "02: act=#{act}"
-# $stderr.puts "curstate=#{@racc_state[-1]}"
- end
-
- while act = _racc_evalact(act, arg)
- end
-
- while not (i = action_pointer[@racc_state[-1]]) or
- not @racc_read_next or
- @racc_t == 0 # $
- if i and i += @racc_t and
- i >= 0 and
- act = action_table[i] and
- action_check[i] == @racc_state[-1]
- ;
-# $stderr.puts "03: act=#{act}"
- else
-# $stderr.puts "04: act=#{act}"
- act = action_default[@racc_state[-1]]
- end
-
- while act = _racc_evalact(act, arg)
- end
- end
- end
- }
- end
-
-
- ###
- ### common
- ###
-
- def _racc_evalact( act, arg )
-# $stderr.puts "ea: act=#{act}"
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
-nerr = 0 # tmp
-
- if act > 0 and act < shift_n
- #
- # shift
- #
-
- if @racc_error_status > 0
- @racc_error_status -= 1 unless @racc_t == 1 # error token
- end
-
- @racc_vstack.push @racc_val
- @racc_state.push act
- @racc_read_next = true
-
- if @yydebug
- @racc_tstack.push @racc_t
- racc_shift @racc_t, @racc_tstack, @racc_vstack
- end
-
- elsif act < 0 and act > -reduce_n
- #
- # reduce
- #
-
- code = catch(:racc_jump) {
- @racc_state.push _racc_do_reduce(arg, act)
- false
- }
- if code
- case code
- when 1 # yyerror
- @racc_user_yyerror = true # user_yyerror
- return -reduce_n
- when 2 # yyaccept
- return shift_n
- else
- raise RuntimeError, '[Racc Bug] unknown jump code'
- end
- end
-
- elsif act == shift_n
- #
- # accept
- #
-
- racc_accept if @yydebug
- throw :racc_end_parse, @racc_vstack[0]
-
- elsif act == -reduce_n
- #
- # error
- #
-
- case @racc_error_status
- when 0
- unless arg[21] # user_yyerror
- nerr += 1
- on_error @racc_t, @racc_val, @racc_vstack
- end
- when 3
- if @racc_t == 0 # is $
- throw :racc_end_parse, nil
- end
- @racc_read_next = true
- end
- @racc_user_yyerror = false
- @racc_error_status = 3
-
- while true
- if i = action_pointer[@racc_state[-1]]
- i += 1 # error token
- if i >= 0 and
- (act = action_table[i]) and
- action_check[i] == @racc_state[-1]
- break
- end
- end
-
- throw :racc_end_parse, nil if @racc_state.size < 2
- @racc_state.pop
- @racc_vstack.pop
- if @yydebug
- @racc_tstack.pop
- racc_e_pop @racc_state, @racc_tstack, @racc_vstack
- end
- end
-
- return act
-
- else
- raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}"
- end
-
- racc_next_state(@racc_state[-1], @racc_state) if @yydebug
-
- nil
- end
-
- def _racc_do_reduce( arg, act )
- action_table, action_check, action_default, action_pointer,
- goto_table, goto_check, goto_default, goto_pointer,
- nt_base, reduce_table, token_table, shift_n,
- reduce_n, use_result, * = arg
- state = @racc_state
- vstack = @racc_vstack
- tstack = @racc_tstack
-
- i = act * -3
- len = reduce_table[i]
- reduce_to = reduce_table[i+1]
- method_id = reduce_table[i+2]
- void_array = []
-
- tmp_t = tstack[-len, len] if @yydebug
- tmp_v = vstack[-len, len]
- tstack[-len, len] = void_array if @yydebug
- vstack[-len, len] = void_array
- state[-len, len] = void_array
-
- # tstack must be updated AFTER method call
- if use_result
- vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
- else
- vstack.push __send__(method_id, tmp_v, vstack)
- end
- tstack.push reduce_to
-
- racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
-
- k1 = reduce_to - nt_base
- if i = goto_pointer[k1]
- i += state[-1]
- if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
- return curstate
- end
- end
- goto_default[k1]
- end
-
- def on_error( t, val, vstack )
- raise ParseError, sprintf("\nparse error on value %s (%s)",
- val.inspect, token_to_str(t) || '?')
- end
-
- def yyerror
- throw :racc_jump, 1
- end
-
- def yyaccept
- throw :racc_jump, 2
- end
-
- def yyerrok
- @racc_error_status = 0
- end
-
-
- # for debugging output
-
- def racc_read_token( t, tok, val )
- @racc_debug_out.print 'read '
- @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
- @racc_debug_out.puts val.inspect
- @racc_debug_out.puts
- end
-
- def racc_shift( tok, tstack, vstack )
- @racc_debug_out.puts "shift #{racc_token2str tok}"
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_reduce( toks, sim, tstack, vstack )
- out = @racc_debug_out
- out.print 'reduce '
- if toks.empty?
- out.print ' '
- else
- toks.each {|t| out.print ' ', racc_token2str(t) }
- end
- out.puts " --> #{racc_token2str(sim)}"
-
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_accept
- @racc_debug_out.puts 'accept'
- @racc_debug_out.puts
- end
-
- def racc_e_pop( state, tstack, vstack )
- @racc_debug_out.puts 'error recovering mode: pop token'
- racc_print_states state
- racc_print_stacks tstack, vstack
- @racc_debug_out.puts
- end
-
- def racc_next_state( curstate, state )
- @racc_debug_out.puts "goto #{curstate}"
- racc_print_states state
- @racc_debug_out.puts
- end
-
- def racc_print_stacks( t, v )
- out = @racc_debug_out
- out.print ' ['
- t.each_index do |i|
- out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
- end
- out.puts ' ]'
- end
-
- def racc_print_states( s )
- out = @racc_debug_out
- out.print ' ['
- s.each {|st| out.print ' ', st }
- out.puts ' ]'
- end
-
- def racc_token2str( tok )
- self.class::Racc_token_to_s_table[tok] or
- raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string"
- end
-
- def token_to_str( t )
- self.class::Racc_token_to_s_table[t]
- end
-
- end
-
-end
-..end /usr/local/lib/ruby/site_ruby/1.8/racc/parser.rb modeval..id4449eb2054
-end # end of racc/parser.rb
-
-
-self.class.module_eval <<'..end src/emitter.rb modeval..iddd2784be19', 'src/emitter.rb', 1
-# vim:sw=4:ts=4
-#
-# YAML for Ruby:
-# - Thanks to Brian Ingerson for YAML.pm
-#
-# Docs in YAML (see /doc/)
-#
-require 'pstore'
-require 'parsedate'
-require 'date'
-
-begin
-require 'stringio'
-rescue LoadError
- # StringIO based on code by MoonWolf
- class StringIO
- def initialize(string="")
- @string=string
- @pos=0
- @eof=(string.size==0)
- end
- def pos
- @pos
- end
- def eof
- @eof
- end
- alias eof? eof
- def readline(rs=$/)
- if @eof
- raise EOFError
- else
- if p = @string[@pos..-1]=~rs
- line = @string[@pos,p+1]
- else
- line = @string[@pos..-1]
- end
- @pos+=line.size
- @eof =true if @pos==@string.size
- $_ = line
- end
- end
- def rewind
- seek(0,0)
- end
- def seek(offset,whence)
- case whence
- when 0
- @pos=offset
- when 1
- @pos+=offset
- when 2
- @pos=@string.size+offset
- end
- @eof=(@pos>=@string.size)
- 0
- end
- end
-
-end
-
-
-module YAML
-
- #
- # Constants
- #
- VERSION = '0.49'
- SUPPORTED_YAML_VERSIONS = ['1.0']
-
- #
- # Parser tokens
- #
- WORD_CHAR = 'A-Za-z0-9'
- PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
- NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
- ESCAPE_CHAR = '[\\x00-\\x08\\x0b-\\x0d\\x0e-\\x1f]'
- INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
- SPACE_INDICATORS = '-#:,?'
- RESTRICTED_INDICATORS = '#:,}]'
- DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
- DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
- ESCAPES = %w{\z \x01 \x02 \x03 \x04 \x05 \x06 \a
- \x08 \t \n \v \f \r \x0e \x0f
- \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
- \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
- }
- UNESCAPES = {
- 'z' => "\x00", 'a' => "\x07", 'b' => "\x08", 't' => "\x09",
- 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
- 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
- }
-
- #
- # Encodings ( $-K to ICONV )
- #
- CHARSETS = {
- 'NONE' => 'LATIN1',
- 'ASCII' => 'US-ASCII',
- 'UTF-8' => 'UTF-8',
- 'EUC' => 'EUC-JP',
- 'SJIS' => 'SHIFT-JIS'
- }
-
- #
- # Error messages
- #
- ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
- ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
- ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
- ERROR_MANY_EXPLICIT = "More than one explicit transfer"
- ERROR_MANY_IMPLICIT = "More than one implicit request"
- ERROR_NO_ANCHOR = "No anchor for alias '%s'"
- ERROR_BAD_ANCHOR = "Invalid anchor: %s"
- ERROR_MANY_ANCHOR = "More than one anchor"
- ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
- ERROR_BAD_ALIAS = "Invalid alias: %s"
- ERROR_MANY_ALIAS = "More than one alias"
- ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
- ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
- ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
-
- #
- # Default settings
- #
- DEFAULTS = {
- :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
- :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
- :WidthType => 'absolute', :BestWidth => 80,
- :UseBlock => false, :UseFold => false, :Encoding => :None
- }
- TRANSFER_DOMAINS = {
- 'yaml.org,2002' => {},
- 'ruby.yaml.org,2002' => {}
- }
- PRIVATE_TYPES = {}
- IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
-
- def YAML.object_maker( obj_class, val )
- if Hash === val
- o = obj_class.new_without_initialize
- val.each_pair { |k,v|
- o.instance_eval "@#{k} = v"
- }
- o
- else
- raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
- end
- end
-
- #
- # YAML documents can be in UTF-8, UTF-16 or UTF-32
- # So let's read and write in Unicode
- #
- @@unicode = false
- begin
- require 'iconv'
- DEFAULTS[:Encoding] = :Utf8
- rescue LoadError
- end
-
- def YAML.unicode; @@unicode; end
- def YAML.unicode=( bool ); @@unicode = bool; end
-
- #
- # YAML Error class
- #
- class Error < StandardError; end
- class ParseError < Error; end
-
- #
- # YAML Generic Model container
- #
- class YamlNode
- attr_accessor :kind, :type_id, :value, :anchor
- def initialize( t, v )
- @type_id = t
- if Hash === v
- @kind = 'map'
- @value = {}
- v.each { |k,v|
- @value[ k.transform ] = [ k, v ]
- }
- elsif Array === v
- @kind = 'seq'
- @value = v
- elsif String === v
- @kind = 'scalar'
- @value = v
- end
- end
-
- #
- # Search for YPath entry and return
- # qualified nodes.
- #
- def select( ypath_str )
- matches = match_path( ypath_str )
-
- #
- # Create a new generic view of the elements selected
- #
- if matches
- result = []
- matches.each { |m|
- result.push m.last
- }
- YamlNode.new( 'seq', result )
- end
- end
-
- #
- # Search for YPath entry and return a list of
- # qualified paths.
- #
- def search( ypath_str )
- matches = match_path( ypath_str )
-
- if matches
- matches.collect { |m|
- path = []
- m.each_index { |i|
- path.push m[i] if ( i % 2 ).zero?
- }
- "/" + path.compact.join( "/" )
- }
- end
- end
-
- def at( seg )
- if Hash === @value and @value.has_key?( seg )
- @value[seg][1]
- elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
- @value[seg.to_i]
- end
- end
-
- #
- # YPath search returning a complete depth array
- #
- def match_path( ypath_str )
- depth = 0
- matches = []
- YPath.each_path( ypath_str ) do |ypath|
- seg = match_segment( ypath, 0 )
- matches += seg if seg
- end
- matches.uniq
- end
-
- #
- # Search a node for a single YPath segment
- #
- def match_segment( ypath, depth )
- deep_nodes = []
- seg = ypath.segments[ depth ]
- if seg == "/"
- unless String === @value
- idx = -1
- @value.collect { |v|
- idx += 1
- if Hash === @value
- match_init = [v[0], v[1][1]]
- match_deep = v[1][1].match_segment( ypath, depth )
- else
- match_init = [idx, v]
- match_deep = v.match_segment( ypath, depth )
- end
- if match_deep
- match_deep.each { |m|
- deep_nodes.push( match_init + m )
- }
- end
- }
- end
- depth += 1
- seg = ypath.segments[ depth ]
- end
- match_nodes =
- case seg
- when "."
- [[nil, self]]
- when ".."
- [["..", nil]]
- when "*"
- unless String === @value
- idx = -1
- @value.collect { |h|
- idx += 1
- if Hash === @value
- [h[0], h[1][1]]
- else
- [idx, h]
- end
- }
- end
- else
- if seg =~ /^"(.*)"$/
- seg = $1
- elsif seg =~ /^'(.*)'$/
- seg = $1
- end
- if ( v = at( seg ) )
- [[ seg, v ]]
- end
- end
- return deep_nodes unless match_nodes
- pred = ypath.predicates[ depth ]
- if pred
- case pred
- when /^\.=/
- pred = $'
- match_nodes.reject! { |n|
- n.last.value != pred
- }
- else
- match_nodes.reject! { |n|
- n.last.at( pred ).nil?
- }
- end
- end
- return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
-
- #puts "DEPTH: #{depth + 1}"
- deep_nodes = []
- match_nodes.each { |n|
- if n[1].is_a? YamlNode
- match_deep = n[1].match_segment( ypath, depth + 1 )
- if match_deep
- match_deep.each { |m|
- deep_nodes.push( n + m )
- }
- end
- else
- deep_nodes = []
- end
- }
- deep_nodes = nil if deep_nodes.length == 0
- deep_nodes
- end
-
- #
- # Transform this node fully into a native type
- #
- def transform
- t = nil
- if @value.is_a? Hash
- t = {}
- @value.each { |k,v|
- t[ k ] = v[1].transform
- }
- elsif @value.is_a? Array
- t = []
- @value.each { |v|
- t.push v.transform
- }
- else
- t = @value
- end
- YAML.transfer_method( @type_id, t )
- end
-
- #
- # We want the node to act like as Hash
- # if it is.
- #
- def []( *k )
- if Hash === @value
- v = @value.[]( *k )
- v[1] if v
- elsif Array === @value
- @value.[]( *k )
- end
- end
-
- def children
- if Hash === @value
- @value.values.collect { |c| c[1] }
- elsif Array === @value
- @value
- end
- end
-
- def children_with_index
- if Hash === @value
- @value.keys.collect { |i| [self[i], i] }
- elsif Array === @value
- i = -1; @value.collect { |v| i += 1; [v, i] }
- end
- end
-
- def emit
- transform.to_yaml
- end
- end
-
- class YPath
- attr_accessor :segments, :predicates, :flags
- def initialize( str )
- @segments = []
- @predicates = []
- @flags = nil
- while str =~ /^\/?(\/|[^\/[]+)(?:\[([^\]]+)\])?/
- @segments.push $1
- @predicates.push $2
- str = $'
- end
- unless str.to_s.empty?
- @segments += str.split( "/" )
- end
- if @segments.length == 0
- @segments.push "."
- end
- end
- def YPath.each_path( str )
- #
- # Find choices
- #
- paths = []
- str = "(#{ str })"
- while str.sub!( /\(([^()]+)\)/, "\n#{ paths.length }\n" )
- paths.push $1.split( '|' )
- end
-
- #
- # Construct all possible paths
- #
- all = [ str ]
- ( paths.length - 1 ).downto( 0 ) do |i|
- all = all.collect do |a|
- paths[i].collect do |p|
- a.gsub( /\n#{ i }\n/, p )
- end
- end.flatten.uniq
- end
- all.collect do |path|
- yield YPath.new( path )
- end
- end
- end
-
- #
- # Class method for creating streams
- #
- def YAML.make_stream( io )
- if String === io
- io = StringIO.new( io )
- #elsif not IO === io
- # raise YAML::Error, "YAML stream must be an IO or String object."
- # cnutter: This test was removed because GzipFile does not < IO in Ruby 1.8
- end
- if YAML::unicode
- def io.readline
- YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding )
- end
- def io.check_unicode
- @utf_encoding = YAML.sniff_encoding( read( 4 ) )
- @ln_sep = YAML.enc_separator( @utf_encoding )
- seek( -4, IO::SEEK_CUR )
- end
- def io.utf_encoding
- @utf_encoding
- end
- io.check_unicode
- else
- def io.utf_encoding
- :None
- end
- end
- io
- end
-
- #
- # Unicode conversion
- #
- def YAML.utf_to_internal( str, from_enc )
- return unless str
- to_enc = CHARSETS[$-K]
- case from_enc
- when :Utf32
- Iconv.iconv( to_enc, 'UTF-32', str )[0]
- when :Utf16
- Iconv.iconv( to_enc, 'UTF-16', str )[0]
- when :Utf8
- Iconv.iconv( to_enc, 'UTF-8', str )[0]
- when :None
- str
- else
- raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % from_enc.inspect
- end
- end
-
- def YAML.internal_to_utf( str, to_enc )
- return unless str
- from_enc = CHARSETS[$-K]
- case to_enc
- when :Utf32
- Iconv.iconv( 'UTF-32', from_enc, str )[0]
- when :Utf16
- Iconv.iconv( 'UTF-16', from_enc, str )[0]
- when :Utf8
- Iconv.iconv( 'UTF-8', from_enc, str )[0]
- when :None
- str
- else
- raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % to_enc.inspect
- end
- end
-
- def YAML.sniff_encoding( str )
- unless YAML::unicode
- :None
- else
- case str
- when /^\x00\x00\xFE\xFF/ # UTF-32
- :Utf32
- when /^\xFE\xFF/ # UTF-32BE
- :Utf16
- else
- :Utf8
- end
- end
- end
-
- def YAML.enc_separator( enc )
- case enc
- when :Utf32
- "\000\000\000\n"
- when :Utf16
- "\000\n"
- when :Utf8
- "\n"
- when :None
- "\n"
- else
- raise YAML::Error, ERROR_UNSUPPORTED_ENCODING % enc.inspect
- end
- end
-
- #
- # Output methods
- #
-
- #
- # Emit a set of values
- #
- class Emitter
- attr_accessor :options
- def initialize( opts )
- opts = {} if opts.class != Hash
- @options = YAML::DEFAULTS.dup.update( opts )
- @headless = 0
- @seq_map = false
- @anchors = {}
- @anchor_extras = {}
- @active_anchors = []
- @level = -1
- self.clear
- end
-
- def clear
- @buffer = []
- end
-
- #
- # Version string
- #
- def version_s
- " %YAML:#{@options[:Version]}" if @options[:UseVersion]
- end
-
- #
- # Header
- #
- def header
- if @headless.nonzero?
- ""
- else
- "---#{version_s} "
- end
- end
-
- #
- # Emit binary data
- #
- def binary_base64( value )
- self << "!binary "
- self.node_text( [value].pack("m"), '|' )
- end
-
- #
- # Emit plain, normal flowing text
- #
- def node_text( value, block = '>' )
- valx = value.dup
- if @options[:UseBlock]
- block = '|'
- elsif not @options[:UseFold] and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
- block = '|'
- end
- str = block.dup
- if valx =~ /\n\Z\n/
- str << "+"
- elsif valx =~ /\Z\n/
- else
- str << "-"
- end
- if valx =~ /#{YAML::ESCAPE_CHAR}/
- valx = YAML::escape( valx )
- end
- if valx =~ /\A[ \t#]/
- str << @options[:Indent].to_s
- end
- if block == '>'
- valx = fold( valx )
- end
- self << str + indent_text( valx ) + "\n"
- end
-
- #
- # Emit a simple, unqouted string
- #
- def simple( value )
- self << value.to_s
- end
-
- #
- # Emit double-quoted string
- #
- def double( value )
- "\"#{YAML.escape( value )}\""
- end
-
- #
- # Emit single-quoted string
- #
- def single( value )
- "'#{value}'"
- end
-
- #
- # Write a text block with the current indent
- #
- def indent_text( text )
- return "" if text.to_s.empty?
- spacing = " " * ( @level * @options[:Indent] )
- return "\n" + text.gsub( /^([^\n])/, "#{spacing}\\1" )
- end
-
- #
- # Write a current indent
- #
- def indent
- #p [ self.id, @level, :INDENT ]
- return " " * ( @level * @options[:Indent] )
- end
-
- #
- # Add indent to the buffer
- #
- def indent!
- self << indent
- end
-
- #
- # Folding paragraphs within a column
- #
- def fold( value )
- value.gsub!( /\A\n+/, '' )
- folded = $&.to_s
- width = (0..@options[:BestWidth])
- while not value.empty?
- last = value.index( /(\n+)/ )
- chop_s = false
- if width.include?( last )
- last += $1.length - 1
- elsif width.include?( value.length )
- last = value.length
- else
- last = value.rindex( /[ \t]/, @options[:BestWidth] )
- chop_s = true
- end
- folded += value.slice!( 0, width.include?( last ) ? last + 1 : @options[:BestWidth] )
- folded.chop! if chop_s
- folded += "\n" unless value.empty?
- end
- folded
- end
-
- #
- # Quick mapping
- #
- def map( type, &e )
- val = Mapping.new
- e.call( val )
- self << "#{type} " if type.length.nonzero?
-
- #
- # Empty hashes
- #
- if val.length.zero?
- self << "{}"
- else
- if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero?
- @headless = 1
- end
-
- defkey = @options.delete( :DefaultKey )
- if defkey
- seq_map_shortcut
- self << "= : "
- defkey.to_yaml( :Emitter => self )
- end
-
- #
- # Emit the key and value
- #
- val.each { |v|
- seq_map_shortcut
- if v[0].is_complex_yaml?
- self << "? "
- end
- v[0].to_yaml( :Emitter => self )
- if v[0].is_complex_yaml?
- self << "\n"
- indent!
- end
- self << ": "
- v[1].to_yaml( :Emitter => self )
- }
- end
- end
-
- def seq_map_shortcut
- if @seq_map
- @anchor_extras[@buffer.length - 1] = "\n" + indent
- @seq_map = false
- else
- self << "\n"
- indent!
- end
- end
-
- #
- # Quick sequence
- #
- def seq( type, &e )
- val = Sequence.new
- e.call( val )
- self << "#{type} " if type.length.nonzero?
-
- #
- # Empty arrays
- #
- if val.length.zero?
- self << "[]"
- else
- if @buffer.length == 1 and @options[:UseHeader] == false and type.length.zero?
- @headless = 1
- end
- #
- # Emit the key and value
- #
- val.each { |v|
- self << "\n"
- indent!
- self << "- "
- @seq_map = true if v.class == Hash
- v.to_yaml( :Emitter => self )
- }
- end
- end
-
- #
- # Concatenate to the buffer
- #
- def <<( str )
- #p [ self.id, @level, str ]
- @buffer.last << str
- end
-
- #
- # Monitor objects and allow references
- #
- def start_object( oid )
- @level += 1
- @buffer.push( "" )
- #p [ self.id, @level, :OPEN ]
- idx = nil
- if oid
- if @anchors.has_key?( oid )
- idx = @active_anchors.index( oid )
- unless idx
- idx = @active_anchors.length
- af_str = "{@options[:AnchorFormat]} " % [ idx + 1 ]
- af_str += @anchor_extras[ @anchors[ oid ] ].to_s
- @buffer[ @anchors[ oid ] ][0,0] = af_str
- @headless = 0 if @anchors[ oid ].zero?
- end
- idx += 1
- @active_anchors.push( oid )
- else
- @anchors[ oid ] = @buffer.length - 1
- end
- end
- return idx
- end
-
- #
- # Output method
- #
- def end_object
- @level -= 1
- @buffer.push( "" )
- #p [ self.id, @level, :END ]
- if @level < 0
- YAML.internal_to_utf( header + @buffer.to_s[@headless..-1], @options[:Encoding] )
- end
- end
- end
-
- #
- # Emitter helper classes
- #
- class Mapping < Array
- def add( k, v )
- push [k, v]
- end
- end
-
- class Sequence < Array
- def add( v )
- push v
- end
- end
-
- #
- # Input methods
- #
-
- #
- # Load a single document from the current stream
- #
- def YAML.load( io )
- yp = YAML::Parser.new.parse( io )
- end
-
- #
- # Parse a single document from the current stream
- #
- def YAML.parse( io )
- yp = YAML::Parser.new( :Model => :Generic ).parse( io )
- end
-
- #
- # Load all documents from the current stream
- #
- def YAML.each_document( io, &doc_proc )
- yp = YAML::Parser.new.parse_documents( io, &doc_proc )
- end
-
- #
- # Identical to each_document
- #
- def YAML.load_documents( io, &doc_proc )
- YAML.each_document( io, &doc_proc )
- end
-
- #
- # Parse all documents from the current stream
- #
- def YAML.each_node( io, &doc_proc )
- yp = YAML::Parser.new( :Model => :Generic ).parse_documents( io, &doc_proc )
- end
-
- #
- # Parse all documents from the current stream
- #
- def YAML.parse_documents( io, &doc_proc )
- YAML.each_node( io, &doc_proc )
- end
-
- #
- # Load all documents from the current stream
- #
- def YAML.load_stream( io )
- yp = YAML::Parser.new
- d = nil
- yp.parse_documents( io ) { |doc|
- d = YAML::Stream.new( yp.options ) if not d
- d.add( doc )
- }
- return d
- end
-
- #
- # Racc parser will go here
- #
- # class Parser; def initialize; raise YAML::Error, "No parser available"; end; end
-
- #
- # Add a transfer method to a domain
- #
- def YAML.add_domain_type( domain, type_re, &transfer_proc )
- type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
- if not YAML::TRANSFER_DOMAINS.has_key?( domain )
- YAML::TRANSFER_DOMAINS[ domain ] = {}
- end
- YAML::TRANSFER_DOMAINS[ domain ][ type_re ] = transfer_proc
- end
-
- #
- # Add a transfer method for a builtin type
- #
- def YAML.add_builtin_type( type_re, &transfer_proc )
- type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
- YAML::TRANSFER_DOMAINS[ 'yaml.org,2002' ][ type_re ] = transfer_proc
- end
-
- #
- # Add a transfer method for a builtin type
- #
- def YAML.add_ruby_type( type, &transfer_proc )
- type_re = /^#{Regexp::quote( type.to_s )}(?::.+)?$/i
- YAML::TRANSFER_DOMAINS[ 'ruby.yaml.org,2002' ][ type_re ] = transfer_proc
- end
-
- #
- # Add a private document type
- #
- def YAML.add_private_type( type_re, &transfer_proc )
- type_re = /^#{Regexp::quote( type_re )}$/ if type_re.class == String
- YAML::PRIVATE_TYPES[ type_re ] = transfer_proc
- end
-
- #
- # Method to extract colon-seperated type and class, returning
- # the type and the constant of the class
- #
- def YAML.read_type_class( type, obj_class )
- type =~ /^([^:]+):(.+)/i
- if $2
- type = $1
- $2.split( "::" ).each { |c|
- obj_class = obj_class.const_get( c )
- }
- end
- return [ type, obj_class ]
- end
-
- #
- # Default private type
- #
- class PrivateType
- attr_accessor :type_id, :value
- def initialize( type, val )
- @type_id = type; @value = val
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out << " !!#{@type_id}"
- value.to_yaml( :Emitter => out )
- }
- end
- end
-
- #
- # Default domain type
- #
- class DomainType
- attr_accessor :domain, :type_id, :value
- def initialize( domain, type, val )
- @domain = domain; @type_id = type; @value = val
- end
- def to_yaml_type
- dom = @domain.dup
- if dom =~ /\.yaml\.org,2002$/
- dom = $`
- end
- "#{dom}/#{@type_id}"
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out << " !#{to_yaml_type} "
- value.to_yaml( :Emitter => out )
- }
- end
- end
-
- #
- # Utility functions
- #
-
- #
- # Handle all transfer methods
- # http://www.yaml.org/spec/#syntax-trans
- #
- def YAML.transfer_method( type, val )
- domain = "yaml.org,2002"
-
- #
- # Figure out the domain
- #
- if type =~ /^(\w+)\/(.+)$/
- domain = "#{$1}.yaml.org,2002"; type = $2
- elsif type =~ /^(#{DNS_NAME_RE},\d{4}(?:-\d{2}){0,2})\/(.+)$/
- domain = $1; type = $2
- end
-
- #
- # Route the data, transfer it
- #
- begin
- r = nil
- if type == ""
- YAML.try_implicit( val )
- elsif type =~ /^!(.*)/
- type = $1
- if YAML::PRIVATE_TYPES.keys.detect { |r| type =~ r }
- YAML::PRIVATE_TYPES[r].call( type, val )
- else
- YAML::PrivateType.new( type, val )
- end
- else
- type = YAML.escape( type )
- if YAML::TRANSFER_DOMAINS.has_key?( domain ) and
- YAML::TRANSFER_DOMAINS[domain].keys.detect { |r| type =~ r }
- YAML::TRANSFER_DOMAINS[domain][r].call( type, val )
- else
- YAML::DomainType.new( domain, type, val )
- end
- end
- end
- end
-
- #
- # Try a string against all implicit YAML types
- # http://www.yaml.org/spec/#trans
- #
- def YAML.detect_implicit( str )
- r = nil
- YAML::IMPLICIT_TYPES.each { |type|
- if YAML::TRANSFER_DOMAINS['yaml.org,2002'].keys.detect { |r| type =~ r }
- val = YAML::TRANSFER_DOMAINS['yaml.org,2002'][r].call( :Implicit, str )
- return type unless Symbol === val and val == :InvalidType
- end
- }
- return 'str'
- end
-
- #
- # Uses the implicit if found
- #
- def YAML.try_implicit( str )
- type = YAML.detect_implicit( str )
- YAML.transfer_method( type, str )
- end
-
- #
- # Make a time with the time zone
- #
- def YAML.mktime( year, mon, day, hour, min, sec, usec, zone = "Z" )
- usec = usec.to_s.to_f * 1000000
- val = Time::utc( year.to_i, mon.to_i, day.to_i, hour.to_i, min.to_i, sec.to_i, usec )
- if zone != "Z"
- hour = zone[0,3].to_i * 3600
- min = zone[3,2].to_i * 60
- ofs = (hour + min)
- val = Time.at( val.to_f - ofs )
- end
- return val
- end
-
- #
- # Retrieve plain scalar regexp
- #
- def YAML.plain_re( allow = '' )
- space_set = ''
- restrict_set = RESTRICTED_INDICATORS.delete( allow )
- restrict_set.split( // ).each { |ind|
- if ind == "#"
- space_set << "[^#\\s]#+|#+[^#\\s]|"
- elsif SPACE_INDICATORS.include?( ind )
- ind = Regexp::quote( ind )
- space_set << "#{ind}+[^#{ind}\\s]|"
- end
- }
- /\A([^#{NOT_PLAIN_CHAR}#{Regexp::quote(INDICATOR_CHAR)}](?:#{space_set}[^#{NOT_PLAIN_CHAR}#{Regexp::quote(restrict_set)}])*)/
- end
-
- #
- # Escape the string, condensing common escapes
- #
- def YAML.escape( value )
- value.gsub( /\\/, "\\\\\\" ).gsub( /"/, "\\\"" ).gsub( /([\x00-\x1f])/ ) { |x| ESCAPES[ x.unpack("C")[0] ] }
- end
-
- #
- # Unescape the condenses escapes
- #
- def YAML.unescape( value )
- value.gsub( /\\(?:([nevbr\\fartz])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { |x|
- if $3
- ["#$3".hex ].pack('U*')
- elsif $2
- [$2].pack( "H2" )
- else
- UNESCAPES[$1]
- end
- }
- end
-
- #
- # YAML::Stream -- for emitting many documents
- #
- class Stream
-
- attr_accessor :documents, :options
-
- def initialize( opts = {} )
- @options = opts
- @documents = []
- end
-
- def []( i )
- @documents[ i ]
- end
-
- def add( doc )
- @documents << doc
- end
-
- def edit( doc_num, doc )
- @documents[ doc_num ] = doc
- end
-
- def emit
- opts = @options.dup
- opts[:UseHeader] = true if @documents.length > 1
- ct = 0
- out = Emitter.new( opts )
- @documents.each { |v|
- if ct > 0
- out << "\n--- "
- end
- v.to_yaml( :Emitter => out )
- ct += 1
- }
- out.end_object
- end
-
- end
-
- #
- # Allocate an Emitter if needed
- #
- def YAML.quick_emit( oid, opts = {}, &e )
- old_opt = nil
- if opts[:Emitter].is_a? YAML::Emitter
- out = opts.delete( :Emitter )
- old_opt = out.options.dup
- out.options.update( opts )
- else
- out = YAML::Emitter.new( opts )
- end
- aidx = out.start_object( oid )
- if aidx
- out.simple( "*#{out.options[:AnchorFormat]} " % [ aidx ] )
- else
- e.call( out )
- end
- if old_opt.is_a? Hash
- out.options = old_opt
- end
- out.end_object
- end
-
- #
- # YAML::Store -- Pstore replacement
- #
- class Store < PStore
- #
- # Constructor
- #
- def initialize( *o )
- @opt = YAML::DEFAULTS.dup
- if String === o.first
- super(o.pop)
- end
- if o.last.is_a? Hash
- @opt.update(o.pop)
- end
- end
-
- #
- # Override Pstore#transaction
- #
- def transaction
- raise YAML::Error, "nested transaction" if @transaction
- raise YAML::Error, "no filename for transaction" unless @filename
- begin
- @transaction = true
- value = nil
- backup = @filename+"~"
- if File::exist?(@filename)
- file = File::open(@filename, "rb+")
- orig = true
- else
- @table = {}
- file = File::open(@filename, "wb+")
- file.write( @table.to_yaml( @opt ) )
- end
- file.flock(File::LOCK_EX)
- if orig
- File::copy @filename, backup
- @table = YAML::load( file )
- end
- begin
- catch(:pstore_abort_transaction) do
- value = yield(self)
- end
- rescue Exception
- @abort = true
- raise
- ensure
- unless @abort
- begin
- file.rewind
- file.write( @table.to_yaml( @opt ) )
- file.truncate(file.pos)
- rescue
- File::rename backup, @filename if File::exist?(backup)
- raise
- end
- end
- @abort = false
- end
- ensure
- @table = nil
- @transaction = false
- file.close if file
- end
- value
- end
- end
-
- #
- # YAML Hash class to support comments and defaults
- #
- class SpecialHash < Hash
- attr_accessor :default
- def inspect
- self.default.to_s
- end
- def to_s
- self.default.to_s
- end
- def update( h )
- if YAML::SpecialHash === h
- @default = h.default if h.default
- end
- super( h )
- end
- def to_yaml( opts = {} )
- opts[:DefaultKey] = self.default
- super( opts )
- end
- end
-
- #
- # Builtin collection: !omap
- #
- class Omap < Array
- def self.[]( *vals )
- o = Omap.new
- 0.step( vals.length - 1, 2 ) { |i|
- o[vals[i]] = vals[i+1]
- }
- o
- end
- def []( k )
- self.assoc( k ).to_a[1]
- end
- def []=( k, *rest )
- val, set = rest.reverse
- if ( tmp = self.assoc( k ) ) and not set
- tmp[1] = val
- else
- self << [ k, val ]
- end
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out.seq( "!omap" ) { |seq|
- self.each { |v|
- seq.add( Hash[ *v ] )
- }
- }
- }
- end
- end
-
- YAML.add_builtin_type( "omap" ) { |type, val|
- if Array === val
- p = Omap.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- raise YAML::Error, "Invalid !omap entry: " + val.inspect
- end
- }
- else
- raise YAML::Error, "Invalid !omap: " + val.inspect
- end
- p
- }
-
- #
- # Builtin collection: !pairs
- #
- class Pairs < Array
- def self.[]( *vals )
- p = Pairs.new
- 0.step( vals.length - 1, 2 ) { |i|
- p[vals[i]] = vals[i+1]
- }
- p
- end
- def []( k )
- self.assoc( k ).to_a
- end
- def []=( k, val )
- self << [ k, val ]
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out.seq( "!pairs" ) { |seq|
- self.each { |v|
- seq.add( Hash[ *v ] )
- }
- }
- }
- end
- end
-
- YAML.add_builtin_type( "pairs" ) { |type, val|
- if Array === val
- p = Pairs.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- raise YAML::Error, "Invalid !pairs entry: " + val.inspect
- end
- }
- else
- raise YAML::Error, "Invalid !pairs: " + val.inspect
- end
- p
- }
-
- #
- # Builtin collection: !set
- #
- class Set < Hash
- def to_yaml_type
- "!set"
- end
- end
-
- YAML.add_builtin_type( 'set' ) { |type, val|
- if Array === val
- val = Set[ *val ]
- elsif Hash === val
- Set[ val ]
- else
- raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
- end
- val
- }
-
- #
- # Ruby-specific collection: !ruby/flexhash
- #
- class FlexHash < Array
- def []( k )
- self.assoc( k ).to_a[1]
- end
- def []=( k, *rest )
- val, set = rest.reverse
- if ( tmp = self.assoc( k ) ) and not set
- tmp[1] = val
- else
- self << [ k, val ]
- end
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out.seq( "!ruby/flexhash" ) { |seq|
- self.each { |v|
- if v[1]
- seq.add( Hash.[]( *v ) )
- else
- seq.add( v[0] )
- end
- }
- }
- }
- end
- end
-
- YAML.add_ruby_type( :flexhash ) { |type, val|
- if Array === val
- p = FlexHash.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- p << [ v, nil ]
- end
- }
- p
- else
- raise YAML::Error, "Invalid !ruby/flexhash: " + val.inspect
- end
- }
-
-end
-
-#
-# Type conversions
-#
-class Object
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- "!ruby/object:#{self.class}"
- end
- def to_yaml_properties
- instance_variables.sort
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- out.map( self.to_yaml_type ) { |map|
- to_yaml_properties.each { |m|
- map.add( m[1..-1], instance_eval( m ) )
- }
- }
- }
- end
-end
-
-class Class
- def new_without_initialize( *args )
- self.class_eval %{
- alias :old_initialize_with_args :initialize
- def initialize( *args ); end
- }
- begin
- result = self.new( *args )
- ensure
- self.class_eval %{
- alias :initialize :old_initialize_with_args
- }
- end
- result
- end
-end
-
-YAML.add_ruby_type( Object ) { |type, val|
- type, obj_class = YAML.read_type_class( type, Object )
- YAML.object_maker( obj_class, val )
-}
-
-#
-# Maps: Hash#to_yaml
-#
-class Hash
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- if self.class == Hash or self.class == YAML::SpecialHash
- "!map"
- else
- "!ruby/hash:#{self.class}"
- end
- end
- def to_yaml( opts = {} )
- opts[:DocType] = self.class if Hash === opts
- YAML::quick_emit( self.id, opts ) { |out|
- hash_type = to_yaml_type
- if not out.options[:ExplicitTypes] and hash_type == "!map"
- hash_type = ""
- end
- out.map( hash_type ) { |map|
- #
- # Sort the hash
- #
- if out.options[:SortKeys]
- map.concat( self.sort )
- else
- map.concat( self.to_a )
- end
- }
- }
- end
-end
-
-hash_proc = Proc.new { |type, val|
- if Array === val
- val = Hash.[]( *val ) # Convert the map to a sequence
- elsif Hash === val
- type, obj_class = YAML.read_type_class( type, Hash )
- if obj_class != Hash
- o = obj_class.new
- o.update( val )
- val = o
- end
- else
- raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
- end
- val
-}
-YAML.add_builtin_type( /^map/, &hash_proc )
-YAML.add_ruby_type( Hash, &hash_proc )
-
-#
-# Structs: export as a !map
-#
-class Struct
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.id, opts ) { |out|
- #
- # Basic struct is passed as a YAML map
- #
- struct_name = self.class.name.gsub( "Struct:", "" )
- out.map( "!ruby/struct#{struct_name}" ) { |map|
- self.members.each { |m|
- map.add( m, self[m] )
- }
- }
- }
- end
-end
-
-YAML.add_ruby_type( Struct ) { |type, val|
- type =~ /^struct:(\w+)/
- if Hash === val
- type = $1
- struct_type = nil
- struct_def = []
- struct_name = ""
- if $1.to_s.length > 1
- struct_name = $1[0..$1.length]
- struct_def << struct_name
- end
-
- #
- # Use existing Struct if it exists
- #
- begin
- struct_type = Struct.const_get( struct_name )
- rescue NameError
- end
- if not struct_type
- struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
- end
-
- #
- # Set the Struct properties
- #
- st = struct_type.new
- st.members.each { |m|
- st.send( "#{m}=", val[m] )
- }
- st
- else
- raise YAML::Error, "Invalid Ruby Struct: " + val.inspect
- end
-}
-
-#
-# Sequences: Array#to_yaml
-#
-class Array
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- if self.class == Array
- "!seq"
- else
- "!ruby/array:#{self.class}"
- end
- end
- def to_yaml( opts = {} )
- opts[:DocType] = self.class if Hash === opts
- YAML::quick_emit( self.id, opts ) { |out|
- array_type = to_yaml_type
- if not out.options[:ExplicitTypes] and array_type == "!seq"
- array_type = ""
- end
-
- out.seq( array_type ) { |seq|
- seq.concat( self )
- }
- }
- end
-end
-
-array_proc = Proc.new { |type, val|
- if Array === val
- type, obj_class = YAML.read_type_class( type, Array )
- if obj_class != Array
- o = obj_class.new
- o.concat( val )
- val = o
- end
- val
- else
- val.to_a
- end
-}
-YAML.add_builtin_type( /^seq/, &array_proc )
-YAML.add_ruby_type( Array, &array_proc )
-
-#
-# String#to_yaml
-#
-class String
- def is_complex_yaml?
- ( self =~ /\n.+/ ? true : false )
- end
- def is_binary_data?
- ( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 )
- end
- def to_yaml( opts = {} )
- complex = false
- if self.is_complex_yaml?
- complex = true
- elsif opts[:BestWidth].to_i > 0
- if self.length > opts[:BestWidth] and opts[:UseFold]
- complex = true
- end
- end
- YAML::quick_emit( complex ? self.id : nil, opts ) { |out|
- if complex
- if self.is_binary_data?
- out.binary_base64( self )
- else
- out.node_text( self )
- end
- else
- ostr = if out.options[:KeepValue]
- self
- elsif empty?
- "''"
- elsif YAML.detect_implicit( self ) != 'str'
- "\"#{YAML.escape( self )}\""
- elsif self =~ /#{YAML::ESCAPE_CHAR}|[#{YAML::SPACE_INDICATORS}] |\n|\'/
- "\"#{YAML.escape( self )}\""
- elsif self =~ /^[^#{YAML::WORD_CHAR}]/
- "\"#{YAML.escape( self )}\""
- else
- self
- end
- out.simple( ostr )
- end
- }
- end
-end
-
-YAML.add_builtin_type( 'str' ) { |type,val| val.to_s }
-YAML.add_builtin_type( 'binary' ) { |type,val|
- enctype = "m"
- if String === val
- val.gsub( /\s+/, '' ).unpack( enctype )[0]
- else
- raise YAML::Error, "Binary data must be represented by a string: " + val.inspect
- end
-}
-
-#
-# Symbol#to_yaml
-#
-class Symbol
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/sym "
- self.id2name.to_yaml( :Emitter => out )
- }
- end
-end
-
-symbol_proc = Proc.new { |type, val|
- if String === val
- val.intern
- else
- raise YAML::Error, "Invalid Symbol: " + val.inspect
- end
-}
-YAML.add_ruby_type( Symbol, &symbol_proc )
-YAML.add_ruby_type( :sym, &symbol_proc )
-
-#
-# Range#to_yaml
-#
-class Range
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/range "
- self.inspect.to_yaml( :Emitter => out )
- }
- end
-end
-
-YAML.add_ruby_type( Range ) { |type, val|
- if String === val and val =~ /^(.*[^.])(\.{2,3})([^.].*)$/
- r1, rdots, r2 = $1, $2, $3
- Range.new( YAML.try_implicit( r1 ), YAML.try_implicit( r2 ), rdots.length == 3 )
- elsif Hash === val
- Range.new( val['begin'], val['end'], val['exclude_end?'] )
- else
- raise YAML::Error, "Invalid Range: " + val.inspect
- end
-}
-
-#
-# Make an RegExp
-#
-class Regexp
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/regexp "
- self.inspect.to_yaml( :Emitter => out )
- }
- end
-end
-
-regexp_proc = Proc.new { |type, val|
- if String === val and val =~ /^\/(.*)\/([mix]*)$/
- val = { 'REGEXP' => $1, 'MODIFIERS' => $2 }
- end
- if Hash === val
- mods = nil
- unless val['MODIFIERS'].to_s.empty?
- mods = 0x00
- if val['MODIFIERS'].include?( 'x' )
- mods |= Regexp::EXTENDED
- elsif val['MODIFIERS'].include?( 'i' )
- mods |= Regexp::IGNORECASE
- elsif val['MODIFIERS'].include?( 'm' )
- mods |= Regexp::POSIXLINE
- end
- end
- Regexp::compile( val['REGEXP'], mods )
- else
- raise YAML::Error, "Invalid Regular expression: " + val.inspect
- end
-}
-YAML.add_domain_type( "perl.yaml.org,2002", /^regexp/, ®exp_proc )
-YAML.add_ruby_type( Regexp, ®exp_proc )
-
-#
-# Emit a Time object as an ISO 8601 timestamp
-#
-class Time
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- tz = "Z"
- # from the tidy Tobias Peters Thanks!
- unless self.utc?
- utc_same_instant = self.dup.utc
- utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
- difference_to_utc = utc_same_writing - utc_same_instant
- if (difference_to_utc < 0)
- difference_sign = '-'
- absolute_difference = -difference_to_utc
- else
- difference_sign = '+'
- absolute_difference = difference_to_utc
- end
- difference_minutes = (absolute_difference/60).round
- tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
- end
- ( self.strftime( "%Y-%m-%d %H:%M:%S." ) +
- "%06d %s" % [usec, tz] ).
- to_yaml( :Emitter => out, :KeepValue => true )
- }
- end
-end
-
-YAML.add_builtin_type( 'time' ) { |type, val|
- 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/
- YAML.mktime( *$~.to_a[1,8] )
- 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/
- YAML.mktime( *$~.to_a[1,8] )
- elsif val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})[ \t]+(\d{2})\:(\d{2})\:(\d{2})(\.\d{1,2})?\Z/
- YAML.mktime( *$~.to_a[1,7] )
- elsif val =~ /\A(\d{4})\-(\d{1,2})\-(\d{1,2})\Z/
- Date.new($1.to_i, $2.to_i, $3.to_i)
- elsif type == :Implicit
- :InvalidType
- else
- raise YAML::TypeError, "Invalid !time string: " + val.inspect
- end
-}
-
-#
-# Emit a Date object as a simple implicit
-#
-class Date
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- self.to_s.to_yaml( opts )
- end
-end
-
-#
-# Send Integer, Booleans, NilClass to String
-#
-class Numeric
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- str = self.to_s
- if str == "Infinity"
- str = ".Inf"
- elsif str == "-Infinity"
- str = "-.Inf"
- elsif str == "NaN"
- str = ".NaN"
- end
- opts[:KeepValue] = true
- str.to_yaml( opts )
- end
-end
-
-YAML.add_builtin_type( 'float' ) { |type, val|
- if val =~ /\A[-+]?[\d][\d,]*\.[\d,]*[eE][-+][0-9]+\Z/ # Float (exponential)
- $&.tr( ',', '' ).to_f
- elsif val =~ /\A[-+]?[\d][\d,]*\.[\d,]*\Z/ # Float (fixed)
- $&.tr( ',', '' ).to_f
- elsif val =~ /\A([-+]?)\.(inf|Inf|INF)\Z/ # Float (english)
- ( $1 == "-" ? -1.0/0.0 : 1.0/0.0 )
- elsif val =~ /\A\.(nan|NaN|NAN)\Z/
- 0.0/0.0
- elsif type == :Implicit
- :InvalidType
- else
- val.to_f
- end
-}
-
-YAML.add_builtin_type( 'int' ) { |type, val|
- if val =~ /\A[-+]?0[0-7,]+\Z/ # Integer (octal)
- $&.oct
- elsif val =~ /\A[-+]?0x[0-9a-fA-F,]+\Z/ # Integer (hex)
- $&.hex
- elsif val =~ /\A[-+]?\d[\d,]*\Z/ # Integer (canonical)
- $&.tr( ',', '' ).to_i
- elsif val =~ /\A([-+]?)(\d[\d,]*(?::[0-5]?[0-9])+)\Z/
- sign = ( $1 == '-' ? -1 : 1 )
- digits = $2.split( /:/ ).collect { |x| x.to_i }
- val = 0; digits.each { |x| val = ( val * 60 ) + x }; val *= sign
- elsif type == :Implicit
- :InvalidType
- else
- val.to_i
- end
-}
-
-class TrueClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "true".to_yaml( opts )
- end
-end
-
-class FalseClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "false".to_yaml( opts )
- end
-end
-
-YAML.add_builtin_type( 'bool' ) { |type, val|
- if val =~ /\A(\+|true|True|TRUE|yes|Yes|YES|on|On|ON)\Z/
- true
- elsif val =~ /\A(\-|false|False|FALSE|no|No|NO|off|Off|OFF)\Z/
- false
- elsif type == :Implicit
- :InvalidType
- else
- raise YAML::TypeError, "Invalid !bool string: " + val.inspect
- end
-}
-
-class NilClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "".to_yaml( opts )
- end
-end
-
-YAML.add_builtin_type( 'null' ) { |type, val|
- if val =~ /\A(\~|null|Null|NULL)\Z/
- nil
- elsif val.empty?
- nil
- elsif type == :Implicit
- :InvalidType
- else
- raise YAML::TypeError, "Invalid !null string: " + val.inspect
- end
-}
-
-#
-# ryan: You know how Kernel.p is a really convenient way to dump ruby
-# structures? The only downside is that it's not as legible as
-# YAML.
-#
-# _why: (listening)
-#
-# ryan: I know you don't want to urinate all over your users' namespaces.
-# But, on the other hand, convenience of dumping for debugging is,
-# IMO, a big YAML use case.
-#
-# _why: Go nuts! Have a pony parade!
-#
-# ryan: Either way, I certainly will have a pony parade.
-#
-module Kernel
- def y( x )
- puts x.to_yaml
- end
-end
-
-#
-# Example of using YAML to replace PStore
-#
-if __FILE__ == $0
- y = YAML::Store.new( "/tmp/yaml.store.1", :Indent => 2,
- :UseHeader => true, :UseVersion => true )
- y.transaction do
- y['names'] = ['Steve', 'Jonathan', 'Tom']
- y['hello'] = {'hi' => 'hello', 'yes' => 'YES!!' }
- end
-end
-
-#
-# Example of using YAML::Stream
-#
-# a = "File ID"
-# y = YAML::Stream.new( :Indent => 2, :UseVersion => 0 )
-# y.add( {'hi2' => 'hello', 'map' => {'good' => 'two'}, 'time' => Time.now, 'try' => /^po(.*)$/, 'bye' => 'goodbye' } )
-# y.add( {'po' => nil, 'oper' => 90 } )
-# y.add( {'hi' => 'wow!', 'bye' => 'wow!'} )
-# y.add( {['Red Socks','Boston'] => ['One', 'Two', 'Three']} )
-# y.add( [true, false, false] ) # This should use aliases
-# puts y.emit
-
-#
-# Example of loading a YAML document
-#
-# obj = YAML::load( "/tmp/yaml.store.1" )
-
-#
-# Examples of using #to_yaml
-#
-# puts [1, 2, 3, nil, 'hello', "Glow all!", 'hi', Time.now, /^po(.*)/im ].to_yaml( :UseBlock => true )
-# puts Hash['hi', 'hello', 'time', Time.now, 'try', /^po(.*)$/, 'bye', 'goodbye' ].to_yaml
-# puts [
-# {'hi' => 'hello', 'time' => Time.now, 'try' => /^po(.*)$/, 'bye' => 'goodbye' },
-# {'po' => nil, 'oper' => 90 },
-# {'hi' => 'wow!', 'bye' => 'wow!'} ].to_yaml
-
-
-..end src/emitter.rb modeval..iddd2784be19
+include_class "org.jruby.yaml.JRubyConstructor"
+include_class "org.jruby.util.IOReader"
+include_class "org.jvyaml.ComposerImpl"
+include_class "org.jvyaml.ParserImpl"
+include_class "org.jvyaml.ScannerImpl"
+include_class "org.jvyaml.ResolverImpl"
module YAML
-
- class Parser < Racc::Parser
-
-module_eval <<'..end src/yaml.y.rb modeval..idae682a68eb', 'src/yaml.y.rb', 140
-
-attr_accessor :finished, :directives, :options
-
-#
-# Reset the directives, EOF flag
-#
-def initialize( opts = {} )
- @directives = { 'YAML' => '1.0', 'TAB' => 'NONE' }
- @options = YAML::DEFAULTS.dup.update( opts )
- @finished = false
- @plain_sets = {
- :AllowInline => YAML.plain_re( ',}]' ),
- :AllowMapping => YAML.plain_re( ':' ),
- :AllowNone => YAML.plain_re
- }
-end
-
-#
-# Iterator for parsing many documents
-#
-def parse_documents( io, &doc_proc )
- @stream = YAML.make_stream( io )
- @lineno = 0
- @charno = 0
- @leftovers = nil
- @options[:Encoding] = @stream.utf_encoding
- while true
- o = _parse
- doc_proc.call( o )
- break if @finished
- end
-end
-
-#
-# Basic single document parsing
-#
-def parse( io )
- @stream = YAML.make_stream( io )
- @lineno = 0
- @charno = 0
- @leftovers = nil
- @options[:Encoding] = @stream.utf_encoding
- _parse
-end
-
-#
-# Common tokenizer and parser
-#
-def _parse
-
- #
- # Parser instance variables
- #
- @anchor = {}
- @lvl = [ Level.new( -1, :Implicit, "" ) ]
- @separator = nil
- @last_tokens = []
- @plain_set = @plain_sets[ :AllowInline ]
-
- reset_indent
- reset_tokens
-
- # Tokenizer
- do_tokenize
-
- @finished = true if eof? and @leftovers.nil?
- return nil if @q.length.zero?
-
- add_end_indent -1
- close_tokens
-
- # @q.each { |tok|
- # p [ tok.sym, tok.data ]
- # }
-
- # Parser
- begin
- do_parse
- rescue Racc::ParseError => rpe
- token = @last_tokens.last
- raise YAML::ParseError, "Parse error at line #{token.lineno}, char #{token.charno}: [#{token.sym}, #{token.data}]"
- end
-end
-
-def do_tokenize
- until eof? and @leftovers.nil? do
- if @leftovers
- yline = @leftovers
- @leftovers = nil
- else
-# ENEBO: readline returns nil instead of "". I wonder if this is a ruby behavioral change thing
- yline = readline
- yline.chomp! if yline
- end
- handle_indent( yline )
- until !yline || yline.empty? do
- handle_content( yline )
- if [ :End, :Pause ].include?( @lvl.last.status )
- @leftovers = yline
- return
- end
- end
- end
-end
-
-def handle_indent( yline )
- if ( indt_match = @lvl.last.indent_re.match( yline ) )
- @indent_raw << "\n" + indt_match[0]
- case indt_match[2]
- when /^#/
- yline.replace ""
- when /^-/
- @indent << "\n" + yline.slice!( 0, indt_match[1].length ) + " "
- @charno += indt_match[1].length
- else
- @indent << "\n" + yline.slice!( 0, indt_match[0].length )
- @charno += indt_match[0].length
- end
- end
-end
-
-def handle_content( yline )
- if @charno == 1
- case yline
- when /\A---( |$)/
- if @q.length.zero?
- reset_indent
- @lvl.last.status = :Header
- @charno += $&.length
- yline.replace $'
- else
- @lvl.last.status = :End
- end
- return
- when /\A\.\.\.( |$)/
- @lvl.last.status = :Pause
- @charno += $&.length
- yline.replace $'
- return
- end
- elsif @lvl.last.status == :Header
- if yline =~ /\A%(\w+):(\S+)/
- @directives[$1] = $2
- case $1
- when "YAML"
- @options[:Version] = $2
- @options[:UseVersion] = true
- end
- len = $&.length
- yline.slice!( 0, len )
- @charno += len
- return
- else
- @lvl.last.status = :Implicit
- end
- end
- if @lvl.last.status != :Block or @q.last.sym == :FSTART
- case yline
- when /\A#/
- # Throwaway comments
- yline.replace ""
- return
- when /\A +/
- # Throwaway space
- len = $&.length
- yline.slice!( 0, len )
- @charno += len
- return
- end
- end
- apply_indent
- if @lvl.last.status == :Block
- add_token :FOLD, yline
- yline.replace ""
- return
- end
- len = 0
- case yline
- when /\A[#{ Regexp::quote( SPACE_INDICATORS ) }]( |$)/
- # Space indicators
- len = $&.length
- c = yline[ 0, 1 ]
- if @lvl.last.status == :Inline
- if c == ':'
- @plain_set = @plain_sets[ :AllowMapping ]
- elsif c == ','
- @plain_set = @plain_sets[ :AllowNone ]
- end
- else
- if c == ':'
- @plain_set = @plain_sets[ :AllowInline ]
- elsif c == '-'
- handle_seq_shortcuts
- if @q[-1] and [ :INDENT, :IOPEN, :IEND ].include?( @q[-1] )
- @lvl.last.spaces = @charno + 1
- @q.last.data = @charno + 1
- end
- end
- end
- add_token c, c
- when /\A([>|])([-+\d]*)/
- len = $&.length
- fold = $&
- fold_type = $1
- @lvl.push Level.new( @lvl.last.spaces + 1, :Block, fold_type == "|" ? :Literal : :Folded )
- @q.push Token.new( :IOPEN, @lvl.last.spaces, @lineno, 1 )
- add_token :FSTART, fold
- when /\A([{\[])/
- len = $&.length
- tok = $&
- @lvl.push Level.new( @lvl.last.spaces + 2, :Inline, @lvl.last.domain )
- @plain_set = @plain_sets[ :AllowNone ]
- add_token tok, tok
- when /\A([}\]])/
- len = $&.length
- tok = $&
- @lvl.pop
- @plain_set = @plain_sets[ :AllowInline ]
- add_token tok, tok
- when /\A&(\w+)/
- len = $&.length
- add_token :ANCHOR, $1
- when /\A\*(\w+)/
- len = $&.length
- add_token :ALIAS, $1
- when /\A!(\S*)/
- len = $&.length
- ttype = $1
- if ttype =~ /(.*)\^(.+)/
- if $1.length > 0
- @lvl.last.domain = $1
- ttype = $1 + $2
- else
- ttype = @lvl.last.domain + $2
- end
- end
- add_token :TRANSFER, ttype
- when /\A"((?:\\\"|[^\n"])*)/
- handle_seq_shortcuts
- len = $&.length
- yline.slice!( 0, len )
- @charno += len
- qstr = $1.to_s
- qstr_indt = "+"
- while yline[0,1] != '"'
- if qstr[-1,1] == "\\"
- qstr = qstr.chop!
- else
- qstr << " "
- end
- yline = readline
- yline =~ /\A(\s#{qstr_indt})((?:\\\"|[^\n"])*)/
- len = $&.to_s.length
- yline.slice!( 0, len )
- @charno += len
- qstr << $2.to_s
- end
- len = 1
- add_token :WORD, YAML.unescape(qstr.gsub( /\\"/, '"' ))
- when /\A'((?:''|[^\n'])*)/
- handle_seq_shortcuts
- len = $&.length
- yline.slice!( 0, len )
- @charno += len
- qstr = $1.to_s
- qstr_indt = "+"
- nl_mode = false
- while yline[0,1] != "'"
- qstr << " " if qstr[-1,1] != "\n"
- yline = readline
- yline =~ /\A(\s#{qstr_indt})((?:''|[^\n'])*)/
- qstr_indt = "{0,#{$1.length}}" if qstr_indt == "+"
- inner_str = $2.to_s.strip
- if inner_str == ""
- qstr = ( nl_mode ? qstr : qstr[0..-2] ) + "\n"
- nl_mode = true
- else
- qstr << $2
- nl_mode = false
- end
- len = $&.to_s.length
- yline.slice!( 0, len )
- @charno += len
- end
- len = 1
- add_token :WORD, qstr.gsub( "''", "'" )
- when @plain_set
- handle_seq_shortcuts
- len = $&.length
- match = $&.strip
- if @q.last and @q.last.sym == :PLAIN
- @q.last.data += " " if @q.last.data !~ /\Z\n/
- @q.last.data += match
- else
- add_token :PLAIN, match
- end
- else
- handle_seq_shortcuts
- len = 1
- c = yline[ 0, 1 ]
- add_token c, c
- end
- yline.slice!( 0, len )
- @charno += len
-end
-
-def handle_seq_shortcuts
- if @q[-1] and @q[-1].sym == '-' and @q[-2] and [:IOPEN, :INDENT, :IEND].include?( @q[-2].sym )
- # Check the current level and indent to match the dash
- @lvl.last.spaces = @q[-1].charno
- @q[-2].data = @q[-1].charno
- # Add open indent after the dash
- @lvl.push Level.new( @charno - 1, @lvl.last.status, @lvl.last.domain )
- @q.push Token.new( :IOPEN, @charno - 1, @lineno, @charno )
- end
-end
-
-#
-# Level descent class added 2002 Dec 31
-# The levels of indentation are tracked using this class.
-# Each level has an indentation space count, a status field
-# indicating what sort of data is contained at this depth,
-# and the domain anchored at this depth.
-#
-class Level
- attr_accessor :spaces, :status, :domain
- def initialize( ct, s, d )
- @spaces, @status, @domain = ct, s, d
- end
- def indent_re
- if @status == :Block
- if @spaces > 0
- /\A( {0,#{ @spaces - 1 }})(#[^\n]+|-( +(?!:)|$)| *)?/
- else
- /\A( *)(#[^\n]+)?/
- end
- else
- /\A( *)(#[^\n]+|-( +(?!:)|$))?/
- end
- end
-end
-
-#
-# Token class added 2002 Dec 26.
-# Thanks to this class, we can now track line numbers
-# and store accessory data to our tokens. This should
-# eventually assist our emitter in reforming a document
-# in its original form.
-#
-class Token
- attr_accessor :sym, :data, :lineno, :charno
- def initialize( s, d, ln, cn )
- @sym, @data, @lineno, @charno = s, d, ln, cn
- end
-end
-
-#
-# Token stack ops
-#
-def reset_indent
- @indent, @indent_raw = "", ""
-end
-
-def reset_tokens
- @q = []
-end
-
-def add_token( sym, data )
- if sym == :FOLD
- if @q.last.sym != :FOLD
- raise YAML::Error, "Improper fold!!"
- end
- if @q.last.data =~ / \Z/
- @lvl.last.domain = :FoldIndt if @lvl.last.domain == :Folded
- elsif @lvl.last.domain == :Folded
- @q.last.data.gsub!( /\n\Z\n/, "\n" ) unless @q.last.data.gsub!( /(.)\Z\n/, '\1 ' )
- elsif @lvl.last.domain == :FoldIndt
- @lvl.last.domain = :Folded
- end
- @q.last.data += data
+ def self.load( io )
+ if String === io
+ ctor = JRubyConstructor.new(self,ComposerImpl.new(ParserImpl.new(ScannerImpl.new(io)),ResolverImpl.new))
else
- @q.push Token.new( sym, data, @lineno, @charno )
+ ctor = JRubyConstructor.new(self,ComposerImpl.new(ParserImpl.new(ScannerImpl.new(IOReader.new(io))),ResolverImpl.new))
end
-end
-
-def apply_indent
- # Turn indent into a token
- unless @indent.empty?
- indt_len = /^ *\Z/.match( @indent )[0].length
- if @lvl.last.status == :Block and @q.last.sym == :FOLD
- add_fold_indent
- end
- if @lvl.last.spaces > indt_len
- add_end_indent indt_len
- end
- if @lvl.last.status == :Block
- fold_txt = ""
- if @q.last.sym == :FSTART
- if @q.last.data =~ /(\d+)/
- if @lvl.last.spaces > 0
- @lvl.last.spaces -= 1
- end
- indt_len = $1.to_i + @lvl.last.spaces
- end
- @lvl.last.spaces = indt_len
- @q.push Token.new( :FOLD, fold_txt, @lineno, 1 )
- @indent.slice!( 0, 1 )
- add_fold_indent
- end
- else
- indt_type = :INDENT
- if @lvl.last.spaces < indt_len
- indt_type = :IOPEN
- end
- if @q.last and @q.last.sym == :PLAIN and ( indt_type == :IOPEN or
- ( @lvl.last.spaces == indt_len and @q[-2] and @q[-2].sym == :IOPEN ) )
- unless @q.last.data.empty?
- @q.last.data += @indent_raw.gsub( /^ +/, '' ).gsub( /\n(\n*)/, '\1' )
- end
- elsif @lvl.last.status != :Inline
- @plain_set = @plain_sets[ :AllowInline ]
- if indt_type == :IOPEN
- @lvl.push Level.new( indt_len, @lvl.last.status, @lvl.last.domain )
- end
- @q.push Token.new( indt_type, indt_len, @lineno, 1 )
- end
- end
- reset_indent
- end
-end
-
-def close_tokens
- @q.push Token.new( false, '$', @lineno, @charno )
-end
-
-def pop_token
- @q.pop
-end
-
-def push_token( tok )
- @q.push tok
-end
-
-#
-# Used by Racc
-# The @last_token stored for error_reporting
-#
-def next_token
- @last_tokens.push @q.first
- if @last_tokens.length > 5
- @last_tokens.shift
- end
- tok = @q.shift
- [ tok.sym, tok.data ]
-end
-
-def add_end_indent( indt_len )
- while @lvl.last.spaces > indt_len
- @q.push Token.new( :IEND, @lvl.pop.spaces, @lineno, 1 )
- end
-end
-
-#
-# Keep line number count
-#
-def readline
- @lineno += 1
- @charno = 1
- begin
- @stream.readline
- rescue IOError
- end
-end
-
-def eof?; @stream.eof?; end
-
-#
-# Handle Hash special keys
-#
-def hash_update( h, item )
- if item.class == Array
- # if h.class != YAML::SpecialHash
- # h = YAML::SpecialHash.new.update( h )
- # end
- if item[0] == :MERGE
- if Hash === item[1]
- h.update( item[1] )
- elsif Array === item[1]
- item[1].flatten.reverse.each { |hmerge|
- h.update( hmerge )
- }
- end
- elsif item[0] == :DEFAULT
- h.default = item[1]
- # elsif item[0] == :COMMENT
- # h.comment = item[1]
- end
- elsif item.class == YAML::SpecialHash
- h = item.update( h )
- elsif item.is_a? Hash
- h.update( item )
- else
- raise YAML::Error, "Invalid update to Hash with item: " + item.inspect
- end
- return h
-end
-
-def attach_transfer( meth, val )
- meth = YAML.unescape( meth )
- if @options[:Model] == :Generic
- val.type_id = meth
- val
- else
- YAML.transfer_method( meth, val )
- end
-end
-
-#
-# Add a new node
-#
-def new_node( type_id, val )
- if @options[:Model] == :Generic
- val = YamlNode.new( type_id, val )
- end
- val
-end
-
-#
-# Take block text and format based on the block def characters
-#
-def process_block( fold_type, fold_text )
- fold_text.chomp! if fold_type.include?( '|' )
- if fold_type.include?( '+' )
- fold_text << "\n"
- else
- fold_text.chomp!( '' )
- if fold_type.include?( '-' )
- fold_text.chomp!
- else
- fold_text << "\n"
- end
- end
- return fold_text
-end
-
-def add_fold_indent
- if @lvl.last.spaces > 0
- @indent.gsub!( /^ {0,#{ @lvl.last.spaces }}/, '' )
- end
- @q.last.data += @indent
-end
-
-def process_plain( p )
- if @options[:Model] == :Generic
- new_node( YAML.detect_implicit( p ), p )
- else
- YAML.try_implicit( p )
- end
-end
-..end src/yaml.y.rb modeval..idae682a68eb
-
-##### racc 1.4.3 generates ###
-
-racc_reduce_table = [
- 0, 0, :racc_error,
- 1, 22, :_reduce_none,
- 1, 22, :_reduce_none,
- 2, 22, :_reduce_3,
- 1, 22, :_reduce_4,
- 1, 25, :_reduce_none,
- 0, 25, :_reduce_6,
- 2, 23, :_reduce_7,
- 1, 23, :_reduce_8,
- 1, 23, :_reduce_9,
- 3, 23, :_reduce_10,
- 2, 24, :_reduce_11,
- 1, 24, :_reduce_none,
- 1, 24, :_reduce_none,
- 1, 24, :_reduce_none,
- 3, 24, :_reduce_15,
- 1, 24, :_reduce_none,
- 1, 24, :_reduce_none,
- 3, 24, :_reduce_18,
- 4, 26, :_reduce_19,
- 3, 26, :_reduce_20,
- 3, 27, :_reduce_21,
- 2, 32, :_reduce_22,
- 1, 31, :_reduce_23,
- 3, 31, :_reduce_24,
- 3, 28, :_reduce_25,
- 2, 28, :_reduce_26,
- 1, 33, :_reduce_27,
- 2, 33, :_reduce_28,
- 3, 33, :_reduce_29,
- 3, 29, :_reduce_30,
- 3, 35, :_reduce_31,
- 3, 35, :_reduce_32,
- 1, 36, :_reduce_none,
- 5, 36, :_reduce_34,
- 1, 34, :_reduce_35,
- 3, 34, :_reduce_36,
- 3, 30, :_reduce_37,
- 2, 30, :_reduce_38,
- 1, 37, :_reduce_39,
- 3, 37, :_reduce_40 ]
-
-racc_reduce_n = 41
-
-racc_shift_n = 74
-
-racc_action_table = [
- 4, 6, 8, 10, 12, 14, 59, 60, 52, 61,
- 58, 3, 30, 10, 12, 34, 51, 15, 4, 6,
- 8, 10, 12, 14, 68, 31, 44, 45, 42, 3,
- 30, 10, 12, 34, 43, 15, 4, 6, 8, 10,
- 12, 14, 50, 31, 33, 62, 49, 3, 20, 21,
- 63, 54, 17, 15, 4, 6, 8, 10, 12, 14,
- 30, 10, 12, 34, 57, 3, 30, 10, 12, 34,
- 52, 15, 4, 6, 8, 10, 12, 14, 25, 31,
- 70, 53, 72, 3, 30, 10, 12, 34, 51, 15,
- 4, 6, 8, 10, 12, 14, nil, nil, nil, nil,
- nil, 3, nil, nil, nil, nil, nil, 15, 4, 6,
- 8, 10, 12, 14, nil, nil, nil, nil, nil, 3,
- nil, nil, nil, nil, nil, 15, 4, 6, 8, 10,
- 12, 14, nil, nil, nil, nil, nil, 3, nil, nil,
- nil, nil, nil, 15, 4, 6, 8, 10, 12, 14,
- nil, nil, nil, nil, nil, 3, nil, nil, nil, nil,
- nil, 15, 4, 6, 8, 10, 12, 14, 8, 10,
- 12, 14, nil, 3, nil, nil, nil, 3, nil, 15,
- nil, nil, nil, 15, 30, 10, 12, 34, nil, 37,
- nil, 25, nil, 3, nil, nil, nil, 31, 33, 15 ]
-
-racc_action_check = [
- 0, 0, 0, 0, 0, 0, 36, 37, 27, 37,
- 36, 0, 15, 15, 15, 15, 27, 0, 53, 53,
- 53, 53, 53, 53, 55, 15, 19, 19, 15, 53,
- 49, 49, 49, 49, 17, 53, 3, 3, 3, 3,
- 3, 3, 26, 49, 49, 41, 26, 3, 3, 3,
- 41, 32, 1, 3, 4, 4, 4, 4, 4, 4,
- 30, 30, 30, 30, 35, 4, 62, 62, 62, 62,
- 56, 4, 51, 51, 51, 51, 51, 51, 58, 62,
- 61, 31, 68, 51, 34, 34, 34, 34, 39, 51,
- 45, 45, 45, 45, 45, 45, nil, nil, nil, nil,
- nil, 45, nil, nil, nil, nil, nil, 45, 21, 21,
- 21, 21, 21, 21, nil, nil, nil, nil, nil, 21,
- nil, nil, nil, nil, nil, 21, 33, 33, 33, 33,
- 33, 33, nil, nil, nil, nil, nil, 33, nil, nil,
- nil, nil, nil, 33, 25, 25, 25, 25, 25, 25,
- nil, nil, nil, nil, nil, 25, nil, nil, nil, nil,
- nil, 25, 72, 72, 72, 72, 72, 72, 8, 8,
- 8, 8, nil, 72, nil, nil, nil, 8, nil, 72,
- nil, nil, nil, 8, 14, 14, 14, 14, nil, 14,
- nil, 14, nil, 14, nil, nil, nil, 14, 14, 14 ]
-
-racc_action_pointer = [
- -2, 52, nil, 34, 52, nil, nil, nil, 164, nil,
- nil, nil, nil, nil, 180, 8, nil, 34, nil, 12,
- nil, 106, nil, nil, nil, 142, 34, 0, nil, nil,
- 56, 65, 43, 124, 80, 56, -2, -1, nil, 72,
- nil, 30, nil, nil, nil, 88, nil, nil, nil, 26,
- nil, 70, nil, 16, nil, 12, 62, nil, 67, nil,
- nil, 72, 62, nil, nil, nil, nil, nil, 66, nil,
- nil, nil, 160, nil ]
-
-racc_action_default = [
- -41, -41, -1, -41, -41, -2, -4, -12, -41, -13,
- -8, -14, -9, -16, -41, -41, -17, -41, -27, -41,
- -26, -6, -3, -7, -11, -6, -41, -41, -33, -35,
- -41, -41, -41, -41, -41, -41, -41, -41, -23, -41,
- -39, -41, -38, 74, -25, -6, -5, -28, -22, -41,
- -30, -6, -10, -6, -15, -41, -41, -18, -41, -21,
- -20, -41, -41, -37, -29, -36, -31, -32, -41, -24,
- -19, -40, -6, -34 ]
-
-racc_goto_table = [
- 23, 47, 40, 38, 29, 48, 27, 39, 36, 1,
- 35, 19, 18, 22, 26, 32, 24, 41, nil, nil,
- nil, nil, 23, nil, nil, 64, 56, nil, nil, nil,
- nil, 66, nil, 67, nil, nil, nil, nil, nil, 65,
- nil, 39, 55, nil, nil, nil, nil, 69, nil, 71,
- nil, nil, 73, nil, 39 ]
-
-racc_goto_check = [
- 2, 4, 14, 11, 15, 4, 2, 2, 10, 1,
- 9, 12, 1, 1, 13, 7, 3, 16, nil, nil,
- nil, nil, 2, nil, nil, 4, 2, nil, nil, nil,
- nil, 4, nil, 4, nil, nil, nil, nil, nil, 15,
- nil, 2, 1, nil, nil, nil, nil, 11, nil, 14,
- nil, nil, 4, nil, 2 ]
-
-racc_goto_pointer = [
- nil, 9, -8, 8, -20, nil, nil, 1, nil, -4,
- -6, -11, 8, 0, -13, -10, 2 ]
-
-racc_goto_default = [
- nil, 46, 2, 5, nil, 7, 9, 11, 13, 16,
- nil, nil, nil, nil, 28, nil, nil ]
-
-racc_token_table = {
- false => 0,
- Object.new => 1,
- :ANCHOR => 2,
- :ALIAS => 3,
- :TRANSFER => 4,
- :WORD => 5,
- :PLAIN => 6,
- :IOPEN => 7,
- :IEND => 8,
- :FSTART => 9,
- :FOLD => 10,
- "-" => 11,
- :INDENT => 12,
- "[" => 13,
- "]" => 14,
- "," => 15,
- ":" => 16,
- "=" => 17,
- "?" => 18,
- "{" => 19,
- "}" => 20 }
-
-racc_use_result_var = true
-
-racc_nt_base = 21
-
-Racc_arg = [
- racc_action_table,
- racc_action_check,
- racc_action_default,
- racc_action_pointer,
- racc_goto_table,
- racc_goto_check,
- racc_goto_default,
- racc_goto_pointer,
- racc_nt_base,
- racc_reduce_table,
- racc_token_table,
- racc_shift_n,
- racc_reduce_n,
- racc_use_result_var ]
-
-Racc_token_to_s_table = [
-'$end',
-'error',
-'ANCHOR',
-'ALIAS',
-'TRANSFER',
-'WORD',
-'PLAIN',
-'IOPEN',
-'IEND',
-'FSTART',
-'FOLD',
-'"-"',
-'INDENT',
-'"["',
-'"]"',
-'","',
-'":"',
-'"="',
-'"?"',
-'"{"',
-'"}"',
-'$start',
-'atom',
-'word_rep',
-'struct_rep',
-'atom_or_empty',
-'scalar_block',
-'implicit_seq',
-'inline_seq',
-'implicit_map',
-'inline_map',
-'in_implicit_seq',
-'basic_seq',
-'in_inline_seq',
-'in_implicit_map',
-'basic_mapping',
-'complex_mapping',
-'in_inline_map']
-
-Racc_debug_parser = false
-
-##### racc system variables end #####
-
- # reduce 0 omitted
-
- # reduce 1 omitted
-
- # reduce 2 omitted
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 17
- def _reduce_3( val, _values, result )
- if @options[:Model] == :Generic
- val[1].anchor = val[0]
- end
- result = @anchor[ val[0] ] = val[1]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 22
- def _reduce_4( val, _values, result )
- result = @anchor[ val[0] ]
- result
- end
-.,.,
-
- # reduce 5 omitted
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 25
- def _reduce_6( val, _values, result )
- result = new_node( 'null', nil )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 32
- def _reduce_7( val, _values, result )
- result = attach_transfer( val[0], val[1] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 33
- def _reduce_8( val, _values, result )
- result = new_node( 'str', val[0] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 34
- def _reduce_9( val, _values, result )
- result = process_plain( val[0] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 35
- def _reduce_10( val, _values, result )
- result = val[1]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 41
- def _reduce_11( val, _values, result )
- result = attach_transfer( val[0], val[1] )
- result
- end
-.,.,
-
- # reduce 12 omitted
-
- # reduce 13 omitted
-
- # reduce 14 omitted
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 45
- def _reduce_15( val, _values, result )
- result = val[1]
- result
- end
-.,.,
-
- # reduce 16 omitted
-
- # reduce 17 omitted
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 48
- def _reduce_18( val, _values, result )
- result = val[1]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 56
- def _reduce_19( val, _values, result )
- result = new_node( 'str', process_block( val[1], val[2] ) )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 60
- def _reduce_20( val, _values, result )
- result = new_node( 'str', '' )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 66
- def _reduce_21( val, _values, result )
- result = new_node( 'seq', val[1] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 68
- def _reduce_22( val, _values, result )
- result = val[1]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 70
- def _reduce_23( val, _values, result )
- result = val
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 73
- def _reduce_24( val, _values, result )
- result.push val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 79
- def _reduce_25( val, _values, result )
- result = new_node( 'seq', val[1] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 80
- def _reduce_26( val, _values, result )
- result = new_node( 'seq', [] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 82
- def _reduce_27( val, _values, result )
- result = val
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 83
- def _reduce_28( val, _values, result )
- result = [ result = new_node( 'null', nil ), val[1] ]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 84
- def _reduce_29( val, _values, result )
- result.push val[2]
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 89
- def _reduce_30( val, _values, result )
- result = new_node( 'map', val[1] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 93
- def _reduce_31( val, _values, result )
- if val[0] == '<<'
- result = [ :MERGE, val[2] ]
- else
- result = { val[0] => val[2] }
- end
- result
+ ctor.getData if ctor.checkData
end
-.,.,
-module_eval <<'.,.,', 'src/yaml.y.rb', 101
- def _reduce_32( val, _values, result )
- result = [ :DEFAULT, val[2] ]
- result
- end
-.,.,
-
- # reduce 33 omitted
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 107
- def _reduce_34( val, _values, result )
- result = { val[1] => val[4] }
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 112
- def _reduce_35( val, _values, result )
- result = hash_update( {}, val[0] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 116
- def _reduce_36( val, _values, result )
- result = hash_update( val[0], val[2] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 122
- def _reduce_37( val, _values, result )
- result = new_node( 'map', val[1] )
- result
- end
-.,.,
-
-module_eval <<'.,.,', 'src/yaml.y.rb', 123
- def _reduce_38( val, _values, result )
- result = new_node( 'map', Hash.new )
- result
+ def self.load_file( filepath )
+ File.open( filepath ) do |f|
+ load( f )
+ end
end
-.,.,
-module_eval <<'.,.,', 'src/yaml.y.rb', 127
- def _reduce_39( val, _values, result )
- result = hash_update( {}, val[0] )
- result
+ # Make YAML module to act exactly as RbYAML
+ def self.method_missing(name,*args)
+ RbYAML.send(name,*args)
end
-.,.,
-module_eval <<'.,.,', 'src/yaml.y.rb', 131
- def _reduce_40( val, _values, result )
- result = hash_update( val[0], val[2] )
- result
+ def self.const_missing(name)
+ RbYAML.const_get(name)
end
-.,.,
-
- def _reduce_none( val, _values, result )
- result
- end
-
- end # class Parser
-
-end # module YAML
+end
diff --git a/src/org/jruby/util/IOReader.java b/src/org/jruby/util/IOReader.java
new file mode 100644
index 00000000000..f751d8c8e3f
--- /dev/null
+++ b/src/org/jruby/util/IOReader.java
@@ -0,0 +1,71 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2006 Ola Bini
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+/**
+ * $Id$
+ */
+package org.jruby.util;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.jruby.RubyString;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * @author Ola Bini
+ * @version $Revision$
+ */
+public class IOReader extends Reader {
+ private IRubyObject io;
+
+ public IOReader(final IRubyObject io) {
+ if(!io.respondsTo("read")) {
+ throw new IllegalArgumentException("Object: " + io + " is not a legal argument to this wrapper, cause it doesn't respond to \"read\".");
+ }
+ this.io = io;
+ }
+
+ public void close() throws IOException {
+ if(io.respondsTo("close")) {
+ io.callMethod("close");
+ }
+ }
+
+ public int read(final char[] arr, final int off, final int len) {
+ final IRubyObject read = io.callMethod("read",io.getRuntime().newFixnum(len));
+ if(read.isNil() || ((RubyString)read).getValue().length() == 0) {
+ return -1;
+ } else {
+ final RubyString str = (RubyString)read;
+ final CharSequence val = str.getValue();
+ System.arraycopy(val.toString().toCharArray(),0,arr,off,val.length());
+ return val.length();
+ }
+ }
+}// IOReader
+
diff --git a/src/org/jruby/yaml/JRubyConstructor.java b/src/org/jruby/yaml/JRubyConstructor.java
new file mode 100644
index 00000000000..79e98b19436
--- /dev/null
+++ b/src/org/jruby/yaml/JRubyConstructor.java
@@ -0,0 +1,258 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2006 Ola Bini
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+/**
+ * $Id$
+ */
+package org.jruby.yaml;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import java.util.regex.Pattern;
+
+import org.jvyaml.Composer;
+import org.jvyaml.Constructor;
+import org.jvyaml.ConstructorException;
+import org.jvyaml.ConstructorImpl;
+import org.jvyaml.SafeConstructorImpl;
+
+import org.jvyaml.nodes.Node;
+
+import org.jruby.IRuby;
+import org.jruby.RubyClass;
+import org.jruby.RubyModule;
+import org.jruby.RubyObject;
+import org.jruby.RubyHash;
+import org.jruby.RubyTime;
+import org.jruby.runtime.builtin.IRubyObject;
+
+/**
+ * @author Ola Bini
+ * @version $Revision$
+ */
+public class JRubyConstructor extends ConstructorImpl {
+ private final static Map yamlConstructors = new HashMap();
+ private final static Map yamlMultiConstructors = new HashMap();
+ private final static Map yamlMultiRegexps = new HashMap();
+ public YamlConstructor getYamlConstructor(final Object key) {
+ return (YamlConstructor)yamlConstructors.get(key);
+ }
+
+ public YamlMultiConstructor getYamlMultiConstructor(final Object key) {
+ return (YamlMultiConstructor)yamlMultiConstructors.get(key);
+ }
+
+ public Pattern getYamlMultiRegexp(final Object key) {
+ return (Pattern)yamlMultiRegexps.get(key);
+ }
+
+ public Set getYamlMultiRegexps() {
+ return yamlMultiRegexps.keySet();
+ }
+
+ public static void addConstructor(final String tag, final YamlConstructor ctor) {
+ yamlConstructors.put(tag,ctor);
+ }
+
+ public static void addMultiConstructor(final String tagPrefix, final YamlMultiConstructor ctor) {
+ yamlMultiConstructors.put(tagPrefix,ctor);
+ yamlMultiRegexps.put(tagPrefix,Pattern.compile("^"+tagPrefix));
+ }
+
+ private final IRuby runtime;
+
+ public JRubyConstructor(final IRubyObject receiver, final Composer composer) {
+ super(composer);
+ this.runtime = receiver.getRuntime();
+ }
+
+ public Object constructRubyScalar(final Node node) {
+ return runtime.newString((String)super.constructScalar(node));
+ }
+
+ public Object constructRubySequence(final Node node) {
+ return runtime.newArray((List)super.constructSequence(node));
+ }
+
+ public Object constructRubyMapping(final Node node) {
+ return RubyHash.newHash(runtime,(Map)super.constructMapping(node),runtime.getNil());
+ }
+
+ public Object constructRubyPairs(final Node node) {
+ return runtime.newArray((List)super.constructPairs(node));
+ }
+
+ public static Object constructYamlNull(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).runtime.getNil();
+ }
+
+ public static Object constructYamlBool(final Constructor ctor, final Node node) {
+ return SafeConstructorImpl.constructYamlBool(ctor,node) == Boolean.TRUE ? ((JRubyConstructor)ctor).runtime.getTrue() : ((JRubyConstructor)ctor).runtime.getFalse();
+ }
+
+ public static Object constructYamlOmap(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).constructRubyPairs(node);
+ }
+
+ public static Object constructYamlPairs(final Constructor ctor, final Node node) {
+ return constructYamlOmap(ctor,node);
+ }
+
+ public static Object constructYamlSet(final Constructor ctor, final Node node) {
+ return SafeConstructorImpl.constructYamlSet(ctor,node);
+ }
+
+ public static Object constructYamlStr(final Constructor ctor, final Node node) {
+ final org.jruby.RubyString str = (org.jruby.RubyString)((JRubyConstructor)ctor).constructRubyScalar(node);
+ return str.getValue().length() == 0 ? str.getRuntime().getNil() : str;
+ }
+
+ public static Object constructYamlSeq(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).constructRubySequence(node);
+ }
+
+ public static Object constructYamlMap(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).constructRubyMapping(node);
+ }
+
+ public static Object constructUndefined(final Constructor ctor, final Node node) {
+ throw new ConstructorException(null,"could not determine a constructor for the tag " + node.getTag(),null);
+ }
+
+ public static Object constructYamlTimestamp(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).runtime.newTime(((Date)SafeConstructorImpl.constructYamlTimestamp(ctor,node)).getTime());
+ }
+
+ public static Object constructYamlInt(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).runtime.newFixnum(((Long)SafeConstructorImpl.constructYamlInt(ctor,node)).longValue());
+ }
+ public static Object constructYamlFloat(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).runtime.newFloat(((Double)SafeConstructorImpl.constructYamlFloat(ctor,node)).doubleValue());
+ }
+ public static Object constructYamlBinary(final Constructor ctor, final Node node) {
+ return ((JRubyConstructor)ctor).runtime.newString(((String)SafeConstructorImpl.constructYamlBinary(ctor,node)));
+ }
+ public static Object constructRuby(final Constructor ctor, final String tag, final Node node) {
+ final IRuby runtime = ((JRubyConstructor)ctor).runtime;
+ RubyModule objClass = runtime.getModule("Object");
+ if(tag != null) {
+ final String[] nms = tag.split("::");
+ for(int i=0,j=nms.length;i