1
0
Fork 0
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:
matz 2008-01-01 05:43:50 +00:00
parent 96e7713754
commit 1448668244
16 changed files with 91 additions and 67 deletions

View file

@ -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

View file

@ -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 )

View file

@ -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
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 == '&amp;'
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!( /&amp;/, '&' ) else
end entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
rv entity_value ? entity_value.value : ref
end
}
end end
end end
end end

View file

@ -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}"

View file

@ -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