Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Remove yaml based on JvYAMLb and add Yecht version 0.0.1 instead. Als…

…o update yaml tests as a copy from Ruby 1.8.7.
  • Loading branch information...
commit dc8d7f6cf8590cadafac2995738a23841f8621c2 1 parent 877efe0
@olabini olabini authored
Showing with 3,165 additions and 2,620 deletions.
  1. +20 −0 bench/bench_yaml.rb
  2. +557 −0 bench/big_yaml.yml
  3. +1 −4 build.xml
  4. BIN  build_lib/jvyamlb-0.2.5.jar
  5. BIN  lib/ruby/site_ruby/1.8/yecht.jar
  6. +397 −453 src/builtin/yaml.rb
  7. +247 −0 src/builtin/yaml/baseemitter.rb
  8. +216 −0 src/builtin/yaml/basenode.rb
  9. +26 −0 src/builtin/yaml/compat.rb
  10. +45 −0 src/builtin/yaml/constants.rb
  11. +111 −0 src/builtin/yaml/dbm.rb
  12. +107 −0 src/builtin/yaml/emitter.rb
  13. +33 −0 src/builtin/yaml/encoding.rb
  14. +34 −0 src/builtin/yaml/error.rb
  15. +458 −0 src/builtin/yaml/rubytypes.rb
  16. +40 −0 src/builtin/yaml/stream.rb
  17. +83 −0 src/builtin/yaml/stringio.rb
  18. +0 −9 src/builtin/yaml/syck.rb
  19. +89 −0 src/builtin/yaml/tag.rb
  20. +195 −0 src/builtin/yaml/types.rb
  21. +54 −0 src/builtin/yaml/yamlnode.rb
  22. +19 −0 src/builtin/yaml/yecht.rb
  23. +52 −0 src/builtin/yaml/ypath.rb
  24. +13 −12 src/org/jruby/Ruby.java
  25. +7 −0 src/org/jruby/RubyBasicObject.java
  26. +13 −0 src/org/jruby/RubyObject.java
  27. +0 −696 src/org/jruby/RubyYAML.java
  28. +0 −47 src/org/jruby/libraries/YamlLibrary.java
  29. +1 −0  src/org/jruby/runtime/builtin/IRubyObject.java
  30. +21 −0 src/org/jruby/util/TypeConverter.java
  31. +0 −703 src/org/jruby/yaml/JRubyConstructor.java
  32. +0 −217 src/org/jruby/yaml/JRubyRepresenter.java
  33. +0 −49 src/org/jruby/yaml/JRubySerializer.java
  34. +5 −90 test/testYAML.rb
  35. +0 −1  test/test_loading_builtin_libraries.rb
  36. +247 −339 test/test_yaml.rb
  37. +74 −0 test/test_yamlstore.rb
