mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/rexml: 1.9 patch from Sam Ruby mentioned in his blog:
<http://intertwingly.net/blog/2007/12/31/Porting-REXML-to-Ruby-1-9> [ruby-core:14639] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
96e7713754
commit
1448668244
16 changed files with 91 additions and 67 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
Tue Jan 1 14:41:56 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* lib/rexml: 1.9 patch from Sam Ruby mentioned in his blog:
|
||||||
|
<http://intertwingly.net/blog/2007/12/31/Porting-REXML-to-Ruby-1-9>
|
||||||
|
[ruby-core:14639]
|
||||||
|
|
||||||
Tue Jan 1 14:15:04 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Tue Jan 1 14:15:04 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (rb_str_substr): offset movement bug. a patch from
|
* string.c (rb_str_substr): offset movement bug. a patch from
|
||||||
|
|
|
@ -117,7 +117,6 @@ module REXML
|
||||||
unless @children.empty?
|
unless @children.empty?
|
||||||
next_indent = indent + 1
|
next_indent = indent + 1
|
||||||
output << ' ['
|
output << ' ['
|
||||||
child = nil # speed
|
|
||||||
@children.each { |child|
|
@children.each { |child|
|
||||||
output << "\n"
|
output << "\n"
|
||||||
f.write( child, output )
|
f.write( child, output )
|
||||||
|
|
|
@ -296,7 +296,7 @@ module REXML
|
||||||
raise "First argument must be either an element name, or an Element object" if element.nil?
|
raise "First argument must be either an element name, or an Element object" if element.nil?
|
||||||
el = @elements.add(element)
|
el = @elements.add(element)
|
||||||
attrs.each do |key, value|
|
attrs.each do |key, value|
|
||||||
el.attributes[key]=Attribute.new(key,value,self)
|
el.attributes[key]=value
|
||||||
end if attrs.kind_of? Hash
|
end if attrs.kind_of? Hash
|
||||||
el
|
el
|
||||||
end
|
end
|
||||||
|
@ -552,7 +552,11 @@ module REXML
|
||||||
|
|
||||||
def attribute( name, namespace=nil )
|
def attribute( name, namespace=nil )
|
||||||
prefix = nil
|
prefix = nil
|
||||||
|
if namespaces.respond_to? :key
|
||||||
|
prefix = namespaces.key(namespace) if namespace
|
||||||
|
else
|
||||||
prefix = namespaces.index(namespace) if namespace
|
prefix = namespaces.index(namespace) if namespace
|
||||||
|
end
|
||||||
prefix = nil if prefix == 'xmlns'
|
prefix = nil if prefix == 'xmlns'
|
||||||
attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )
|
attributes.get_attribute( "#{prefix ? prefix + ':' : ''}#{name}" )
|
||||||
end
|
end
|
||||||
|
@ -704,7 +708,6 @@ module REXML
|
||||||
# A private helper method
|
# A private helper method
|
||||||
def each_with_something( test, max=0, name=nil )
|
def each_with_something( test, max=0, name=nil )
|
||||||
num = 0
|
num = 0
|
||||||
child=nil
|
|
||||||
@elements.each( name ){ |child|
|
@elements.each( name ){ |child|
|
||||||
yield child if test.call(child) and num += 1
|
yield child if test.call(child) and num += 1
|
||||||
return if max>0 and num == max
|
return if max>0 and num == max
|
||||||
|
@ -754,7 +757,6 @@ module REXML
|
||||||
raise "index (#{index}) must be >= 1" if index < 1
|
raise "index (#{index}) must be >= 1" if index < 1
|
||||||
name = literalize(name) if name
|
name = literalize(name) if name
|
||||||
num = 0
|
num = 0
|
||||||
child = nil
|
|
||||||
@element.find { |child|
|
@element.find { |child|
|
||||||
child.kind_of? Element and
|
child.kind_of? Element and
|
||||||
(name.nil? ? true : child.has_name?( name )) and
|
(name.nil? ? true : child.has_name?( name )) and
|
||||||
|
@ -1217,7 +1219,8 @@ module REXML
|
||||||
def get_attribute_ns(namespace, name)
|
def get_attribute_ns(namespace, name)
|
||||||
each_attribute() { |attribute|
|
each_attribute() { |attribute|
|
||||||
if name == attribute.name &&
|
if name == attribute.name &&
|
||||||
namespace == attribute.namespace()
|
namespace == attribute.namespace() &&
|
||||||
|
( !namespace.empty? || !attribute.fully_expanded_name.index(':') )
|
||||||
return attribute
|
return attribute
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,14 +56,14 @@ module REXML
|
||||||
|
|
||||||
def check_encoding str
|
def check_encoding str
|
||||||
# We have to recognize UTF-16, LSB UTF-16, and UTF-8
|
# We have to recognize UTF-16, LSB UTF-16, and UTF-8
|
||||||
if str[0] == 0xfe && str[1] == 0xff
|
if str[0,2] == "\xfe\xff"
|
||||||
str[0,2] = ""
|
str[0,2] = ""
|
||||||
return UTF_16
|
return UTF_16
|
||||||
elsif str[0] == 0xff && str[1] == 0xfe
|
elsif str[0,2] == "\xff\xfe"
|
||||||
str[0,2] = ""
|
str[0,2] = ""
|
||||||
return UNILE
|
return UNILE
|
||||||
end
|
end
|
||||||
str =~ /^\s*<\?xml\s+version\s*=\s*(['"]).*?\1\s+encoding\s*=\s*(["'])(.*?)\2/um
|
str =~ /^\s*<\?xml\s+version\s*=\s*(['"]).*?\1\s+encoding\s*=\s*(["'])(.*?)\2/m
|
||||||
return $3.upcase if $3
|
return $3.upcase if $3
|
||||||
return UTF_8
|
return UTF_8
|
||||||
end
|
end
|
||||||
|
|
|
@ -139,7 +139,7 @@ module REXML
|
||||||
if @parent
|
if @parent
|
||||||
matches.each do |entity_reference|
|
matches.each do |entity_reference|
|
||||||
entity_value = @parent.entity( entity_reference[0] )
|
entity_value = @parent.entity( entity_reference[0] )
|
||||||
rv.gsub!( /%#{entity_reference};/um, entity_value )
|
rv.gsub!( /%#{entity_reference.join};/um, entity_value )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return rv
|
return rv
|
||||||
|
|
|
@ -31,6 +31,7 @@ module REXML
|
||||||
@level = 0
|
@level = 0
|
||||||
@ie_hack = ie_hack
|
@ie_hack = ie_hack
|
||||||
@width = 80
|
@width = 80
|
||||||
|
@compact = false
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -256,10 +256,16 @@ module REXML
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ''.respond_to? :chars
|
||||||
|
string(string).chars.collect { |c|
|
||||||
|
if map.has_key? c then map[c] else c end
|
||||||
|
}.compact.join
|
||||||
|
else
|
||||||
string(string).unpack('U*').collect { |c|
|
string(string).unpack('U*').collect { |c|
|
||||||
if map.has_key? c then map[c] else c end
|
if map.has_key? c then map[c] else c end
|
||||||
}.compact.pack('U*')
|
}.compact.pack('U*')
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# UNTESTED
|
# UNTESTED
|
||||||
def Functions::boolean( object=nil )
|
def Functions::boolean( object=nil )
|
||||||
|
|
|
@ -242,6 +242,11 @@ module REXML
|
||||||
@document_status = :after_doctype
|
@document_status = :after_doctype
|
||||||
@source.read if @source.buffer.size<2
|
@source.read if @source.buffer.size<2
|
||||||
md = @source.match(/\s*/um, true)
|
md = @source.match(/\s*/um, true)
|
||||||
|
if @source.encoding == "UTF-8"
|
||||||
|
if @source.buffer.respond_to? :force_encoding
|
||||||
|
@source.buffer.force_encoding(Encoding::UTF_8)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if @document_status == :in_doctype
|
if @document_status == :in_doctype
|
||||||
|
|
|
@ -149,17 +149,26 @@ module REXML
|
||||||
procs = get_procs( :end_prefix_mapping, event[1] )
|
procs = get_procs( :end_prefix_mapping, event[1] )
|
||||||
listeners = get_listeners( :end_prefix_mapping, event[1] )
|
listeners = get_listeners( :end_prefix_mapping, event[1] )
|
||||||
if procs or listeners
|
if procs or listeners
|
||||||
namespace_mapping.each do |prefix, uri|
|
namespace_mapping.each do |ns_prefix, ns_uri|
|
||||||
# notify observers of namespaces
|
# notify observers of namespaces
|
||||||
procs.each { |ob| ob.call( prefix ) } if procs
|
procs.each { |ob| ob.call( ns_prefix ) } if procs
|
||||||
listeners.each { |ob| ob.end_prefix_mapping(prefix) } if listeners
|
listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
when :text
|
when :text
|
||||||
#normalized = @parser.normalize( event[1] )
|
#normalized = @parser.normalize( event[1] )
|
||||||
#handle( :characters, normalized )
|
#handle( :characters, normalized )
|
||||||
copy = event[1].clone
|
copy = event[1].clone
|
||||||
@entities.each { |key, value| copy = copy.gsub("&#{key};", value) }
|
|
||||||
|
esub = proc { |match|
|
||||||
|
if @entities.has_key?($1)
|
||||||
|
@entities[$1].gsub(Text::REFERENCE, &esub)
|
||||||
|
else
|
||||||
|
match
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
copy.gsub!( Text::REFERENCE, &esub )
|
||||||
copy.gsub!( Text::NUMERICENTITY ) {|m|
|
copy.gsub!( Text::NUMERICENTITY ) {|m|
|
||||||
m=$1
|
m=$1
|
||||||
m = "0#{m}" if m[0] == ?x
|
m = "0#{m}" if m[0] == ?x
|
||||||
|
|
|
@ -30,7 +30,10 @@ module REXML
|
||||||
return
|
return
|
||||||
when :start_element
|
when :start_element
|
||||||
tag_stack.push(event[1])
|
tag_stack.push(event[1])
|
||||||
el = @build_context = @build_context.add_element( event[1], event[2] )
|
el = @build_context = @build_context.add_element( event[1] )
|
||||||
|
event[2].each do |key, value|
|
||||||
|
el.attributes[key]=Attribute.new(key,value,self)
|
||||||
|
end
|
||||||
when :end_element
|
when :end_element
|
||||||
tag_stack.pop
|
tag_stack.pop
|
||||||
@build_context = @build_context.parent
|
@build_context = @build_context.parent
|
||||||
|
|
|
@ -332,12 +332,12 @@ module REXML
|
||||||
predicates << expr[1..-2] if expr
|
predicates << expr[1..-2] if expr
|
||||||
end
|
end
|
||||||
#puts "PREDICATES = #{predicates.inspect}"
|
#puts "PREDICATES = #{predicates.inspect}"
|
||||||
predicates.each{ |expr|
|
predicates.each{ |pred|
|
||||||
#puts "ORING #{expr}"
|
#puts "ORING #{pred}"
|
||||||
preds = []
|
preds = []
|
||||||
parsed << :predicate
|
parsed << :predicate
|
||||||
parsed << preds
|
parsed << preds
|
||||||
OrExpr(expr, preds)
|
OrExpr(pred, preds)
|
||||||
}
|
}
|
||||||
#puts "PREDICATES = #{predicates.inspect}"
|
#puts "PREDICATES = #{predicates.inspect}"
|
||||||
path
|
path
|
||||||
|
|
|
@ -59,6 +59,9 @@ module REXML
|
||||||
@to_utf = true
|
@to_utf = true
|
||||||
else
|
else
|
||||||
@to_utf = false
|
@to_utf = false
|
||||||
|
if @buffer.respond_to? :force_encoding
|
||||||
|
@buffer.force_encoding Encoding::UTF_8
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -147,13 +150,13 @@ module REXML
|
||||||
str = @source.read( 2 )
|
str = @source.read( 2 )
|
||||||
if encoding
|
if encoding
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
elsif 0xfe == str[0] && 0xff == str[1]
|
elsif str[0,2] == "\xfe\xff"
|
||||||
@line_break = "\000>"
|
@line_break = "\000>"
|
||||||
elsif 0xff == str[0] && 0xfe == str[1]
|
elsif str[0,2] == "\xff\xfe"
|
||||||
@line_break = ">\000"
|
@line_break = ">\000"
|
||||||
elsif 0xef == str[0] && 0xbb == str[1]
|
elsif str[0,2] == "\xef\xbb"
|
||||||
str += @source.read(1)
|
str += @source.read(1)
|
||||||
str = '' if (0xbf == str[2])
|
str = '' if (str[2,1] == "\xBF")
|
||||||
@line_break = ">"
|
@line_break = ">"
|
||||||
else
|
else
|
||||||
@line_break = ">"
|
@line_break = ">"
|
||||||
|
@ -193,6 +196,9 @@ module REXML
|
||||||
str = @source.readline(@line_break)
|
str = @source.readline(@line_break)
|
||||||
str = decode(str) if @to_utf and str
|
str = decode(str) if @to_utf and str
|
||||||
@buffer << str
|
@buffer << str
|
||||||
|
if not @to_utf and @buffer.respond_to? :force_encoding
|
||||||
|
@buffer.force_encoding Encoding::UTF_8
|
||||||
|
end
|
||||||
rescue Exception, NameError
|
rescue Exception, NameError
|
||||||
@source = nil
|
@source = nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,7 @@ module REXML
|
||||||
# Enumerable objects.
|
# Enumerable objects.
|
||||||
def initialize(*enums)
|
def initialize(*enums)
|
||||||
@gens = enums
|
@gens = enums
|
||||||
@biggest = @gens[0]
|
@length = @gens.collect {|x| x.size }.max
|
||||||
@gens.each {|x| @biggest = x if x.size > @biggest.size }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the number of enumerated Enumerable objects, i.e. the size
|
# Returns the number of enumerated Enumerable objects, i.e. the size
|
||||||
|
@ -24,8 +23,8 @@ module REXML
|
||||||
|
|
||||||
# Enumerates rows of the Enumerable objects.
|
# Enumerates rows of the Enumerable objects.
|
||||||
def each
|
def each
|
||||||
@biggest.zip( *@gens ) {|a|
|
@length.times {|i|
|
||||||
yield(*a[1..-1])
|
yield @gens.collect {|x| x[i]}
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
|
@ -308,37 +308,24 @@ module REXML
|
||||||
|
|
||||||
# Unescapes all possible entities
|
# Unescapes all possible entities
|
||||||
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
|
def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
|
||||||
rv = string.clone
|
string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) { |ref|
|
||||||
rv.gsub!( /\r\n?/, "\n" )
|
if ref[1] == ?#
|
||||||
matches = rv.scan( REFERENCE )
|
if ref[2] == ?x
|
||||||
return rv if matches.size == 0
|
[ref[3...-1].to_i(16)].pack('U*')
|
||||||
rv.gsub!( NUMERICENTITY ) {|m|
|
|
||||||
m=$1
|
|
||||||
m = "0#{m}" if m[0] == ?x
|
|
||||||
[Integer(m)].pack('U*')
|
|
||||||
}
|
|
||||||
matches.collect!{|x|x[0]}.compact!
|
|
||||||
if matches.size > 0
|
|
||||||
if doctype
|
|
||||||
matches.each do |entity_reference|
|
|
||||||
unless filter and filter.include?(entity_reference)
|
|
||||||
entity_value = doctype.entity( entity_reference )
|
|
||||||
re = /&#{entity_reference};/
|
|
||||||
rv.gsub!( re, entity_value ) if entity_value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
matches.each do |entity_reference|
|
[ref[2...-1].to_i].pack('U*')
|
||||||
unless filter and filter.include?(entity_reference)
|
end
|
||||||
entity_value = DocType::DEFAULT_ENTITIES[ entity_reference ]
|
elsif ref == '&'
|
||||||
re = /&#{entity_reference};/
|
'&'
|
||||||
rv.gsub!( re, entity_value.value ) if entity_value
|
elsif filter and filter.include?( ref[1...-1] )
|
||||||
end
|
ref
|
||||||
end
|
elsif doctype
|
||||||
end
|
doctype.entity( ref[1...-1] ) or ref
|
||||||
rv.gsub!( /&/, '&' )
|
else
|
||||||
end
|
entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
|
||||||
rv
|
entity_value ? entity_value.value : ref
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,8 +33,8 @@ module REXML
|
||||||
sattr = [:start_attribute, nil]
|
sattr = [:start_attribute, nil]
|
||||||
eattr = [:end_attribute]
|
eattr = [:end_attribute]
|
||||||
text = [:text, nil]
|
text = [:text, nil]
|
||||||
k,v = event[2].find { |k,v|
|
k,v = event[2].find { |key,value|
|
||||||
sattr[1] = k
|
sattr[1] = key
|
||||||
#puts "Looking for #{sattr.inspect}"
|
#puts "Looking for #{sattr.inspect}"
|
||||||
m = @current.next( sattr )
|
m = @current.next( sattr )
|
||||||
#puts "Got #{m.inspect}"
|
#puts "Got #{m.inspect}"
|
||||||
|
@ -47,7 +47,7 @@ module REXML
|
||||||
@current = m
|
@current = m
|
||||||
else
|
else
|
||||||
#puts "Didn't get end"
|
#puts "Didn't get end"
|
||||||
text[1] = v
|
text[1] = value
|
||||||
#puts "Looking for #{text.inspect}"
|
#puts "Looking for #{text.inspect}"
|
||||||
m = m.next( text )
|
m = m.next( text )
|
||||||
#puts "Got #{m.inspect}"
|
#puts "Got #{m.inspect}"
|
||||||
|
|
|
@ -222,7 +222,7 @@ module REXML
|
||||||
when :child
|
when :child
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
nt = nil
|
nt = nil
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
nt = node.node_type
|
nt = node.node_type
|
||||||
new_nodeset += node.children if nt == :element or nt == :document
|
new_nodeset += node.children if nt == :element or nt == :document
|
||||||
end
|
end
|
||||||
|
@ -266,7 +266,7 @@ module REXML
|
||||||
|
|
||||||
when :ancestor
|
when :ancestor
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
while node.parent
|
while node.parent
|
||||||
node = node.parent
|
node = node.parent
|
||||||
new_nodeset << node unless new_nodeset.include? node
|
new_nodeset << node unless new_nodeset.include? node
|
||||||
|
@ -277,7 +277,7 @@ module REXML
|
||||||
|
|
||||||
when :ancestor_or_self
|
when :ancestor_or_self
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
if node.node_type == :element
|
if node.node_type == :element
|
||||||
new_nodeset << node
|
new_nodeset << node
|
||||||
while ( node.parent )
|
while ( node.parent )
|
||||||
|
@ -341,7 +341,7 @@ module REXML
|
||||||
when :descendant
|
when :descendant
|
||||||
results = []
|
results = []
|
||||||
nt = nil
|
nt = nil
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
nt = node.node_type
|
nt = node.node_type
|
||||||
results += expr( path_stack.dclone.unshift( :descendant_or_self ),
|
results += expr( path_stack.dclone.unshift( :descendant_or_self ),
|
||||||
node.children ) if nt == :element or nt == :document
|
node.children ) if nt == :element or nt == :document
|
||||||
|
@ -376,7 +376,7 @@ module REXML
|
||||||
|
|
||||||
when :preceding
|
when :preceding
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
new_nodeset += preceding( node )
|
new_nodeset += preceding( node )
|
||||||
end
|
end
|
||||||
#puts "NEW NODESET => #{new_nodeset.inspect}"
|
#puts "NEW NODESET => #{new_nodeset.inspect}"
|
||||||
|
@ -385,7 +385,7 @@ module REXML
|
||||||
|
|
||||||
when :following
|
when :following
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
new_nodeset += following( node )
|
new_nodeset += following( node )
|
||||||
end
|
end
|
||||||
nodeset = new_nodeset
|
nodeset = new_nodeset
|
||||||
|
@ -395,7 +395,7 @@ module REXML
|
||||||
#puts "In :namespace"
|
#puts "In :namespace"
|
||||||
new_nodeset = []
|
new_nodeset = []
|
||||||
prefix = path_stack.shift
|
prefix = path_stack.shift
|
||||||
for node in nodeset
|
nodeset.each do |node|
|
||||||
if (node.node_type == :element or node.node_type == :attribute)
|
if (node.node_type == :element or node.node_type == :attribute)
|
||||||
if @namespaces
|
if @namespaces
|
||||||
namespaces = @namespaces
|
namespaces = @namespaces
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue