From eb71e5cd67f4ce4da5ba331f93a8e36c65457b94 Mon Sep 17 00:00:00 2001 From: tenderlove Date: Sat, 3 Apr 2010 21:50:47 +0000 Subject: * lib/yaml: Moved to ext/syck/lib, Syck only uses Syck constant. * lib/yaml.rb: Added an engine manager for choosing YAML engine. * ext/syck/lib/syck/rubytypes.rb: squashed warnings when using Psych git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27212 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 + ext/syck/lib/syck.rb | 456 ++++++++++++++++++++++++++++++++++++ ext/syck/lib/syck/baseemitter.rb | 242 ++++++++++++++++++++ ext/syck/lib/syck/basenode.rb | 223 ++++++++++++++++++ ext/syck/lib/syck/constants.rb | 45 ++++ ext/syck/lib/syck/dbm.rb | 111 +++++++++ ext/syck/lib/syck/encoding.rb | 35 +++ ext/syck/lib/syck/error.rb | 34 +++ ext/syck/lib/syck/loader.rb | 14 ++ ext/syck/lib/syck/rubytypes.rb | 464 +++++++++++++++++++++++++++++++++++++ ext/syck/lib/syck/store.rb | 43 ++++ ext/syck/lib/syck/stream.rb | 41 ++++ ext/syck/lib/syck/stringio.rb | 85 +++++++ ext/syck/lib/syck/syck.rb | 17 ++ ext/syck/lib/syck/tag.rb | 92 ++++++++ ext/syck/lib/syck/types.rb | 192 ++++++++++++++++ ext/syck/lib/syck/yamlnode.rb | 54 +++++ ext/syck/lib/syck/ypath.rb | 54 +++++ ext/syck/rubyext.c | 10 +- ext/syck/syck.h | 1 - lib/yaml.rb | 470 ++------------------------------------ lib/yaml/baseemitter.rb | 242 -------------------- lib/yaml/basenode.rb | 223 ------------------ lib/yaml/constants.rb | 45 ---- lib/yaml/dbm.rb | 111 --------- lib/yaml/encoding.rb | 35 --- lib/yaml/error.rb | 34 --- lib/yaml/loader.rb | 14 -- lib/yaml/rubytypes.rb | 446 ------------------------------------ lib/yaml/store.rb | 43 ---- lib/yaml/stream.rb | 41 ---- lib/yaml/stringio.rb | 85 ------- lib/yaml/syck.rb | 19 -- lib/yaml/tag.rb | 92 -------- lib/yaml/types.rb | 192 ---------------- lib/yaml/yamlnode.rb | 54 ----- lib/yaml/ypath.rb | 54 ----- test/psych/test_engine_manager.rb | 57 +++++ test/yaml/test_engine_manager.rb | 3 + test/yaml/test_yaml.rb | 2 +- test/yaml/test_yamlstore.rb | 2 +- 41 files changed, 2299 insertions(+), 2184 deletions(-) create mode 100644 ext/syck/lib/syck.rb create mode 100644 ext/syck/lib/syck/baseemitter.rb create mode 100644 ext/syck/lib/syck/basenode.rb create mode 100644 ext/syck/lib/syck/constants.rb create mode 100644 ext/syck/lib/syck/dbm.rb create mode 100644 ext/syck/lib/syck/encoding.rb create mode 100644 ext/syck/lib/syck/error.rb create mode 100644 ext/syck/lib/syck/loader.rb create mode 100644 ext/syck/lib/syck/rubytypes.rb create mode 100644 ext/syck/lib/syck/store.rb create mode 100644 ext/syck/lib/syck/stream.rb create mode 100644 ext/syck/lib/syck/stringio.rb create mode 100644 ext/syck/lib/syck/syck.rb create mode 100644 ext/syck/lib/syck/tag.rb create mode 100644 ext/syck/lib/syck/types.rb create mode 100644 ext/syck/lib/syck/yamlnode.rb create mode 100644 ext/syck/lib/syck/ypath.rb delete mode 100644 lib/yaml/baseemitter.rb delete mode 100644 lib/yaml/basenode.rb delete mode 100644 lib/yaml/constants.rb delete mode 100644 lib/yaml/dbm.rb delete mode 100644 lib/yaml/encoding.rb delete mode 100644 lib/yaml/error.rb delete mode 100644 lib/yaml/loader.rb delete mode 100644 lib/yaml/rubytypes.rb delete mode 100644 lib/yaml/store.rb delete mode 100644 lib/yaml/stream.rb delete mode 100644 lib/yaml/stringio.rb delete mode 100644 lib/yaml/syck.rb delete mode 100644 lib/yaml/tag.rb delete mode 100644 lib/yaml/types.rb delete mode 100644 lib/yaml/yamlnode.rb delete mode 100644 lib/yaml/ypath.rb create mode 100644 test/psych/test_engine_manager.rb create mode 100644 test/yaml/test_engine_manager.rb diff --git a/ChangeLog b/ChangeLog index 762235eef5..0cfbd40e9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sun Apr 4 06:46:16 2010 Aaron Patterson + + * lib/yaml: Moved to ext/syck/lib, Syck only uses Syck constant. + * lib/yaml.rb: Added an engine manager for choosing YAML engine. + * ext/syck/lib/syck/rubytypes.rb: squashed warnings when using Psych + Sat Apr 3 22:47:51 2010 Tanaka Akira * time.c: don't define STRUCT_WIDEVAL. diff --git a/ext/syck/lib/syck.rb b/ext/syck/lib/syck.rb new file mode 100644 index 0000000000..0f43c139bc --- /dev/null +++ b/ext/syck/lib/syck.rb @@ -0,0 +1,456 @@ +# -*- 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 'syck.so' +require 'syck/error' +require 'syck/syck' +require 'syck/tag' +require 'syck/stream' +require 'syck/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 Syck. Serialized nodes are available in the extension as +# SyckNode 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 Syck + + DefaultResolver.use_types_at( @@tagged_classes ) + + # Returns a new default parser + def self.parser; Parser.new.set_resolver( self.resolver ); end + + # Returns a new generic parser + def self.generic_parser + warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE + Parser.new.set_resolver( GenericResolver ) + end + + # Returns the default resolver + def self.resolver + warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE + DefaultResolver + end + + # Returns a new default emitter + def self.emitter + warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE + Emitter.new.set_resolver( self.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 self.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 self.load( io ) + yp = parser.load( io ) + end + + # + # Load a document from the file located at _filepath_. + # + # YAML.load_file( 'animals.yaml' ) + # #=> ['badger', 'elephant', 'tiger'] + # + def self.load_file( filepath ) + File.open( filepath ) do |f| + load( f ) + end + end + + # + # Parse the first document from the current _io_ stream + # + # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } + # #=> #, + # #, + # #]> + # + # Can also load from a string. + # + # YAML.parse( "--- :locked" ) + # #=> # + # + def self.parse( io ) + yp = generic_parser.load( io ) + end + + # + # Parse a document from the file located at _filepath_. + # + # YAML.parse_file( 'animals.yaml' ) + # #=> #, + # #, + # #]> + # + def self.parse_file( filepath ) + File.open( filepath ) do |f| + parse( f ) + 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 self.each_document( io, &block ) + warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE + 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 self.load_documents( io, &doc_proc ) + yp = 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_. + # + # 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 self.each_node( io, &doc_proc ) + warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE + 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_. + # + # 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 self.parse_documents( io, &doc_proc ) + warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE + self.each_node( io, &doc_proc ) + end + + # + # Loads all documents from the current _io_ stream, + # returning a +YAML::Stream+ object containing all + # loaded documents. + # + def self.load_stream( io ) + d = nil + parser.load_documents( io ) do |doc| + d = Stream.new if not d + d.add( doc ) + end + 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 self.dump_stream( *objs ) + d = Stream.new + objs.each do |doc| + d.add( doc ) + end + d.emit + end + + # + # Add a global handler for a YAML domain type. + # + def self.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 self.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 self.add_ruby_type( type_tag, &transfer_proc ) + warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE + resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc ) + end + + # + # Add a private document type + # + def self.add_private_type( type_re, &transfer_proc ) + warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE + resolver.add_type( "x-private:" + type_re, transfer_proc ) + end + + # + # Detect typing of a string + # + def self.detect_implicit( val ) + warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE + resolver.detect_implicit( val ) + end + + # + # Convert a type_id to a taguri + # + def self.tagurize( val ) + warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE + resolver.tagurize( val ) + end + + # + # Apply a transfer method to a Ruby object + # + def self.transfer( type_id, obj ) + warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE + resolver.transfer( tagurize( type_id ), obj ) + end + + # + # Apply any implicit a node may qualify for + # + def self.try_implicit( obj ) + warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE + transfer( detect_implicit( obj ), obj ) + end + + # + # Method to extract colon-seperated type and class, returning + # the type and the constant of the class + # + def self.read_type_class( type, obj_class ) + warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE + 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 + + # + # Allocate blank object + # + def self.object_maker( obj_class, val ) + warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE + if Hash === val + o = obj_class.allocate + val.each_pair { |k,v| + o.instance_variable_set("@#{k}", v) + } + o + else + raise Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect + end + end + + # + # Allocate an Emitter if needed + # + def self.quick_emit( oid, opts = {}, &e ) + warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE + out = + if opts.is_a? Emitter + opts + else + emitter.reset( opts ) + end + out.emit( oid, &e ) + end + +end + +require 'syck/rubytypes' +require 'syck/types' + +module Kernel + # + # 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. + # + + # 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 + + diff --git a/ext/syck/lib/syck/baseemitter.rb b/ext/syck/lib/syck/baseemitter.rb new file mode 100644 index 0000000000..5e39e450de --- /dev/null +++ b/ext/syck/lib/syck/baseemitter.rb @@ -0,0 +1,242 @@ +# +# BaseEmitter +# + +require 'syck/constants' +require 'syck/encoding' +require 'syck/error' + +module Syck + module BaseEmitter + def options( opt = nil ) + if opt + @options[opt] || 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 =~ /#{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( Syck.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 ) + "\"#{Syck.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 + $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 diff --git a/ext/syck/lib/syck/basenode.rb b/ext/syck/lib/syck/basenode.rb new file mode 100644 index 0000000000..fc701a99f3 --- /dev/null +++ b/ext/syck/lib/syck/basenode.rb @@ -0,0 +1,223 @@ +# +# YAML::BaseNode class +# + +module Syck + + # + # YAML Generic Model container + # + module BaseNode + + # + # Search for YPath entry and return + # qualified nodes. + # + def select( ypath_str ) + warn "#{caller[0]}: select is deprecated" if $VERBOSE + matches = match_path( ypath_str ) + + # + # Create a new generic view of the elements selected + # + if matches + result = [] + matches.each { |m| + result.push m.last + } + Syck.transfer( 'seq', result ) + end + end + + # + # Search for YPath entry and return + # transformed nodes. + # + def select!( ypath_str ) + warn "#{caller[0]}: select!() is deprecated" if $VERBOSE + 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 ) + warn "#{caller[0]}: search() is deprecated" if $VERBOSE + 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 ) + warn "#{caller[0]}: at() is deprecated" if $VERBOSE + 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 ) + warn "#{caller[0]}: match_path is deprecated" if $VERBOSE + require 'yaml/ypath' + 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 ) + warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE + 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,| 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 + warn "#{caller[0]}: children_with_index is deprecated, use children" if $VERBOSE + 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 + diff --git a/ext/syck/lib/syck/constants.rb b/ext/syck/lib/syck/constants.rb new file mode 100644 index 0000000000..19fe42ef85 --- /dev/null +++ b/ext/syck/lib/syck/constants.rb @@ -0,0 +1,45 @@ +# +# Constants used throughout the library +# +module Syck + + # + # 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 diff --git a/ext/syck/lib/syck/dbm.rb b/ext/syck/lib/syck/dbm.rb new file mode 100644 index 0000000000..95611afb04 --- /dev/null +++ b/ext/syck/lib/syck/dbm.rb @@ -0,0 +1,111 @@ +require 'syck' +require 'dbm' +# +# YAML + DBM = YDBM +# - Same interface as DBM class +# +module Syck + +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 Syck.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 = Syck.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 Syck.load( v ) } + self + end + def values + super.collect { |v| Syck.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] = Syck.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 diff --git a/ext/syck/lib/syck/encoding.rb b/ext/syck/lib/syck/encoding.rb new file mode 100644 index 0000000000..dad062994c --- /dev/null +++ b/ext/syck/lib/syck/encoding.rb @@ -0,0 +1,35 @@ +# +# Handle Unicode-to-Internal conversion +# + +module Syck + + # + # Escape the string, condensing common escapes + # + def self.escape( value, skip = "" ) + warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE + value.gsub( /\\/, "\\\\\\" ). + gsub( /"/, "\\\"" ). + gsub( /([\x00-\x1f])/ ) do + skip[$&] || ESCAPES[ $&.unpack("C")[0] ] + end + end + + # + # Unescape the condenses escapes + # + def self.unescape( value ) + warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE + value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { + if $3 + ["#$3".hex ].pack('U*') + elsif $2 + [$2].pack( "H2" ) + else + UNESCAPES[$1] + end + } + end + +end diff --git a/ext/syck/lib/syck/error.rb b/ext/syck/lib/syck/error.rb new file mode 100644 index 0000000000..0bac872411 --- /dev/null +++ b/ext/syck/lib/syck/error.rb @@ -0,0 +1,34 @@ +# +# Error messages and exception class +# + +module Syck + + # + # 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 diff --git a/ext/syck/lib/syck/loader.rb b/ext/syck/lib/syck/loader.rb new file mode 100644 index 0000000000..925c9ee4b2 --- /dev/null +++ b/ext/syck/lib/syck/loader.rb @@ -0,0 +1,14 @@ +# +# YAML::Loader class +# .. type handling .. +# +module Syck + class Loader + TRANSFER_DOMAINS = { + 'yaml.org,2002' => {}, + 'ruby.yaml.org,2002' => {} + } + PRIVATE_TYPES = {} + IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ] + end +end diff --git a/ext/syck/lib/syck/rubytypes.rb b/ext/syck/lib/syck/rubytypes.rb new file mode 100644 index 0000000000..6b2937bba0 --- /dev/null +++ b/ext/syck/lib/syck/rubytypes.rb @@ -0,0 +1,464 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +require 'date' + +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" + def to_yaml_style; end + def to_yaml_properties; instance_variables.sort; end + def to_yaml( opts = {} ) + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end + alias :syck_to_yaml :to_yaml +end + +class Hash + yaml_as "tag:ruby.yaml.org,2002:hash" + yaml_as "tag:yaml.org,2002:map" + def yaml_initialize( tag, val ) + if Array === val + update Hash.[]( *val ) # Convert the map to a sequence + elsif Hash === val + update val + else + raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + each do |k, v| + map.add( k, v ) + end + end + end + end +end + +class Struct + yaml_as "tag:ruby.yaml.org,2002:struct" + def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end + def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end + def self.yaml_new( klass, tag, val ) + if Hash === val + struct_type = nil + + # + # Use existing Struct if it exists + # + props = {} + val.delete_if { |k,v| props[k] = v if k =~ /^@/ } + begin + struct_name, struct_type = YAML.read_type_class( tag, Struct ) + rescue NameError + end + if not struct_type + struct_def = [ tag.split( ':', 4 ).last ] + struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) + end + + # + # Set the Struct properties + # + st = YAML::object_maker( struct_type, {} ) + st.members.each do |m| + st.send( "#{m}=", val[m.to_s] ) + end + props.each do |k,v| + st.instance_variable_set(k, v) + end + st + else + raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + # + # Basic struct is passed as a YAML map + # + out.map( taguri, to_yaml_style ) do |map| + self.members.each do |m| + map.add( m.to_s, self[m.to_s] ) + end + self.to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end +end + +class Array + yaml_as "tag:ruby.yaml.org,2002:array" + yaml_as "tag:yaml.org,2002:seq" + def yaml_initialize( tag, val ); concat( val.to_a ); end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + each do |x| + seq.add( x ) + end + end + end + end +end + +class Exception + yaml_as "tag:ruby.yaml.org,2002:exception" + def Exception.yaml_new( klass, tag, val ) + o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } ) + val.each_pair do |k,v| + o.instance_variable_set("@#{k}", v) + end + o + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + map.add( 'message', message ) + to_yaml_properties.each do |m| + map.add( m[1..-1], instance_variable_get( m ) ) + end + end + end + end +end + +class String + yaml_as "tag:ruby.yaml.org,2002:string" + yaml_as "tag:yaml.org,2002:binary" + yaml_as "tag:yaml.org,2002:str" + def is_complex_yaml? + to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/ + end + def is_binary_data? + self.count("^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty? + end + def String.yaml_new( klass, tag, val ) + val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary" + val = { 'str' => val } if String === val + if Hash === val + s = klass.allocate + # Thank you, NaHi + String.instance_method(:initialize). + bind(s). + call( val.delete( 'str' ) ) + val.each { |k,v| s.instance_variable_set( k, v ) } + s + else + raise YAML::TypeError, "Invalid String: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out| + if is_binary_data? + out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal ) + elsif to_yaml_properties.empty? + out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'str', "#{self}" ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Symbol + yaml_as "tag:ruby.yaml.org,2002:symbol" + yaml_as "tag:ruby.yaml.org,2002:sym" + def Symbol.yaml_new( klass, tag, val ) + if String === val + val = YAML::load( val ) if val =~ /\A(["']).*\1\z/ + val.intern + else + raise YAML::TypeError, "Invalid Symbol: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain ) + end + end +end + +class Range + yaml_as "tag:ruby.yaml.org,2002:range" + def Range.yaml_new( klass, tag, val ) + inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")' + opts = {} + if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o + r1, rdots, r2 = $1, $2, $3 + opts = { + 'begin' => YAML.load( "--- #{r1}" ), + 'end' => YAML.load( "--- #{r2}" ), + 'excl' => rdots.length == 3 + } + val = {} + elsif Hash === val + opts['begin'] = val.delete('begin') + opts['end'] = val.delete('end') + opts['excl'] = val.delete('excl') + end + if Hash === opts + r = YAML::object_maker( klass, {} ) + # Thank you, NaHi + Range.instance_method(:initialize). + bind(r). + call( opts['begin'], opts['end'], opts['excl'] ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Range: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or + # self.end.is_complex_yaml? or self.end.respond_to? :to_str or + # not to_yaml_properties.empty? + out.map( taguri, to_yaml_style ) do |map| + map.add( 'begin', self.begin ) + map.add( 'end', self.end ) + map.add( 'excl', self.exclude_end? ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + # else + # out.scalar( taguri ) do |sc| + # sc.embed( self.begin ) + # sc.concat( self.exclude_end? ? "..." : ".." ) + # sc.embed( self.end ) + # end + # end + end + end +end + +class Regexp + yaml_as "tag:ruby.yaml.org,2002:regexp" + def Regexp.yaml_new( klass, tag, val ) + if String === val and val =~ /^\/(.*)\/([mix]*)$/ + val = { 'regexp' => $1, 'mods' => $2 } + end + if Hash === val + mods = nil + unless val['mods'].to_s.empty? + mods = 0x00 + mods |= Regexp::EXTENDED if val['mods'].include?( 'x' ) + mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' ) + mods |= Regexp::MULTILINE if val['mods'].include?( 'm' ) + end + val.delete( 'mods' ) + r = YAML::object_maker( klass, {} ) + Regexp.instance_method(:initialize). + bind(r). + call( val.delete( 'regexp' ), mods ) + val.each { |k,v| r.instance_variable_set( k, v ) } + r + else + raise YAML::TypeError, "Invalid Regular expression: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + if to_yaml_properties.empty? + out.scalar( taguri, self.inspect, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + src = self.inspect + if src =~ /\A\/(.*)\/([a-z]*)\Z/ + map.add( 'regexp', $1 ) + map.add( 'mods', $2 ) + else + raise YAML::TypeError, "Invalid Regular expression: " + src + end + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Time + yaml_as "tag:ruby.yaml.org,2002:time" + yaml_as "tag:yaml.org,2002:timestamp" + def Time.yaml_new( klass, tag, val ) + if Hash === val + t = val.delete( 'at' ) + val.each { |k,v| t.instance_variable_set( k, v ) } + t + else + raise YAML::TypeError, "Invalid Time: " + val.inspect + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |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 + standard = self.strftime( "%Y-%m-%d %H:%M:%S" ) + standard += ".%06d" % [usec] if usec.nonzero? + standard += " %s" % [tz] + if to_yaml_properties.empty? + out.scalar( taguri, standard, :plain ) + else + out.map( taguri, to_yaml_style ) do |map| + map.add( 'at', standard ) + to_yaml_properties.each do |m| + map.add( m, instance_variable_get( m ) ) + end + end + end + end + end +end + +class Date + yaml_as "tag:yaml.org,2002:timestamp#ymd" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain ) + end + end +end + +class Integer + yaml_as "tag:yaml.org,2002:int" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain ) + end + end +end + +class Float + yaml_as "tag:yaml.org,2002:float" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + str = self.to_s + if str == "Infinity" + str = ".Inf" + elsif str == "-Infinity" + str = "-.Inf" + elsif str == "NaN" + str = ".NaN" + end + out.scalar( "tag:yaml.org,2002:float", str, :plain ) + end + end +end + +class Rational + yaml_as "tag:ruby.yaml.org,2002:object:Rational" + def Rational.yaml_new( klass, tag, val ) + if val.is_a? String + Rational( val ) + else + Rational( val['numerator'], val['denominator'] ) + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, nil ) do |map| + map.add( 'denominator', denominator ) + map.add( 'numerator', numerator ) + end + end + end +end + +class Complex + yaml_as "tag:ruby.yaml.org,2002:object:Complex" + def Complex.yaml_new( klass, tag, val ) + if val.is_a? String + Complex( val ) + else + Complex( val['real'], val['image'] ) + end + end + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( self, opts ) do |out| + out.map( taguri, nil ) do |map| + map.add( 'image', imaginary ) + map.add( 'real', real ) + end + end + end +end + +class TrueClass + yaml_as "tag:yaml.org,2002:bool#yes" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "true", :plain ) + end + end +end + +class FalseClass + yaml_as "tag:yaml.org,2002:bool#no" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "false", :plain ) + end + end +end + +class NilClass + yaml_as "tag:yaml.org,2002:null" + def to_yaml( opts = {} ) + return super unless YAML::ENGINE.syck? + YAML::quick_emit( nil, opts ) do |out| + out.scalar( taguri, "", :plain ) + end + end +end + diff --git a/ext/syck/lib/syck/store.rb b/ext/syck/lib/syck/store.rb new file mode 100644 index 0000000000..8f27cf49c0 --- /dev/null +++ b/ext/syck/lib/syck/store.rb @@ -0,0 +1,43 @@ +# +# YAML::Store +# +require 'syck' +require 'pstore' + +class Syck::Store < PStore + def initialize( *o ) + @opt = Syck::DEFAULTS.dup + if String === o.first + super(o.shift) + end + if o.last.is_a? Hash + @opt.update(o.pop) + end + end + + def dump(table) + @table.to_yaml(@opt) + end + + def load(content) + table = Syck::load(content) + if table == false + {} + else + table + end + end + + def marshal_dump_supports_canonical_option? + false + end + + EMPTY_MARSHAL_DATA = {}.to_yaml + EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA) + def empty_marshal_data + EMPTY_MARSHAL_DATA + end + def empty_marshal_checksum + EMPTY_MARSHAL_CHECKSUM + end +end diff --git a/ext/syck/lib/syck/stream.rb b/ext/syck/lib/syck/stream.rb new file mode 100644 index 0000000000..cd77a033c6 --- /dev/null +++ b/ext/syck/lib/syck/stream.rb @@ -0,0 +1,41 @@ +module Syck + + # + # 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 ) + warn "#{caller[0]}: edit is deprecated" if $VERBOSE + @documents[ doc_num ] = doc + end + + def emit( io = nil ) + # opts = @options.dup + # opts[:UseHeader] = true if @documents.length > 1 + out = Syck.emitter + out.reset( io || io2 = StringIO.new ) + @documents.each { |v| + v.to_yaml( out ) + } + io || ( io2.rewind; io2.read ) + end + + end + +end diff --git a/ext/syck/lib/syck/stringio.rb b/ext/syck/lib/syck/stringio.rb new file mode 100644 index 0000000000..77a2b827e5 --- /dev/null +++ b/ext/syck/lib/syck/stringio.rb @@ -0,0 +1,85 @@ +warn "#{caller[0]}: yaml/stringio is deprecated" if $VERBOSE + +# +# Limited StringIO if no core lib is available +# +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 + + # + # Class method for creating streams + # + def Syck.make_stream( io ) + if String === io + io = StringIO.new( io ) + elsif not IO === io + raise Syck::Error, "YAML stream must be an IO or String object." + end + if Syck::unicode + def io.readline + Syck.utf_to_internal( readline( @ln_sep ), @utf_encoding ) + end + def io.check_unicode + @utf_encoding = Syck.sniff_encoding( read( 4 ) ) + @ln_sep = Syck.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 + +end + diff --git a/ext/syck/lib/syck/syck.rb b/ext/syck/lib/syck/syck.rb new file mode 100644 index 0000000000..2bd44e9f2a --- /dev/null +++ b/ext/syck/lib/syck/syck.rb @@ -0,0 +1,17 @@ +# +# YAML::Syck module +# .. glues syck and yaml.rb together .. +# +require 'syck' +require 'syck/basenode' + +module Syck + + # + # Mixin BaseNode functionality + # + class Node + include Syck::BaseNode + end + +end diff --git a/ext/syck/lib/syck/tag.rb b/ext/syck/lib/syck/tag.rb new file mode 100644 index 0000000000..bfb4dc714d --- /dev/null +++ b/ext/syck/lib/syck/tag.rb @@ -0,0 +1,92 @@ +# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 +# $Id$ +# +# = yaml/tag.rb: methods for associating a taguri to a class. +# +# Author:: why the lucky stiff +# +module Syck + # 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 self.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 + 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 + # + def self.tagged_classes + @@tagged_classes + end +end + +class Module + # :stopdoc: + + # 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 + Syck.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 != Syck.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 + Syck.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 + end + # :startdoc: +end diff --git a/ext/syck/lib/syck/types.rb b/ext/syck/lib/syck/types.rb new file mode 100644 index 0000000000..5c129acba4 --- /dev/null +++ b/ext/syck/lib/syck/types.rb @@ -0,0 +1,192 @@ +# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4 +# +# Classes required by the full core typeset +# + +module Syck + + # + # Default private type + # + class PrivateType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( type, val ) + @type_id = type; @value = val + @value.taguri = "x-private:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Default domain type + # + class DomainType + def self.tag_subclasses?; false; end + verbose, $VERBOSE = $VERBOSE, nil + def initialize( domain, type, val ) + @domain = domain; @type_id = type; @value = val + @value.taguri = "tag:#{ @domain }:#{ @type_id }" + end + def to_yaml( opts = {} ) + @value.to_yaml( opts ) + end + ensure + $VERBOSE = verbose + end + + # + # Unresolved objects + # + class Object + def self.tag_subclasses?; false; end + def to_yaml( opts = {} ) + Syck.quick_emit( self, 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 + end + end + 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 Syck::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 + yaml_as "tag:yaml.org,2002:omap" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise Syck::Error, "Invalid !omap entry: " + val.inspect + end + end + else + raise Syck::Error, "Invalid !omap: " + val.inspect + end + self + end + def self.[]( *vals ) + o = Omap.new + 0.step( vals.length - 1, 2 ) do |i| + o[vals[i]] = vals[i+1] + end + 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 = {} ) + Syck.quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !pairs + # + class Pairs < ::Array + yaml_as "tag:yaml.org,2002:pairs" + def yaml_initialize( tag, val ) + if Array === val + val.each do |v| + if Hash === v + concat( v.to_a ) # Convert the map to a sequence + else + raise Syck::Error, "Invalid !pairs entry: " + val.inspect + end + end + else + raise Syck::Error, "Invalid !pairs: " + val.inspect + end + self + end + 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 = {} ) + Syck.quick_emit( self, opts ) do |out| + out.seq( taguri, to_yaml_style ) do |seq| + self.each do |v| + seq.add( Hash[ *v ] ) + end + end + end + end + end + + # + # Builtin collection: !set + # + class Set < ::Hash + yaml_as "tag:yaml.org,2002:set" + end +end diff --git a/ext/syck/lib/syck/yamlnode.rb b/ext/syck/lib/syck/yamlnode.rb new file mode 100644 index 0000000000..2fa57b1f97 --- /dev/null +++ b/ext/syck/lib/syck/yamlnode.rb @@ -0,0 +1,54 @@ +# +# YAML::YamlNode class +# +require 'syck/basenode' + +module Syck + + # + # YAML Generic Model container + # + class YamlNode + include BaseNode + attr_accessor :kind, :type_id, :value, :anchor + def initialize(t, v) + @type_id = t + if Hash === v + @kind = 'map' + @value = {} + v.each {|key,val| + @value[key.transform] = [key, val] + } + elsif Array === v + @kind = 'seq' + @value = v + elsif String === v + @kind = 'scalar' + @value = v + end + 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 + Syck.transfer_method( @type_id, t ) + end + + end + +end diff --git a/ext/syck/lib/syck/ypath.rb b/ext/syck/lib/syck/ypath.rb new file mode 100644 index 0000000000..024dcb7f4e --- /dev/null +++ b/ext/syck/lib/syck/ypath.rb @@ -0,0 +1,54 @@ +# +# YAML::YPath +# + +warn "#{caller[0]}: YAML::YPath is deprecated" if $VERBOSE + +module Syck + + 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 self.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 + +end diff --git a/ext/syck/rubyext.c b/ext/syck/rubyext.c index 2f78b6ddaf..da741d687c 100644 --- a/ext/syck/rubyext.c +++ b/ext/syck/rubyext.c @@ -2111,9 +2111,7 @@ syck_out_scalar(int argc, VALUE *argv, VALUE self) void Init_syck() { - VALUE rb_yaml = rb_define_module( "YAML" ); - VALUE rb_syck = rb_define_module_under( rb_yaml, "Syck" ); - rb_define_const( rb_syck, "VERSION", rb_str_new2( SYCK_VERSION ) ); + VALUE rb_syck = rb_define_module_under( rb_cObject, "Syck" ); rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 ); /* @@ -2258,7 +2256,7 @@ Init_syck() /* * Define YAML::PrivateType class */ - cPrivateType = rb_define_class_under( rb_yaml, "PrivateType", rb_cObject ); + cPrivateType = rb_define_class_under( rb_syck, "PrivateType", rb_cObject ); rb_define_attr( cPrivateType, "type_id", 1, 1 ); rb_define_attr( cPrivateType, "value", 1, 1 ); rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2); @@ -2266,7 +2264,7 @@ Init_syck() /* * Define YAML::DomainType class */ - cDomainType = rb_define_class_under( rb_yaml, "DomainType", rb_cObject ); + cDomainType = rb_define_class_under( rb_syck, "DomainType", rb_cObject ); rb_define_attr( cDomainType, "domain", 1, 1 ); rb_define_attr( cDomainType, "type_id", 1, 1 ); rb_define_attr( cDomainType, "value", 1, 1 ); @@ -2275,7 +2273,7 @@ Init_syck() /* * Define YAML::Object class */ - cYObject = rb_define_class_under( rb_yaml, "Object", rb_cObject ); + cYObject = rb_define_class_under( rb_syck, "Object", rb_cObject ); rb_define_attr( cYObject, "class", 1, 1 ); rb_define_attr( cYObject, "ivars", 1, 1 ); rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2); diff --git a/ext/syck/syck.h b/ext/syck/syck.h index 81b3d67952..488d27e54a 100644 --- a/ext/syck/syck.h +++ b/ext/syck/syck.h @@ -12,7 +12,6 @@ #define SYCK_YAML_MAJOR 1 #define SYCK_YAML_MINOR 0 -#define SYCK_VERSION "0.60" #define YAML_DOMAIN "yaml.org,2002" #include diff --git a/lib/yaml.rb b/lib/yaml.rb index d9802abd76..28e13fe05f 100644 --- a/lib/yaml.rb +++ b/lib/yaml.rb @@ -1,460 +1,40 @@ -# -*- 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/error' -require 'yaml/syck' -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 Syck. Serialized nodes are available in the extension as -# SyckNode 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 + class EngineManager # :nodoc: + attr_reader :yamler - Resolver = YAML::Syck::Resolver - DefaultResolver = YAML::Syck::DefaultResolver - DefaultResolver.use_types_at( @@tagged_classes ) - GenericResolver = YAML::Syck::GenericResolver - Parser = YAML::Syck::Parser - Emitter = YAML::Syck::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 - warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE - Parser.new.set_resolver( GenericResolver ) - end - - # Returns the default resolver - def YAML.resolver - warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE - DefaultResolver - end - - # Returns a new default emitter - def YAML.emitter - warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE - 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 - - # - # 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 - - # - # Parse the first document from the current _io_ stream - # - # File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) } - # #=> #, - # #, - # #]> - # - # Can also load from a string. - # - # YAML.parse( "--- :locked" ) - # #=> # - # - def YAML.parse( io ) - yp = generic_parser.load( io ) - end - - # - # Parse a document from the file located at _filepath_. - # - # YAML.parse_file( 'animals.yaml' ) - # #=> #, - # #, - # #]> - # - def YAML.parse_file( filepath ) - File.open( filepath ) do |f| - parse( f ) - end + def initialize + @yamler = nil 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 ) - warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE - yp = parser.load_documents( io, &block ) + def syck? + 'syck' == @yamler 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 ) - yp = parser.load_documents( io, &doc_proc ) - end + def yamler= engine + raise(ArgumentError, "bad engine") unless %w{syck psych}.include?(engine) - # - # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for - # each consecutive document in the YAML stream contained in _io_. - # - # 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 ) - warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE - yp = generic_parser.load_documents( io, &doc_proc ) - end + @yamler = engine + require engine - # - # Calls _block_ with a tree of +YAML::BaseNodes+, one tree for - # each consecutive document in the YAML stream contained in _io_. - # - # 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 ) - warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE - YAML.each_node( io, &doc_proc ) + Object.class_eval <<-eorb, __FILE__, __LINE__ + 1 + remove_const 'YAML' + YAML = #{engine.capitalize} + remove_method :to_yaml + alias :to_yaml :#{engine}_to_yaml + eorb + engine end + 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 - 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 - 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 ) - warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE - 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 ) - warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE - resolver.add_type( "x-private:" + type_re, transfer_proc ) - end - - # - # Detect typing of a string - # - def YAML.detect_implicit( val ) - warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE - resolver.detect_implicit( val ) - end - - # - # Convert a type_id to a taguri - # - def YAML.tagurize( val ) - warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE - resolver.tagurize( val ) - end - - # - # Apply a transfer method to a Ruby object - # - def YAML.transfer( type_id, obj ) - warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE - resolver.transfer( YAML.tagurize( type_id ), obj ) - end - - # - # Apply any implicit a node may qualify for - # - def YAML.try_implicit( obj ) - warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE - YAML.transfer( YAML.detect_implicit( obj ), obj ) - 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 ) - warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE - 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 - - # - # Allocate blank object - # - def YAML.object_maker( obj_class, val ) - warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE - 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 - end - - # - # Allocate an Emitter if needed - # - def YAML.quick_emit( oid, opts = {}, &e ) - warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE - out = - if opts.is_a? YAML::Emitter - opts - else - emitter.reset( opts ) - end - out.emit( oid, &e ) - end - + ENGINE = YAML::EngineManager.new end -require 'yaml/rubytypes' -require 'yaml/types' - -module Kernel - # - # 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. - # - - # 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 +module Syck + ENGINE = YAML::ENGINE end +module Psych + ENGINE = YAML::ENGINE +end +YAML::ENGINE.yamler = 'syck' diff --git a/lib/yaml/baseemitter.rb b/lib/yaml/baseemitter.rb deleted file mode 100644 index 59d9eddc76..0000000000 --- a/lib/yaml/baseemitter.rb +++ /dev/null @@ -1,242 +0,0 @@ -# -# 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 - $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 diff --git a/lib/yaml/basenode.rb b/lib/yaml/basenode.rb deleted file mode 100644 index f92f8c8c3a..0000000000 --- a/lib/yaml/basenode.rb +++ /dev/null @@ -1,223 +0,0 @@ -# -# YAML::BaseNode class -# - -module YAML - - # - # YAML Generic Model container - # - module BaseNode - - # - # Search for YPath entry and return - # qualified nodes. - # - def select( ypath_str ) - warn "#{caller[0]}: select is deprecated" if $VERBOSE - 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 ) - warn "#{caller[0]}: select!() is deprecated" if $VERBOSE - 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 ) - warn "#{caller[0]}: search() is deprecated" if $VERBOSE - 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 ) - warn "#{caller[0]}: at() is deprecated" if $VERBOSE - 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 ) - warn "#{caller[0]}: match_path is deprecated" if $VERBOSE - require 'yaml/ypath' - 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 ) - warn "#{caller[0]}: match_segment is deprecated" if $VERBOSE - 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,| 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 - warn "#{caller[0]}: children_with_index is deprecated, use children" if $VERBOSE - 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 - diff --git a/lib/yaml/constants.rb b/lib/yaml/constants.rb deleted file mode 100644 index 728d3b7932..0000000000 --- a/lib/yaml/constants.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# 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 diff --git a/lib/yaml/dbm.rb b/lib/yaml/dbm.rb deleted file mode 100644 index a28fd04f19..0000000000 --- a/lib/yaml/dbm.rb +++ /dev/null @@ -1,111 +0,0 @@ -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 diff --git a/lib/yaml/encoding.rb b/lib/yaml/encoding.rb deleted file mode 100644 index 0a1b1fce24..0000000000 --- a/lib/yaml/encoding.rb +++ /dev/null @@ -1,35 +0,0 @@ -# -# Handle Unicode-to-Internal conversion -# - -module YAML - - # - # Escape the string, condensing common escapes - # - def YAML.escape( value, skip = "" ) - warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE - value.gsub( /\\/, "\\\\\\" ). - gsub( /"/, "\\\"" ). - gsub( /([\x00-\x1f])/ ) do - skip[$&] || ESCAPES[ $&.unpack("C")[0] ] - end - end - - # - # Unescape the condenses escapes - # - def YAML.unescape( value ) - warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE - value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { - if $3 - ["#$3".hex ].pack('U*') - elsif $2 - [$2].pack( "H2" ) - else - UNESCAPES[$1] - end - } - end - -end diff --git a/lib/yaml/error.rb b/lib/yaml/error.rb deleted file mode 100644 index 75de0ec18a..0000000000 --- a/lib/yaml/error.rb +++ /dev/null @@ -1,34 +0,0 @@ -# -# 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 diff --git a/lib/yaml/loader.rb b/lib/yaml/loader.rb deleted file mode 100644 index eb0709e103..0000000000 --- a/lib/yaml/loader.rb +++ /dev/null @@ -1,14 +0,0 @@ -# -# YAML::Loader class -# .. type handling .. -# -module YAML - class Loader - TRANSFER_DOMAINS = { - 'yaml.org,2002' => {}, - 'ruby.yaml.org,2002' => {} - } - PRIVATE_TYPES = {} - IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ] - end -end diff --git a/lib/yaml/rubytypes.rb b/lib/yaml/rubytypes.rb deleted file mode 100644 index 71f911a738..0000000000 --- a/lib/yaml/rubytypes.rb +++ /dev/null @@ -1,446 +0,0 @@ -# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 -require 'date' - -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" - def to_yaml_style; end - def to_yaml_properties; instance_variables.sort; end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.map( taguri, to_yaml_style ) do |map| - to_yaml_properties.each do |m| - map.add( m[1..-1], instance_variable_get( m ) ) - end - end - end - end -end - -class Hash - yaml_as "tag:ruby.yaml.org,2002:hash" - yaml_as "tag:yaml.org,2002:map" - def yaml_initialize( tag, val ) - if Array === val - update Hash.[]( *val ) # Convert the map to a sequence - elsif Hash === val - update val - else - raise YAML::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.map( taguri, to_yaml_style ) do |map| - each do |k, v| - map.add( k, v ) - end - end - end - end -end - -class Struct - yaml_as "tag:ruby.yaml.org,2002:struct" - def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end - def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end - def self.yaml_new( klass, tag, val ) - if Hash === val - struct_type = nil - - # - # Use existing Struct if it exists - # - props = {} - val.delete_if { |k,v| props[k] = v if k =~ /^@/ } - begin - struct_name, struct_type = YAML.read_type_class( tag, Struct ) - rescue NameError - end - if not struct_type - struct_def = [ tag.split( ':', 4 ).last ] - struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) ) - end - - # - # Set the Struct properties - # - st = YAML::object_maker( struct_type, {} ) - st.members.each do |m| - st.send( "#{m}=", val[m.to_s] ) - end - props.each do |k,v| - st.instance_variable_set(k, v) - end - st - else - raise YAML::TypeError, "Invalid Ruby Struct: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - # - # Basic struct is passed as a YAML map - # - out.map( taguri, to_yaml_style ) do |map| - self.members.each do |m| - map.add( m.to_s, self[m.to_s] ) - end - self.to_yaml_properties.each do |m| - map.add( m, instance_variable_get( m ) ) - end - end - end - end -end - -class Array - yaml_as "tag:ruby.yaml.org,2002:array" - yaml_as "tag:yaml.org,2002:seq" - def yaml_initialize( tag, val ); concat( val.to_a ); end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.seq( taguri, to_yaml_style ) do |seq| - each do |x| - seq.add( x ) - end - end - end - end -end - -class Exception - yaml_as "tag:ruby.yaml.org,2002:exception" - def Exception.yaml_new( klass, tag, val ) - o = YAML.object_maker( klass, { 'mesg' => val.delete( 'message' ) } ) - val.each_pair do |k,v| - o.instance_variable_set("@#{k}", v) - end - o - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.map( taguri, to_yaml_style ) do |map| - map.add( 'message', message ) - to_yaml_properties.each do |m| - map.add( m[1..-1], instance_variable_get( m ) ) - end - end - end - end -end - -class String - yaml_as "tag:ruby.yaml.org,2002:string" - yaml_as "tag:yaml.org,2002:binary" - yaml_as "tag:yaml.org,2002:str" - def is_complex_yaml? - to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/ - end - def is_binary_data? - self.count("^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty? - end - def String.yaml_new( klass, tag, val ) - val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary" - val = { 'str' => val } if String === val - if Hash === val - s = klass.allocate - # Thank you, NaHi - String.instance_method(:initialize). - bind(s). - call( val.delete( 'str' ) ) - val.each { |k,v| s.instance_variable_set( k, v ) } - s - else - raise YAML::TypeError, "Invalid String: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out| - if is_binary_data? - out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal ) - elsif to_yaml_properties.empty? - out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style ) - else - out.map( taguri, to_yaml_style ) do |map| - map.add( 'str', "#{self}" ) - to_yaml_properties.each do |m| - map.add( m, instance_variable_get( m ) ) - end - end - end - end - end -end - -class Symbol - yaml_as "tag:ruby.yaml.org,2002:symbol" - yaml_as "tag:ruby.yaml.org,2002:sym" - def Symbol.yaml_new( klass, tag, val ) - if String === val - val = YAML::load( val ) if val =~ /\A(["']).*\1\z/ - val.intern - else - raise YAML::TypeError, "Invalid Symbol: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain ) - end - end -end - -class Range - yaml_as "tag:ruby.yaml.org,2002:range" - def Range.yaml_new( klass, tag, val ) - inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")' - opts = {} - if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o - r1, rdots, r2 = $1, $2, $3 - opts = { - 'begin' => YAML.load( "--- #{r1}" ), - 'end' => YAML.load( "--- #{r2}" ), - 'excl' => rdots.length == 3 - } - val = {} - elsif Hash === val - opts['begin'] = val.delete('begin') - opts['end'] = val.delete('end') - opts['excl'] = val.delete('excl') - end - if Hash === opts - r = YAML::object_maker( klass, {} ) - # Thank you, NaHi - Range.instance_method(:initialize). - bind(r). - call( opts['begin'], opts['end'], opts['excl'] ) - val.each { |k,v| r.instance_variable_set( k, v ) } - r - else - raise YAML::TypeError, "Invalid Range: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or - # self.end.is_complex_yaml? or self.end.respond_to? :to_str or - # not to_yaml_properties.empty? - out.map( taguri, to_yaml_style ) do |map| - map.add( 'begin', self.begin ) - map.add( 'end', self.end ) - map.add( 'excl', self.exclude_end? ) - to_yaml_properties.each do |m| - map.add( m, instance_variable_get( m ) ) - end - end - # else - # out.scalar( taguri ) do |sc| - # sc.embed( self.begin ) - # sc.concat( self.exclude_end? ? "..." : ".." ) - # sc.embed( self.end ) - # end - # end - end - end -end - -class Regexp - yaml_as "tag:ruby.yaml.org,2002:regexp" - def Regexp.yaml_new( klass, tag, val ) - if String === val and val =~ /^\/(.*)\/([mix]*)$/ - val = { 'regexp' => $1, 'mods' => $2 } - end - if Hash === val - mods = nil - unless val['mods'].to_s.empty? - mods = 0x00 - mods |= Regexp::EXTENDED if val['mods'].include?( 'x' ) - mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' ) - mods |= Regexp::MULTILINE if val['mods'].include?( 'm' ) - end - val.delete( 'mods' ) - r = YAML::object_maker( klass, {} ) - Regexp.instance_method(:initialize). - bind(r). - call( val.delete( 'regexp' ), mods ) - val.each { |k,v| r.instance_variable_set( k, v ) } - r - else - raise YAML::TypeError, "Invalid Regular expression: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - if to_yaml_properties.empty? - out.scalar( taguri, self.inspect, :plain ) - else - out.map( taguri, to_yaml_style ) do |map| - src = self.inspect - if src =~ /\A\/(.*)\/([a-z]*)\Z/ - map.add( 'regexp', $1 ) - map.add( 'mods', $2 ) - else - raise YAML::TypeError, "Invalid Regular expression: " + src - end - to_yaml_properties.each do |m| - map.add( m, instance_variable_get( m ) ) - end - end - end - end - end -end - -class Time - yaml_as "tag:ruby.yaml.org,2002:time" - yaml_as "tag:yaml.org,2002:timestamp" - def Time.yaml_new( klass, tag, val ) - if Hash === val - t = val.delete( 'at' ) - val.each { |k,v| t.instance_variable_set( k, v ) } - t - else - raise YAML::TypeError, "Invalid Time: " + val.inspect - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |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 - standard = self.strftime( "%Y-%m-%d %H:%M:%S" ) - standard += ".%06d" % [usec] if usec.nonzero? - standard += " %s" % [tz] - if to_yaml_properties.empty? - out.scalar( taguri, standard, :plain ) - else - out.map( taguri, to_yaml_style ) do |map| - map.add( 'at', standard ) - to_yaml_properties.each do |m| - map.add( m, instance_variable_get( m ) ) - end - end - end - end - end -end - -class Date - yaml_as "tag:yaml.org,2002:timestamp#ymd" - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain ) - end - end -end - -class Integer - yaml_as "tag:yaml.org,2002:int" - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain ) - end - end -end - -class Float - yaml_as "tag:yaml.org,2002:float" - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - str = self.to_s - if str == "Infinity" - str = ".Inf" - elsif str == "-Infinity" - str = "-.Inf" - elsif str == "NaN" - str = ".NaN" - end - out.scalar( "tag:yaml.org,2002:float", str, :plain ) - end - end -end - -class Rational - yaml_as "tag:ruby.yaml.org,2002:object:Rational" - def Rational.yaml_new( klass, tag, val ) - if val.is_a? String - Rational( val ) - else - Rational( val['numerator'], val['denominator'] ) - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.map( taguri, nil ) do |map| - map.add( 'denominator', denominator ) - map.add( 'numerator', numerator ) - end - end - end -end - -class Complex - yaml_as "tag:ruby.yaml.org,2002:object:Complex" - def Complex.yaml_new( klass, tag, val ) - if val.is_a? String - Complex( val ) - else - Complex( val['real'], val['image'] ) - end - end - def to_yaml( opts = {} ) - YAML::quick_emit( self, opts ) do |out| - out.map( taguri, nil ) do |map| - map.add( 'image', imaginary ) - map.add( 'real', real ) - end - end - end -end - -class TrueClass - yaml_as "tag:yaml.org,2002:bool#yes" - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - out.scalar( taguri, "true", :plain ) - end - end -end - -class FalseClass - yaml_as "tag:yaml.org,2002:bool#no" - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - out.scalar( taguri, "false", :plain ) - end - end -end - -class NilClass - yaml_as "tag:yaml.org,2002:null" - def to_yaml( opts = {} ) - YAML::quick_emit( nil, opts ) do |out| - out.scalar( taguri, "", :plain ) - end - end -end - diff --git a/lib/yaml/store.rb b/lib/yaml/store.rb deleted file mode 100644 index e3a8e9fcdd..0000000000 --- a/lib/yaml/store.rb +++ /dev/null @@ -1,43 +0,0 @@ -# -# YAML::Store -# -require 'yaml' -require 'pstore' - -class YAML::Store < PStore - def initialize( *o ) - @opt = YAML::DEFAULTS.dup - if String === o.first - super(o.shift) - end - if o.last.is_a? Hash - @opt.update(o.pop) - end - end - - def dump(table) - @table.to_yaml(@opt) - end - - def load(content) - table = YAML::load(content) - if table == false - {} - else - table - end - end - - def marshal_dump_supports_canonical_option? - false - end - - EMPTY_MARSHAL_DATA = {}.to_yaml - EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA) - def empty_marshal_data - EMPTY_MARSHAL_DATA - end - def empty_marshal_checksum - EMPTY_MARSHAL_CHECKSUM - end -end diff --git a/lib/yaml/stream.rb b/lib/yaml/stream.rb deleted file mode 100644 index 3a5227ec9e..0000000000 --- a/lib/yaml/stream.rb +++ /dev/null @@ -1,41 +0,0 @@ -module YAML - - # - # 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 ) - warn "#{caller[0]}: edit is deprecated" if $VERBOSE - @documents[ doc_num ] = doc - end - - def emit( io = nil ) - # opts = @options.dup - # opts[:UseHeader] = true if @documents.length > 1 - out = YAML.emitter - out.reset( io || io2 = StringIO.new ) - @documents.each { |v| - v.to_yaml( out ) - } - io || ( io2.rewind; io2.read ) - end - - end - -end diff --git a/lib/yaml/stringio.rb b/lib/yaml/stringio.rb deleted file mode 100644 index 147caf0bcd..0000000000 --- a/lib/yaml/stringio.rb +++ /dev/null @@ -1,85 +0,0 @@ -warn "#{caller[0]}: yaml/stringio is deprecated" if $VERBOSE - -# -# Limited StringIO if no core lib is available -# -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 - - # - # 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." - 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 - -end - diff --git a/lib/yaml/syck.rb b/lib/yaml/syck.rb deleted file mode 100644 index faf57e8036..0000000000 --- a/lib/yaml/syck.rb +++ /dev/null @@ -1,19 +0,0 @@ -# -# YAML::Syck module -# .. glues syck and yaml.rb together .. -# -require 'syck' -require 'yaml/basenode' - -module YAML - module Syck - - # - # Mixin BaseNode functionality - # - class Node - include YAML::BaseNode - end - - end -end diff --git a/lib/yaml/tag.rb b/lib/yaml/tag.rb deleted file mode 100644 index ac587165c2..0000000000 --- a/lib/yaml/tag.rb +++ /dev/null @@ -1,92 +0,0 @@ -# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4 -# $Id$ -# -# = yaml/tag.rb: methods for associating a taguri to a class. -# -# Author:: why the lucky stiff -# -module YAML - # 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 - 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 - # - def YAML.tagged_classes - @@tagged_classes - end -end - -class Module - # :stopdoc: - - # 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 - end - # :startdoc: -end diff --git a/lib/yaml/types.rb b/lib/yaml/types.rb deleted file mode 100644 index 60aebc0481..0000000000 --- a/lib/yaml/types.rb +++ /dev/null @@ -1,192 +0,0 @@ -# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4 -# -# Classes required by the full core typeset -# - -module YAML - - # - # Default private type - # - class PrivateType - def self.tag_subclasses?; false; end - verbose, $VERBOSE = $VERBOSE, nil - def initialize( type, val ) - @type_id = type; @value = val - @value.taguri = "x-private:#{ @type_id }" - end - def to_yaml( opts = {} ) - @value.to_yaml( opts ) - end - ensure - $VERBOSE = verbose - end - - # - # Default domain type - # - class DomainType - def self.tag_subclasses?; false; end - verbose, $VERBOSE = $VERBOSE, nil - def initialize( domain, type, val ) - @domain = domain; @type_id = type; @value = val - @value.taguri = "tag:#{ @domain }:#{ @type_id }" - end - def to_yaml( opts = {} ) - @value.to_yaml( opts ) - end - ensure - $VERBOSE = verbose - end - - # - # Unresolved objects - # - class Object - def self.tag_subclasses?; false; end - def to_yaml( opts = {} ) - YAML::quick_emit( self, 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 - end - end - 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 - yaml_as "tag:yaml.org,2002:omap" - def yaml_initialize( tag, val ) - if Array === val - val.each do |v| - if Hash === v - concat( v.to_a ) # Convert the map to a sequence - else - raise YAML::Error, "Invalid !omap entry: " + val.inspect - end - end - else - raise YAML::Error, "Invalid !omap: " + val.inspect - end - self - end - def self.[]( *vals ) - o = Omap.new - 0.step( vals.length - 1, 2 ) do |i| - o[vals[i]] = vals[i+1] - end - 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, opts ) do |out| - out.seq( taguri, to_yaml_style ) do |seq| - self.each do |v| - seq.add( Hash[ *v ] ) - end - end - end - end - end - - # - # Builtin collection: !pairs - # - class Pairs < ::Array - yaml_as "tag:yaml.org,2002:pairs" - def yaml_initialize( tag, val ) - if Array === val - val.each do |v| - if Hash === v - concat( v.to_a ) # Convert the map to a sequence - else - raise YAML::Error, "Invalid !pairs entry: " + val.inspect - end - end - else - raise YAML::Error, "Invalid !pairs: " + val.inspect - end - self - end - 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, opts ) do |out| - out.seq( taguri, to_yaml_style ) do |seq| - self.each do |v| - seq.add( Hash[ *v ] ) - end - end - end - end - end - - # - # Builtin collection: !set - # - class Set < ::Hash - yaml_as "tag:yaml.org,2002:set" - end -end diff --git a/lib/yaml/yamlnode.rb b/lib/yaml/yamlnode.rb deleted file mode 100644 index 8afa142669..0000000000 --- a/lib/yaml/yamlnode.rb +++ /dev/null @@ -1,54 +0,0 @@ -# -# YAML::YamlNode class -# -require 'yaml/basenode' - -module YAML - - # - # YAML Generic Model container - # - class YamlNode - include BaseNode - attr_accessor :kind, :type_id, :value, :anchor - def initialize(t, v) - @type_id = t - if Hash === v - @kind = 'map' - @value = {} - v.each {|key,val| - @value[key.transform] = [key, val] - } - elsif Array === v - @kind = 'seq' - @value = v - elsif String === v - @kind = 'scalar' - @value = v - end - 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 - - end - -end diff --git a/lib/yaml/ypath.rb b/lib/yaml/ypath.rb deleted file mode 100644 index 470163557d..0000000000 --- a/lib/yaml/ypath.rb +++ /dev/null @@ -1,54 +0,0 @@ -# -# YAML::YPath -# - -warn "#{caller[0]}: YAML::YPath is deprecated" if $VERBOSE - -module YAML - - 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 - -end diff --git a/test/psych/test_engine_manager.rb b/test/psych/test_engine_manager.rb new file mode 100644 index 0000000000..8bd7d6c1da --- /dev/null +++ b/test/psych/test_engine_manager.rb @@ -0,0 +1,57 @@ +require_relative 'helper' +require 'yaml' + +module Psych + class TestEngineManager < TestCase + def teardown + YAML::ENGINE.yamler = 'syck' + end + + def test_bad_engine + assert_raises(ArgumentError) do + YAML::ENGINE.yamler = 'foooo' + end + end + + def test_set_psych + YAML::ENGINE.yamler = 'psych' + assert_equal Psych, YAML + assert_equal 'psych', YAML::ENGINE.yamler + end + + def test_set_syck + YAML::ENGINE.yamler = 'syck' + assert_equal Syck, YAML + assert_equal 'syck', YAML::ENGINE.yamler + end + + A = Struct.new(:name) + + def test_dump_types + YAML::ENGINE.yamler = 'psych' + + assert_to_yaml ::Object.new + assert_to_yaml Time.now + assert_to_yaml Date.today + assert_to_yaml('a' => 'b') + assert_to_yaml A.new('foo') + assert_to_yaml %w{a b} + assert_to_yaml Exception.new('foo') + assert_to_yaml "hello!" + assert_to_yaml :fooo + assert_to_yaml(1..10) + assert_to_yaml(/hello!~/) + assert_to_yaml 1 + assert_to_yaml 1.2 + assert_to_yaml Rational(1, 2) + assert_to_yaml Complex(1, 2) + assert_to_yaml true + assert_to_yaml false + assert_to_yaml nil + end + + def assert_to_yaml obj + assert obj.to_yaml, "#{obj.class} to_yaml works" + end + end +end diff --git a/test/yaml/test_engine_manager.rb b/test/yaml/test_engine_manager.rb new file mode 100644 index 0000000000..529fc49d38 --- /dev/null +++ b/test/yaml/test_engine_manager.rb @@ -0,0 +1,3 @@ +require 'test/unit' +require 'yaml' + diff --git a/test/yaml/test_yaml.rb b/test/yaml/test_yaml.rb index bda68cccf3..606c2676f1 100644 --- a/test/yaml/test_yaml.rb +++ b/test/yaml/test_yaml.rb @@ -4,7 +4,7 @@ # require 'test/unit' require 'yaml' -require 'yaml/ypath' +require 'syck/ypath' # [ruby-core:01946] module YAML_Tests diff --git a/test/yaml/test_yamlstore.rb b/test/yaml/test_yamlstore.rb index 69302095e5..1374d32d24 100644 --- a/test/yaml/test_yamlstore.rb +++ b/test/yaml/test_yamlstore.rb @@ -1,5 +1,5 @@ require 'test/unit' -require 'yaml/store' +require 'syck/store' class YAMLStoreTest < Test::Unit::TestCase def setup -- cgit v1.2.3