View
20 bench/bench_yaml.rb
@@ -0,0 +1,20 @@
+
+require 'benchmark'
+require 'yaml'
+
+def bench_yaml(bm)
+ oldbm = $bm
+ $bm = bm
+
+ str = File.read(File.join(File.dirname(__FILE__), "big_yaml.yml"))
+ result = YAML.load(str)
+
+ $bm.report("1k parse") { 1_000.times { YAML.parse(str) } }
+ $bm.report("1k loads") { 1_000.times { YAML.load(str) } }
+ $bm.report("1k dumps") { 1_000.times { result.to_yaml } }
+ $bm.report("1k roundtrip") { 1_000.times { YAML.load(result.to_yaml) } }
+end
+
+if $0 == __FILE__
+ (ARGV[0] || 10).to_i.times { Benchmark.bm(30) {|bm| bench_yaml(bm)} }
+end
View
557 bench/big_yaml.yml
@@ -0,0 +1,557 @@
+---
+abc:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - [1, 2, 3, 4, 5]
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+ccdcd:
+ abc:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc2:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc3:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc4:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc5:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc6:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+abc2:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - [1, 2, 3, 4, 5]
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+ccdcd2:
+ abc:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc2:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc3:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc4:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc5:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc6:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+abc3:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - [1, 2, 3, 4, 5]
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+ccdcd3:
+ abc:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc2:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc3:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc4:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc5:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc6:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+abc4:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - [1, 2, 3, 4, 5]
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
+ccdcd4:
+ abc:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc2:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc3:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc4:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc5:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ abc6:
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+ - foo
+ - bar
+ - qux
+
View
5 build.xml
@@ -108,6 +108,7 @@
<copy todir="${jruby.classes.dir}/builtin">
<fileset dir="${lib.dir}/ruby/site_ruby/1.8/builtin">
<include name="**/*.rb"/>
+ <include name="**/*.jar"/>
</fileset>
</copy>
@@ -243,7 +244,6 @@
<zipfileset src="${build.lib.dir}/asm-tree-3.2.jar"/>
<zipfileset src="${build.lib.dir}/bytelist.jar"/>
<zipfileset src="${build.lib.dir}/constantine.jar"/>
- <zipfileset src="${build.lib.dir}/jvyamlb-0.2.5.jar"/>
<zipfileset src="${build.lib.dir}/jline-0.9.93.jar"/>
<zipfileset src="${build.lib.dir}/jcodings.jar"/>
<zipfileset src="${build.lib.dir}/joni.jar"/>
@@ -286,7 +286,6 @@
<zipfileset src="${build.lib.dir}/asm-util-3.2.jar"/>
<zipfileset src="${build.lib.dir}/bytelist.jar"/>
<zipfileset src="${build.lib.dir}/constantine.jar"/>
- <zipfileset src="${build.lib.dir}/jvyamlb-0.2.5.jar"/>
<zipfileset src="${build.lib.dir}/jcodings.jar"/>
<zipfileset src="${build.lib.dir}/joni.jar"/>
<zipfileset src="${build.lib.dir}/jna-posix.jar"/>
@@ -312,7 +311,6 @@
<zipfileset src="${build.lib.dir}/asm-tree-3.2.jar"/>
<zipfileset src="${build.lib.dir}/constantine.jar"/>
<zipfileset src="${build.lib.dir}/bytelist.jar"/>
- <zipfileset src="${build.lib.dir}/jvyamlb-0.2.5.jar"/>
<zipfileset src="${build.lib.dir}/jline-0.9.93.jar"/>
<zipfileset src="${build.lib.dir}/jcodings.jar"/>
<zipfileset src="${build.lib.dir}/joni.jar"/>
@@ -405,7 +403,6 @@
<zipfileset src="${build.lib.dir}/asm-tree-3.2.jar"/>
<zipfileset src="${build.lib.dir}/bytelist.jar"/>
<zipfileset src="${build.lib.dir}/constantine.jar"/>
- <zipfileset src="${build.lib.dir}/jvyamlb-0.2.5.jar"/>
<zipfileset src="${build.lib.dir}/jline-0.9.93.jar"/>
<zipfileset src="${build.lib.dir}/jcodings.jar"/>
<zipfileset src="${build.lib.dir}/joni.jar"/>
View
BIN  build_lib/jvyamlb-0.2.5.jar
Binary file not shown
View
BIN  lib/ruby/site_ruby/1.8/yecht.jar
Binary file not shown
View
850 src/builtin/yaml.rb
@@ -1,493 +1,437 @@
-require 'java' #needed for the module JavaUtilities, which JavaEmbedUtils have a dependency on
-require 'date'
-require 'yaml_internal'
-
-class Java::OrgJrubyYaml::JRubyRepresenter
- def kind_of?(other)
- if other == YAML::Emitter
- return true
- else
- super
- end
- end
-end
-
+# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
+# $Id$
+#
+# = yaml.rb: top-level module with methods for loading and parsing YAML documents
+#
+# Author:: why the lucky stiff
+#
+
+require 'stringio'
+require 'yaml/compat'
+require 'yaml/error'
+require 'yaml/yecht'
+require 'yaml/tag'
+require 'yaml/stream'
+require 'yaml/constants'
+
+# == YAML
+#
+# YAML(tm) (rhymes with 'camel') is a
+# straightforward machine parsable data serialization format designed for
+# human readability and interaction with scripting languages such as Perl
+# and Python. YAML is optimized for data serialization, formatted
+# dumping, configuration files, log files, Internet messaging and
+# filtering. This specification describes the YAML information model and
+# serialization format. Together with the Unicode standard for characters, it
+# provides all the information necessary to understand YAML Version 1.0
+# and construct computer programs to process it.
+#
+# See http://yaml.org/ for more information. For a quick tutorial, please
+# visit YAML In Five Minutes (http://yaml.kwiki.org/?YamlInFiveMinutes).
+#
+# == About This Library
+#
+# The YAML 1.0 specification outlines four stages of YAML loading and dumping.
+# This library honors all four of those stages, although data is really only
+# available to you in three stages.
+#
+# The four stages are: native, representation, serialization, and presentation.
+#
+# The native stage refers to data which has been loaded completely into Ruby's
+# own types. (See +YAML::load+.)
+#
+# The representation stage means data which has been composed into
+# +YAML::BaseNode+ objects. In this stage, the document is available as a
+# tree of node objects. You can perform YPath queries and transformations
+# at this level. (See +YAML::parse+.)
+#
+# The serialization stage happens inside the parser. The YAML parser used in
+# Ruby is called Yecht. Serialized nodes are available in the extension as
+# Node structs.
+#
+# The presentation stage is the YAML document itself. This is accessible
+# to you as a string. (See +YAML::dump+.)
+#
+# For more information about the various information models, see Chapter
+# 3 of the YAML 1.0 Specification (http://yaml.org/spec/#id2491269).
+#
+# The YAML module provides quick access to the most common loading (YAML::load)
+# and dumping (YAML::dump) tasks. This module also provides an API for registering
+# global types (YAML::add_domain_type).
+#
+# == Example
+#
+# A simple round-trip (load and dump) of an object.
+#
+# require "yaml"
+#
+# test_obj = ["dogs", "cats", "badgers"]
+#
+# yaml_obj = YAML::dump( test_obj )
+# # -> ---
+# - dogs
+# - cats
+# - badgers
+# ruby_obj = YAML::load( yaml_obj )
+# # => ["dogs", "cats", "badgers"]
+# ruby_obj == test_obj
+# # => true
+#
+# To register your custom types with the global resolver, use +add_domain_type+.
+#
+# YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
+# Widget.new( val )
+# end
+#
module YAML
- #
- # 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
- }
-
- class Error < StandardError; end
-
- def self.parse(obj)
-# Proxy.new(YAML::load(obj))
- YAML::JvYAML::Node::from_internal(YAML::_parse_internal(obj)) || false
- end
-
- def YAML.parse_file( filepath )
- File.open( filepath ) do |f|
- parse( f )
- end
- end
- def self.add_domain_type(*args)
- warn "YAML::add_domain_type isn't supported on JRuby"
- end
-
- def self.parse_documents(*args)
- warn "YAML::parse_documents isn't supported on JRuby"
- end
-
- class Proxy
- def initialize(v)
- @value = v
- end
-
- def transform
- @value
- end
- end
-
- class YPath
- def self.each_path(*args)
- warn "YAML::YPath.each_path isn't supported on JRuby"
- end
- end
-
- class Emitter
- def initialize
- @out = YAML::JvYAML::Out.new self
- end
-
- def reset(opts)
- @opts = opts
- self
- end
-
- def emit(oid, &proc)
- proc.call(@out)
- end
-
- def has_key?(key)
- end
- end
-
- class Object
- attr_accessor :class, :ivars
- def initialize(cl, iv)
- @class, @ivars = cl, iv
- end
+ Resolver = YAML::Yecht::Resolver
+ DefaultResolver = YAML::Yecht::DefaultResolver
+ DefaultResolver.use_types_at( @@tagged_classes )
+ GenericResolver = YAML::Yecht::GenericResolver
+ Parser = YAML::Yecht::Parser
+ Emitter = YAML::Yecht::Emitter
+
+ # Returns a new default parser
+ def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end
+ # Returns a new generic parser
+ def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end
+ # Returns the default resolver
+ def YAML.resolver; DefaultResolver; end
+ # Returns a new default emitter
+ def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end
+
+ #
+ # Converts _obj_ to YAML and writes the YAML result to _io_.
+ #
+ # File.open( 'animals.yaml', 'w' ) do |out|
+ # YAML.dump( ['badger', 'elephant', 'tiger'], out )
+ # end
+ #
+ # If no _io_ is provided, a string containing the dumped YAML
+ # is returned.
+ #
+ # YAML.dump( :locked )
+ # #=> "--- :locked"
+ #
+ def YAML.dump( obj, io = nil )
+ obj.to_yaml( io || io2 = StringIO.new )
+ io || ( io2.rewind; io2.read )
+ end
+
+ #
+ # Load a document from the current _io_ stream.
+ #
+ # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
+ # #=> ['badger', 'elephant', 'tiger']
+ #
+ # Can also load from a string.
+ #
+ # YAML.load( "--- :locked" )
+ # #=> :locked
+ #
+ def YAML.load( io )
+ yp = parser.load( io )
+ end
- def to_yaml( opts = {} )
- YAML::quick_emit( object_id, opts ) do |out|
- out.map( "tag:ruby.yaml.org,2002:object:#{ @class }", to_yaml_style ) do |map|
- @ivars.each do |k,v|
- map.add( k, v )
- end
+ #
+ # Load a document from the file located at _filepath_.
+ #
+ # YAML.load_file( 'animals.yaml' )
+ # #=> ['badger', 'elephant', 'tiger']
+ #
+ def YAML.load_file( filepath )
+ File.open( filepath ) do |f|
+ load( f )
end
- end
end
- end
-
- def YAML.emitter; Emitter.new; end
-
- #
- # Allocate an Emitter if needed
- #
- def YAML.quick_emit( oid, opts = {}, &e )
- out =
- if opts.is_a? YAML::Emitter
- opts
- else
- emitter.reset( opts )
- end
- out.emit( oid, &e )
- end
-
- module JvYAML
- class Out
- attr_accessor :emitter
-
- def initialize(emitter)
- @emitter = emitter
- end
-
- def map(type_id, style = nil)
- map = Map.new(type_id, {}, style)
- yield map
- map.to_s
- end
- def seq(type_id, style = nil)
- seq = Seq.new(type_id, [], style)
- yield seq
- seq
- end
-
- def scalar(type_id, str, style = nil)
- Scalar.new(type_id, str, style)
- end
- end
-
- class Node
- attr_accessor :value
- attr_accessor :style
- attr_accessor :type_id
-
- def transform
- org.jruby.yaml.JRubyConstructor.new(self, nil).construct_document(to_internal)
- end
-
- def to_str
- YAML.dump(self)
- end
+ #
+ # Parse the first document from the current _io_ stream
+ #
+ # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
+ # #=> #<YAML::Yecht::Node:0x82ccce0
+ # @kind=:seq,
+ # @value=
+ # [#<YAML::Yecht::Node:0x82ccd94
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="badger">,
+ # #<YAML::Yecht::Node:0x82ccd58
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="elephant">,
+ # #<YAML::Yecht::Node:0x82ccd1c
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="tiger">]>
+ #
+ # Can also load from a string.
+ #
+ # YAML.parse( "--- :locked" )
+ # #=> #<YAML::Yecht::Node:0x82edddc
+ # @type_id="tag:ruby.yaml.org,2002:sym",
+ # @value=":locked", @kind=:scalar>
+ #
+ def YAML.parse( io )
+ yp = generic_parser.load( io )
+ end
- def to_s
- YAML.dump(self)
- end
-
- def self.from_internal(internal)
- case internal
- when org.jvyamlb.nodes.ScalarNode
- Scalar.new(internal.tag, internal.value, internal.style.chr)
- when org.jvyamlb.nodes.MappingNode
- Map.new(internal.tag, internal.value.inject({}) {|h, obj| h[from_internal(obj[0])] = from_internal(obj[1]); h}, internal.flow_style)
- when org.jvyamlb.nodes.SequenceNode
- Seq.new(internal.tag, internal.value.map {|obj| from_internal(obj)}, internal.flow_style)
+ #
+ # Parse a document from the file located at _filepath_.
+ #
+ # YAML.parse_file( 'animals.yaml' )
+ # #=> #<YAML::Yecht::Node:0x82ccce0
+ # @kind=:seq,
+ # @value=
+ # [#<YAML::Yecht::Node:0x82ccd94
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="badger">,
+ # #<YAML::Yecht::Node:0x82ccd58
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="elephant">,
+ # #<YAML::Yecht::Node:0x82ccd1c
+ # @kind=:scalar,
+ # @type_id="str",
+ # @value="tiger">]>
+ #
+ def YAML.parse_file( filepath )
+ File.open( filepath ) do |f|
+ parse( f )
end
- end
- end
-
- class Scalar < Node
- def initialize(type_id, val, style)
- @kind = :scalar
- self.type_id = type_id
- self.value = val
- self.style = style
- end
-
- def to_internal
- org.jvyamlb.nodes.ScalarNode.new(self.type_id, org.jruby.util.ByteList.new(self.value.to_java_bytes, false), self.style[0])
- end
-
- def to_yaml_node(repr)
- repr.scalar(self.type_id,self.value,self.style)
- end
- end
-
- class Seq < Node
- def initialize(type_id, val, style)
- @kind = :seq
- self.type_id = type_id
- self.value = val
- self.style = style
- end
- def add(v)
- @value << v
- end
-
- def to_internal
- org.jvyamlb.nodes.SequenceNode.new(self.type_id, self.value.map {|v| v.to_internal }, self.style)
- end
-
- def to_yaml_node(repr)
- repr.seq(self.type_id,self.value,self.style)
- end
- end
-
- class Map < Node
- def initialize(type_id, val, style)
- @kind = :map
- self.type_id = type_id
- self.value = val
- self.style = style
- end
- def add(k, v)
- @value[k] = v
- end
-
- def to_internal
- org.jvyamlb.nodes.MappingNode.new(self.type_id, self.value.inject({}) {|h, v| h[v[0].to_internal] = v[1].to_internal ;h }, self.style)
- end
-
- def to_yaml_node(repr)
- repr.map(self.type_id,self.value,self.style)
- end
- end
- end
-
- #
- # YAML::Stream -- for emitting many documents
- #
- class Stream
- include Enumerable
- 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 each(&block)
- @documents.each(&block)
- end
-
- def emit
- YAML::dump_all(@documents)
- end
- end
-
+ #
+ # Calls _block_ with each consecutive document in the YAML
+ # stream contained in _io_.
+ #
+ # File.open( 'many-docs.yaml' ) do |yf|
+ # YAML.each_document( yf ) do |ydoc|
+ # ## ydoc contains the single object
+ # ## from the YAML document
+ # end
+ # end
+ #
+ def YAML.each_document( io, &block )
+ yp = parser.load_documents( io, &block )
+ end
+
+ #
+ # Calls _block_ with each consecutive document in the YAML
+ # stream contained in _io_.
+ #
+ # File.open( 'many-docs.yaml' ) do |yf|
+ # YAML.load_documents( yf ) do |ydoc|
+ # ## ydoc contains the single object
+ # ## from the YAML document
+ # end
+ # end
+ #
+ def YAML.load_documents( io, &doc_proc )
+ YAML.each_document( io, &doc_proc )
+ end
+
+ #
+ # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
+ # each consecutive document in the YAML stream contained in _io_.
#
- # Default private type
+ # File.open( 'many-docs.yaml' ) do |yf|
+ # YAML.each_node( yf ) do |ydoc|
+ # ## ydoc contains a tree of nodes
+ # ## from the YAML document
+ # end
+ # end
+ #
+ def YAML.each_node( io, &doc_proc )
+ yp = generic_parser.load_documents( io, &doc_proc )
+ end
+
+ #
+ # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for
+ # each consecutive document in the YAML stream contained in _io_.
#
- class PrivateType
- def self.tag_subclasses?; false; end
- attr_accessor :type_id, :value
- verbose, $VERBOSE = $VERBOSE, nil
- def initialize( type, val )
- @type_id = type; @value = val
+ # File.open( 'many-docs.yaml' ) do |yf|
+ # YAML.parse_documents( yf ) do |ydoc|
+ # ## ydoc contains a tree of nodes
+ # ## from the YAML document
+ # end
+ # end
+ #
+ def YAML.parse_documents( io, &doc_proc )
+ YAML.each_node( io, &doc_proc )
+ end
+
+ #
+ # Loads all documents from the current _io_ stream,
+ # returning a +YAML::Stream+ object containing all
+ # loaded documents.
+ #
+ def YAML.load_stream( io )
+ d = nil
+ parser.load_documents( io ) do |doc|
+ d = YAML::Stream.new if not d
+ d.add( doc )
end
- def to_yaml_node(repr)
- @value.to_yaml_node(repr)
+ return d
+ end
+
+ #
+ # Returns a YAML stream containing each of the items in +objs+,
+ # each having their own document.
+ #
+ # YAML.dump_stream( 0, [], {} )
+ # #=> --- 0
+ # --- []
+ # --- {}
+ #
+ def YAML.dump_stream( *objs )
+ d = YAML::Stream.new
+ objs.each do |doc|
+ d.add( doc )
end
- ensure
- $VERBOSE = verbose
+ d.emit
+ end
+
+ #
+ # Add a global handler for a YAML domain type.
+ #
+ def YAML.add_domain_type( domain, type_tag, &transfer_proc )
+ resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc )
+ end
+
+ #
+ # Add a transfer method for a builtin type
+ #
+ def YAML.add_builtin_type( type_tag, &transfer_proc )
+ resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc )
+ end
+
+ #
+ # Add a transfer method for a builtin type
+ #
+ def YAML.add_ruby_type( type_tag, &transfer_proc )
+ resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
+ end
+
+ #
+ # Add a private document type
+ #
+ def YAML.add_private_type( type_re, &transfer_proc )
+ resolver.add_type( "x-private:" + type_re, transfer_proc )
+ end
+
+ #
+ # Detect typing of a string
+ #
+ def YAML.detect_implicit( val )
+ resolver.detect_implicit( val )
end
#
# Convert a type_id to a taguri
#
def YAML.tagurize( val )
- if /^tag:.*?:.*$/ =~ val.to_s
- val
- elsif /^(.*?)\/(.*)$/ =~ val.to_s
- "tag:#$1.yaml.org,2002:#$2"
- elsif val.kind_of?(Integer)
- val
- else
- "tag:yaml.org,2002:#{val}"
- end
- end
-
-# From yaml/tag.rb
- # A dictionary of taguris which map to
- # Ruby classes.
- @@tagged_classes = {}
-
- #
- # Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
- # to classes when loading YAML. Taguris are of the form:
- #
- # tag:authorityName,date:specific
- #
- # The +authorityName+ is a domain name or email address. The +date+ is the date the type
- # was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
- # the type being added.
- #
- # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
- # +date+. The +specific+ is simply the name of the type:
- #
- # tag:yaml.org,2002:int
- # tag:yaml.org,2002:float
- # tag:yaml.org,2002:timestamp
- #
- # The domain must be owned by you on the +date+ declared. If you don't own any domains on the
- # date you declare the type, you can simply use an e-mail address.
- #
- # tag:why@ruby-lang.org,2004:notes/personal
- #
- def YAML.tag_class( tag, cls )
- if @@tagged_classes.has_key? tag
- warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
- end
- @@tagged_classes[tag] = cls
+ resolver.tagurize( val )
end
- # Returns the complete dictionary of taguris, paired with classes. The key for
- # the dictionary is the full taguri. The value for each key is the class constant
- # associated to that taguri.
#
- # YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
+ # Apply a transfer method to a Ruby object
#
- def YAML.tagged_classes
- @@tagged_classes
+ def YAML.transfer( type_id, obj )
+ resolver.transfer( YAML.tagurize( type_id ), obj )
end
-end
-# From yaml/tag.rb
-class Module
- # :stopdoc:
+ #
+ # Apply any implicit a node may qualify for
+ #
+ def YAML.try_implicit( obj )
+ YAML.transfer( YAML.detect_implicit( obj ), obj )
+ end
- # Adds a taguri _tag_ to a class, used when dumping or loading the class
- # in YAML. See YAML::tag_class for detailed information on typing and
- # taguris.
- def yaml_as( tag, sc = true )
- verbose, $VERBOSE = $VERBOSE, nil
- class_eval <<-"end;", __FILE__, __LINE__+1
- attr_writer :taguri
- def taguri
- if respond_to? :to_yaml_type
- YAML::tagurize( to_yaml_type[1..-1] )
- else
- return @taguri if defined?(@taguri) and @taguri
- tag = #{ tag.dump }
- if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag]
- tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
- end
- tag
- end
- end
- def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
- end;
- YAML::tag_class tag, self
- ensure
- $VERBOSE = verbose
- end
- # Transforms the subclass name into a name suitable for display
- # in a subclassed tag.
- def yaml_tag_class_name
- self.name
- end
- # Transforms the subclass name found in the tag into a Ruby
- # constant name.
- def yaml_tag_read_class( name )
- name
+ #
+ # 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 )
+ scheme, domain, type, tclass = type.split( ':', 4 )
+ tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
+ return [ type, obj_class ]
end
-end
- Hash::yaml_as "tag:ruby.yaml.org,2002:hash"
- Hash::yaml_as "tag:yaml.org,2002:map"
-
- Array::yaml_as "tag:ruby.yaml.org,2002:array"
- Array::yaml_as "tag:yaml.org,2002:seq"
-
- String::yaml_as "tag:ruby.yaml.org,2002:string"
- String::yaml_as "tag:yaml.org,2002:binary"
- String::yaml_as "tag:yaml.org,2002:str"
-
- Range::yaml_as "tag:ruby.yaml.org,2002:range"
-
- Regexp::yaml_as "tag:ruby.yaml.org,2002:regexp"
-
- Integer::yaml_as "tag:yaml.org,2002:int", false
-
- Time::yaml_as "tag:ruby.yaml.org,2002:time"
- Time::yaml_as "tag:yaml.org,2002:timestamp"
-
- Date::yaml_as "tag:yaml.org,2002:timestamp#ymd"
-
- Float::yaml_as "tag:yaml.org,2002:float"
-
- NilClass::yaml_as "tag:yaml.org,2002:null"
-
- YAML::tag_class "tag:yaml.org,2002:bool#yes", TrueClass
- YAML::tag_class "tag:yaml.org,2002:bool#no", FalseClass
- YAML::tag_class "tag:ruby.yaml.org,2002:object", Object
- YAML::tag_class "tag:ruby.yaml.org,2002:exception", Exception
- YAML::tag_class "tag:ruby.yaml.org,2002:struct", Struct
- YAML::tag_class "tag:ruby.yaml.org,2002:symbol", Symbol
- YAML::tag_class "tag:ruby.yaml.org,2002:sym", Symbol
-
-# From yaml/types.rb
-module YAML
#
- # Builtin collection: !omap
+ # Allocate blank object
#
- class Omap < ::Array
- yaml_as "tag:yaml.org,2002:omap"
- def self.[]( *vals )
- o = Omap.new
- 0.step( vals.length - 1, 2 ) do |i|
- o[vals[i]] = vals[i+1]
- end
+ def YAML.object_maker( obj_class, val )
+ if Hash === val
+ o = obj_class.allocate
+ val.each_pair { |k,v|
+ o.instance_variable_set("@#{k}", v)
+ }
o
+ else
+ raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
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
+ end
+
+ #
+ # Allocate an Emitter if needed
+ #
+ def YAML.quick_emit( oid, opts = {}, &e )
+ out =
+ if opts.is_a? YAML::Emitter
+ opts
else
- self << [ k, val ]
+ emitter.reset( opts )
end
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml_node(repr)
- sequ = []
- self.each do |v|
- sequ << Hash[ *v ]
- end
-
- repr.seq(taguri,sequ,to_yaml_style)
- end
- end
+ out.emit( oid, &e )
+ end
+
+end
-
- #
- # Builtin collection: !pairs
- #
- class Pairs < ::Array
- yaml_as "tag:yaml.org,2002:pairs"
- 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_node(repr)
- sequ = []
- self.each do |v|
- sequ << Hash[ *v ]
- end
- repr.seq(taguri,sequ,to_yaml_style)
- end
- end
+require 'yaml/rubytypes'
+require 'yaml/types'
+module Kernel
#
- # Builtin collection: !set
+ # 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.
#
- class Set < ::Hash
- yaml_as "tag:yaml.org,2002:set"
- end
+ # _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.
+ #
+
+ # Prints any supplied _objects_ out in YAML. Intended as
+ # a variation on +Kernel::p+.
+ #
+ # S = Struct.new(:name, :state)
+ # s = S['dave', 'TX']
+ # y s
+ #
+ # _produces:_
+ #
+ # --- !ruby/struct:S
+ # name: dave
+ # state: TX
+ #
+ def y( object, *objects )
+ objects.unshift object
+ puts( if objects.length == 1
+ YAML::dump( *objects )
+ else
+ YAML::dump_stream( *objects )
+ end )
+ end
+ private :y
end
-
-require 'yaml/syck'
+
+
View
247 src/builtin/yaml/baseemitter.rb
@@ -0,0 +1,247 @@
+#
+# BaseEmitter
+#
+
+require 'yaml/constants'
+require 'yaml/encoding'
+require 'yaml/error'
+
+module YAML
+
+ module BaseEmitter
+
+ def options( opt = nil )
+ if opt
+ @options[opt] || YAML::DEFAULTS[opt]
+ else
+ @options
+ end
+ end
+
+ def options=( opt )
+ @options = opt
+ 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 = nil )
+ @seq_map = false
+ valx = value.dup
+ unless block
+ block =
+ if options(:UseBlock)
+ '|'
+ elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
+ '|'
+ else
+ '>'
+ end
+
+ indt = $&.to_i if block =~ /\d+/
+ if valx =~ /(\A\n*[ \t#]|^---\s+)/
+ indt = options(:Indent) unless indt.to_i > 0
+ block += indt.to_s
+ end
+
+ block +=
+ if valx =~ /\n\Z\n/
+ "+"
+ elsif valx =~ /\Z\n/
+ ""
+ else
+ "-"
+ end
+ end
+ block += "\n"
+ if block[0] == ?"
+ esc_skip = ( "\t\n" unless valx =~ /^[ \t]/ ) || ""
+ valx = fold( YAML::escape( valx, esc_skip ) + "\"" ).chomp
+ self << '"' + indent_text( valx, indt, false )
+ else
+ if block[0] == ?>
+ valx = fold( valx )
+ end
+ #p [block, indt]
+ self << block + indent_text( valx, indt )
+ end
+ end
+
+ #
+ # Emit a simple, unqouted string
+ #
+ def simple( value )
+ @seq_map = false
+ 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, mod, first_line = true )
+ return "" if text.to_s.empty?
+ spacing = indent( mod )
+ text = text.gsub( /\A([^\n])/, "#{ spacing }\\1" ) if first_line
+ return text.gsub( /\n^([^\n])/, "\n#{spacing}\\1" )
+ end
+
+ #
+ # Write a current indent
+ #
+ def indent( mod = nil )
+ #p [ self.id, level, mod, :INDENT ]
+ if level <= 0
+ mod ||= 0
+ else
+ mod ||= options(:Indent)
+ mod += ( level - 1 ) * options(:Indent)
+ end
+ return " " * mod
+ end
+
+ #
+ # Add indent to the buffer
+ #
+ def indent!
+ self << indent
+ end
+
+ #
+ # Folding paragraphs within a column
+ #
+ def fold( value )
+ value.gsub( /(^[ \t]+.*$)|(\S.{0,#{options(:BestWidth) - 1}})(?:[ \t]+|(\n+(?=[ \t]|\Z))|$)/ ) do |s|
+ $1 || $2 + ( $3 || "\n" )
+ end
+ 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 << "{}"
+ @seq_map = false
+ else
+ # FIXME
+ # 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
+ # FIXME: seq_map needs to work with the new anchoring system
+ # 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 )
+ @seq_map = false
+ val = Sequence.new
+ e.call( val )
+ self << "#{type} " if type.length.nonzero?
+
+ #
+ # Empty arrays
+ #
+ if val.length.zero?
+ self << "[]"
+ else
+ # FIXME
+ # 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
+
+ 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
+
+end
View
216 src/builtin/yaml/basenode.rb
@@ -0,0 +1,216 @@
+#
+# YAML::BaseNode class
+#
+require 'yaml/ypath'
+
+module YAML
+
+ #
+ # YAML Generic Model container
+ #
+ module BaseNode
+
+ #
+ # 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
+ }
+ YAML.transfer( 'seq', result )
+ end
+ end
+
+ #
+ # Search for YPath entry and return
+ # transformed 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.transform
+ }
+ 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
+ self[seg]
+ 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].transform, v[1]]
+ match_deep = v[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 "*"
+ if @value.is_a? Enumerable
+ idx = -1
+ @value.collect { |h|
+ idx += 1
+ if Hash === @value
+ [h[0].transform, h[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? BaseNode
+ 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
+
+ #
+ # We want the node to act like as Hash
+ # if it is.
+ #
+ def []( *key )
+ if Hash === @value
+ v = @value.detect { |k,v| k.transform == key.first }
+ v[1] if v
+ elsif Array === @value
+ @value.[]( *key )
+ 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
+
+end
+
View
26 src/builtin/yaml/compat.rb
@@ -0,0 +1,26 @@
+#
+# Ruby 1.6 -> 1.8 compatibility
+# (an isolated incident)
+#
+class Object; alias_method :object_id, :id; end unless Object.respond_to? :object_id
+
+class Object; def instance_variable_set(k, v); self.instance_eval "#{k} = v"; end; end \
+ unless Object.respond_to? :instance_variable_set
+
+class Object; def instance_variable_get(k); self.instance_eval "#{k}"; end; end \
+ unless Object.respond_to? :instance_variable_get
+
+unless Object.respond_to? :allocate
+ class Object
+ def allocate
+ name = self.class.name
+ if Marshal::const_defined? :MAJOR_VERSION
+ ostr = sprintf( "%c%co:%c%s\000", Marshal::MAJOR_VERSION, Marshal::MINOR_VERSION,
+ name.length + 5, name )
+ else
+ ostr = sprintf( "\004\006o:%c%s\000", name.length + 5, name )
+ end
+ ::Marshal.load( ostr )
+ end
+ end
+end
View
45 src/builtin/yaml/constants.rb
@@ -0,0 +1,45 @@
+#
+# Constants used throughout the library
+#
+module YAML
+
+ #
+ # Constants
+ #
+ VERSION = '0.60'
+ 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-\\x09\\x0b-\\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{\x00 \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 = {
+ 'a' => "\x07", 'b' => "\x08", 't' => "\x09",
+ 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
+ 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
+ }
+
+ #
+ # 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
+ }
+
+end
View
111 src/builtin/yaml/dbm.rb
@@ -0,0 +1,111 @@
+require 'yaml'
+require 'dbm'
+#
+# YAML + DBM = YDBM
+# - Same interface as DBM class
+#
+module YAML
+
+class DBM < ::DBM
+ VERSION = "0.1"
+ def []( key )
+ fetch( key )
+ end
+ def []=( key, val )
+ store( key, val )
+ end
+ def fetch( keystr, ifnone = nil )
+ begin
+ val = super( keystr )
+ return YAML::load( val ) if String === val
+ rescue IndexError
+ end
+ if block_given?
+ yield keystr
+ else
+ ifnone
+ end
+ end
+ def index( keystr )
+ super( keystr.to_yaml )
+ end
+ def values_at( *keys )
+ keys.collect { |k| fetch( k ) }
+ end
+ def delete( key )
+ v = super( key )
+ if String === v
+ v = YAML::load( v )
+ end
+ v
+ end
+ def delete_if
+ del_keys = keys.dup
+ del_keys.delete_if { |k| yield( k, fetch( k ) ) == false }
+ del_keys.each { |k| delete( k ) }
+ self
+ end
+ def reject
+ hsh = self.to_hash
+ hsh.reject { |k,v| yield k, v }
+ end
+ def each_pair
+ keys.each { |k| yield k, fetch( k ) }
+ self
+ end
+ def each_value
+ super { |v| yield YAML::load( v ) }
+ self
+ end
+ def values
+ super.collect { |v| YAML::load( v ) }
+ end
+ def has_value?( val )
+ each_value { |v| return true if v == val }
+ return false
+ end
+ def invert
+ h = {}
+ keys.each { |k| h[ self.fetch( k ) ] = k }
+ h
+ end
+ def replace( hsh )
+ clear
+ update( hsh )
+ end
+ def shift
+ a = super
+ a[1] = YAML::load( a[1] ) if a
+ a
+ end
+ def select( *keys )
+ if block_given?
+ self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact
+ else
+ values_at( *keys )
+ end
+ end
+ def store( key, val )
+ super( key, val.to_yaml )
+ val
+ end
+ def update( hsh )
+ hsh.keys.each do |k|
+ self.store( k, hsh.fetch( k ) )
+ end
+ self
+ end
+ def to_a
+ a = []
+ keys.each { |k| a.push [ k, self.fetch( k ) ] }
+ a
+ end
+ def to_hash
+ h = {}
+ keys.each { |k| h[ k ] = self.fetch( k ) }
+ h
+ end
+ alias :each :each_pair
+end
+
+end
View
107 src/builtin/yaml/emitter.rb
@@ -0,0 +1,107 @@
+#
+# Output classes and methods
+#
+
+require 'yaml/baseemitter'
+require 'yaml/encoding'
+
+module YAML
+
+ #
+ # Emit a set of values
+ #
+
+ class Emitter
+
+ include BaseEmitter
+
+ 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
+
+ def level
+ @level
+ end
+
+ #
+ # Version string
+ #
+ def version_s
+ " %YAML:#{@options[:Version]}" if @options[:UseVersion]
+ end
+
+ #
+ # Header
+ #
+ def header
+ if @headless.nonzero?
+ ""
+ else
+ "---#{version_s} "
+ 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
+ header + @buffer.to_s[@headless..-1].to_s
+ end
+ end
+ end
+
+end
+
View
33 src/builtin/yaml/encoding.rb
@@ -0,0 +1,33 @@
+#
+# Handle Unicode-to-Internal conversion
+#
+
+module YAML
+
+ #
+ # Escape the string, condensing common escapes
+ #
+ def YAML.escape( value, skip = "" )
+ value.gsub( /\\/, "\\\\\\" ).
+ gsub( /"/, "\\\"" ).
+ gsub( /([\x00-\x1f])/ ) do |x|
+ skip[x] || ESCAPES[ x.unpack("C")[0] ]
+ end
+ end
+
+ #
+ # Unescape the condenses escapes
+ #
+ def YAML.unescape( value )
+ value.gsub( /\\(?:([nevfbart\\])|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
+
+end
View
34 src/builtin/yaml/error.rb
@@ -0,0 +1,34 @@
+#
+# Error messages and exception class
+#
+
+module YAML
+
+ #
+ # 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"
+
+ #
+ # YAML Error classes
+ #
+
+ class Error < StandardError; end
+ class ParseError < Error; end
+ class TypeError < StandardError; end
+
+end
View
458 src/builtin/yaml/rubytypes.rb
@@ -0,0 +1,458 @@
+# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
+require 'date'
+require 'yaml/compat'
+
+# For Compatibility with Syck 0.60
+# class Module
+# yaml_as "tag:ruby.yaml.org,2002:module"
+
+# def Module.yaml_new( klass, tag, val )
+# if String === val
+# val.split(/::/).inject(Object) do |m, n|
+# begin
+# m.const_get(n)
+# rescue NameError
+# raise ArgumentError, "undefined class/module #{n} in #{val}"
+# end
+# end
+# else
+# raise YAML::TypeError, "Invalid Module: " + val.inspect
+# end
+# end
+
+# def to_yaml( opts = {} )
+# YAML::quick_emit( nil, opts ) { |out|
+# out.scalar( "tag:ruby.yaml.org,2002:module", self.name, :plain )
+# }
+# end
+# end
+
+# class Class
+# yaml_as "tag:ruby.yaml.org,2002:class"
+
+# def Class.yaml_new( klass, tag, val )
+# if String === val
+# val.split(/::/).inject(Object) do |m, n|
+# begin
+# m.const_get(n)
+# rescue NameError
+# raise ArgumentError, "undefined class/module #{n} in #{val}"
+# end
+# end
+# else
+# raise YAML::TypeError, "Invalid Class: " + val.inspect
+# end
+# end
+
+# def to_yaml( opts = {} )
+# YAML::quick_emit( nil, opts ) { |out|
+# out.scalar( "tag:ruby.yaml.org,2002:class", self.name, :plain )
+# }
+# end
+# end
+
+class Class
+ def to_yaml( opts = {} )
+ raise TypeError, "can't dump anonymous class %s" % self.class
+ end
+end
+
+class Object
+ yaml_as "tag:ruby.yaml.org,2002:object"