15c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko###########################################################################
25c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# Module for ABI Compliance Checker to create ABI dumps in XML format
35c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko#
45c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# Copyright (C) 2009-2011 Institute for System Programming, RAS
55c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# Copyright (C) 2011-2012 Nokia Corporation and/or its subsidiary(-ies)
68bfdcd89d96039c2f655682c39386097759501ceAndrey Ponomarenko# Copyright (C) 2011-2012 ROSA Laboratory
78bfdcd89d96039c2f655682c39386097759501ceAndrey Ponomarenko# Copyright (C) 2012-2015 Andrey Ponomarenko's ABI Laboratory
85c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko#
95c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# Written by Andrey Ponomarenko
105c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko#
115c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# This program is free software: you can redistribute it and/or modify
125c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# it under the terms of the GNU General Public License or the GNU Lesser
135c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# General Public License as published by the Free Software Foundation.
145c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko#
155c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# This program is distributed in the hope that it will be useful,
165c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# but WITHOUT ANY WARRANTY; without even the implied warranty of
175c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
185c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# GNU General Public License for more details.
195c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko#
205c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# You should have received a copy of the GNU General Public License
215c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# and the GNU Lesser General Public License along with this program.
225c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko# If not, see <http://www.gnu.org/licenses/>.
235c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko###########################################################################
245c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenkouse strict;
255c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
2674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkomy $TAG_ID = 0;
2774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkomy $INDENT = "    ";
2874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
295c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenkosub createXmlDump($)
305c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko{
315c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    my $ABI = $_[0];
325c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    my $ABI_DUMP = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
335c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
345c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= "<ABI_dump version=\"".$ABI->{"ABI_DUMP_VERSION"}."\"";
355c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= " xml_format=\"".$ABI->{"XML_ABI_DUMP_VERSION"}."\"";
365c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= " acc=\"".$ABI->{"ABI_COMPLIANCE_CHECKER_VERSION"}."\">\n";
375c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
385c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("library", $ABI->{"LibraryName"});
395c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("library_version", $ABI->{"LibraryVersion"});
405c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("language", $ABI->{"Language"});
415c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
425c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("gcc", $ABI->{"GccVersion"});
435c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("architecture", $ABI->{"Arch"});
445c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("target", $ABI->{"Target"});
455c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= addTag("word_size", $ABI->{"WordSize"});
465c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
475c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if($ABI->{"Mode"}) {
485c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= addTag("mode", $ABI->{"Mode"});
495c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
505c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if($ABI->{"SrcBin"}) {
515c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= addTag("kind", "SrcBin");
525c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
535c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    elsif($ABI->{"BinOnly"}) {
545c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= addTag("kind", "BinOnly");
555c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
565c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
575c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @Headers = keys(%{$ABI->{"Headers"}}))
585c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
595c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        @Headers = sort {$ABI->{"Headers"}{$a}<=>$ABI->{"Headers"}{$b}} @Headers;
605c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("headers");
615c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (@Headers) {
625c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
635c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
645c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("headers");
655c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
665c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
675c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @NameSpaces = keys(%{$ABI->{"NameSpaces"}}))
685c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
695c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("namespaces");
705c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $NameSpace (sort {lc($a) cmp lc($b)} @NameSpaces) {
715c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $NameSpace);
725c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
735c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("namespaces");
745c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
755c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
765c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @TypeInfo = keys(%{$ABI->{"TypeInfo"}}))
775c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
785c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("type_info");
795c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $ID (sort {$a<=>$b} @TypeInfo)
805c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
815c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            my %TInfo = %{$ABI->{"TypeInfo"}{$ID}};
825c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= openTag("data_type");
835c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("id", $ID);
845c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            foreach my $Attr ("Name", "Type", "Size",
85f48ec93de57523ec5eef23a60d3b50c71c106983Andrey Ponomarenko            "Header", "Line", "NameSpace", "Class", "Return", "Algn")
865c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
875c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                if(defined $TInfo{$Attr}) {
885c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag(lc($Attr), $TInfo{$Attr});
895c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
905c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
915c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($TInfo{"Private"}) {
925c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("access", "private");
935c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
945c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($TInfo{"Protected"}) {
955c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("access", "protected");
965c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
975c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @Positions = keys(%{$TInfo{"Memb"}}))
985c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
995c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("members");
1005c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $Pos (sort { $a<=>$b } @Positions)
1015c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
1025c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("field");
1035c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("name", $TInfo{"Memb"}{$Pos}{"name"});
1045c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(my $MTid = $TInfo{"Memb"}{$Pos}{"type"}) {
1055c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("type", $MTid);
1065c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
10701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Access = $TInfo{"Memb"}{$Pos}{"access"}) {
10801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("access", $Access);
10901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
1105c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    my $Val = $TInfo{"Memb"}{$Pos}{"value"};
1115c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(defined $Val) {
1125c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("value", $Val);
1135c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
1145c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(my $Align = $TInfo{"Memb"}{$Pos}{"algn"}) {
1155c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("algn", $Align);
1165c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
11701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Bitfield = $TInfo{"Memb"}{$Pos}{"bitfield"}) {
11801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("bitfield", $Bitfield);
11901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
12001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if($TInfo{"Memb"}{$Pos}{"mutable"}) {
12101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("spec", "mutable");
12201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
1235c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("pos", $Pos);
1245c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("field");
1255c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
1265c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("members");
1275c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
12801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my @Positions = keys(%{$TInfo{"Param"}}))
12901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
13001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= openTag("parameters");
13101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                foreach my $Pos (sort { $a<=>$b } @Positions)
13201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                {
13301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI_DUMP .= openTag("param");
13401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $PTid = $TInfo{"Param"}{$Pos}{"type"}) {
13501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("type", $PTid);
13601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
13701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI_DUMP .= addTag("pos", $Pos);
13801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI_DUMP .= closeTag("param");
13901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
14001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= closeTag("parameters");
14101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
1425c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @Positions = keys(%{$TInfo{"TParam"}}))
1435c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
1445c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("template_parameters");
1455c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $Pos (sort { $a<=>$b } @Positions)
1465c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
1475c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("param");
1485c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("name", $TInfo{"TParam"}{$Pos}{"name"});
1495c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("pos", $Pos);
1505c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("param");
1515c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
1525c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("template_parameters");
1535c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
1545c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @Offsets = keys(%{$TInfo{"VTable"}}))
1555c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
1565c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("vtable");
1575c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $Offset (sort { $a<=>$b } @Offsets)
1585c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
1595c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("entry");
1605c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("offset", $Offset);
1615c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("value", $TInfo{"VTable"}{$Offset});
1625c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("entry");
1635c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
1645c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("vtable");
1655c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
1666ecc3c24482247066afd37e68b95e3f2076d5a3bAndrey Ponomarenko            if(my $BTid = $TInfo{"BaseType"}) {
1675c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("base_type", $BTid);
1685c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
1695c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @BaseIDs = keys(%{$TInfo{"Base"}}))
1705c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
1715c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                @BaseIDs = sort { $TInfo{"Base"}{$a}{"pos"}<=>$TInfo{"Base"}{$b}{"pos"} } @BaseIDs;
1725c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("base");
1735c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $BaseID (@BaseIDs)
1745c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
1755c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("class");
1765c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("id", $BaseID);
1775c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(my $Access = $TInfo{"Base"}{$BaseID}{"access"}) {
1785c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("access", $Access);
1795c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
1805c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(my $Virt = $TInfo{"Base"}{$BaseID}{"virtual"}) {
1815c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("inherit", "virtual");
1825c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
1835c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("pos", $TInfo{"Base"}{$BaseID}{"pos"});
1845c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("class");
1855c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
1865c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("base");
1875c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
1885c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($TInfo{"Copied"}) {
18901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= addTag("note", "copied");
19001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
19101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if($TInfo{"Spec"}) {
19201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= addTag("note", "specialization");
1935c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
1949927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko            if($TInfo{"Forward"}) {
1959927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko                $ABI_DUMP .= addTag("note", "forward");
1969927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko            }
1975c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("data_type");
1985c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
1995c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("type_info");
2005c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
2015c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
2025c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @Constants = keys(%{$ABI->{"Constants"}}))
2035c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
2045c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("constants");
2055c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Constant (@Constants)
2065c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
2075c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            my %CInfo = %{$ABI->{"Constants"}{$Constant}};
2085c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= openTag("constant");
2095c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Constant);
2105c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("value", $CInfo{"Value"});
2115c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("header", $CInfo{"Header"});
2125c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("constant");
2135c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
2145c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("constants");
2155c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
2165c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
2175c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @SymbolInfo = keys(%{$ABI->{"SymbolInfo"}}))
2185c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
2195c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        my %TR = (
2205c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            "MnglName" => "mangled",
2215c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            "ShortName" => "short"
2225c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        );
2235c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("symbol_info");
2245c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $ID (sort {$a<=>$b} @SymbolInfo)
2255c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
2265c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            my %SInfo = %{$ABI->{"SymbolInfo"}{$ID}};
2275c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= openTag("symbol");
2285c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("id", $ID);
2295c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            foreach my $Attr ("MnglName", "ShortName", "Class",
23001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            "Header", "Line", "Return", "NameSpace", "Value")
2315c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
2325c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                if(defined $SInfo{$Attr})
2335c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
2345c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    my $Tag = $Attr;
2355c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if($TR{$Attr}) {
2365c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $Tag = $TR{$Attr};
2375c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
2385c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag(lc($Tag), $SInfo{$Attr});
2395c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
2405c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2415c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Constructor"}) {
2425c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("kind", "constructor");
2435c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2445c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Destructor"}) {
2455c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("kind", "destructor");
2465c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
24701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if($SInfo{"Data"}) {
24801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= addTag("kind", "data");
24901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
2505c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Virt"}) {
2515c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "virtual");
2525c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2535c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            elsif($SInfo{"PureVirt"}) {
2545c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "pure virtual");
2555c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2565c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            elsif($SInfo{"Static"}) {
2575c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "static");
2585c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2595c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"InLine"}) {
2605c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "inline");
2615c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2625c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Const"}) {
2635c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "const");
2645c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
26501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if($SInfo{"Volatile"}) {
26601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI_DUMP .= addTag("spec", "volatile");
26701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
2685c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Private"}) {
2695c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("access", "private");
2705c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2715c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Protected"}) {
2725c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("access", "protected");
2735c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2745c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if($SInfo{"Artificial"}) {
2755c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("note", "artificial");
2765c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2775c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my $Lang = $SInfo{"Lang"}) {
2785c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= addTag("lang", $Lang);
2795c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
2805c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @Positions = keys(%{$SInfo{"Param"}}))
2815c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
2825c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("parameters");
2835c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $Pos (sort { $a<=>$b } @Positions)
2845c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
2855c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("param");
28601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $PName = $SInfo{"Param"}{$Pos}{"name"}) {
28701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("name", $PName);
28801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
28901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $PTid = $SInfo{"Param"}{$Pos}{"type"}) {
29001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("type", $PTid);
2915c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
29201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my $Default = $SInfo{"Param"}{$Pos}{"default"};
29301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(defined $Default) {
2945c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("default", $Default);
2955c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
2965c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    if(my $Align = $SInfo{"Param"}{$Pos}{"algn"}) {
2975c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                        $ABI_DUMP .= addTag("algn", $Align);
2985c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    }
29901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(defined $SInfo{"Param"}{$Pos}{"reg"}) {
30001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $ABI_DUMP .= addTag("call", "register");
30101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
3025c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("pos", $Pos);
3035c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("param");
3045c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
3055c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("parameters");
3065c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
3075c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            if(my @Positions = keys(%{$SInfo{"TParam"}}))
3085c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
3095c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= openTag("template_parameters");
3105c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                foreach my $Pos (sort { $a<=>$b } @Positions)
3115c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                {
3125c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= openTag("param");
3135c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= addTag("name", $SInfo{"TParam"}{$Pos}{"name"});
3145c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                    $ABI_DUMP .= closeTag("param");
3155c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                }
3165c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko                $ABI_DUMP .= closeTag("template_parameters");
3175c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
3185c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("symbol");
3195c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3205c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("symbol_info");
3215c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3225c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3235c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @Libs = keys(%{$ABI->{"Symbols"}}))
3245c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
3255c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("symbols");
3265c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Lib (sort {lc($a) cmp lc($b)} @Libs)
3275c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
32835c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko            $ABI_DUMP .= openTag("library", "name", $Lib);
3295c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            foreach my $Symbol (sort {lc($a) cmp lc($b)} keys(%{$ABI->{"Symbols"}{$Lib}}))
3305c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
33135c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                if((my $Size = $ABI->{"Symbols"}{$Lib}{$Symbol})<0)
33235c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                { # data
33335c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                    $ABI_DUMP .= addTag("symbol", $Symbol, "size", -$Size);
33435c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                }
33535c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                else
33635c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                { # functions
33735c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                    $ABI_DUMP .= addTag("symbol", $Symbol);
33835c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko                }
3395c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
3405c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("library");
3415c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3425c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("symbols");
3435c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3445c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3455c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @DepLibs = keys(%{$ABI->{"DepSymbols"}}))
3465c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
3475c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("dep_symbols");
3485c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Lib (sort {lc($a) cmp lc($b)} @DepLibs)
3495c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
35035c44fd1428ba96f71ba80f1d45c175a9ab4a197Andrey Ponomarenko            $ABI_DUMP .= openTag("library", "name", $Lib);
3515c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            foreach my $Symbol (sort {lc($a) cmp lc($b)} keys(%{$ABI->{"DepSymbols"}{$Lib}}))
3525c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            {
35301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if((my $Size = $ABI->{"DepSymbols"}{$Lib}{$Symbol})<0)
35401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                { # data
35501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI_DUMP .= addTag("symbol", $Symbol, "size", -$Size);
35601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
35701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                else
35801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                { # functions
35901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI_DUMP .= addTag("symbol", $Symbol);
36001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
3615c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            }
3625c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("library");
3635c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3645c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("dep_symbols");
3655c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3665c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3675c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @VSymbols = keys(%{$ABI->{"SymbolVersion"}}))
3685c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
3695c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("symbol_version");
3705c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Symbol (sort {lc($a) cmp lc($b)} @VSymbols)
3715c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        {
3725c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= openTag("symbol");
3735c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Symbol);
3745c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("version", $ABI->{"SymbolVersion"}{$Symbol});
3755c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= closeTag("symbol");
3765c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3775c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("symbol_version");
3785c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3795c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3805c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @SkipTypes = keys(%{$ABI->{"SkipTypes"}}))
3815c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
3825c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("skip_types");
3835c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (sort {lc($a) cmp lc($b)} @SkipTypes) {
3845c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
3855c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3865c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("skip_types");
3875c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3885c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3895c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @SkipSymbols = keys(%{$ABI->{"SkipSymbols"}}))
3905c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
3915c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("skip_symbols");
3925c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (sort {lc($a) cmp lc($b)} @SkipSymbols) {
3935c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
3945c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
3955c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("skip_symbols");
3965c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
3975c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
3985c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @SkipNameSpaces = keys(%{$ABI->{"SkipNameSpaces"}}))
3995c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
4005c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("skip_namespaces");
4015c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (sort {lc($a) cmp lc($b)} @SkipNameSpaces) {
4025c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
4035c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
4045c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("skip_namespaces");
4055c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
4065c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
4075c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @SkipHeaders = keys(%{$ABI->{"SkipHeaders"}}))
4085c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
4095c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("skip_headers");
4105c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (sort {lc($a) cmp lc($b)} @SkipHeaders) {
4115c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
4125c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
4135c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("skip_headers");
4145c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
4155c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
4165c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    if(my @TargetHeaders = keys(%{$ABI->{"TargetHeaders"}}))
4175c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    {
4185c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= openTag("target_headers");
4195c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        foreach my $Name (sort {lc($a) cmp lc($b)} @TargetHeaders) {
4205c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko            $ABI_DUMP .= addTag("name", $Name);
4215c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        }
4225c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko        $ABI_DUMP .= closeTag("target_headers");
4235c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    }
4245c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
4255c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    $ABI_DUMP .= "</ABI_dump>\n";
4265c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
4275c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    checkTags();
4285c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
4295c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko    return $ABI_DUMP;
4305c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko}
4315c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenko
43201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenkosub readXmlDump($)
43301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko{
43401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    my $ABI_DUMP = readFile($_[0]);
43501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    my %ABI = {};
43601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
43701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"LibraryName"} = parseTag(\$ABI_DUMP, "library");
43801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"LibraryVersion"} = parseTag(\$ABI_DUMP, "library_version");
43901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"Language"} = parseTag(\$ABI_DUMP, "language");
44001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"GccVersion"} = parseTag(\$ABI_DUMP, "gcc");
44101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"Arch"} = parseTag(\$ABI_DUMP, "architecture");
44201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"Target"} = parseTag(\$ABI_DUMP, "target");
44301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"WordSize"} = parseTag(\$ABI_DUMP, "word_size");
44401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
44501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    my $Pos = 0;
44601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
44701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $Headers = parseTag(\$ABI_DUMP, "headers"))
44801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
44901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$Headers, "name")) {
45001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"Headers"}{$Name} = $Pos++;
45101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
45201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
45301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
45401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $NameSpaces = parseTag(\$ABI_DUMP, "namespaces"))
45501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
45601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$NameSpaces, "name")) {
45701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"NameSpaces"}{$Name} = 1;
45801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
45901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
46001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
46101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $TypeInfo = parseTag(\$ABI_DUMP, "type_info"))
46201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
46301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $DataType = parseTag(\$TypeInfo, "data_type"))
46401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        {
46501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my %TInfo = ();
46601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my $ID = parseTag(\$DataType, "id");
46701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
46801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Members = parseTag(\$DataType, "members"))
46901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
47001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
47101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $Field = parseTag(\$Members, "field"))
47201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                {
47301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my %MInfo = ();
47401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $MInfo{"name"} = parseTag(\$Field, "name");
47501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Tid = parseTag(\$Field, "type")) {
47601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{"type"} = $Tid;
47701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
47801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Access = parseTag(\$Field, "access")) {
47901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{"access"} = $Access;
48001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
48101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my $Val = parseTag(\$Field, "value");
48201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(defined $Val) {
48301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{"value"} = $Val;
48401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
48501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Align = parseTag(\$Field, "algn")) {
48601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{"algn"} = $Align;
48701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
48801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Bitfield = parseTag(\$Field, "bitfield")) {
48901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{"bitfield"} = $Bitfield;
49001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
49101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Spec = parseTag(\$Field, "spec")) {
49201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $MInfo{$Spec} = 1;
49301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
49401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"Memb"}{$Pos++} = \%MInfo;
49501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
49601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
49701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
49801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Parameters = parseTag(\$DataType, "parameters"))
49901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
50001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
50101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $Parameter = parseTag(\$Parameters, "param"))
50201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                {
50301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my %PInfo = ();
50401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Tid = parseTag(\$Parameter, "type")) {
50501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $PInfo{"type"} = $Tid;
50601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
50701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"Param"}{$Pos++} = \%PInfo;
50801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
50901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
51001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $TParams = parseTag(\$DataType, "template_parameters"))
51101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
51201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
51301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $TParam = parseTag(\$TParams, "param")) {
51401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"TParam"}{$Pos++}{"name"} = parseTag(\$TParam, "name");
51501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
51601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
51701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $VTable = parseTag(\$DataType, "vtable"))
51801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
51901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
52001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $Entry = parseTag(\$VTable, "entry")) {
52101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"VTable"}{parseTag(\$Entry, "offset")} = parseTag(\$Entry, "value");
52201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
52301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
52401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $BTid = parseTag(\$DataType, "base_type")) {
5256ecc3c24482247066afd37e68b95e3f2076d5a3bAndrey Ponomarenko                $TInfo{"BaseType"} = $BTid;
52601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
52701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Base = parseTag(\$DataType, "base"))
52801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
52901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
53001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $Class = parseTag(\$Base, "class"))
53101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                {
53201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my %CInfo = ();
53301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $CInfo{"pos"} = parseTag(\$Class, "pos");
53401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Access = parseTag(\$Class, "access")) {
53501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $CInfo{"access"} = $Access;
53601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
53701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Inherit = parseTag(\$Class, "inherit"))
53801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    {
53901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        if($Inherit eq "virtual") {
54001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                            $CInfo{"virtual"} = 1;
54101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        }
54201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
54301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"Base"}{parseTag(\$Class, "id")} = \%CInfo;
54401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
54501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
54601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            while(my $Note = parseTag(\$DataType, "note"))
54701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
54801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if($Note eq "copied") {
54901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"Copied"} = 1;
55001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
55101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                elsif($Note eq "specialization") {
55201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{"Spec"} = 1;
55301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
5549927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko                elsif($Note eq "forward") {
5559927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko                    $TInfo{"Forward"} = 1;
5569927e33079b748463e883b96c4759f43f4d5de67Andrey Ponomarenko                }
55701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
558f48ec93de57523ec5eef23a60d3b50c71c106983Andrey Ponomarenko            foreach my $Attr ("Name", "Type", "Size",
559f48ec93de57523ec5eef23a60d3b50c71c106983Andrey Ponomarenko            "Header", "Line", "NameSpace", "Class", "Return", "Algn")
56001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
56101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                my $Val = parseTag(\$DataType, lc($Attr));
56201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if(defined $Val) {
56301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $TInfo{$Attr} = $Val;
56401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
56501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
56601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Access = parseTag(\$DataType, "access")) {
56701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $TInfo{ucfirst($Access)} = 1;
56801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
56901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"TypeInfo"}{$ID} = \%TInfo;
57001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
57101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
57201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
57301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $Constants = parseTag(\$ABI_DUMP, "constants"))
57401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
57501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Constant = parseTag(\$Constants, "constant"))
57601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        {
57701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Name = parseTag(\$Constant, "name"))
57801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
57901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                my %CInfo = ();
58001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $CInfo{"Value"} = parseTag(\$Constant, "value");
58101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $CInfo{"Header"} = parseTag(\$Constant, "header");
58201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $ABI{"Constants"}{$Name} = \%CInfo;
58301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
58401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
58501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
58601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
58701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SymbolInfo = parseTag(\$ABI_DUMP, "symbol_info"))
58801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
58901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        my %TR = (
59001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            "MnglName"=>"mangled",
59101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            "ShortName"=>"short"
59201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        );
59301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Symbol = parseTag(\$SymbolInfo, "symbol"))
59401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        {
59501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my %SInfo = ();
59601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my $ID = parseTag(\$Symbol, "id");
59701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
59801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Parameters = parseTag(\$Symbol, "parameters"))
59901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
60001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
60101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $Parameter = parseTag(\$Parameters, "param"))
60201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                {
60301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my %PInfo = ();
60401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $PName = parseTag(\$Parameter, "name")) {
60501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $PInfo{"name"} = $PName;
60601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
60701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $PTid = parseTag(\$Parameter, "type")) {
60801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $PInfo{"type"} = $PTid;
60901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
61001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    my $Default = parseTag(\$Parameter, "default", "spaces");
61101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(defined $Default) {
61201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $PInfo{"default"} = $Default;
61301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
61401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Align = parseTag(\$Parameter, "algn")) {
61501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        $PInfo{"algn"} = $Align;
61601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
61701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    if(my $Call = parseTag(\$Parameter, "call"))
61801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    {
61901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        if($Call eq "register") {
62001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                            $PInfo{"reg"} = 1;
62101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                        }
62201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    }
62301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{"Param"}{$Pos++} = \%PInfo;
62401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
62501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
62601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $TParams = parseTag(\$Symbol, "template_parameters"))
62701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
62801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $Pos = 0;
62901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                while(my $TParam = parseTag(\$TParams, "param")) {
63001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{"TParam"}{$Pos++}{"name"} = parseTag(\$TParam, "name");
63101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
63201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
63301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
63401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            foreach my $Attr ("MnglName", "ShortName", "Class",
63501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            "Header", "Line", "Return", "NameSpace", "Value")
63601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
63701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                my $Tag = lc($Attr);
63801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if($TR{$Attr}) {
63901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $Tag = $TR{$Attr};
64001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
64101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                my $Val = parseTag(\$Symbol, $Tag);
64201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if(defined $Val) {
64301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{$Attr} = $Val;
64401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
64501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
64601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Kind = parseTag(\$Symbol, "kind")) {
64701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $SInfo{ucfirst($Kind)} = 1;
64801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
64901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            while(my $Spec = parseTag(\$Symbol, "spec"))
65001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
65101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if($Spec eq "virtual") {
65201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{"Virt"} = 1;
65301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
65401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                elsif($Spec eq "pure virtual") {
65501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{"PureVirt"} = 1;
65601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
65701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                elsif($Spec eq "inline") {
65801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{"InLine"} = 1;
65901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
66001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                else
66101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                { # const, volatile, static
66201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $SInfo{ucfirst($Spec)} = 1;
66301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
66401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
66501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Access = parseTag(\$Symbol, "access")) {
66601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $SInfo{ucfirst($Access)} = 1;
66701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
66801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Note = parseTag(\$Symbol, "note")) {
66901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $SInfo{ucfirst($Note)} = 1;
67001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
67101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            if(my $Lang = parseTag(\$Symbol, "lang")) {
67201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                $SInfo{"Lang"} = $Lang;
67301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
67401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SymbolInfo"}{$ID} = \%SInfo;
67501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
67601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
67701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
67801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $Symbols = parseTag(\$ABI_DUMP, "symbols"))
67901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
68001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        my %LInfo = ();
68101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $LibSymbols = parseTag_E(\$Symbols, "library", \%LInfo))
68201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        {
68301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my %SInfo = ();
68401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            while(my $Symbol = parseTag_E(\$LibSymbols, "symbol", \%SInfo))
68501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
68601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if(my $Size = $SInfo{"size"}) {
68701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI{"Symbols"}{$LInfo{"name"}}{$Symbol} = -$Size;
68801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
68901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                else {
69001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI{"Symbols"}{$LInfo{"name"}}{$Symbol} = 1;
69101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
69201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                %SInfo = ();
69301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
69401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            %LInfo = ();
69501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
69601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
69701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
69801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $DepSymbols = parseTag(\$ABI_DUMP, "dep_symbols"))
69901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
70001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        my %LInfo = ();
70101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $LibSymbols = parseTag_E(\$DepSymbols, "library", \%LInfo))
70201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        {
70301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            my %SInfo = ();
70401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            while(my $Symbol = parseTag_E(\$LibSymbols, "symbol", \%SInfo))
70501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            {
70601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                if(my $Size = $SInfo{"size"}) {
70701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI{"DepSymbols"}{$LInfo{"name"}}{$Symbol} = -$Size;
70801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
70901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                else {
71001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                    $ABI{"DepSymbols"}{$LInfo{"name"}}{$Symbol} = 1;
71101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                }
71201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko                %SInfo = ();
71301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            }
71401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            %LInfo = ();
71501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
71601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
71701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
71801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"SymbolVersion"} = {};
71901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
72001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SymbolVersion = parseTag(\$ABI_DUMP, "symbol_version"))
72101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
72201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Symbol = parseTag(\$SymbolVersion, "symbol")) {
72301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SymbolVersion"}{parseTag(\$Symbol, "name")} = parseTag(\$Symbol, "version");
72401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
72501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
72601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
72701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"SkipTypes"} = {};
72801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
72901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SkipTypes = parseTag(\$ABI_DUMP, "skip_types"))
73001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
73101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$SkipTypes, "name")) {
73201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SkipTypes"}{$Name} = 1;
73301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
73401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
73501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
73601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"SkipSymbols"} = {};
73701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
73801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SkipSymbols = parseTag(\$ABI_DUMP, "skip_symbols"))
73901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
74001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$SkipSymbols, "name")) {
74101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SkipSymbols"}{$Name} = 1;
74201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
74301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
74401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
74501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"SkipNameSpaces"} = {};
74601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
74701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SkipNameSpaces = parseTag(\$ABI_DUMP, "skip_namespaces"))
74801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
74901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$SkipNameSpaces, "name")) {
75001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SkipNameSpaces"}{$Name} = 1;
75101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
75201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
75301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
75401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"SkipHeaders"} = {};
75501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
75601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $SkipHeaders = parseTag(\$ABI_DUMP, "skip_headers"))
75701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
75801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$SkipHeaders, "name")) {
75901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SkipHeaders"}{$Name} = 1;
76001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
76101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
76201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
76301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $TargetHeaders = parseTag(\$ABI_DUMP, "target_headers"))
76401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
76501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        while(my $Name = parseTag(\$TargetHeaders, "name")) {
76601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"TargetHeaders"}{$Name} = 1;
76701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
76801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
76901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
77001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $Mode = parseTag(\$ABI_DUMP, "mode")) {
77101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        $ABI{"Mode"} = $Mode;
77201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
77301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    if(my $Kind = parseTag(\$ABI_DUMP, "kind"))
77401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    {
77501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        if($Kind eq "BinOnly") {
77601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"BinOnly"} = 1;
77701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
77801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        elsif($Kind eq "SrcBin") {
77901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko            $ABI{"SrcBin"} = 1;
78001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko        }
78101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    }
78201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
78301117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    my %RInfo = ();
78401117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    parseTag_E(\$ABI_DUMP, "ABI_dump", \%RInfo);
78501117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
78601117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"ABI_DUMP_VERSION"} = $RInfo{"version"};
78701117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"XML_ABI_DUMP_VERSION"} = $RInfo{"xml_format"};
78801117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    $ABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $RInfo{"acc"};
78901117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
79001117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko    return \%ABI;
79101117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko}
79201117f17f0064f91d93bfd2dafe8fcd36e636f33Andrey Ponomarenko
79374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkosub parseTag_E($$$)
79474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko{
79574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my ($CodeRef, $Tag, $Info) = @_;
79674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    if(not $Tag or not $CodeRef
79774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    or not $Info) {
79874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        return undef;
79974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
80074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    if(${$CodeRef}=~s/\<\Q$Tag\E(\s+([^<>]+)|)\>((.|\n)*?)\<\/\Q$Tag\E\>//)
80174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    {
80274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        my ($Ext, $Content) = ($2, $3);
80374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content=~s/\A\s+//g;
80474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content=~s/\s+\Z//g;
80574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        if($Ext)
80674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        {
80774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            while($Ext=~s/(\w+)\=\"([^\"]*)\"//)
80874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            {
80974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko                my ($K, $V) = ($1, $2);
81074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko                $Info->{$K} = xmlSpecChars_R($V);
81174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            }
81274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        }
81374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        if(substr($Content, 0, 1) ne "<") {
81474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            $Content = xmlSpecChars_R($Content);
81574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        }
81674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        return $Content;
81774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
81874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    return undef;
81974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko}
82074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
82174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkosub addTag(@)
82274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko{
82374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Tag = shift(@_);
82474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Val = shift(@_);
82574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my @Ext = @_;
82674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Content = openTag($Tag, @Ext);
82774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    chomp($Content);
82874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $Content .= xmlSpecChars($Val);
82974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $Content .= "</$Tag>\n";
83074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $TAG_ID-=1;
83174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
83274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    return $Content;
83374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko}
83474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
83574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkosub openTag(@)
83674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko{
83774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Tag = shift(@_);
83874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my @Ext = @_;
83974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Content = "";
84074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    foreach (1 .. $TAG_ID) {
84174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content .= $INDENT;
84274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
84374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $TAG_ID+=1;
84474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    if(@Ext)
84574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    {
84674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content .= "<".$Tag;
84774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        my $P = 0;
84874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        while($P<=$#Ext-1)
84974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        {
85074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            $Content .= " ".$Ext[$P];
85174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            $Content .= "=\"".xmlSpecChars($Ext[$P+1])."\"";
85274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko            $P+=2;
85374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        }
85474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content .= ">\n";
85574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
85674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    else {
85774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content .= "<".$Tag.">\n";
85874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
85974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    return $Content;
86074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko}
86174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
86274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkosub closeTag($)
86374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko{
86474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Tag = $_[0];
86574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    my $Content = "";
86674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $TAG_ID-=1;
86774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    foreach (1 .. $TAG_ID) {
86874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        $Content .= $INDENT;
86974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
87074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    $Content .= "</".$Tag.">\n";
87174b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    return $Content;
87274b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko}
87374b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
87474b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenkosub checkTags()
87574b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko{
87674b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    if($TAG_ID!=0) {
87774b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko        printMsg("WARNING", "the number of opened tags is not equal to number of closed tags");
87874b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko    }
87974b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko}
88074b33ee9348fd163e65f1879e860c7067ae2f61fAndrey Ponomarenko
8815c09ef3aadb39afc16c59258feebbee1e49609d9Andrey Ponomarenkoreturn 1;