Files
2025-09-29 00:52:08 +02:00

164 lines
4.0 KiB
Ruby
Executable File

#
# Filename:: include.rb
# Description:: xml include, for projbuild
#
# Author:: Greg Smith <greg@rockstarnorth.com>
#
#
#-----------------------------------------------------------------------------
# Uses
#-----------------------------------------------------------------------------
require 'xml'
#-----------------------------------------------------------------------------
# Implementation
#-----------------------------------------------------------------------------
module Pipeline
module XMLUtil
# class LibXML::XML::Node
# # DW - its far faster to call this since it doesn't iterate over all the attributes as per attributes.length
# def attributes?
# attributes.first
# end
# end
class Include
include Singleton
def initialize( )
schema_filename = "$(toolsconfig)/projbuild/projbuild.xsd"
Pipeline::Globals.instance().in_env do |e|
schema_filename = e.subst(schema_filename)
end
set_schema(schema_filename)
end
def set_schema( schema_filename )
parser = XML::Parser.file(schema_filename)
@schema = parser.parse
@schema_elements = @schema.find( 'xs:element' )
@schema_elements_all = []
@schema_elements.each { |schema_node|
next unless ( schema_node.attributes? )
@schema_elements_all << schema_node
}
end
def allow_count( node_name, child_name )
@schema_elements_all.each { |schema_node|
attributes = schema_node.attributes
next if ( attributes['name'] != node_name )
schema_node_elements = schema_node.find("xs:complexType/xs:sequence/xs:element")
schema_node_elements.each { |schema_elem|
next unless ( schema_elem.attributes? )
attributes = schema_elem.attributes
next if ( attributes['ref'] != child_name )
return -1 if attributes['maxOccurs'] == "unbounded"
}
schema_node_elements = nil
}
schema_elements = nil
1
end
def merge_node( xml_node, xml_include )
if ( xml_include.attributes? ) then
include_attributes = xml_include.attributes
target_attributes = xml_node.attributes
include_attributes.each do |attribute|
target_attributes[attribute.name] = attribute.value
end
end
text_nodes = xml_include.find("text()")
if ( text_nodes.size > 0 ) then
text_nodes.each do |text_node|
next if ( text_node.content.strip == '' )
#xml_node << text_node.copy(false) # this leads to an segmentation fault
# so copy by hand... for some libxml internals reason this does not lead to a segmentation fault!
new_node = nil
if (text_node.name=="text")
xml_node.content = text_node.content
else
new_node = XML::Node.new(text_node.name)
text_node.attributes.each { |attr| new_node.attributes = attr }
new_node.content = text_node.content
xml_node << new_node
end
end
end
text_nodes = nil
xml_include.each do |node|
next if node.name == "text"
allowed = allow_count(xml_node.name,node.name)
xml_dest = xml_node.find_first(node.name)
if allowed == -1 or xml_dest == nil then
xml_new = XML::Node.new(node.name)
#temporary... makes it easier to read the xml...
xml_node << ("\n" + " " * (node.path.split("/").size - 1))
xml_node << xml_new
merge_node(xml_new,node)
else
merge_node(xml_dest,node)
end
end
xml_node
end
def merge_file( xml_node, path )
parser = XML::Parser.file(path)
doc = parser.parse
xml_new = doc.root
if doc.root["xinclude"] != nil then
include_path = doc.root["xinclude"]
Pipeline::Globals.instance().in_env do |e|
include_path = e.subst(include_path)
end
merge_file(xml_new,include_path)
end
merge_node(xml_node,xml_new)
end
end
end # XMLUtil module
end # Pipeline module