summaryrefslogtreecommitdiff
path: root/lib/yaml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yaml')
-rw-r--r--lib/yaml/baseemitter.rb241
-rw-r--r--lib/yaml/basenode.rb216
-rw-r--r--lib/yaml/constants.rb45
-rw-r--r--lib/yaml/dbm.rb220
-rw-r--r--lib/yaml/emitter.rb107
-rw-r--r--lib/yaml/encoding.rb29
-rw-r--r--lib/yaml/error.rb33
-rw-r--r--lib/yaml/loader.rb14
-rw-r--r--lib/yaml/rubytypes.rb505
-rw-r--r--lib/yaml/store.rb157
-rw-r--r--lib/yaml/stream.rb44
-rw-r--r--lib/yaml/stringio.rb83
-rw-r--r--lib/yaml/syck.rb27
-rw-r--r--lib/yaml/types.rb196
-rw-r--r--lib/yaml/yaml.gemspec30
-rw-r--r--lib/yaml/yamlnode.rb54
-rw-r--r--lib/yaml/ypath.rb52
17 files changed, 322 insertions, 1731 deletions
diff --git a/lib/yaml/baseemitter.rb b/lib/yaml/baseemitter.rb
deleted file mode 100644
index 007ee7be5e..0000000000
--- a/lib/yaml/baseemitter.rb
+++ /dev/null
@@ -1,241 +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 = '>' )
- @seq_map = false
- valx = value.dup
- if options(:UseBlock)
- block = '|'
- elsif not options(:UseFold) and valx =~ /\n[ \t]/ and not valx =~ /#{YAML::ESCAPE_CHAR}/
- block = '|'
- end
- str = block.dup
- if valx =~ /\n\Z\n/
- str << "+"
- elsif valx =~ /\Z\n/
- else
- str << "-"
- end
- if valx =~ /#{YAML::ESCAPE_CHAR}/
- valx = YAML::escape( valx )
- end
- if valx =~ /\A[ \t#]/
- str << options(:Indent).to_s
- end
- if block == '>'
- valx = fold( valx )
- end
- self << str + indent_text( valx ) + "\n"
- end
-
- #
- # Emit a simple, unqouted string
- #
- def simple( value )
- @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 )
- return "" if text.to_s.empty?
- spacing = " " * ( level * options(:Indent) )
- return "\n" + text.gsub( /^([^\n])/, "#{spacing}\\1" )
- end
-
- #
- # Write a current indent
- #
- def indent
- #p [ self.id, @level, :INDENT ]
- return " " * ( level * options(:Indent) )
- end
-
- #
- # Add indent to the buffer
- #
- def indent!
- self << indent
- end
-
- #
- # Folding paragraphs within a column
- #
- def fold( value )
- value.gsub!( /\A\n+/, '' )
- folded = $&.to_s
- width = (0..options(:BestWidth))
- while not value.empty?
- last = value.index( /(\n+)/ )
- chop_s = false
- if width.include?( last )
- last += $1.length - 1
- elsif width.include?( value.length )
- last = value.length
- else
- last = value.rindex( /[ \t]/, options(:BestWidth) )
- chop_s = true
- end
- folded += value.slice!( 0, width.include?( last ) ? last + 1 : options(:BestWidth) )
- folded.chop! if chop_s
- folded += "\n" unless value.empty?
- end
- folded
- end
-
- #
- # Quick mapping
- #
- def map( type, &e )
- val = Mapping.new
- e.call( val )
- self << "#{type} " if type.length.nonzero?
-
- #
- # Empty hashes
- #
- if val.length.zero?
- self << "{}"
- @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 e88a76f3d2..0000000000
--- a/lib/yaml/basenode.rb
+++ /dev/null
@@ -1,216 +0,0 @@
-#
-# YAML::BaseNode class
-#
-require 'yaml/ypath'
-
-module YAML
-
- #
- # YAML Generic Model container
- #
- module BaseNode
-
- #
- # Search for YPath entry and return
- # qualified nodes.
- #
- def select( ypath_str )
- matches = match_path( ypath_str )
-
- #
- # Create a new generic view of the elements selected
- #
- if matches
- result = []
- matches.each { |m|
- result.push m.last
- }
- self.class.new( 'seq', result )
- end
- end
-
- #
- # Search for YPath entry and return
- # transformed nodes.
- #
- def select!( ypath_str )
- matches = match_path( ypath_str )
-
- #
- # Create a new generic view of the elements selected
- #
- if matches
- result = []
- matches.each { |m|
- result.push m.last.transform
- }
- result
- end
- end
-
- #
- # Search for YPath entry and return a list of
- # qualified paths.
- #
- def search( ypath_str )
- matches = match_path( ypath_str )
-
- if matches
- matches.collect { |m|
- path = []
- m.each_index { |i|
- path.push m[i] if ( i % 2 ).zero?
- }
- "/" + path.compact.join( "/" )
- }
- end
- end
-
- def at( seg )
- if Hash === @value and @value.has_key?( seg )
- @value[seg][1]
- elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i]
- @value[seg.to_i]
- end
- end
-
- #
- # YPath search returning a complete depth array
- #
- def match_path( ypath_str )
- depth = 0
- matches = []
- YPath.each_path( ypath_str ) do |ypath|
- seg = match_segment( ypath, 0 )
- matches += seg if seg
- end
- matches.uniq
- end
-
- #
- # Search a node for a single YPath segment
- #
- def match_segment( ypath, depth )
- deep_nodes = []
- seg = ypath.segments[ depth ]
- if seg == "/"
- unless String === @value
- idx = -1
- @value.collect { |v|
- idx += 1
- if Hash === @value
- match_init = [v[0], v[1][1]]
- match_deep = v[1][1].match_segment( ypath, depth )
- else
- match_init = [idx, v]
- match_deep = v.match_segment( ypath, depth )
- end
- if match_deep
- match_deep.each { |m|
- deep_nodes.push( match_init + m )
- }
- end
- }
- end
- depth += 1
- seg = ypath.segments[ depth ]
- end
- match_nodes =
- case seg
- when "."
- [[nil, self]]
- when ".."
- [["..", nil]]
- when "*"
- if @value.is_a? Enumerable
- idx = -1
- @value.collect { |h|
- idx += 1
- if Hash === @value
- [h[0], h[1][1]]
- else
- [idx, h]
- end
- }
- end
- else
- if seg =~ /^"(.*)"$/
- seg = $1
- elsif seg =~ /^'(.*)'$/
- seg = $1
- end
- if ( v = at( seg ) )
- [[ seg, v ]]
- end
- end
- return deep_nodes unless match_nodes
- pred = ypath.predicates[ depth ]
- if pred
- case pred
- when /^\.=/
- pred = $'
- match_nodes.reject! { |n|
- n.last.value != pred
- }
- else
- match_nodes.reject! { |n|
- n.last.at( pred ).nil?
- }
- end
- end
- return match_nodes + deep_nodes unless ypath.segments.length > depth + 1
-
- #puts "DEPTH: #{depth + 1}"
- deep_nodes = []
- match_nodes.each { |n|
- if n[1].is_a? 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 []( *k )
- if Hash === @value
- v = @value.[]( *k )
- v[1] if v
- elsif Array === @value
- @value.[]( *k )
- end
- end
-
- def children
- if Hash === @value
- @value.values.collect { |c| c[1] }
- elsif Array === @value
- @value
- end
- end
-
- def children_with_index
- if Hash === @value
- @value.keys.collect { |i| [self[i], i] }
- elsif Array === @value
- i = -1; @value.collect { |v| i += 1; [v, i] }
- end
- end
-
- def emit
- transform.to_yaml
- end
- end
-
-end
-
diff --git a/lib/yaml/constants.rb b/lib/yaml/constants.rb
deleted file mode 100644
index fb833d3077..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
index 87d6009250..a3cbaeccf6 100644
--- a/lib/yaml/dbm.rb
+++ b/lib/yaml/dbm.rb
@@ -1,23 +1,71 @@
+# frozen_string_literal: false
require 'yaml'
-require 'dbm'
-#
-# YAML + DBM = YDBM
-# - Same interface as DBM class
-#
+
+begin
+ require 'dbm'
+rescue LoadError
+end
+
module YAML
+# YAML + DBM = YDBM
+#
+# YAML::DBM provides the same interface as ::DBM.
+#
+# However, while DBM only allows strings for both keys and values,
+# this library allows one to use most Ruby objects for values
+# by first converting them to YAML. Keys must be strings.
+#
+# Conversion to and from YAML is performed automatically.
+#
+# See the documentation for ::DBM and ::YAML for more information.
class DBM < ::DBM
- VERSION = "0.1"
+
+ # :call-seq:
+ # ydbm[key] -> value
+ #
+ # Return value associated with +key+ from database.
+ #
+ # Returns +nil+ if there is no such +key+.
+ #
+ # See #fetch for more information.
def []( key )
fetch( key )
end
+
+ # :call-seq:
+ # ydbm[key] = value
+ #
+ # Set +key+ to +value+ in database.
+ #
+ # +value+ will be converted to YAML before storage.
+ #
+ # See #store for more information.
def []=( key, val )
store( key, val )
end
+
+ # :call-seq:
+ # ydbm.fetch( key, ifnone = nil )
+ # ydbm.fetch( key ) { |key| ... }
+ #
+ # Return value associated with +key+.
+ #
+ # If there is no value for +key+ and no block is given, returns +ifnone+.
+ #
+ # Otherwise, calls block passing in the given +key+.
+ #
+ # See ::DBM#fetch for more information.
def fetch( keystr, ifnone = nil )
begin
val = super( keystr )
- return YAML::load( val ) if String === val
+ if String === val
+ if YAML.respond_to?(:safe_load)
+ return YAML.safe_load( val )
+ else
+ return YAML.load( val )
+ end
+ end
rescue IndexError
end
if block_given?
@@ -26,58 +74,163 @@ class DBM < ::DBM
ifnone
end
end
+
+ # Deprecated, used YAML::DBM#key instead.
+ # ----
+ # Note:
+ # YAML::DBM#index makes warning from internal of ::DBM#index.
+ # It says 'DBM#index is deprecated; use DBM#key', but DBM#key
+ # behaves not same as DBM#index.
+ #
def index( keystr )
super( keystr.to_yaml )
end
+
+ # :call-seq:
+ # ydbm.key(value) -> string
+ #
+ # Returns the key for the specified value.
+ def key( keystr )
+ invert[keystr]
+ end
+
+ # :call-seq:
+ # ydbm.values_at(*keys)
+ #
+ # Returns an array containing the values associated with the given keys.
def values_at( *keys )
keys.collect { |k| fetch( k ) }
end
+
+ # :call-seq:
+ # ydbm.delete(key)
+ #
+ # Deletes value from database associated with +key+.
+ #
+ # Returns value or +nil+.
def delete( key )
v = super( key )
if String === v
- v = YAML::load( v )
+ if YAML.respond_to?(:safe_load)
+ v = YAML.safe_load( v )
+ else
+ v = YAML.load( v )
+ end
end
v
end
- def delete_if
+
+ # :call-seq:
+ # ydbm.delete_if { |key, value| ... }
+ #
+ # Calls the given block once for each +key+, +value+ pair in the database.
+ # Deletes all entries for which the block returns true.
+ #
+ # Returns +self+.
+ def delete_if # :yields: [key, value]
del_keys = keys.dup
del_keys.delete_if { |k| yield( k, fetch( k ) ) == false }
- del_keys.each { |k| delete( k ) }
+ del_keys.each { |k| delete( k ) }
self
end
+
+ # :call-seq:
+ # ydbm.reject { |key, value| ... }
+ #
+ # Converts the contents of the database to an in-memory Hash, then calls
+ # Hash#reject with the specified code block, returning a new Hash.
def reject
hsh = self.to_hash
hsh.reject { |k,v| yield k, v }
end
- def each_pair
+
+ # :call-seq:
+ # ydbm.each_pair { |key, value| ... }
+ #
+ # Calls the given block once for each +key+, +value+ pair in the database.
+ #
+ # Returns +self+.
+ def each_pair # :yields: [key, value]
keys.each { |k| yield k, fetch( k ) }
self
end
- def each_value
- super { |v| yield YAML::load( v ) }
+
+ # :call-seq:
+ # ydbm.each_value { |value| ... }
+ #
+ # Calls the given block for each value in database.
+ #
+ # Returns +self+.
+ def each_value # :yields: value
+ super { |v| yield YAML.respond_to?(:safe_load) ? YAML.safe_load( v ) : YAML.load( v ) }
self
end
+
+ # :call-seq:
+ # ydbm.values
+ #
+ # Returns an array of values from the database.
def values
- super.collect { |v| YAML::load( v ) }
+ super.collect { |v| YAML.respond_to?(:safe_load) ? YAML.safe_load( v ) : YAML.load( v ) }
end
+
+ # :call-seq:
+ # ydbm.has_value?(value)
+ #
+ # Returns true if specified +value+ is found in the database.
def has_value?( val )
each_value { |v| return true if v == val }
return false
end
+
+ # :call-seq:
+ # ydbm.invert -> hash
+ #
+ # Returns a Hash (not a DBM database) created by using each value in the
+ # database as a key, with the corresponding key as its value.
+ #
+ # Note that all values in the hash will be Strings, but the keys will be
+ # actual objects.
def invert
h = {}
keys.each { |k| h[ self.fetch( k ) ] = k }
h
end
+
+ # :call-seq:
+ # ydbm.replace(hash) -> ydbm
+ #
+ # Replaces the contents of the database with the contents of the specified
+ # object. Takes any object which implements the each_pair method, including
+ # Hash and DBM objects.
def replace( hsh )
clear
update( hsh )
end
+
+ # :call-seq:
+ # ydbm.shift -> [key, value]
+ #
+ # Removes a [key, value] pair from the database, and returns it.
+ # If the database is empty, returns +nil+.
+ #
+ # The order in which values are removed/returned is not guaranteed.
def shift
a = super
- a[1] = YAML::load( a[1] ) if a
+ if a
+ a[1] = YAML.respond_to?(:safe_load) ? YAML.safe_load( a[1] ) : YAML.load( a[1] )
+ end
a
end
+
+ # :call-seq:
+ # ydbm.select { |key, value| ... }
+ # ydbm.select(*keys)
+ #
+ # If a block is provided, returns a new array containing [key, value] pairs
+ # for which the block returns true.
+ #
+ # Otherwise, same as #values_at
def select( *keys )
if block_given?
self.keys.collect { |k| v = self[k]; [k, v] if yield k, v }.compact
@@ -85,27 +238,58 @@ class DBM < ::DBM
values_at( *keys )
end
end
+
+ # :call-seq:
+ # ydbm.store(key, value) -> value
+ #
+ # Stores +value+ in database with +key+ as the index. +value+ is converted
+ # to YAML before being stored.
+ #
+ # Returns +value+
def store( key, val )
super( key, val.to_yaml )
val
end
+
+ # :call-seq:
+ # ydbm.update(hash) -> ydbm
+ #
+ # Updates the database with multiple values from the specified object.
+ # Takes any object which implements the each_pair method, including
+ # Hash and DBM objects.
+ #
+ # Returns +self+.
def update( hsh )
- hsh.keys.each do |k|
- self.store( k, hsh.fetch( k ) )
+ hsh.each_pair do |k,v|
+ self.store( k, v )
end
self
end
+
+ # :call-seq:
+ # ydbm.to_a -> array
+ #
+ # Converts the contents of the database to an array of [key, value] arrays,
+ # and returns it.
def to_a
a = []
keys.each { |k| a.push [ k, self.fetch( k ) ] }
a
end
+
+
+ # :call-seq:
+ # ydbm.to_hash -> hash
+ #
+ # Converts the contents of the database to an in-memory Hash object, and
+ # returns it.
def to_hash
h = {}
keys.each { |k| h[ k ] = self.fetch( k ) }
h
end
+
alias :each :each_pair
end
-end
+end if defined?(DBM)
diff --git a/lib/yaml/emitter.rb b/lib/yaml/emitter.rb
deleted file mode 100644
index a6be4a6733..0000000000
--- a/lib/yaml/emitter.rb
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# Output classes and methods
-#
-
-require 'yaml/baseemitter'
-require 'yaml/encoding'
-
-module YAML
-
- #
- # Emit a set of values
- #
-
- class Emitter
-
- include BaseEmitter
-
- attr_accessor :options
-
- def initialize( opts )
- opts = {} if opts.class != Hash
- @options = YAML::DEFAULTS.dup.update( opts )
- @headless = 0
- @seq_map = false
- @anchors = {}
- @anchor_extras = {}
- @active_anchors = []
- @level = -1
- self.clear
- end
-
- def clear
- @buffer = []
- end
-
- def level
- @level
- end
-
- #
- # Version string
- #
- def version_s
- " %YAML:#{@options[:Version]}" if @options[:UseVersion]
- end
-
- #
- # Header
- #
- def header
- if @headless.nonzero?
- ""
- else
- "---#{version_s} "
- end
- end
-
- #
- # Concatenate to the buffer
- #
- def <<( str )
- #p [ self.id, @level, str ]
- @buffer.last << str
- end
-
- #
- # Monitor objects and allow references
- #
- def start_object( oid )
- @level += 1
- @buffer.push( "" )
- #p [ self.id, @level, :OPEN ]
- idx = nil
- if oid
- if @anchors.has_key?( oid )
- idx = @active_anchors.index( oid )
- unless idx
- idx = @active_anchors.length
- af_str = "&#{@options[:AnchorFormat]} " % [ idx + 1 ]
- af_str += @anchor_extras[ @anchors[ oid ] ].to_s
- @buffer[ @anchors[ oid ] ][0,0] = af_str
- @headless = 0 if @anchors[ oid ].zero?
- end
- idx += 1
- @active_anchors.push( oid )
- else
- @anchors[ oid ] = @buffer.length - 1
- end
- end
- return idx
- end
-
- #
- # Output method
- #
- def end_object
- @level -= 1
- @buffer.push( "" )
- #p [ self.id, @level, :END ]
- if @level < 0
- header + @buffer.to_s[@headless..-1].to_s
- end
- end
- end
-
-end
-
diff --git a/lib/yaml/encoding.rb b/lib/yaml/encoding.rb
deleted file mode 100644
index e361163ac6..0000000000
--- a/lib/yaml/encoding.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Handle Unicode-to-Internal conversion
-#
-
-module YAML
-
- #
- # Escape the string, condensing common escapes
- #
- def YAML.escape( value )
- value.gsub( /\\/, "\\\\\\" ).gsub( /"/, "\\\"" ).gsub( /([\x00-\x1f])/ ) { |x| ESCAPES[ x.unpack("C")[0] ] }
- end
-
- #
- # Unescape the condenses escapes
- #
- def YAML.unescape( value )
- value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) { |x|
- if $3
- ["#$3".hex ].pack('U*')
- elsif $2
- [$2].pack( "H2" )
- else
- UNESCAPES[$1]
- end
- }
- end
-
-end
diff --git a/lib/yaml/error.rb b/lib/yaml/error.rb
deleted file mode 100644
index a9df22749b..0000000000
--- a/lib/yaml/error.rb
+++ /dev/null
@@ -1,33 +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
-
-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 f718df9b9f..0000000000
--- a/lib/yaml/rubytypes.rb
+++ /dev/null
@@ -1,505 +0,0 @@
-require 'date'
-#
-# Type conversions
-#
-
-class Class
- def to_yaml( opts = {} )
- raise ArgumentError, "can't dump anonymous class %s" % self.class
- end
-end
-
-class Object
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- "!ruby/object:#{self.class}"
- end
- def to_yaml_properties
- instance_variables.sort
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out.map( self.to_yaml_type ) { |map|
- to_yaml_properties.each { |m|
- map.add( m[1..-1], instance_eval( m ) )
- }
- }
- }
- end
-end
-
-YAML.add_ruby_type( /^object/ ) { |type, val|
- type, obj_class = YAML.read_type_class( type, Object )
- YAML.object_maker( obj_class, val )
-}
-
-#
-# Maps: Hash#to_yaml
-#
-class Hash
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- if self.class == Hash or self.class == YAML::SpecialHash
- "!map"
- else
- "!ruby/hash:#{self.class}"
- end
- end
- def to_yaml( opts = {} )
- opts[:DocType] = self.class if Hash === opts
- YAML::quick_emit( self.object_id, opts ) { |out|
- hash_type = to_yaml_type
- if not out.options(:ExplicitTypes) and hash_type == "!map"
- hash_type = ""
- end
- out.map( hash_type ) { |map|
- #
- # Sort the hash
- #
- if out.options(:SortKeys)
- map.concat( self.sort )
- else
- map.concat( self.to_a )
- end
- }
- }
- end
-end
-
-hash_proc = Proc.new { |type, val|
- if Array === val
- val = Hash.[]( *val ) # Convert the map to a sequence
- elsif Hash === val
- type, obj_class = YAML.read_type_class( type, Hash )
- if obj_class != Hash
- o = obj_class.new
- o.update( val )
- val = o
- end
- else
- raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
- end
- val
-}
-YAML.add_ruby_type( /^hash/, &hash_proc )
-
-module YAML
-
- #
- # Ruby-specific collection: !ruby/flexhash
- #
- class FlexHash < Array
- def []( k )
- self.assoc( k ).to_a[1]
- end
- def []=( k, *rest )
- val, set = rest.reverse
- if ( tmp = self.assoc( k ) ) and not set
- tmp[1] = val
- else
- self << [ k, val ]
- end
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out.seq( "!ruby/flexhash" ) { |seq|
- self.each { |v|
- if v[1]
- seq.add( Hash.[]( *v ) )
- else
- seq.add( v[0] )
- end
- }
- }
- }
- end
- end
-
- YAML.add_ruby_type( 'flexhash' ) { |type, val|
- if Array === val
- p = FlexHash.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- p << [ v, nil ]
- end
- }
- p
- else
- raise YAML::Error, "Invalid !ruby/flexhash: " + val.inspect
- end
- }
-end
-
-#
-# Structs: export as a !map
-#
-class Struct
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- #
- # Basic struct is passed as a YAML map
- #
- struct_name = self.class.name.gsub( "Struct::", "" )
- out.map( "!ruby/struct:#{struct_name}" ) { |map|
- self.members.each { |m|
- map.add( m, self[m] )
- }
- }
- }
- end
-end
-
-YAML.add_ruby_type( /^struct/ ) { |type, val|
- if Hash === val
- struct_type = nil
-
- #
- # Use existing Struct if it exists
- #
- begin
- struct_name, struct_type = YAML.read_type_class( type, Struct )
- rescue NameError
- end
- if not struct_type
- struct_def = [ type.split( ':', 4 ).last ]
- struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
- end
-
- #
- # Set the Struct properties
- #
- st = struct_type.new
- st.members.each { |m|
- st.send( "#{m}=", val[m] )
- }
- st
- else
- raise YAML::Error, "Invalid Ruby Struct: " + val.inspect
- end
-}
-
-#
-# Sequences: Array#to_yaml
-#
-class Array
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- if self.class == Array
- "!seq"
- else
- "!ruby/array:#{self.class}"
- end
- end
- def to_yaml( opts = {} )
- opts[:DocType] = self.class if Hash === opts
- YAML::quick_emit( self.object_id, opts ) { |out|
- array_type = to_yaml_type
- if not out.options(:ExplicitTypes) and array_type == "!seq"
- array_type = ""
- end
-
- out.seq( array_type ) { |seq|
- seq.concat( self )
- }
- }
- end
-end
-
-array_proc = Proc.new { |type, val|
- if Array === val
- type, obj_class = YAML.read_type_class( type, Array )
- if obj_class != Array
- o = obj_class.new
- o.concat( val )
- val = o
- end
- val
- else
- val.to_a
- end
-}
-YAML.add_ruby_type( /^array/, &array_proc )
-
-#
-# Exception#to_yaml
-#
-class Exception
- def is_complex_yaml?
- true
- end
- def to_yaml_type
- "!ruby/exception:#{self.class}"
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out.map( self.to_yaml_type ) { |map|
- map.add( 'message', self.message )
- to_yaml_properties.each { |m|
- map.add( m[1..-1], instance_eval( m ) )
- }
- }
- }
- end
-end
-
-YAML.add_ruby_type( /^exception/ ) { |type, val|
- type, obj_class = YAML.read_type_class( type, Exception )
- o = YAML.object_maker( obj_class, { 'mesg' => val.delete( 'message' ) }, true )
- val.each_pair { |k,v|
- o.instance_eval "@#{k} = v"
- }
- o
-}
-
-
-#
-# String#to_yaml
-#
-class String
- def is_complex_yaml?
- ( self =~ /\n.+/ ? true : false )
- end
- def is_binary_data?
- ( self.count( "^ -~", "^\r\n" ) / self.size > 0.3 || self.count( "\x00" ) > 0 )
- end
- def to_yaml( opts = {} )
- complex = false
- if self.is_complex_yaml?
- complex = true
- elsif opts[:BestWidth].to_i > 0
- if self.length > opts[:BestWidth] and opts[:UseFold]
- complex = true
- end
- end
- YAML::quick_emit( complex ? self.object_id : nil, opts ) { |out|
- if complex
- if self.is_binary_data?
- out.binary_base64( self )
- elsif self =~ /^ |#{YAML::ESCAPE_CHAR}| $/
- complex = false
- else
- out.node_text( self )
- end
- end
- if not complex
- ostr = if out.options(:KeepValue)
- self
- elsif empty?
- "''"
- elsif self =~ /^[^#{YAML::WORD_CHAR}]|#{YAML::ESCAPE_CHAR}|[#{YAML::SPACE_INDICATORS}]( |$)| $|\n|\'/
- "\"#{YAML.escape( self )}\""
- elsif YAML.detect_implicit( self ) != 'str'
- "\"#{YAML.escape( self )}\""
- else
- self
- end
- out.simple( ostr )
- end
- }
- end
-end
-
-#
-# Symbol#to_yaml
-#
-class Symbol
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/sym "
- self.id2name.to_yaml( :Emitter => out )
- }
- end
-end
-
-symbol_proc = Proc.new { |type, val|
- if String === val
- val.intern
- else
- raise YAML::Error, "Invalid Symbol: " + val.inspect
- end
-}
-YAML.add_ruby_type( 'symbol', &symbol_proc )
-YAML.add_ruby_type( 'sym', &symbol_proc )
-
-#
-# Range#to_yaml
-#
-class Range
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/range "
- self.inspect.to_yaml( :Emitter => out )
- }
- end
-end
-
-YAML.add_ruby_type( 'range' ) { |type, val|
- if String === val and val =~ /^(.*[^.])(\.{2,3})([^.].*)$/
- r1, rdots, r2 = $1, $2, $3
- Range.new( YAML.try_implicit( r1 ), YAML.try_implicit( r2 ), rdots.length == 3 )
- elsif Hash === val
- Range.new( val['begin'], val['end'], val['exclude_end?'] )
- else
- raise YAML::Error, "Invalid Range: " + val.inspect
- end
-}
-
-#
-# Make an RegExp
-#
-class Regexp
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- out << "!ruby/regexp "
- self.inspect.to_yaml( :Emitter => out )
- }
- end
-end
-
-regexp_proc = Proc.new { |type, val|
- if String === val and val =~ /^\/(.*)\/([mix]*)$/
- val = { 'REGEXP' => $1, 'MODIFIERS' => $2 }
- end
- if Hash === val
- mods = nil
- unless val['MODIFIERS'].to_s.empty?
- mods = 0x00
- if val['MODIFIERS'].include?( 'x' )
- mods |= Regexp::EXTENDED
- elsif val['MODIFIERS'].include?( 'i' )
- mods |= Regexp::IGNORECASE
- elsif val['MODIFIERS'].include?( 'm' )
- mods |= Regexp::POSIXLINE
- end
- end
- Regexp::compile( val['REGEXP'], mods )
- else
- raise YAML::Error, "Invalid Regular expression: " + val.inspect
- end
-}
-YAML.add_domain_type( "perl.yaml.org,2002", /^regexp/, &regexp_proc )
-YAML.add_ruby_type( 'regexp', &regexp_proc )
-
-#
-# Emit a Time object as an ISO 8601 timestamp
-#
-class Time
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( nil, opts ) { |out|
- tz = "Z"
- # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
- unless self.utc?
- utc_same_instant = self.dup.utc
- utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
- difference_to_utc = utc_same_writing - utc_same_instant
- if (difference_to_utc < 0)
- difference_sign = '-'
- absolute_difference = -difference_to_utc
- else
- difference_sign = '+'
- absolute_difference = difference_to_utc
- end
- difference_minutes = (absolute_difference/60).round
- tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
- end
- ( self.strftime( "%Y-%m-%d %H:%M:%S." ) +
- "%06d %s" % [usec, tz] ).
- to_yaml( :Emitter => out, :KeepValue => true )
- }
- end
-end
-
-#
-# Emit a Date object as a simple implicit
-#
-class Date
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- self.to_s.to_yaml( opts )
- end
-end
-
-#
-# Send Integer, Booleans, NilClass to String
-#
-class Numeric
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- str = self.to_s
- if str == "Infinity"
- str = ".Inf"
- elsif str == "-Infinity"
- str = "-.Inf"
- elsif str == "NaN"
- str = ".NaN"
- end
- opts[:KeepValue] = true
- str.to_yaml( opts )
- end
-end
-
-class TrueClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "true".to_yaml( opts )
- end
-end
-
-class FalseClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "false".to_yaml( opts )
- end
-end
-
-class NilClass
- def is_complex_yaml?
- false
- end
- def to_yaml( opts = {} )
- opts[:KeepValue] = true
- "".to_yaml( opts )
- end
-end
-
diff --git a/lib/yaml/store.rb b/lib/yaml/store.rb
index 2e74b27221..27c823b9f9 100644
--- a/lib/yaml/store.rb
+++ b/lib/yaml/store.rb
@@ -1,75 +1,98 @@
+# frozen_string_literal: false
#
# YAML::Store
#
require 'yaml'
-require 'pstore'
-module YAML
+begin
+ require 'pstore'
+rescue LoadError
+end
- class Store < PStore
- #
- # Constructor
- #
- 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
+# YAML::Store provides the same functionality as PStore, except it uses YAML
+# to dump objects instead of Marshal.
+#
+# == Example
+#
+# require 'yaml/store'
+#
+# Person = Struct.new :first_name, :last_name
+#
+# people = [Person.new("Bob", "Smith"), Person.new("Mary", "Johnson")]
+#
+# store = YAML::Store.new "test.store"
+#
+# store.transaction do
+# store["people"] = people
+# store["greeting"] = { "hello" => "world" }
+# end
+#
+# After running the above code, the contents of "test.store" will be:
+#
+# ---
+# people:
+# - !ruby/struct:Person
+# first_name: Bob
+# last_name: Smith
+# - !ruby/struct:Person
+# first_name: Mary
+# last_name: Johnson
+# greeting:
+# hello: world
- #
- # Override Pstore#transaction
- #
- def transaction
- raise YAML::Error, "nested transaction" if @transaction
- raise YAML::Error, "no filename for transaction" unless @filename
- begin
- @transaction = true
- value = nil
- backup = @filename+"~"
- if File::exist?(@filename)
- file = File::open(@filename, "rb+")
- orig = true
- else
- @table = {}
- file = File::open(@filename, "wb+")
- file.write( @table.to_yaml( @opt ) )
- end
- file.flock(File::LOCK_EX)
- if orig
- File::copy @filename, backup
- @table = YAML::load( file )
- end
- begin
- catch(:pstore_abort_transaction) do
- value = yield(self)
- end
- rescue Exception
- @abort = true
- raise
- ensure
- unless @abort
- begin
- file.rewind
- file.write( @table.to_yaml( @opt ) )
- file.truncate(file.pos)
- rescue
- File::rename backup, @filename if File::exist?(backup)
- raise
- end
- end
- @abort = false
- end
- ensure
- @table = nil
- @transaction = false
- file.close if file
- end
- value
- end
- end
+class YAML::Store < PStore
-end
+ # :call-seq:
+ # initialize( file_name, yaml_opts = {} )
+ # initialize( file_name, thread_safe = false, yaml_opts = {} )
+ #
+ # Creates a new YAML::Store object, which will store data in +file_name+.
+ # If the file does not already exist, it will be created.
+ #
+ # YAML::Store objects are always reentrant. But if _thread_safe_ is set to true,
+ # then it will become thread-safe at the cost of a minor performance hit.
+ #
+ # Options passed in through +yaml_opts+ will be used when converting the
+ # store to YAML via Hash#to_yaml().
+ def initialize( *o )
+ @opt = {}
+ if o.last.is_a? Hash
+ @opt.update(o.pop)
+ end
+ super(*o)
+ end
+
+ # :stopdoc:
+
+ def dump(table)
+ table.to_yaml(@opt)
+ end
+
+ def load(content)
+ table = if YAML.respond_to?(:safe_load)
+ if Psych::VERSION >= "3.1"
+ YAML.safe_load(content, permitted_classes: [Symbol])
+ else
+ YAML.safe_load(content, [Symbol])
+ end
+ else
+ YAML.load(content)
+ end
+ if table == false || table == nil
+ {}
+ else
+ table
+ end
+ end
+
+ def marshal_dump_supports_canonical_option?
+ false
+ end
+
+ def empty_marshal_data
+ {}.to_yaml(@opt)
+ end
+ def empty_marshal_checksum
+ CHECKSUM_ALGO.digest(empty_marshal_data)
+ end
+end if defined?(::PStore)
diff --git a/lib/yaml/stream.rb b/lib/yaml/stream.rb
deleted file mode 100644
index 943c51526b..0000000000
--- a/lib/yaml/stream.rb
+++ /dev/null
@@ -1,44 +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 )
- @documents[ doc_num ] = doc
- end
-
- def emit
- opts = @options.dup
- opts[:UseHeader] = true if @documents.length > 1
- ct = 0
- out = YAML::Syck::Emitter.new( opts )
- @documents.each { |v|
- if ct > 0
- out << "\n--- "
- end
- v.to_yaml( :Emitter => out )
- ct += 1
- }
- out.end_object
- end
-
- end
-
-end
diff --git a/lib/yaml/stringio.rb b/lib/yaml/stringio.rb
deleted file mode 100644
index 8ad949fa2b..0000000000
--- a/lib/yaml/stringio.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# 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 267067feb5..0000000000
--- a/lib/yaml/syck.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# YAML::Syck module
-# .. glues syck and yaml.rb together ..
-#
-require 'syck'
-require 'yaml/basenode'
-require 'yaml/baseemitter'
-
-module YAML
- module Syck
-
- #
- # Mixin BaseNode functionality
- #
- class Node
- include YAML::BaseNode
- end
-
- #
- # Mixin BaseEmitter functionality
- #
- class Emitter
- include YAML::BaseEmitter
- end
-
- end
-end
diff --git a/lib/yaml/types.rb b/lib/yaml/types.rb
deleted file mode 100644
index f7772cb3a0..0000000000
--- a/lib/yaml/types.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-#
-# Classes required by the full core typeset
-#
-
-module YAML
-
- #
- # Default private type
- #
- class PrivateType
- attr_accessor :type_id, :value
- def initialize( type, val )
- @type_id = type; @value = val
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out << " !!#{@type_id}"
- value.to_yaml( :Emitter => out )
- }
- end
- end
-
- #
- # Default domain type
- #
- class DomainType
- attr_accessor :domain, :type_id, :value
- def initialize( domain, type, val )
- @domain = domain; @type_id = type; @value = val
- end
- def to_yaml_type
- dom = @domain.dup
- if dom =~ /\.yaml\.org,2002$/
- dom = $`
- end
- "#{dom}/#{@type_id}"
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out << " !#{to_yaml_type} "
- value.to_yaml( :Emitter => out )
- }
- end
- end
-
- #
- # YAML Hash class to support comments and defaults
- #
- class SpecialHash < Object::Hash
- attr_accessor :default
- def inspect
- self.default.to_s
- end
- def to_s
- self.default.to_s
- end
- def update( h )
- if YAML::SpecialHash === h
- @default = h.default if h.default
- end
- super( h )
- end
- def to_yaml( opts = {} )
- opts[:DefaultKey] = self.default
- super( opts )
- end
- end
-
- #
- # Builtin collection: !omap
- #
- class Omap < Array
- def self.[]( *vals )
- o = Omap.new
- 0.step( vals.length - 1, 2 ) { |i|
- o[vals[i]] = vals[i+1]
- }
- o
- end
- def []( k )
- self.assoc( k ).to_a[1]
- end
- def []=( k, *rest )
- val, set = rest.reverse
- if ( tmp = self.assoc( k ) ) and not set
- tmp[1] = val
- else
- self << [ k, val ]
- end
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out.seq( "!omap" ) { |seq|
- self.each { |v|
- seq.add( Hash[ *v ] )
- }
- }
- }
- end
- end
-
- YAML.add_builtin_type( "omap" ) { |type, val|
- if Array === val
- p = Omap.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- raise YAML::Error, "Invalid !omap entry: " + val.inspect
- end
- }
- else
- raise YAML::Error, "Invalid !omap: " + val.inspect
- end
- p
- }
-
- #
- # Builtin collection: !pairs
- #
- class Pairs < Array
- def self.[]( *vals )
- p = Pairs.new
- 0.step( vals.length - 1, 2 ) { |i|
- p[vals[i]] = vals[i+1]
- }
- p
- end
- def []( k )
- self.assoc( k ).to_a
- end
- def []=( k, val )
- self << [ k, val ]
- val
- end
- def has_key?( k )
- self.assoc( k ) ? true : false
- end
- def is_complex_yaml?
- true
- end
- def to_yaml( opts = {} )
- YAML::quick_emit( self.object_id, opts ) { |out|
- out.seq( "!pairs" ) { |seq|
- self.each { |v|
- seq.add( Hash[ *v ] )
- }
- }
- }
- end
- end
-
- YAML.add_builtin_type( "pairs" ) { |type, val|
- if Array === val
- p = Pairs.new
- val.each { |v|
- if Hash === v
- p.concat( v.to_a ) # Convert the map to a sequence
- else
- raise YAML::Error, "Invalid !pairs entry: " + val.inspect
- end
- }
- else
- raise YAML::Error, "Invalid !pairs: " + val.inspect
- end
- p
- }
-
- #
- # Builtin collection: !set
- #
- class Set < Hash
- def to_yaml_type
- "!set"
- end
- end
-
- YAML.add_builtin_type( 'set' ) { |type, val|
- if Array === val
- val = Set[ *val ]
- elsif Hash === val
- Set[ val ]
- else
- raise YAML::Error, "Invalid map explicitly tagged !map: " + val.inspect
- end
- val
- }
-
-end
diff --git a/lib/yaml/yaml.gemspec b/lib/yaml/yaml.gemspec
new file mode 100644
index 0000000000..17e1ce89e0
--- /dev/null
+++ b/lib/yaml/yaml.gemspec
@@ -0,0 +1,30 @@
+name = File.basename(__FILE__, ".gemspec")
+version = ["lib", Array.new(name.count("-")+1, "..").join("/")].find do |dir|
+ break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
+ /^\s*LOADER_VERSION\s*=\s*"(.*)"/ =~ line and break $1
+ end rescue nil
+end
+
+Gem::Specification.new do |spec|
+ spec.name = name
+ spec.version = version
+ spec.authors = ["Aaron Patterson", "SHIBATA Hiroshi"]
+ spec.email = ["aaron@tenderlovemaking.com", "hsbt@ruby-lang.org"]
+
+ spec.summary = "YAML Ain't Markup Language"
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/yaml"
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
+ `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+end
diff --git a/lib/yaml/yamlnode.rb b/lib/yaml/yamlnode.rb
deleted file mode 100644
index e36a18e694..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 { |k,v|
- @value[ k.transform ] = [ k, v ]
- }
- 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 81348ca043..0000000000
--- a/lib/yaml/ypath.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# YAML::YPath
-#
-
-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