From dbac74b8535e0dbad76b07bb68f2346f46b068da Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 8 Jun 2006 22:42:53 +0000 Subject: [PATCH] adding Jv/RbYAML code and docs to cnutter_work1 git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@2057 961051c9-f516-0410-bf72-c9f7e237a7b7 --- .classpath | 1 + docs/jvyaml/CREDITS | 4 + docs/jvyaml/LICENSE | 19 + docs/jvyaml/README | 31 + docs/rbyaml/LICENSE | 19 + docs/rbyaml/README | 31 + lib/jvyaml.jar | Bin 0 -> 119775 bytes src/builtin/yaml.rb | 3573 +--------------------- src/org/jruby/util/IOReader.java | 71 + src/org/jruby/yaml/JRubyConstructor.java | 258 ++ 10 files changed, 457 insertions(+), 3550 deletions(-) create mode 100644 docs/jvyaml/CREDITS create mode 100644 docs/jvyaml/LICENSE create mode 100644 docs/jvyaml/README create mode 100644 docs/rbyaml/LICENSE create mode 100644 docs/rbyaml/README create mode 100644 lib/jvyaml.jar create mode 100644 src/org/jruby/util/IOReader.java create mode 100644 src/org/jruby/yaml/JRubyConstructor.java 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 0000000000000000000000000000000000000000..1cade98941416999261008026f5be0fc4a84906b GIT binary patch literal 119775 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
bO6NY+%FtEtzXuQ4g0mZx3;M1rDafw$tz07Ku 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 Rset=`cG)1m*X}+@%O46>=t%$o literal 0 HcmV?d00001 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