2 ###########################################################################
3 # ABI-compliance-checker v1.13, lightweight tool for statically checking
4 # backward binary compatibility of shared C/C++ libraries in Linux.
5 # Copyright (C) The Linux Foundation
6 # Copyright (C) Institute for System Programming, RAS
7 # Author: Andrey Ponomarenko
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 2 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ###########################################################################
23 Getopt
::Long
::Configure
("posix_default", "no_ignore_case");
26 my $ABI_COMPLIANCE_CHECKER_VERSION = "1.13";
27 my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $HeaderCheckingMode_Separately, $GenerateDescriptor, $TestSystem, $DumpInfo_DescriptorPath, $CheckHeadersOnly, $InterfacesListPath, $AppPath, $ShowExpendTime);
29 my $CmdName = get_FileName
($0);
30 GetOptions
("h|help!" => \
$Help,
31 "v|version!" => \
$ShowVersion,
33 "l|library=s" => \
$TargetLibraryName,
34 "d1|descriptor1=s" => \
$Descriptor{1}{"Path"},
35 "d2|descriptor2=s" => \
$Descriptor{2}{"Path"},
37 "app|application=s" => \
$AppPath,
38 "symbols_list|int_list=s" => \
$InterfacesListPath,
39 "dump_abi|dump_info=s" => \
$DumpInfo_DescriptorPath,
40 "headers_only!" => \
$CheckHeadersOnly,
42 "d|descriptor_template!" => \
$GenerateDescriptor,
43 "separately!" => \
$HeaderCheckingMode_Separately,
44 "test!" => \
$TestSystem,
45 "time!" => \
$ShowExpendTime
53 $CmdName - check ABI compatibility of shared C/C++ library versions
56 Lightweight tool for statically checking backward binary compatibility of shared C/C++ libraries
57 in Linux. It checks header files along with shared objects in two library versions and searches
58 for ABI changes that may lead to incompatibility. Breakage of the binary compatibility may result
59 in crashing or incorrect behavior of applications built with an old version of a library when
60 it is running with a new one.
62 ABI Compliance Checker was intended for library developers that are interested in ensuring
63 backward binary compatibility. Also it can be used for checking forward binary compatibility
64 and checking applications portability to the new library version.
66 This tool is free software: you can redistribute it and/or modify it under the terms of the GNU GPL.
72 $CmdName -l <library_name> -d1 <1st_version_descriptor> -d2 <2nd_version_descriptor>
82 Library name (without version).
83 It affects only on the path and the title of the report.
85 -d1|-descriptor1 <path>
86 Path to descriptor of 1st library version.
88 -d2|-descriptor2 <path>
89 Path to descriptor of 2nd library version.
92 -app|-application <path>
93 This option allow to specify the application that should be tested for portability
94 to the new library version.
96 -dump_abi|-dump_info <descriptor_path>
97 Dump library ABI information using specified descriptor.
98 This command will create '<library>_<ver1>.abi.tar.gz' file in the directory 'abi_dumps/<library>/'.
99 You can transfer it anywhere and pass instead of library descriptor.
102 Check header files without shared objects. It is easy to run, but may provide
103 a low quality ABI compliance report with false positives and without
104 detecting of added/withdrawn interfaces.
106 -symbols_list|-int_list <path>
107 This option allow to specify a file with a list of interfaces (mangled names in C++)
108 that should be checked, other library interfaces will not be checked.
111 -d|-descriptor_template
112 Create library descriptor template 'library-descriptor.xml' in the current directory.
115 Check headers individually. This mode requires more time for checking ABI compliance,
116 but possible compiler errors in one header can't affect others.
119 Run internal tests (create two binary-incompatible versions of an artificial library
120 and run ABI-Compliance-Checker on it).
128 /usr/local/atk/atk-1.28.0/include/
132 /usr/local/atk/atk-1.28.0/lib/libatk-1.0.so
136 /usr/include/glib-2.0/
137 /usr/lib/glib-2.0/include/
141 Report bugs to <abi-compliance-checker\@linuxtesting.org>
142 For more information, please see: http://ispras.linux-foundation.org/index.php/ABI_compliance_checker
147 my $Descriptor_Template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
150 <!-- Template for the library version descriptor -->
157 <!-- Version of the library -->
161 <!-- The list of paths to header files and/or
162 directories with header files, one per line -->
166 <!-- The list of paths to shared objects and/or
167 directories with shared objects, one per line -->
175 <!-- The list of paths to be searched for header files
176 needed for compiling of library headers, one per line -->
180 <!-- Additional gcc options, one per line -->
184 <!-- The list of opaque types, one per line -->
188 <!-- The list of functions (mangled/symbol names in C++)
189 that should be skipped while testing, one per line -->
193 <!-- The list of header files that should be included before other headers, one per line.
194 For example, it is a tree.h for libxml2 and ft2build.h for freetype2 -->
199 my %Operator_Indication = (
214 "lshiftassign" => "<<=",
215 "rshiftassign" => ">>=",
228 "delete" => " delete",
229 "vecnew" => " new[]",
230 "vecdelete" => " delete[]",
234 "plusassign" => "+=",
237 "minusassign" => "-=",
241 "multassign" => "*=",
257 elsif(int($Number)==1)
261 elsif(int($Number)==2)
265 elsif(int($Number)==3)
279 my $MAX_COMMAND_LINE_ARGUMENTS = 4096;
283 my %HeaderCompileError;
297 my %TemplateInstance_Func;
298 my %TemplateInstance;
302 my %Typedef_BaseName;
315 my %InternalInterfaces;
317 my %InterfacesList_App;
318 my %CheckedInterfaces;
322 my %Include_Preamble;
324 my %HeaderName_Destinations;
325 my %Header_Dependency;
328 my %SoLib_DefaultPath;
331 my %CompleteSignature;
333 my %Interface_Library;
334 my %Library_Interface;
342 #Problem descriptions
344 my %ConstantProblems;
348 my $ContentSpanStart = "<span class=\"section\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
349 my $ContentSpanEnd = "</span>\n";
350 my $ContentDivStart = "<div id=\"CONTENT_ID\" style=\"display:none;\">\n";
351 my $ContentDivEnd = "</div>\n";
352 my $Content_Counter = 0;
354 sub readDescriptor
($)
356 my $LibVersion = $_[0];
357 if(not -e
$Descriptor{$LibVersion}{"Path"})
361 my $Descriptor_File = readFile
($Descriptor{$LibVersion}{"Path"});
362 $Descriptor_File =~ s/\/\*(.|\n)+?\*\///g;
363 $Descriptor_File =~ s/<\!--(.|\n)+?-->//g;
364 if(not $Descriptor_File)
366 print "ERROR: descriptor d$LibVersion is empty\n";
369 $Descriptor{$LibVersion}{"Version"} = parseTag
(\
$Descriptor_File, "version");
370 if(not $Descriptor{$LibVersion}{"Version"})
372 print "ERROR: version in the descriptor d$LibVersion was not specified (section <version>)\n\n";
375 $Descriptor{$LibVersion}{"Headers"} = parseTag
(\
$Descriptor_File, "headers");
376 if(not $Descriptor{$LibVersion}{"Headers"})
378 print "ERROR: header files in the descriptor d$LibVersion were not specified (section <headers>)\n";
381 if(not $CheckHeadersOnly)
383 $Descriptor{$LibVersion}{"Libs"} = parseTag
(\
$Descriptor_File, "libs");
384 if(not $Descriptor{$LibVersion}{"Libs"})
386 print "ERROR: shared objects in the descriptor d$LibVersion were not specified (section <libs>)\n";
390 $Descriptor{$LibVersion}{"Include_Paths"} = parseTag
(\
$Descriptor_File, "include_paths");
391 $Descriptor{$LibVersion}{"Gcc_Options"} = parseTag
(\
$Descriptor_File, "gcc_options");
392 foreach my $Option (split("\n", $Descriptor{$LibVersion}{"Gcc_Options"}))
394 $Option =~ s/\A\s+|\s+\Z//g;
395 next if(not $Option);
396 $CompilerOptions{$LibVersion} .= " ".$Option;
398 $Descriptor{$LibVersion}{"Opaque_Types"} = parseTag
(\
$Descriptor_File, "opaque_types");
399 foreach my $Type_Name (split("\n", $Descriptor{$LibVersion}{"Opaque_Types"}))
401 $Type_Name =~ s/\A\s+|\s+\Z//g;
402 next if(not $Type_Name);
403 $OpaqueTypes{$LibVersion}{$Type_Name} = 1;
405 $Descriptor{$LibVersion}{"Skip_interfaces"} = parseTag
(\
$Descriptor_File, "skip_interfaces");
406 foreach my $Interface_Name (split("\n", $Descriptor{$LibVersion}{"Skip_interfaces"}))
408 $Interface_Name =~ s/\A\s+|\s+\Z//g;
409 next if(not $Interface_Name);
410 $InternalInterfaces{$LibVersion}{$Interface_Name} = 1;
412 $Descriptor{$LibVersion}{"Include_Preamble"} = parseTag
(\
$Descriptor_File, "include_preamble");
414 foreach my $Header_Name (split("\n", $Descriptor{$LibVersion}{"Include_Preamble"}))
416 $Header_Name =~ s/\A\s+|\s+\Z//g;
417 next if(not $Header_Name);
418 $Include_Preamble{$LibVersion}{$Header_Name}{"Position"} = $Position;
421 my $Descriptors_Dir = "descriptors_storage/$TargetLibraryName";
422 system("mkdir", "-p", $Descriptors_Dir);
423 my $Descriptor_Name = $TargetLibraryName."_".$Descriptor{$LibVersion}{"Version"}.".desc";
424 if($Descriptor{$LibVersion}{"Path"} ne $Descriptors_Dir."/".$Descriptor_Name)
426 system("cp", "-f", $Descriptor{$LibVersion}{"Path"}, $Descriptors_Dir."/".$Descriptor_Name);
428 $ERR_PATH{$LibVersion} = "header_compile_errors/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"};
433 my ($CodeRef, $Tag) = @_;
434 return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
435 if(${$CodeRef} =~ s/\<$Tag\>((.|\n)+?)\<\/$Tag\>//)
438 $Content=~s/(\A\s+|\s+\Z)//g;
457 "identifier_node"=>1,
470 "template_type_parm"=>1,
480 my $InfoPath = $_[0];
481 return if(not $InfoPath or not -f
$InfoPath);
482 my $InfoPath_New = $InfoPath.".1";
483 #my $Keywords = join("\\|", keys(%check_node));#|grep "$Keywords"
484 system("sed ':a;N;\$!ba;s/\\n[^\@]//g' ".esc
($InfoPath)."|sed 's/ [ ]\\+/ /g' > ".esc
($InfoPath_New));
485 system("rm", "-fr", $InfoPath);
487 open(INFO
, $InfoPath_New) || die ("can't open file '\$InfoPath_New\': $!\n");
491 if(/\A@([0-9]+)[ ]+([a-zA-Z_]+)[ ]+(.*)\Z/)
493 next if(not $check_node{$2});
494 $LibInfo{$Version}{$1}{"info_type"}=$2;
495 $LibInfo{$Version}{$1}{"info"}=$3;
499 system("rm", "-fr", $InfoPath_New);
501 setTemplateParams_All
();
506 %TemplateInstance = ();
509 sub setTemplateParams_All
()
511 foreach (keys(%{$LibInfo{$Version}}))
513 if($LibInfo{$Version}{$_}{"info_type"} eq "template_decl")
515 setTemplateParams
($_);
520 sub setTemplateParams
($)
522 my $TypeInfoId = $_[0];
523 my $Info = $LibInfo{$Version}{$TypeInfoId}{"info"};
524 if($Info =~ /(inst|spcs)[ ]*:[ ]*@([0-9]+) /)
526 my $TmplInst_InfoId = $2;
527 setTemplateInstParams
($TmplInst_InfoId);
528 my $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
529 while($TmplInst_Info =~ /chan[ ]*:[ ]*@([0-9]+) /)
531 $TmplInst_InfoId = $1;
532 $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
533 setTemplateInstParams
($TmplInst_InfoId);
538 sub setTemplateInstParams
($)
540 my $TmplInst_Id = $_[0];
541 my $Info = $LibInfo{$Version}{$TmplInst_Id}{"info"};
542 my ($Params_InfoId, $ElemId) = ();
543 if($Info =~ /purp[ ]*:[ ]*@([0-9]+) /)
547 if($Info =~ /valu[ ]*:[ ]*@([0-9]+) /)
551 if($Params_InfoId and $ElemId)
553 my $Params_Info = $LibInfo{$Version}{$Params_InfoId}{"info"};
554 while($Params_Info =~ s/ ([0-9]+)[ ]*:[ ]*@([0-9]+) //)
556 my ($Param_Pos, $Param_TypeId) = ($1, $2);
557 return if($LibInfo{$Version}{$Param_TypeId}{"info_type"} eq "template_type_parm");
558 if($LibInfo{$ElemId}{"info_type"} eq "function_decl")
560 $TemplateInstance_Func{$Version}{$ElemId}{$Param_Pos} = $Param_TypeId;
564 $TemplateInstance{$Version}{getTypeDeclId
($ElemId)}{$ElemId}{$Param_Pos} = $Param_TypeId;
572 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
573 if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+)/)
585 my $Ptd = pointTo
($_[0]);
588 if(($LibInfo{$Version}{$_[0]}{"info"} =~ m/unql[ ]*:/) and not ($LibInfo{$Version}{$_[0]}{"info"} =~ m/qual[ ]*:/))
592 elsif(($LibInfo{$Version}{$_[0]}{"info_type"} eq "pointer_type") and ($LibInfo{$Version}{$Ptd}{"info_type"} eq "function_type" or $LibInfo{$Version}{$Ptd}{"info_type"} eq "method_type"))
609 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
610 if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+)/)
620 sub getTypeDescr_All
()
622 foreach (sort {int($a)<=>int($b)} keys(%{$LibInfo{$Version}}))
624 if($LibInfo{$Version}{$_}{"info_type"}=~/_type\Z/ and $LibInfo{$Version}{$_}{"info_type"}!~/function_type|method_type/)
626 getTypeDescr
(getTypeDeclId
($_), $_);
629 $TypeDescr{$Version}{""}{-1}{"Name"} = "...";
630 $TypeDescr{$Version}{""}{-1}{"Type"} = "Intrinsic";
631 $TypeDescr{$Version}{""}{-1}{"Tid"} = -1;
636 my ($TypeDeclId, $TypeId) = @_;
637 $Tid_TDid{$Version}{$TypeId} = $TypeDeclId;
638 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTypeAttr
($TypeDeclId, $TypeId);
639 if(not $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
641 delete($TypeDescr{$Version}{$TypeDeclId}{$TypeId});
644 if(not $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}})
646 $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
652 my ($TypeDeclId, $TypeId) = @_;
653 my ($BaseTypeSpec, %TypeAttr) = ();
654 if($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
656 return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
658 $TypeAttr{"Tid"} = $TypeId;
659 $TypeAttr{"TDid"} = $TypeDeclId;
660 $TypeAttr{"Type"} = getTypeType
($TypeDeclId, $TypeId);
661 if($TypeAttr{"Type"} eq "Unknown")
665 elsif($TypeAttr{"Type"} eq "FuncPtr")
667 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getFuncPtrAttr
(pointTo
($TypeId), $TypeDeclId, $TypeId);
668 $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
669 return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
671 elsif($TypeAttr{"Type"} eq "Array")
673 ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType
($TypeDeclId, $TypeId);
674 my %BaseTypeAttr = getTypeAttr
($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
675 my $ArrayElemNum = getSize
($TypeId)/8;
676 $ArrayElemNum = $ArrayElemNum/$BaseTypeAttr{"Size"} if($BaseTypeAttr{"Size"});
677 $TypeAttr{"Size"} = $ArrayElemNum;
680 $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[".$ArrayElemNum."]";
684 $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[]";
686 $TypeAttr{"Name"} = correctName
($TypeAttr{"Name"});
687 $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
688 $TypeAttr{"Header"} = $BaseTypeAttr{"Header"};
689 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
690 $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
693 elsif($TypeAttr{"Type"} =~ /Intrinsic|Union|Struct|Enum|Class/)
695 if($TemplateInstance{$Version}{$TypeDeclId}{$TypeId})
697 my @Template_Params = ();
698 foreach my $Param_Pos (sort {int($a)<=>int($b)} keys(%{$TemplateInstance{$Version}{$TypeDeclId}{$TypeId}}))
700 my $Type_Id = $TemplateInstance{$Version}{$TypeDeclId}{$TypeId}{$Param_Pos};
701 my $Param = get_TemplateParam
($Type_Id);
706 @Template_Params = (@Template_Params, $Param);
708 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr
($TypeDeclId, $TypeId);
709 $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}."< ".join(", ", @Template_Params)." >";
710 $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = correctName
($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"});
711 $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
712 return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
716 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr
($TypeDeclId, $TypeId);
717 return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
722 ($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType
($TypeDeclId, $TypeId);
723 my %BaseTypeAttr = getTypeAttr
($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
724 if($BaseTypeSpec and $BaseTypeAttr{"Name"})
726 if(($TypeAttr{"Type"} eq "Pointer") and $BaseTypeAttr{"Name"}=~/\([\*]+\)/)
728 $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
729 $TypeAttr{"Name"} =~ s/\(([*]+)\)/($1*)/g;
733 $TypeAttr{"Name"} = $BaseTypeAttr{"Name"}." ".$BaseTypeSpec;
736 elsif($BaseTypeAttr{"Name"})
738 $TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
740 if($TypeAttr{"Type"} eq "Typedef")
742 $TypeAttr{"Name"} = getNameByInfo
($TypeDeclId);
743 $TypeAttr{"NameSpace"} = getNameSpace
($TypeDeclId);
744 if($TypeAttr{"NameSpace"})
746 $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
748 ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation
($TypeDeclId);
749 if($TypeAttr{"NameSpace"}=~/\Astd(::|\Z)/ and $BaseTypeAttr{"NameSpace"}=~/\Astd(::|\Z)/)
751 $StdCxxTypedef{$Version}{$BaseTypeAttr{"Name"}} = $TypeAttr{"Name"};
753 $Typedef_BaseName{$Version}{$TypeAttr{"Name"}} = $BaseTypeAttr{"Name"};
755 if(not $TypeAttr{"Size"})
757 if($TypeAttr{"Type"} eq "Pointer")
759 $TypeAttr{"Size"} = $POINTER_SIZE;
763 $TypeAttr{"Size"} = $BaseTypeAttr{"Size"};
766 $TypeAttr{"Name"} = correctName
($TypeAttr{"Name"});
767 $TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
768 $TypeAttr{"Header"} = $BaseTypeAttr{"Header"} if(not $TypeAttr{"Header"});
769 %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
770 $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
775 sub get_TemplateParam
($)
778 if(getNodeType
($Type_Id) eq "integer_cst")
780 return getNodeIntCst
($Type_Id);
782 elsif(getNodeType
($Type_Id) eq "string_cst")
784 return getNodeStrCst
($Type_Id);
788 my $Type_DId = getTypeDeclId
($Type_Id);
789 my %ParamAttr = getTypeAttr
($Type_DId, $Type_Id);
790 if(not $ParamAttr{"Name"})
794 if($ParamAttr{"Name"}=~/\>/)
796 if($StdCxxTypedef{$Version}{$ParamAttr{"Name"}})
798 return $StdCxxTypedef{$Version}{$ParamAttr{"Name"}};
800 elsif(my $Covered = cover_stdcxx_typedef
($ParamAttr{"Name"}))
806 return $ParamAttr{"Name"};
811 return $ParamAttr{"Name"};
816 sub cover_stdcxx_typedef
($)
818 my $TypeName = $_[0];
819 my $TypeName_Covered = $TypeName;
820 while($TypeName=~s/>[ ]*(const|volatile|restrict| |\*|\&)\Z/>/g){};
821 if(my $Cover = $StdCxxTypedef{$Version}{$TypeName})
823 $TypeName = esc_l
($TypeName);
824 $TypeName_Covered=~s/$TypeName/$Cover /g;
826 return correctName
($TypeName_Covered);
831 return $LibInfo{$Version}{$_[0]}{"info_type"};
837 my $CstTypeId = getTreeAttr
($CstId, "type");
838 if($EnumMembName_Id{$Version}{$CstId})
840 return $EnumMembName_Id{$Version}{$CstId};
842 elsif($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*([^ ]+) /)
846 if(getNodeType
($CstTypeId) eq "boolean_type")
857 if(getNodeType
($CstTypeId) eq "boolean_type")
879 if($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*(.+)[ ]+lngt/)
892 $String=~s/([()*])/\\$1/g;
896 sub getFuncPtrAttr
($$$)
898 my ($FuncTypeId, $TypeDeclId, $TypeId) = @_;
899 my $FuncInfo = $LibInfo{$Version}{$FuncTypeId}{"info"};
900 my $FuncInfo_Type = $LibInfo{$Version}{$FuncTypeId}{"info_type"};
901 my $FuncPtrCorrectName = "";
902 my %TypeAttr = ("Size"=>$POINTER_SIZE, "Type"=>"FuncPtr", "TDid"=>$TypeDeclId, "Tid"=>$TypeId);
904 if($FuncInfo =~ /retn[ ]*:[ ]*\@([0-9]+) /)
906 my $ReturnTypeId = $1;
907 my %ReturnAttr = getTypeAttr
(getTypeDeclId
($ReturnTypeId), $ReturnTypeId);
908 $FuncPtrCorrectName .= $ReturnAttr{"Name"};
909 $TypeAttr{"Return"} = $ReturnTypeId;
911 if($FuncInfo =~ /prms[ ]*:[ ]*@([0-9]+) /)
913 my $ParamTypeInfoId = $1;
915 while($ParamTypeInfoId)
917 my $ParamTypeInfo = $LibInfo{$Version}{$ParamTypeInfoId}{"info"};
918 last if($ParamTypeInfo !~ /valu[ ]*:[ ]*@([0-9]+) /);
919 my $ParamTypeId = $1;
920 my %ParamAttr = getTypeAttr
(getTypeDeclId
($ParamTypeId), $ParamTypeId);
921 last if($ParamAttr{"Name"} eq "void");
922 $TypeAttr{"Memb"}{$Position}{"type"} = $ParamTypeId;
923 push(@ParamTypeName, $ParamAttr{"Name"});
924 last if($ParamTypeInfo !~ /chan[ ]*:[ ]*@([0-9]+) /);
925 $ParamTypeInfoId = $1;
929 if($FuncInfo_Type eq "function_type")
931 $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
933 elsif($FuncInfo_Type eq "method_type")
935 if($FuncInfo =~ /clas[ ]*:[ ]*@([0-9]+) /)
938 my $ClassName = $TypeDescr{$Version}{getTypeDeclId
($ClassId)}{$ClassId}{"Name"};
941 $FuncPtrCorrectName .= " ($ClassName\:\:*) (".join(", ", @ParamTypeName).")";
945 $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
950 $FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
953 $TypeAttr{"Name"} = correctName
($FuncPtrCorrectName);
959 my $Info = $LibInfo{$Version}{$_[0]}{"info"};
960 if($Info =~ /name[ ]*:[ ]*@([0-9]+) /)
962 return getNameByInfo
($1);
966 if($LibInfo{$Version}{$_[0]}{"info_type"} eq "integer_type")
968 if($LibInfo{$Version}{$_[0]}{"info"} =~ /unsigned/)
970 return "unsigned int";
984 sub selectBaseType
($$)
986 my ($TypeDeclId, $TypeId) = @_;
987 my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
989 my $Type_Type = getTypeType
($TypeDeclId, $TypeId);
991 if(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
993 return ($1, getTypeDeclId
($1), "const");
995 elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
997 return ($1, getTypeDeclId
($1), "restrict");
999 elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
1001 return ($1, getTypeDeclId
($1), "volatile");
1003 elsif((not ($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:/)) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
1005 return ($1, getTypeDeclId
($1), "");
1007 elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "reference_type")
1009 if($TypeInfo =~ /refd[ ]*:[ ]*@([0-9]+) /)
1011 return ($1, getTypeDeclId
($1), "&");
1018 elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "array_type")
1020 if($TypeInfo =~ /elts[ ]*:[ ]*@([0-9]+) /)
1022 return ($1, getTypeDeclId
($1), "");
1029 elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "pointer_type")
1031 if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+) /)
1033 return ($1, getTypeDeclId
($1), "*");
1046 sub getFuncDescr_All
()
1048 foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
1050 if($LibInfo{$Version}{$_}{"info_type"} eq "function_decl")
1057 sub getVarDescr_All
()
1059 foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
1061 if($LibInfo{$Version}{$_}{"info_type"} eq "var_decl")
1070 my $FuncInfoId = $_[0];
1071 if($LibInfo{$Version}{getNameSpaceId
($FuncInfoId)}{"info_type"} eq "function_decl")
1075 ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation
($FuncInfoId);
1076 if((not $FuncDescr{$Version}{$FuncInfoId}{"Header"}) or ($FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/))
1078 delete($FuncDescr{$Version}{$FuncInfoId});
1081 $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getNameByInfo
($FuncInfoId);
1082 $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName
($FuncInfoId);
1083 if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1085 delete($FuncDescr{$Version}{$FuncInfoId});
1088 if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"})
1090 $FuncDescr{$Version}{$FuncInfoId}{"Name"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1091 $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1093 if(not is_in_library
($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
1095 delete $FuncDescr{$Version}{$FuncInfoId};
1098 $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getTypeId
($FuncInfoId);
1099 delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
1100 $FuncDescr{$Version}{$FuncInfoId}{"Data"} = 1;
1101 set_Class_And_Namespace
($FuncInfoId);
1102 setFuncAccess
($FuncInfoId);
1103 if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_ZTV/)
1105 delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
1107 if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\A_Z/)
1109 delete($FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
1113 sub getTrivialTypeAttr
($$)
1115 my ($TypeInfoId, $TypeId) = @_;
1117 return if(getTypeTypeByTypeId
($TypeId)!~/Intrinsic|Union|Struct|Enum/);
1118 setTypeAccess
($TypeId, \
%TypeAttr);
1119 ($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation
($TypeInfoId);
1120 if(($TypeAttr{"Header"} eq "<built-in>") or ($TypeAttr{"Header"} eq "<internal>"))
1122 delete($TypeAttr{"Header"});
1124 $TypeAttr{"Name"} = getNameByInfo
($TypeInfoId);
1125 $TypeAttr{"Name"} = getTypeName
($TypeId) if(not $TypeAttr{"Name"});
1126 my $NameSpaceId = getNameSpaceId
($TypeInfoId);
1127 if($NameSpaceId ne $TypeId)
1129 $TypeAttr{"NameSpace"} = getNameSpace
($TypeInfoId);
1131 if($TypeAttr{"NameSpace"} and isNotAnon
($TypeAttr{"Name"}))
1133 $TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
1135 $TypeAttr{"Name"} = correctName
($TypeAttr{"Name"});
1136 if(isAnon
($TypeAttr{"Name"}))
1138 $TypeAttr{"Name"} = "anon-";
1139 $TypeAttr{"Name"} .= $TypeAttr{"Header"}."-".$TypeAttr{"Line"};
1141 $TypeAttr{"Size"} = getSize
($TypeId)/8;
1142 $TypeAttr{"Type"} = getTypeType
($TypeInfoId, $TypeId);
1143 if($TypeAttr{"Type"} eq "Struct" and has_methods
($TypeId))
1145 $TypeAttr{"Type"} = "Class";
1147 if(($TypeAttr{"Type"} eq "Struct") or ($TypeAttr{"Type"} eq "Class"))
1149 setBaseClasses
($TypeInfoId, $TypeId, \
%TypeAttr);
1151 setTypeMemb
($TypeInfoId, $TypeId, \
%TypeAttr);
1152 $TypeAttr{"Tid"} = $TypeId;
1153 $TypeAttr{"TDid"} = $TypeInfoId;
1154 $Tid_TDid{$Version}{$TypeId} = $TypeInfoId;
1155 if(not $TName_Tid{$Version}{$TypeAttr{"Name"}})
1157 $TName_Tid{$Version}{$TypeAttr{"Name"}} = $TypeId;
1165 my $Info = $LibInfo{$Version}{$TypeId}{"info"};
1166 return ($Info=~/(fncs)[ ]*:[ ]*@([0-9]+) /);
1169 sub setBaseClasses
($$$)
1171 my ($TypeInfoId, $TypeId, $TypeAttr) = @_;
1172 my $Info = $LibInfo{$Version}{$TypeId}{"info"};
1173 if($Info =~ /binf[ ]*:[ ]*@([0-9]+) /)
1175 $Info = $LibInfo{$Version}{$1}{"info"};
1176 while($Info =~ /accs[ ]*:[ ]*([a-z]+) /)
1178 last if($Info !~ s/accs[ ]*:[ ]*([a-z]+) //);
1180 last if($Info !~ s/binf[ ]*:[ ]*@([0-9]+) //);
1182 my $ClassId = getBinfClassId
($BInfoId);
1183 if($Access eq "pub")
1185 $TypeAttr->{"BaseClass"}{$ClassId} = "public";
1187 elsif($Access eq "prot")
1189 $TypeAttr->{"BaseClass"}{$ClassId} = "protected";
1191 elsif($Access eq "priv")
1193 $TypeAttr->{"BaseClass"}{$ClassId} = "private";
1197 $TypeAttr->{"BaseClass"}{$ClassId} = "private";
1203 sub getBinfClassId
($)
1205 my $Info = $LibInfo{$Version}{$_[0]}{"info"};
1206 $Info =~ /type[ ]*:[ ]*@([0-9]+) /;
1210 sub get_func_signature
($)
1212 my $FuncInfoId = $_[0];
1213 my $PureSignature = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1214 my @ParamTypes = ();
1215 foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$FuncDescr{$Version}{$FuncInfoId}{"Param"}}))
1216 {#checking parameters
1217 my $ParamType_Id = $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$ParamPos}{"type"};
1218 my $ParamType_Name = uncover_typedefs
($TypeDescr{$Version}{getTypeDeclId
($ParamType_Id)}{$ParamType_Id}{"Name"});
1219 @ParamTypes = (@ParamTypes, $ParamType_Name);
1221 $PureSignature = $PureSignature."(".join(", ", @ParamTypes).")";
1222 $PureSignature = delete_keywords
($PureSignature);
1223 return correctName
($PureSignature);
1226 sub delete_keywords
($)
1228 my $TypeName = $_[0];
1229 $TypeName =~ s/(\W|\A)(enum |struct |union |class )/$1/g;
1233 sub uncover_typedefs
($)
1235 my $TypeName = $_[0];
1236 return "" if(not $TypeName);
1237 return $Cache{"uncover_typedefs"}{$Version}{$TypeName} if(defined $Cache{"uncover_typedefs"}{$Version}{$TypeName});
1238 my ($TypeName_New, $TypeName_Pre) = (correctName
($TypeName), "");
1239 while($TypeName_New ne $TypeName_Pre)
1241 $TypeName_Pre = $TypeName_New;
1242 my $TypeName_Copy = $TypeName_New;
1244 while($TypeName_Copy=~s/(\W|\A)([a-z_][\w:]*)(\W|\Z)//io)
1247 next if(not $Word or $Word=~/\A(true|false|const|int|long|void|short|float|unsigned|char|double|class|struct|union|enum)\Z/);
1250 foreach my $Word (keys(%Words))
1252 my $BaseType_Name = $Typedef_BaseName{$Version}{$Word};
1253 next if($TypeName_New=~/(\W|\A)(struct $Word|union $Word|enum $Word)(\W|\Z)/);
1254 next if(not $BaseType_Name);
1255 if($BaseType_Name=~/\([*]+\)/)
1257 $TypeName_New =~ /$Word(.*)\Z/;
1258 my $Type_Suffix = $1;
1259 $TypeName_New = $BaseType_Name;
1260 if($TypeName_New =~ s/\(([*]+)\)/($1 $Type_Suffix)/)
1262 $TypeName_New = correctName
($TypeName_New);
1267 if($TypeName_New =~ s/(\W|\A)$Word(\W|\Z)/$1$BaseType_Name$2/g)
1269 $TypeName_New = correctName
($TypeName_New);
1274 $Cache{"uncover_typedefs"}{$Version}{$TypeName} = $TypeName_New;
1275 return $TypeName_New;
1280 my $FuncInfoId = $_[0];
1281 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1282 return 0 if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
1283 my $FuncMnglNameInfoId = $1;
1284 return ($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} =~ /\*[ ]*INTERNAL[ ]*\*/);
1287 sub set_Class_And_Namespace
($)
1289 my $FuncInfoId = $_[0];
1290 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1291 if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1293 my $NameSpaceInfoId = $1;
1294 if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
1296 my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
1297 if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1299 my $NameSpaceId = $1;
1300 my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
1301 if($NameSpaceIdentifier =~ /strg[ ]*:[ ]*(.*)[ ]+lngt/)
1304 $NameSpace =~ s/[ ]+\Z//g;
1305 $FuncDescr{$Version}{$FuncInfoId}{"NameSpace"} = $NameSpace;
1309 elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
1311 $FuncDescr{$Version}{$FuncInfoId}{"Class"} = $NameSpaceInfoId;
1318 my $FuncInfoId = $_[0];
1319 return if(isInternal
($FuncInfoId));
1320 ($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation
($FuncInfoId);
1321 if(not $FuncDescr{$Version}{$FuncInfoId}{"Header"} or $FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/)
1323 delete($FuncDescr{$Version}{$FuncInfoId});
1326 setFuncAccess
($FuncInfoId);
1327 setFuncKind
($FuncInfoId);
1328 if($FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"})
1330 delete($FuncDescr{$Version}{$FuncInfoId});
1333 $FuncDescr{$Version}{$FuncInfoId}{"Type"} = getFuncType
($FuncInfoId);
1334 $FuncDescr{$Version}{$FuncInfoId}{"Return"} = getFuncReturn
($FuncInfoId);
1335 delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
1336 $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getFuncShortName
(getFuncOrig
($FuncInfoId));
1337 if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\._/)
1339 delete($FuncDescr{$Version}{$FuncInfoId});
1342 if(defined $TemplateInstance_Func{$Version}{$FuncInfoId})
1344 my @TmplParams = ();
1345 foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$TemplateInstance_Func{$Version}{$FuncInfoId}}))
1347 my $Param = get_TemplateParam
($TemplateInstance_Func{$Version}{$FuncInfoId}{$ParamPos});
1350 delete($FuncDescr{$Version}{$FuncInfoId});
1353 push(@TmplParams, $Param);
1355 $FuncDescr{$Version}{$FuncInfoId}{"ShortName"} .= "<".join(", ", @TmplParams).">";
1357 setFuncParams
($FuncInfoId);
1358 $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName
($FuncInfoId);
1359 if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1361 delete($FuncDescr{$Version}{$FuncInfoId});
1365 if((is_in_library
($FuncDescr{$Version}{$FuncInfoId}{"ShortName"}, $Version) or $CheckHeadersOnly) and not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and ($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function"))
1367 $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1369 set_Class_And_Namespace
($FuncInfoId);
1370 if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and not $FuncDescr{$Version}{$FuncInfoId}{"Class"})
1371 {#this section only for c++ functions without class that have not been mangled in the tree
1372 $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $mangled_name{get_func_signature
($FuncInfoId)};
1374 if(not is_in_library
($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
1376 delete($FuncDescr{$Version}{$FuncInfoId});
1379 if($FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
1381 delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
1383 my $FuncBody = getFuncBody
($FuncInfoId);
1384 if($FuncBody eq "defined")
1386 $FuncDescr{$Version}{$FuncInfoId}{"InLine"} = 1;
1388 if($CheckHeadersOnly and $FuncDescr{$Version}{$FuncInfoId}{"InLine"})
1390 delete($FuncDescr{$Version}{$FuncInfoId});
1393 if(($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Method") or $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
1395 if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1397 delete($FuncDescr{$Version}{$FuncInfoId});
1401 if(getFuncSpec
($FuncInfoId) eq "Virt")
1403 $FuncDescr{$Version}{$FuncInfoId}{"Virt"} = 1;
1405 if(getFuncSpec
($FuncInfoId) eq "PureVirt")
1406 {#pure virtual methods
1407 $FuncDescr{$Version}{$FuncInfoId}{"PureVirt"} = 1;
1409 if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_Z/ and $FuncDescr{$Version}{$FuncInfoId}{"Class"})
1411 if($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function")
1413 $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
1416 if(getFuncLink
($FuncInfoId) eq "Static")
1418 $FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
1420 delete($FuncDescr{$Version}{$FuncInfoId}{"Type"});
1425 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1426 if($FuncInfo =~ /body[ ]*:[ ]*undefined(\ |\Z)/i)
1430 elsif($FuncInfo =~ /body[ ]*:[ ]*@([0-9]+)(\ |\Z)/i)
1440 sub getTypeShortName
($)
1442 my $TypeName = $_[0];
1443 $TypeName =~ s/\<.*\>//g;
1444 $TypeName =~ s/.*\:\://g;
1450 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
1451 if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1463 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
1464 if($TypeInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1476 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1477 if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1489 my ($TypeDeclId, $TypeId, $TypeAttr) = @_;
1490 my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
1492 my $TypeType = $TypeAttr->{"Type"};
1494 my $BasePosition = 0;
1497 if($TypeType eq "Enum")
1499 $TypeMembInfoId = getEnumMembInfoId
($TypeId);
1500 while($TypeMembInfoId)
1502 $TypeAttr->{"Memb"}{$Position}{"value"} = getEnumMembVal
($TypeMembInfoId);
1503 my $MembName = getEnumMembName
($TypeMembInfoId);
1504 $TypeAttr->{"Memb"}{$Position}{"name"} = getEnumMembName
($TypeMembInfoId);
1505 $EnumMembName_Id{$Version}{getTreeAttr
($TypeMembInfoId, "valu")} = ($TypeAttr->{"NameSpace"})?$TypeAttr->{"NameSpace"}."::".$MembName:$MembName;
1506 $TypeMembInfoId = getNextMembInfoId
($TypeMembInfoId);
1510 elsif(($TypeType eq "Struct") or ($TypeType eq "Class") or ($TypeType eq "Union"))
1512 $TypeMembInfoId = getStructMembInfoId
($TypeId);
1513 while($TypeMembInfoId)
1515 if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} ne "field_decl")
1517 $TypeMembInfoId = getNextStructMembInfoId
($TypeMembInfoId);
1520 $StructMembName = getStructMembName
($TypeMembInfoId);
1521 if($StructMembName =~ /_vptr\./)
1523 $TypeMembInfoId = getNextStructMembInfoId
($TypeMembInfoId);
1526 if(not $StructMembName)
1528 #$TypeAttr->{"Base"}{$BasePosition}{"type"} = getStructMembType($TypeMembInfoId);
1529 #$TypeAttr->{"Base"}{$BasePosition}{"access"} = getStructMembAccess($TypeMembInfoId);
1531 $TypeMembInfoId = getNextStructMembInfoId
($TypeMembInfoId);
1534 $TypeAttr->{"Memb"}{$Position}{"type"} = getStructMembType
($TypeMembInfoId);
1535 $TypeAttr->{"Memb"}{$Position}{"name"} = $StructMembName;
1536 $TypeAttr->{"Memb"}{$Position}{"access"} = getStructMembAccess
($TypeMembInfoId);
1537 $TypeAttr->{"Memb"}{$Position}{"bitfield"} = getStructMembBitFieldSize
($TypeMembInfoId);
1539 $TypeMembInfoId = getNextStructMembInfoId
($TypeMembInfoId);
1545 sub setFuncParams
($)
1547 my $FuncInfoId = $_[0];
1548 my $ParamInfoId = getFuncParamInfoId
($FuncInfoId);
1549 my $FunctionType = getFuncType
($FuncInfoId);
1550 if($FunctionType eq "Method")
1552 $ParamInfoId = getNextElem
($ParamInfoId);
1557 my $ParamTypeId = getFuncParamType
($ParamInfoId);
1558 last if($TypeDescr{$Version}{getTypeDeclId
($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void");
1559 if($TypeDescr{$Version}{getTypeDeclId
($ParamTypeId)}{$ParamTypeId}{"Type"} eq "Restrict")
1560 {#delete restrict spec
1561 $ParamTypeId = getRestrictBase
($ParamTypeId);
1563 $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = $ParamTypeId;
1564 $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = getFuncParamName
($ParamInfoId);
1565 if(not $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"})
1567 $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = "p".($Position+1);
1569 $ParamInfoId = getNextElem
($ParamInfoId);
1572 if(detect_nolimit_args
($FuncInfoId))
1574 $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = -1;
1578 sub detect_nolimit_args
($)
1580 my $FuncInfoId = $_[0];
1581 my $FuncTypeId = getFuncTypeId
($FuncInfoId);
1582 my $ParamListElemId = getFuncParamTreeListId
($FuncTypeId);
1585 while($ParamListElemId)
1587 my $ParamTypeId = getTreeAttr
($ParamListElemId, "valu");
1588 if($TypeDescr{$Version}{getTypeDeclId
($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void")
1593 $ParamListElemId = getNextElem
($ParamListElemId);
1596 return ($Position>=1 and not $HaveVoid);
1599 sub getFuncParamTreeListId
($)
1601 my $FuncTypeId = $_[0];
1602 if($LibInfo{$Version}{$FuncTypeId}{"info"} =~ /prms[ ]*:[ ]*@([0-9]+) /)
1614 my ($Id, $Attr) = @_;
1615 if($LibInfo{$Version}{$Id}{"info"} =~ /$Attr[ ]*:[ ]*@([0-9]+) /)
1625 sub getRestrictBase
($)
1628 my $TypeDeclId = getTypeDeclId
($TypeId);
1629 my $BaseTypeId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"Tid"};
1630 my $BaseTypeDeclId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"TDid"};
1634 sub setFuncAccess
($)
1636 my $FuncInfoId = $_[0];
1637 if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1640 if($Access eq "prot")
1642 $FuncDescr{$Version}{$FuncInfoId}{"Protected"} = 1;
1644 elsif($Access eq "priv")
1646 $FuncDescr{$Version}{$FuncInfoId}{"Private"} = 1;
1651 sub setTypeAccess
($$)
1653 my ($TypeId, $TypeAttr) = @_;
1654 my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
1655 if($TypeInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1658 if($Access eq "prot")
1660 $TypeAttr->{"Protected"} = 1;
1662 elsif($Access eq "priv")
1664 $TypeAttr->{"Private"} = 1;
1671 my $FuncInfoId = $_[0];
1672 if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /pseudo tmpl/)
1674 $FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"} = 1;
1676 elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*constructor /)
1678 $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} = 1;
1680 elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*destructor /)
1682 $FuncDescr{$Version}{$FuncInfoId}{"Destructor"} = 1;
1688 my $FuncInfoId = $_[0];
1689 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1690 if($FuncInfo =~ m/spec[ ]*:[ ]*pure /)
1694 elsif($FuncInfo =~ m/spec[ ]*:[ ]*virt /)
1700 if($FuncInfo =~ /spec[ ]*:[ ]*([a-zA-Z]+) /)
1713 my $FuncInfoId = $_[0];
1714 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1715 if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1727 my $FuncInfoId = $_[0];
1728 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1729 if($FuncInfo =~ /link[ ]*:[ ]*static /)
1735 if($FuncInfo =~ /link[ ]*:[ ]*([a-zA-Z]+) /)
1748 my $FuncInfoId = $_[0];
1749 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1750 if($FuncInfo =~ /chan[ ]*:[ ]*@([0-9]+) /)
1760 sub getFuncParamInfoId
($)
1762 my $FuncInfoId = $_[0];
1763 my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1764 if($FuncInfo =~ /args[ ]*:[ ]*@([0-9]+) /)
1774 sub getFuncParamType
($)
1776 my $ParamInfoId = $_[0];
1777 my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
1778 if($ParamInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1788 sub getFuncParamName
($)
1790 my $ParamInfoId = $_[0];
1791 my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
1792 return "" if($ParamInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
1793 my $NameInfoId = $1;
1794 return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1795 my $FuncParamName = $1;
1796 $FuncParamName =~ s/[ ]+\Z//g;
1797 return $FuncParamName;
1800 sub getEnumMembInfoId
($)
1802 my $TypeInfoId = $_[0];
1803 my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1804 if($TypeInfo =~ /csts[ ]*:[ ]*@([0-9]+) /)
1814 sub getStructMembInfoId
($)
1816 my $TypeInfoId = $_[0];
1817 my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1818 if($TypeInfo =~ /flds[ ]*:[ ]*@([0-9]+) /)
1830 my $TypeInfoId = $_[0];
1831 my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1832 return "" if($TypeInfo !~ /scpe[ ]*:[ ]*@([0-9]+) /);
1833 my $NameSpaceInfoId = $1;
1834 if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
1836 my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
1837 if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1839 my $NameSpaceId = $1;
1840 my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
1841 return "" if($NameSpaceIdentifier !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1843 $NameSpace =~ s/[ ]+\Z//g;
1844 my $BaseNameSpace = getNameSpace
($NameSpaceInfoId);
1845 $NameSpace = $BaseNameSpace."::".$NameSpace if($BaseNameSpace);
1853 elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
1855 my %NameSpaceAttr = getTypeAttr
(getTypeDeclId
($NameSpaceInfoId), $NameSpaceInfoId);
1856 return $NameSpaceAttr{"Name"};
1864 sub getNameSpaceId
($)
1866 my $TypeInfoId = $_[0];
1867 my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1868 if($TypeInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1878 sub getEnumMembName
($)
1880 my $TypeMembInfoId = $_[0];
1881 return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /purp[ ]*:[ ]*@([0-9]+)/);
1883 return "" if($LibInfo{$Version}{$Purp}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1884 my $EnumMembName = $1;
1885 $EnumMembName =~ s/[ ]+\Z//g;
1886 return $EnumMembName;
1889 sub getStructMembName
($)
1891 my $TypeMembInfoId = $_[0];
1892 return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /name[ ]*:[ ]*@([0-9]+) /);
1893 my $NameInfoId = $1;
1894 return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1895 my $StructMembName = $1;
1896 $StructMembName =~ s/[ ]+\Z//g;
1897 return $StructMembName;
1900 sub getEnumMembVal
($)
1902 my $TypeMembInfoId = $_[0];
1903 return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /valu[ ]*:[ ]*@([0-9]+) /);
1905 if($LibInfo{$Version}{$Valu}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
1917 my $Info = $LibInfo{$Version}{$_[0]}{"info"};
1918 if($Info =~ /size[ ]*:[ ]*@([0-9]+) /)
1920 my $SizeInfoId = $1;
1921 if($LibInfo{$Version}{$SizeInfoId}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
1936 sub getStructMembType
($)
1938 my $TypeMembInfoId = $_[0];
1939 if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /type[ ]*:[ ]*@([0-9]+) /)
1949 sub getStructMembBitFieldSize
($)
1951 my $TypeMembInfoId = $_[0];
1952 if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ / bitfield /)
1954 return getSize
($TypeMembInfoId);
1962 sub getStructMembAccess
($)
1964 my $MembInfo = $LibInfo{$Version}{$_[0]}{"info"};
1965 if($MembInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1968 if($Access eq "prot")
1972 elsif($Access eq "priv")
1987 sub getNextMembInfoId
($)
1989 my $TypeMembInfoId = $_[0];
1990 if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
2000 sub getNextStructMembInfoId
($)
2002 my $TypeMembInfoId = $_[0];
2003 if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
2015 my $TypeMembInfoId = $_[0];
2016 if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} eq "field_decl")
2018 if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /name[ ]*:[ ]*@([0-9]+) /)
2033 sub getTypeHeader
($)
2035 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2036 if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2046 sub register_header
($$$)
2048 my ($Destination, $Position, $LibVersion) = @_;
2049 return if(not $Destination);
2050 if($Destination=~/\A\// and not -f
$Destination)
2052 print "\nERROR: specified header \'$Destination\' does not exist\n";
2055 my $Header_Name = get_FileName
($Destination);
2056 $Headers{$LibVersion}{$Destination}{"Name"} = $Header_Name;
2057 $Headers{$LibVersion}{$Destination}{"Position"} = $Position;
2058 $Headers{$LibVersion}{$Destination}{"Identity"} = $Destination;
2059 $HeaderName_Destinations{$LibVersion}{$Header_Name}{$Destination} = 1;
2064 my $LibVersion = $_[0];
2065 foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Include_Paths"}))
2067 $Dest =~ s/\A\s+|\s+\Z//g;
2071 print "ERROR: can't access \'$Dest\'\n";
2073 $Header_Dependency{$LibVersion}{$Dest} = 1;
2075 foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
2076 {#fill %Header_Dependency
2079 foreach my $Dir (cmd_find
($Dest,"d",""))
2082 $Header_Dependency{$LibVersion}{$Dir} = 1;
2087 $Header_Dependency{$LibVersion}{get_Dir
($Dest)} = 1;
2091 foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
2093 $Dest =~ s/\A\s+|\s+\Z//g;
2095 if(is_header
($Dest, $LibVersion))
2097 register_header
($Dest, $Position, $LibVersion);
2102 foreach my $Destination (sort {lc($a) cmp lc($b)} (cmd_find
($Dest,"f","")))
2104 chomp($Destination);
2105 next if(not is_header
($Destination, $LibVersion));
2106 register_header
($Destination, $Position, $LibVersion);
2112 print "WARNING: \'$Dest\' was not found in the specified include paths\n";
2113 register_header
($Dest, $Position, $LibVersion);
2117 if(keys(%{$Headers{$LibVersion}})==1)
2119 my $Destination = (keys(%{$Headers{$LibVersion}}))[0];
2120 $Headers{$LibVersion}{$Destination}{"Identity"} = $Headers{$LibVersion}{$Destination}{"Name"};
2122 foreach my $Header_Name (keys(%{$HeaderName_Destinations{$LibVersion}}))
2123 {#set relative paths (for dublicates)
2124 if(keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}})>1)
2126 my $FirstDest = (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))[0];
2127 my $Prefix = get_Dir
($FirstDest);
2128 while($Prefix =~ /\A(.+)\/[^\
/]+\Z/)
2131 my $Changes_Number = 0;
2133 foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2135 if($Dest =~ /\A$Prefix\/(.*)\Z
/)
2137 $Identity{$Dest} = $1;
2141 if($Changes_Number eq keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2143 foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2145 $Headers{$LibVersion}{$Dest}{"Identity"} = $Identity{$Dest};
2149 $Prefix = $NewPrefix;
2153 if(not keys(%{$Headers{$LibVersion}}))
2155 print "ERROR: header files were not found\n";
2163 if($Path =~ /\A(.*\/)([^\
/]*)\Z/)
2176 return "" if($Path =~ m
*\A\
./*);
2177 if($Path =~ /\A(.*)\/([^\
/]*)\Z/)
2190 $Str =~ s/([()\[\]{}$ &'"`;,<>])/\\$1/g;
2196 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2197 if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2209 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2210 if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2222 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2223 if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2235 my ($TypeDeclId, $TypeId) = @_;
2236 return "Const" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2237 return "Typedef" if($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:/ and $LibInfo{$Version}{$TypeId}{"info"} !~ /qual[ ]*:/);
2238 return "Volatile" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2239 return "Restrict" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2240 my $TypeType = getTypeTypeByTypeId
($TypeId);
2241 if($TypeType eq "Struct")
2243 if($TypeDeclId and $LibInfo{$Version}{$TypeDeclId}{"info_type"} eq "template_decl")
2259 sub getTypeTypeByTypeId
($)
2262 my $TypeType = $LibInfo{$Version}{$TypeId}{"info_type"};
2263 if($TypeType =~ /integer_type|real_type|boolean_type|void_type|complex_type/)
2267 elsif(isFuncPtr
($TypeId))
2271 elsif($TypeType eq "pointer_type")
2275 elsif($TypeType eq "reference_type")
2279 elsif($TypeType eq "union_type")
2283 elsif($TypeType eq "enumeral_type")
2287 elsif($TypeType eq "record_type")
2291 elsif($TypeType eq "array_type")
2295 elsif($TypeType eq "complex_type")
2299 elsif($TypeType eq "function_type")
2301 return "FunctionType";
2303 elsif($TypeType eq "method_type")
2305 return "MethodType";
2313 sub getNameByInfo
($)
2315 my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2316 return "" if($TypeInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
2317 my $TypeNameInfoId = $1;
2318 return "" if($LibInfo{$Version}{$TypeNameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
2320 $TypeName =~ s/[ ]+\Z//g;
2324 sub getFuncShortName
($)
2326 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2327 if($FuncInfo =~ / operator /)
2329 if($FuncInfo =~ /note[ ]*:[ ]*conversion /)
2331 return "operator ".get_TypeName
($FuncDescr{$Version}{$_[0]}{"Return"});
2335 return "" if($FuncInfo !~ / operator[ ]+([a-zA-Z]+) /);
2336 return "operator".$Operator_Indication{$1};
2341 return "" if($FuncInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
2342 my $FuncNameInfoId = $1;
2343 return "" if($LibInfo{$Version}{$FuncNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+lngt/);
2348 sub getFuncMnglName
($)
2350 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2351 return "" if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
2352 my $FuncMnglNameInfoId = $1;
2353 return "" if($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+/);
2354 my $FuncMnglName = $1;
2355 $FuncMnglName =~ s/[ ]+\Z//g;
2356 return $FuncMnglName;
2359 sub getFuncReturn
($)
2361 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2362 return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
2363 my $FuncTypeInfoId = $1;
2364 return "" if($LibInfo{$Version}{$FuncTypeInfoId}{"info"} !~ /retn[ ]*:[ ]*@([0-9]+) /);
2365 my $FuncReturnTypeId = $1;
2366 if($TypeDescr{$Version}{getTypeDeclId
($FuncReturnTypeId)}{$FuncReturnTypeId}{"Type"} eq "Restrict")
2367 {#delete restrict spec
2368 $FuncReturnTypeId = getRestrictBase
($FuncReturnTypeId);
2370 return $FuncReturnTypeId;
2375 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2376 if($FuncInfo =~ /orig[ ]*:[ ]*@([0-9]+) /)
2386 sub unmangleArray
(@)
2388 if($#_>$MAX_COMMAND_LINE_ARGUMENTS)
2390 my @Half = splice(@_, 0, ($#_+1)/2);
2391 return (unmangleArray
(@Half), unmangleArray
(@_))
2395 my $UnmangleCommand = "c++filt ".join(" ", @_);
2396 return split("\n", `$UnmangleCommand`);
2400 sub get_Signature($$)
2402 my ($Interface, $LibVersion) = @_;
2403 return $Cache{"get_Signature"}{$Interface}{$LibVersion} if($Cache{"get_Signature"}{$Interface}{$LibVersion});
2404 my ($MnglName, $SymbolVersion) = ($Interface, "");
2405 if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
2407 ($MnglName, $SymbolVersion) = ($1, $2);
2409 if($MnglName =~ /\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZThn|_ZTv0_n)/)
2411 $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
2412 return $Cache{"get_Signature"}{$Interface}{$LibVersion};
2414 if(not $CompleteSignature{$LibVersion}{$Interface})
2416 if($Interface =~ /\A_Z/)
2418 $Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
2419 return $Cache{"get_Signature"}{$Interface}{$LibVersion};
2423 $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Interface;
2427 my ($Func_Signature, @Param_Types_FromUnmangledName) = ();
2428 my $ShortName = $CompleteSignature{$LibVersion}{$Interface}{"ShortName"};
2429 if($Interface =~ /\A_Z/)
2431 if($CompleteSignature{$LibVersion}{$Interface}{"Class"})
2433 $Func_Signature = get_TypeName($CompleteSignature{$LibVersion}{$Interface}{"Class"}, $LibVersion)."::".(($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})?"~":"").$ShortName;
2437 $Func_Signature = $ShortName;
2439 @Param_Types_FromUnmangledName = get_Signature_Parts($tr_name{$MnglName}, 0);
2443 $Func_Signature = $MnglName;
2445 my @ParamArray = ();
2446 foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Interface}{"Param"}}))
2448 next if($Pos eq "");
2449 my $ParamTypeId = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"type"};
2450 my $ParamTypeName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ParamTypeId}}{$ParamTypeId}{"Name"};
2451 $ParamTypeName = $Param_Types_FromUnmangledName[$Pos] if(not $ParamTypeName);
2452 if(my $ParamName = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"name"})
2454 if($ParamTypeName=~/\([*]+\)/)
2456 $ParamTypeName=~s/\(([*]+)\)/\($1$ParamName\)/;
2457 push(@ParamArray, $ParamTypeName);
2461 push(@ParamArray, $ParamTypeName." ".$ParamName);
2466 push(@ParamArray, $ParamTypeName);
2469 if(not $CompleteSignature{$LibVersion}{$Interface}{"Data"})
2471 if($Interface=~/\A_Z/)
2473 if($CompleteSignature{$LibVersion}{$Interface}{"Constructor"})
2475 if($Interface=~/C1/)
2477 $Func_Signature .= " [in-charge]";
2479 elsif($Interface=~/C2/)
2481 $Func_Signature .= " [not-in-charge]";
2484 elsif($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})
2486 if($Interface=~/D1/)
2488 $Func_Signature .= " [in-charge]";
2490 elsif($Interface=~/D2/)
2492 $Func_Signature .= " [not-in-charge]";
2494 elsif($Interface=~/D0/)
2496 $Func_Signature .= " [in-charge-deleting]";
2500 $Func_Signature .= " (".join(", ", @ParamArray).")";
2502 if($Interface=~/\A_ZNK/)
2504 $Func_Signature .= " const";
2506 $Func_Signature .= "\@".$SymbolVersion if($SymbolVersion);
2507 $Cache{"get_Signature"}{$Interface}{$LibVersion} = $Func_Signature;
2508 return $Func_Signature;
2511 sub getVarNameByAttr($)
2513 my $FuncInfoId = $_[0];
2515 return "" if(not $FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
2516 if($FuncDescr{$Version}{$FuncInfoId}{"Class"})
2518 $VarName .= $TypeDescr{$Version}{getTypeDeclId($FuncDescr{$Version}{$FuncInfoId}{"Class"})}{$FuncDescr{$Version}{$FuncInfoId}{"Class"}}{"Name"};
2521 $VarName .= $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
2525 sub mangleFuncName($)
2532 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2533 return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
2534 my $FuncTypeInfoId = $1;
2535 my $FunctionType = $LibInfo{$Version}{$FuncTypeInfoId}{"info_type"};
2536 if($FunctionType eq "method_type")
2540 elsif($FunctionType eq "function_type")
2546 return $FunctionType;
2550 sub getFuncTypeId($)
2552 my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2553 if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+)( |\Z)/)
2565 return (not isAnon($_[0]));
2570 return (($_[0] =~ m/\.\_[0-9]+/) or ($_[0] =~ m/anon-/));
2573 sub unmangled_Compact($$)
2574 #Removes all non-essential (for C++ language) whitespace from a string. If
2575 #the whitespace is essential it will be replaced with exactly one ' '
2576 #character. Works correctly only for unmangled names.
2577 #If level > 1 is supplied, can relax its intent to compact the string.
2580 my $level = $_[1] || 1;
2581 my $o1 = ($level>1)?' ':'';
2582 #First, we reduce all spaces that we can
2583 my $coms='[-()<>:*&~!|+=%@~"?.,/[^'."']";
2584 my $coms_nobr='[-()<:*&~!|+=%@~"?.,'."']";
2585 my $clos='[),;:\]]';
2586 $result=~s/^\s+//gm;
2587 $result=~s/\s+$//gm;
2588 $result=~s/((?!\n)\s)+/ /g;
2589 $result=~s/(\w+)\s+($coms+)/$1$o1$2/gm;
2590 #$result=~s/(\w)(\()/$1$o1$2/gm if $o1;
2591 $result=~s/($coms+)\s+(\w+)/$1$o1$2/gm;
2592 $result=~s/(\()\s+(\w)/$1$2/gm if $o1;
2593 $result=~s/(\w)\s+($clos)/$1$2/gm;
2594 $result=~s/($coms+)\s+($coms+)/$1 $2/gm;
2595 $result=~s/($coms_nobr+)\s+($coms+)/$1$o1$2/gm;
2596 $result=~s/($coms+)\s+($coms_nobr+)/$1$o1$2/gm;
2597 #don't forget about >> and <:. In unmangled names global-scope modifier
2598 #is not used, so <: will always be a digraph and requires no special treatment.
2599 #We also try to remove other parts that are better to be removed here than in other places
2601 $result=~s/\bconst\s+const\b/const/gm;
2602 $result=~s/\bvolatile\s+volatile\b/volatile/gm;
2603 $result=~s/\bconst\s+volatile\b\s+const\b/const volatile/gm;
2604 $result=~s/\bvolatile\s+const\b\s+volatile\b/const volatile/gm;
2605 #Place cv in proper order
2606 $result=~s/\bvolatile\s+const\b/const volatile/gm;
2610 sub unmangled_PostProcess($)
2613 #s/\bunsigned int\b/unsigned/g;
2614 $result =~ s/\bshort unsigned int\b/unsigned short/g;
2615 $result =~ s/\bshort int\b/short/g;
2616 $result =~ s/\blong long unsigned int\b/unsigned long long/g;
2617 $result =~ s/\blong unsigned int\b/unsigned long/g;
2618 $result =~ s/\blong long int\b/long long/g;
2619 $result =~ s/\blong int\b/long/g;
2620 $result =~ s/\)const\b/\) const/g;
2621 $result =~ s/\blong long unsigned\b/unsigned long long/g;
2622 $result =~ s/\blong unsigned\b/unsigned long/g;
2626 # From libtodb2/libtodb.pm
2627 # Trim string spaces.
2631 $string =~ s/^\s+//;
2632 $string =~ s/\s+$//;
2637 {#type name correction
2638 my $CorrectName = $_[0];
2639 $CorrectName = unmangled_Compact($CorrectName, 1);
2640 $CorrectName = unmangled_PostProcess($CorrectName);
2641 return $CorrectName;
2644 sub getDump_AllInOne()
2646 return if(not keys(%Headers));
2647 `mkdir -p temp
&& rm
-f temp
/*`;
2648 my $Header_Depend = "";
2649 foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
2651 $Header_Depend .= " -I".esc($Dep);
2653 my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
2654 open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
2655 foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
2657 print LIB_HEADER "#include <$Preamble_Header>\n";
2659 foreach my $Destination (sort {int($Headers{$Version}{$a}{"Position"})<=>int($Headers{$Version}{$b}{"Position"})} keys(%{$Headers{$Version}}))
2661 my $HName = get_FileName($Destination);
2662 next if($Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$HName} and $HeaderName_Destinations{$Version}{$HName} and keys(%{$HeaderName_Destinations{$Version}{$HName}})==1));
2663 print LIB_HEADER "#include <$Destination>\n";
2666 system("g++ >".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
2669 print "WARNING: some errors have occured while compiling header(s), fix it first!\nyou can see compilation errors in the file \'$ERR_PATH{$Version}\'\n";
2671 $ConstantsSrc{$Version} = cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
2672 system("mkdir", "-p", "header_compile_errors/$TargetLibraryName/temp/");
2673 system("cp", "-f", "temp/$TargetLibraryName"."_v$Version.h", "header_compile_errors/$TargetLibraryName/temp/");
2674 return (split("\n", `find
. -maxdepth
1 -name
"$Lib_VersionName\.h*\.tu"`))[0];
2677 sub getDump_Separately($)
2681 my $Destination = $_[0];
2682 my $Header_Depend = "";
2683 foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
2685 $Header_Depend .= " -I".esc($Dep);
2687 my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
2688 open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
2689 foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
2691 print LIB_HEADER "#include <$Preamble_Header>\n";
2693 my $Destination_HName = get_FileName($Destination);
2694 if(not ( $Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$Destination_HName} and $HeaderName_Destinations{$Version}{$Destination_HName} and keys(%{$HeaderName_Destinations{$Version}{$Destination_HName}})==1) ))
2696 print LIB_HEADER "#include <$Destination>\n";
2699 system("g++ >>".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
2702 $HeaderCompileError{get_FileName($Destination)} = 1;
2704 $ConstantsSrc{$Version} .= cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
2705 return (split("\n", `find
. -maxdepth
1 -name
"$Lib_VersionName\.h*\.tu"`))[0];
2711 return "" if(not $Path or not -e $Path);
2712 my $Cmd = "file ".esc($Path);
2713 my $Cmd_Out = `$Cmd`;
2717 sub cmd_preprocessor
($$$)
2719 my ($Path, $AddOpt, $Grep) = @_;
2720 return "" if(not $Path or not -f
$Path);
2721 my $Cmd = "g++ -dD -E -x c++-header ".esc
($Path)." 2>/dev/null $AddOpt";
2724 $Cmd .= " | grep \"$Grep\"";
2726 my $Cmd_Out = `$Cmd`;
2732 my ($Path, $Grep) = @_;
2733 return "" if(not $Path or not -e $Path);
2734 my $Cmd = "cat ".esc($Path);
2737 $Cmd .= " | grep \"$Grep\"";
2739 my $Cmd_Out = `$Cmd`;
2745 my ($Path, $Type, $Name) = @_;
2746 return () if(not $Path or not -e
$Path);
2747 my $Cmd = "find ".esc
($Path);
2750 $Cmd .= " -type $Type";
2754 $Cmd .= " -name \"$Name\"";
2756 return split("\n", `$Cmd`);
2762 return "" if(not $Path or not -e $Path);
2763 my $Cmd = "tar -xvzf ".esc($Path);
2764 my $Cmd_Out = `$Cmd`;
2770 my ($Destination, $LibVersion) = @_;
2771 return 0 if(-d
$Destination);
2772 return 1 if($Destination =~ /\.(h|hh|hhh|hpp|tcc)\Z/i);
2773 return 0 if($Destination =~ /\.\w+\Z/i);#cpp|c|gch|tu|fs|pas
2774 if($Destination =~ /\A\//)
2776 return (cmd_file
($Destination) =~ /:[ ]*ASCII C[\+]* program text/);
2780 foreach my $Prefix (keys(%{$Header_Dependency{$LibVersion}}))
2782 my $Path = $Prefix."/".$Destination;
2785 if(cmd_file
($Path) =~ /:[ ]*ASCII C[\+]* program text/)
2795 sub parseHeaders_AllInOne
($)
2798 print "checking header(s) ".$Descriptor{$Version}{"Version"}." ...\n";
2799 system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
2800 system("rm", "-fr", $ERR_PATH{$Version});
2801 my $DumpPath = getDump_AllInOne
();
2804 print "\nERROR: can't create gcc syntax tree for header(s)\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
2809 system("rm", "-fr", "temp");
2814 my $Destination = $_[0];
2815 my $DumpPath = getDump_Separately
($Destination);
2818 print "ERROR: can't create gcc syntax tree for header\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
2823 system("rm", "-fr", "temp");
2826 sub is_in_library
($$)
2828 my ($MnglName, $LibVersion) = @_;
2829 return ($Interface_Library{$LibVersion}{$MnglName} or ($SymVer{$LibVersion}{$MnglName} and $Interface_Library{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}));
2832 sub prepareInterfaces
($)
2834 my $LibVersion = $_[0];
2835 my (@MnglNames, @UnMnglNames) = ();
2836 if($CheckHeadersOnly)
2838 foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
2840 if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
2842 push(@MnglNames, $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"});
2845 if($#MnglNames > -1)
2847 @UnMnglNames = reverse(unmangleArray
(@MnglNames));
2848 foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
2850 if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
2852 my $UnmangledName = pop(@UnMnglNames);
2853 $tr_name{$FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"}} = $UnmangledName;
2858 my (%NotMangled_Int, %Mangled_Int) = ();
2859 foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
2861 my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
2862 if($MnglName=~/\A_Z/)
2864 $Mangled_Int{$FuncInfoId} = $MnglName;
2868 $NotMangled_Int{$FuncInfoId} = $MnglName;
2870 next if(not $MnglName or not is_in_library
($MnglName, $LibVersion) and not $CheckHeadersOnly);
2871 next if($MnglName =~ /\A_Z/ and $tr_name{$MnglName} =~ /\.\_[0-9]/);
2872 next if(not $FuncDescr{$LibVersion}{$FuncInfoId}{"Header"});
2873 %{$CompleteSignature{$LibVersion}{$MnglName}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2874 #interface and its symlink have same signatures
2875 if($SymVer{$LibVersion}{$MnglName})
2877 %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2879 delete($FuncDescr{$LibVersion}{$FuncInfoId});
2881 if(keys(%Mangled_Int))
2883 foreach my $Interface_Id (keys(%NotMangled_Int))
2885 delete($CompleteSignature{$LibVersion}{$NotMangled_Int{$Interface_Id}});
2893 my $LibVersion = $_[0];
2894 foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
2896 my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
2897 if(not $MnglName or not is_in_library
($MnglName, $LibVersion) and not $CheckHeadersOnly)
2899 delete($FuncDescr{$LibVersion}{$FuncInfoId});
2902 if(defined $InterfacesListPath and not $InterfacesList{$MnglName})
2904 delete($FuncDescr{$LibVersion}{$FuncInfoId});
2907 if(defined $AppPath and not $InterfacesList_App{$MnglName})
2909 delete($FuncDescr{$LibVersion}{$FuncInfoId});
2912 my %FuncInfo = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2913 detect_TypeUsing
($Tid_TDid{$LibVersion}{$FuncInfo{"Return"}}, $FuncInfo{"Return"}, $LibVersion);
2914 detect_TypeUsing
($Tid_TDid{$LibVersion}{$FuncInfo{"Class"}}, $FuncInfo{"Class"}, $LibVersion);
2915 foreach my $Param_Pos (keys(%{$FuncInfo{"Param"}}))
2917 my $Param_TypeId = $FuncInfo{"Param"}{$Param_Pos}{"type"};
2918 detect_TypeUsing
($Tid_TDid{$LibVersion}{$Param_TypeId}, $Param_TypeId, $LibVersion);
2921 foreach my $TDid (keys(%{$TypeDescr{$LibVersion}}))
2923 foreach my $Tid (keys(%{$TypeDescr{$LibVersion}{$TDid}}))
2925 if(not $UsedType{$LibVersion}{$TDid}{$Tid})
2927 delete($TypeDescr{$LibVersion}{$TDid}{$Tid});
2928 if(not keys(%{$TypeDescr{$LibVersion}{$TDid}}))
2930 delete($TypeDescr{$LibVersion}{$TDid});
2932 delete($Tid_TDid{$LibVersion}{$Tid}) if($Tid_TDid{$LibVersion}{$Tid} eq $TDid);
2938 sub detect_TypeUsing
($$$)
2940 my ($TypeDeclId, $TypeId, $LibVersion) = @_;
2941 return if($UsedType{$LibVersion}{$TypeDeclId}{$TypeId});
2942 my %Type = get_Type
($TypeDeclId, $TypeId, $LibVersion);
2943 if($Type{"Type"} =~ /Struct|Union|Class|FuncPtr|Enum/)
2945 $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2946 foreach my $Memb_Pos (keys(%{$Type{"Memb"}}))
2948 my $Member_TypeId = $Type{"Memb"}{$Memb_Pos}{"type"};
2949 detect_TypeUsing
($Tid_TDid{$LibVersion}{$Member_TypeId}, $Member_TypeId, $LibVersion);
2951 if($Type{"Type"} eq "FuncPtr")
2953 my $ReturnType = $Type{"Return"};
2954 detect_TypeUsing
($Tid_TDid{$LibVersion}{$ReturnType}, $ReturnType, $LibVersion);
2957 elsif($Type{"Type"} =~ /Const|Pointer|Ref|Volatile|Restrict|Array|/)
2959 $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2960 detect_TypeUsing
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
2962 elsif($Type{"Type"} eq "Intrinsic")
2964 $UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2968 delete($TypeDescr{$LibVersion}{$TypeDeclId}{$TypeId});
2969 if(not keys(%{$TypeDescr{$LibVersion}{$TypeDeclId}}))
2971 delete($TypeDescr{$LibVersion}{$TypeDeclId});
2973 delete($Tid_TDid{$LibVersion}{$TypeId}) if($Tid_TDid{$LibVersion}{$TypeId} eq $TypeDeclId);
2977 sub initializeClassVirtFunc
($)
2979 my $LibVersion = $_[0];
2980 foreach my $Interface (keys(%{$CompleteSignature{$LibVersion}}))
2982 if($CompleteSignature{$LibVersion}{$Interface}{"Virt"})
2984 my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{"Name"};
2985 $ClassVirtFunc{$LibVersion}{$ClassName}{$Interface} = 1;
2986 $ClassIdVirtFunc{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{$Interface} = 1;
2987 $ClassId{$LibVersion}{$ClassName} = $CompleteSignature{$LibVersion}{$Interface}{"Class"};
2992 sub checkVirtFuncRedefinitions
($)
2994 my $LibVersion = $_[0];
2995 foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
2997 $CheckedTypes{$Class_Name} = 1;
2998 foreach my $VirtFuncName (keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
3000 $CompleteSignature{$LibVersion}{$VirtFuncName}{"VirtualRedefine"} = find_virtual_method_in_base_classes
($VirtFuncName, $ClassId{$LibVersion}{$Class_Name}, $LibVersion);
3005 sub setVirtFuncPositions
($)
3007 my $LibVersion = $_[0];
3008 foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
3010 $CheckedTypes{$Class_Name} = 1;
3012 foreach my $VirtFuncName (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
3014 if($ClassVirtFunc{1}{$Class_Name}{$VirtFuncName} and $ClassVirtFunc{2}{$Class_Name}{$VirtFuncName} and not $CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"} and not $CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
3016 $CompleteSignature{$LibVersion}{$VirtFuncName}{"Position"} = $Position;
3023 sub check_VirtualTable
($$)
3025 my ($TargetFunction, $LibVersion) = @_;
3026 my $Class_Id = $CompleteSignature{$LibVersion}{$TargetFunction}{"Class"};
3027 my $Class_DId = $Tid_TDid{$LibVersion}{$Class_Id};
3028 my %Class_Type = get_Type
($Class_DId, $Class_Id, $LibVersion);
3029 $CheckedTypes{$Class_Type{"Name"}} = 1;
3030 foreach my $VirtFuncName (keys(%{$ClassVirtFunc{2}{$Class_Type{"Name"}}}))
3032 if($ClassId{1}{$Class_Type{"Name"}} and not $ClassVirtFunc{1}{$Class_Type{"Name"}}{$VirtFuncName} and $AddedInt{$VirtFuncName})
3034 if($CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
3036 if($TargetFunction eq $VirtFuncName)
3038 my $BaseClass_Id = $CompleteSignature{2}{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
3039 my %BaseClass_Type = get_Type
($Tid_TDid{2}{$BaseClass_Id}, $BaseClass_Id, 2);
3040 my $BaseClass_Name = $BaseClass_Type{"Name"};
3041 %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition"}{$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}}}=(
3042 "Type_Name"=>$Class_Type{"Name"},
3043 "Type_Type"=>$Class_Type{"Type"},
3044 "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
3045 "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
3046 "Target"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
3047 "Signature"=>$tr_name{$TargetFunction},
3048 "Old_Value"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
3049 "New_Value"=>$tr_name{$TargetFunction},
3050 "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3051 "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3054 elsif($TargetFunction ne $VirtFuncName)
3056 %{$CompatProblems{$TargetFunction}{"Added_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
3057 "Type_Name"=>$Class_Type{"Name"},
3058 "Type_Type"=>$Class_Type{"Type"},
3059 "Header"=>$Class_Type{"Header"},
3060 "Line"=>$Class_Type{"Line"},
3061 "Target"=>$tr_name{$VirtFuncName},
3062 "Signature"=>$tr_name{$TargetFunction},
3063 "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3064 "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3068 foreach my $VirtFuncName (keys(%{$ClassVirtFunc{1}{$Class_Type{"Name"}}}))
3070 if($ClassId{2}{$Class_Type{"Name"}} and not $ClassVirtFunc{2}{$Class_Type{"Name"}}{$VirtFuncName} and $WithdrawnInt{$VirtFuncName})
3072 if($CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"})
3074 if($TargetFunction eq $VirtFuncName)
3076 my $BaseClass_Id = $CompleteSignature{1}{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
3077 my $BaseClass_Name = $TypeDescr{1}{$Tid_TDid{1}{$BaseClass_Id}}{$BaseClass_Id}{"Name"};
3078 %{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition_B"}{$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}}}=(
3079 "Type_Name"=>$Class_Type{"Name"},
3080 "Type_Type"=>$Class_Type{"Type"},
3081 "Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
3082 "Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
3083 "Target"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
3084 "Signature"=>$tr_name{$TargetFunction},
3085 "Old_Value"=>$tr_name{$TargetFunction},
3086 "New_Value"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
3087 "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3088 "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3093 %{$CompatProblems{$TargetFunction}{"Withdrawn_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
3094 "Type_Name"=>$Class_Type{"Name"},
3095 "Type_Type"=>$Class_Type{"Type"},
3096 "Header"=>$Class_Type{"Header"},
3097 "Line"=>$Class_Type{"Line"},
3098 "Target"=>$tr_name{$VirtFuncName},
3099 "Signature"=>$tr_name{$TargetFunction},
3100 "Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3101 "New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3107 sub find_virtual_method_in_base_classes
($$$)
3109 my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
3110 foreach my $BaseClass_Id (keys(%{$TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$Checked_ClassId}}{$Checked_ClassId}{"BaseClass"}}))
3112 my $VirtMethodInClass = find_virtual_method_in_class
($VirtFuncName, $BaseClass_Id, $LibVersion);
3113 if($VirtMethodInClass)
3115 return $VirtMethodInClass;
3117 my $VirtMethodInBaseClasses = find_virtual_method_in_base_classes
($VirtFuncName, $BaseClass_Id, $LibVersion);
3118 if($VirtMethodInBaseClasses)
3120 return $VirtMethodInBaseClasses;
3126 sub find_virtual_method_in_class
($$$)
3128 my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
3129 my $Suffix = getFuncSuffix
($VirtFuncName, $LibVersion);
3130 foreach my $Checked_VirtFuncName (keys(%{$ClassIdVirtFunc{$LibVersion}{$Checked_ClassId}}))
3132 if($Suffix eq getFuncSuffix
($Checked_VirtFuncName, $LibVersion)
3133 and ((not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} and not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"} and $CompleteSignature{$LibVersion}{$VirtFuncName}{"ShortName"} eq $CompleteSignature{$LibVersion}{$Checked_VirtFuncName}{"ShortName"}) or ($CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} or $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"})))
3135 return $Checked_VirtFuncName;
3141 sub getFuncSuffix
($$)
3143 my ($FuncName, $LibVersion) = @_;
3144 my $ClassId = $CompleteSignature{$LibVersion}{$FuncName}{"Class"};
3145 my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ClassId}}{$ClassId}{"Name"};
3146 my $ShortName = $CompleteSignature{$LibVersion}{$FuncName}{"ShortName"};
3147 my $Suffix = $tr_name{$FuncName};
3148 $Suffix =~ s/\A$ClassName\:\:[~]*$ShortName[ ]*//g;
3152 sub isRecurType
($$$$)
3154 foreach (@RecurTypes)
3156 if($_->{"Tid1"} eq $_[0]
3157 and $_->{"TDid1"} eq $_[1]
3158 and $_->{"Tid2"} eq $_[2]
3159 and $_->{"TDid2"} eq $_[3])
3167 sub find_MemberPair_Pos_byName
($$)
3169 my ($Member_Name, $Pair_Type) = @_;
3170 foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
3172 if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"name"} eq $Member_Name)
3174 return $MemberPair_Pos;
3180 sub getBitfieldSum
($$)
3182 my ($Member_Pos, $Pair_Type) = @_;
3183 my $BitfieldSum = 0;
3184 while($Member_Pos>-1)
3186 return $BitfieldSum if(not $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"});
3187 $BitfieldSum += $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"};
3190 return $BitfieldSum;
3193 sub find_MemberPair_Pos_byVal
($$)
3195 my ($Member_Value, $Pair_Type) = @_;
3196 foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
3198 if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"value"} eq $Member_Value)
3200 return $MemberPair_Pos;
3206 my %Priority_Value=(
3212 sub max_priority
($$)
3214 my ($Priority1, $Priority2) = @_;
3215 if(cmp_priority
($Priority1, $Priority2))
3225 sub cmp_priority
($$)
3227 my ($Priority1, $Priority2) = @_;
3228 return ($Priority_Value{$Priority1}>$Priority_Value{$Priority2});
3231 sub set_Problems_Priority
()
3233 foreach my $InterfaceName (sort keys(%CompatProblems))
3235 foreach my $Kind (sort keys(%{$CompatProblems{$InterfaceName}}))
3237 foreach my $Location (sort keys(%{$CompatProblems{$InterfaceName}{$Kind}}))
3239 my $IsInTypeInternals = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"IsInTypeInternals"};
3240 my $InitialType_Type = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"InitialType_Type"};
3241 if($Kind eq "Function_Become_Static")
3243 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3245 elsif($Kind eq "Function_Become_NonStatic")
3247 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3249 elsif($Kind eq "Parameter_Type_And_Size")
3251 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3253 elsif($Kind eq "Parameter_Type")
3255 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3257 elsif($Kind eq "Withdrawn_Parameter")
3259 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3261 elsif($Kind eq "Added_Parameter")
3263 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3265 elsif($Kind eq "Parameter_BaseType_And_Size")
3267 if($InitialType_Type eq "Pointer")
3269 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3273 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3276 elsif($Kind eq "Parameter_BaseType")
3278 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3280 elsif($Kind eq "Parameter_PointerLevel")
3282 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3284 elsif($Kind eq "Return_Type_And_Size")
3286 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3288 elsif($Kind eq "Return_Type")
3290 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3292 elsif($Kind eq "Return_BaseType_And_Size")
3294 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3296 elsif($Kind eq "Return_BaseType")
3298 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3300 elsif($Kind eq "Return_PointerLevel")
3302 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3304 if($Kind eq "Added_Virtual_Function")
3306 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3308 elsif($Kind eq "Withdrawn_Virtual_Function")
3310 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3312 elsif($Kind eq "Virtual_Function_Position")
3314 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3316 elsif($Kind eq "Virtual_Function_Redefinition")
3318 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3320 elsif($Kind eq "Virtual_Function_Redefinition_B")
3322 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3324 elsif($Kind eq "Size")
3326 if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3328 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3332 if($IsInTypeInternals)
3334 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3338 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3342 elsif($Kind eq "BaseType")
3344 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3346 elsif($Kind eq "Added_Member_And_Size")
3348 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3350 elsif($Kind eq "Added_Middle_Member_And_Size")
3352 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3354 elsif($Kind eq "Withdrawn_Member_And_Size")
3356 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3358 elsif($Kind eq "Withdrawn_Member")
3360 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3362 elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
3364 if($IsInTypeInternals)
3366 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3370 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3373 elsif($Kind eq "Withdrawn_Middle_Member")
3375 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3377 elsif($Kind eq "Member_Rename")
3379 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3381 elsif($Kind eq "Enum_Member_Value")
3383 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3385 elsif($Kind eq "Enum_Member_Name")
3387 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3389 elsif($Kind eq "Member_Type_And_Size")
3391 if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3393 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3397 if($IsInTypeInternals)
3399 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3403 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3407 elsif($Kind eq "Member_Type")
3409 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3411 elsif($Kind eq "Member_BaseType_And_Size")
3413 if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3415 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3419 if($IsInTypeInternals)
3421 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3425 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3429 elsif($Kind eq "Member_BaseType")
3431 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3433 elsif($Kind eq "Member_PointerLevel")
3435 if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3437 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3441 if($IsInTypeInternals)
3443 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3447 $CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3458 my %TypeDescriptor=(
3463 push(@RecurTypes, \
%TypeDescriptor);
3466 sub mergeTypes
($$$$)
3468 my ($Type1_Id, $Type1_DId, $Type2_Id, $Type2_DId) = @_;
3469 my (%Sub_SubProblems, %SubProblems) = ();
3470 if((not $Type1_Id and not $Type1_DId) or (not $Type2_Id and not $Type2_DId))
3471 {#Not Empty Inputs Only
3474 if($Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId})
3476 return %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}};
3478 my %Type1 = get_Type
($Type1_DId, $Type1_Id, 1);
3479 my %Type2 = get_Type
($Type2_DId, $Type2_Id, 2);
3480 my %Type1_Pure = get_PureType
($Type1_DId, $Type1_Id, 1);
3481 my %Type2_Pure = get_PureType
($Type2_DId, $Type2_Id, 2);
3482 return () if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"});
3483 if(isRecurType
($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"}))
3484 {#Recursive Declarations
3487 return if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
3488 return if($OpaqueTypes{1}{$Type1_Pure{"Name"}} or $OpaqueTypes{2}{$Type1_Pure{"Name"}} or $OpaqueTypes{1}{$Type1{"Name"}} or $OpaqueTypes{2}{$Type1{"Name"}});
3490 my %Typedef_1 = goToFirst
($Type1{"TDid"}, $Type1{"Tid"}, 1, "Typedef");
3491 my %Typedef_2 = goToFirst
($Type2{"TDid"}, $Type2{"Tid"}, 2, "Typedef");
3492 if($Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef" and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
3494 my %Base_1 = get_OneStep_BaseType
($Typedef_1{"TDid"}, $Typedef_1{"Tid"}, 1);
3495 my %Base_2 = get_OneStep_BaseType
($Typedef_2{"TDid"}, $Typedef_2{"Tid"}, 2);
3496 if($Base_1{"Name"}!~/anon\-/ and $Base_2{"Name"}!~/anon\-/
3497 and ($Base_1{"Name"} ne $Base_2{"Name"}))
3499 %{$SubProblems{"BaseType"}{$Typedef_1{"Name"}}}=(
3500 "Type_Name"=>$Typedef_1{"Name"},
3501 "Type_Type"=>"Typedef",
3502 "Header"=>$Typedef_2{"Header"},
3503 "Line"=>$Typedef_2{"Line"},
3504 "Old_Value"=>$Base_1{"Name"},
3505 "New_Value"=>$Base_2{"Name"} );
3509 if(($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} ne "Pointer") and $Type1_Pure{"Name"}!~/anon\-/)
3514 pushType
($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"});
3515 if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} =~ /Struct|Class|Union/))
3517 if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3519 %{$SubProblems{"Size"}{$Type1_Pure{"Name"}}}=(
3520 "Type_Name"=>$Type1_Pure{"Name"},
3521 "Type_Type"=>$Type1_Pure{"Type"},
3522 "Header"=>$Type2_Pure{"Header"},
3523 "Line"=>$Type2_Pure{"Line"},
3524 "Old_Value"=>$Type1_Pure{"Size"},
3525 "New_Value"=>$Type2_Pure{"Size"} );
3528 if($Type1_Pure{"Name"} and $Type2_Pure{"Name"} and ($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Name"} !~ /\Avoid[ ]*\*/) and ($Type2_Pure{"Name"} =~ /\Avoid[ ]*\*/))
3533 if($Type1_Pure{"BaseType"}{"Tid"} and $Type2_Pure{"BaseType"}{"Tid"})
3535 %Sub_SubProblems = &mergeTypes
($Type1_Pure{"BaseType"}{"Tid"}, $Type1_Pure{"BaseType"}{"TDid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"TDid"});
3536 foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3538 foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
3540 %{$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}} = %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
3541 $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
3545 foreach my $Member_Pos (sort keys(%{$Type1_Pure{"Memb"}}))
3547 next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
3548 my $Member_Name = $Type1_Pure{"Memb"}{$Member_Pos}{"name"};
3549 next if(not $Member_Name);
3550 my $Member_Location = $Member_Name;
3551 my $MemberPair_Pos = find_MemberPair_Pos_byName
($Member_Name, \
%Type2_Pure);
3552 if(($MemberPair_Pos eq "lost") and (($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class")))
3554 if($Member_Pos > keys(%{$Type2_Pure{"Memb"}}) - 1)
3556 if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3558 %{$SubProblems{"Withdrawn_Member_And_Size"}{$Member_Name}}=(
3559 "Target"=>$Member_Name,
3560 "Type_Name"=>$Type1_Pure{"Name"},
3561 "Type_Type"=>$Type1_Pure{"Type"},
3562 "Header"=>$Type2_Pure{"Header"},
3563 "Line"=>$Type2_Pure{"Line"},
3564 "Old_Size"=>$Type1_Pure{"Size"},
3565 "New_Size"=>$Type2_Pure{"Size"} );
3569 %{$SubProblems{"Withdrawn_Member"}{$Member_Name}}=(
3570 "Target"=>$Member_Name,
3571 "Type_Name"=>$Type1_Pure{"Name"},
3572 "Type_Type"=>$Type1_Pure{"Type"},
3573 "Header"=>$Type2_Pure{"Header"},
3574 "Line"=>$Type2_Pure{"Line"} );
3578 elsif($Member_Pos < keys(%{$Type1_Pure{"Memb"}}) - 1)
3580 my $MemberType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3581 my %MemberType_Pure = get_PureType
($Tid_TDid{1}{$MemberType_Id}, $MemberType_Id, 1);
3582 my $MemberStraightPairType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
3583 my %MemberStraightPairType_Pure = get_PureType
($Tid_TDid{2}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 2);
3585 if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName
($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \
%Type1_Pure) eq "lost")
3587 %{$SubProblems{"Member_Rename"}{$Member_Name}}=(
3588 "Target"=>$Member_Name,
3589 "Type_Name"=>$Type1_Pure{"Name"},
3590 "Type_Type"=>$Type1_Pure{"Type"},
3591 "Header"=>$Type2_Pure{"Header"},
3592 "Line"=>$Type2_Pure{"Line"},
3593 "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3594 "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
3595 $MemberPair_Pos = $Member_Pos;
3599 if($Type1_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3601 my $BitfieldSum = getBitfieldSum
($Member_Pos-1, \
%Type1_Pure)%($POINTER_SIZE*8);
3602 if($BitfieldSum and $BitfieldSum-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"}>=0)
3604 %{$SubProblems{"Withdrawn_Middle_Member"}{$Member_Name}}=(
3605 "Target"=>$Member_Name,
3606 "Type_Name"=>$Type1_Pure{"Name"},
3607 "Type_Type"=>$Type1_Pure{"Type"},
3608 "Header"=>$Type2_Pure{"Header"},
3609 "Line"=>$Type2_Pure{"Line"} );
3613 %{$SubProblems{"Withdrawn_Middle_Member_And_Size"}{$Member_Name}}=(
3614 "Target"=>$Member_Name,
3615 "Type_Name"=>$Type1_Pure{"Name"},
3616 "Type_Type"=>$Type1_Pure{"Type"},
3617 "Header"=>$Type2_Pure{"Header"},
3618 "Line"=>$Type2_Pure{"Line"} );
3623 if($Type1_Pure{"Type"} eq "Enum")
3625 my $Member_Value1 = $Type1_Pure{"Memb"}{$Member_Pos}{"value"};
3626 next if(not $Member_Value1);
3627 my $Member_Value2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"};
3628 if($MemberPair_Pos eq "lost")
3630 $MemberPair_Pos = find_MemberPair_Pos_byVal
($Member_Value1, \
%Type2_Pure);
3631 if($MemberPair_Pos ne "lost")
3633 %{$SubProblems{"Enum_Member_Name"}{$Type1_Pure{"Memb"}{$Member_Pos}{"value"}}}=(
3634 "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
3635 "Type_Name"=>$Type1_Pure{"Name"},
3636 "Type_Type"=>"Enum",
3637 "Header"=>$Type2_Pure{"Header"},
3638 "Line"=>$Type2_Pure{"Line"},
3639 "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3640 "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"name"} );
3645 if($Member_Value1 ne "" and $Member_Value2 ne "")
3647 if($Member_Value1 ne $Member_Value2)
3649 %{$SubProblems{"Enum_Member_Value"}{$Member_Name}}=(
3650 "Target"=>$Member_Name,
3651 "Type_Name"=>$Type1_Pure{"Name"},
3652 "Type_Type"=>"Enum",
3653 "Header"=>$Type2_Pure{"Header"},
3654 "Line"=>$Type2_Pure{"Line"},
3655 "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
3656 "New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"} );
3662 my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3663 my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
3664 %Sub_SubProblems = detectTypeChange
($MemberType1_Id, $MemberType2_Id, "Member");
3665 foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3667 %{$SubProblems{$Sub_SubProblemType}{$Member_Name}}=(
3668 "Target"=>$Member_Name,
3669 "Member_Position"=>$Member_Pos,
3670 "Type_Name"=>$Type1_Pure{"Name"},
3671 "Type_Type"=>$Type1_Pure{"Type"},
3672 "Header"=>$Type2_Pure{"Header"},
3673 "Line"=>$Type2_Pure{"Line"});
3674 @{$SubProblems{$Sub_SubProblemType}{$Member_Name}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}};
3676 if($MemberType1_Id and $MemberType2_Id)
3677 {#checking member type change (replace)
3678 %Sub_SubProblems = &mergeTypes
($MemberType1_Id, $Tid_TDid{1}{$MemberType1_Id}, $MemberType2_Id, $Tid_TDid{2}{$MemberType2_Id});
3679 foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3681 foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
3683 my $NewLocation = ($Sub_SubLocation)?$Member_Location."->".$Sub_SubLocation:$Member_Location;
3684 %{$SubProblems{$Sub_SubProblemType}{$NewLocation}}=(
3685 "IsInTypeInternals"=>"Yes");
3686 @{$SubProblems{$Sub_SubProblemType}{$NewLocation}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
3687 if($Sub_SubLocation !~ /\-\>/)
3689 $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Member_Type_Name"} = get_TypeName
($MemberType1_Id, 1);
3690 $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName
($MemberType1_Id, 1);
3696 if(($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class"))
3698 foreach my $Member_Pos (sort keys(%{$Type2_Pure{"Memb"}}))
3699 {#checking added members
3700 next if(not $Type2_Pure{"Memb"}{$Member_Pos}{"name"});
3701 my $MemberPair_Pos = find_MemberPair_Pos_byName
($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \
%Type1_Pure);
3702 if($MemberPair_Pos eq "lost")
3704 if($Member_Pos > keys(%{$Type1_Pure{"Memb"}}) - 1)
3706 if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3708 if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3710 my $BitfieldSum = getBitfieldSum
($Member_Pos-1, \
%Type2_Pure)%($POINTER_SIZE*8);
3711 next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
3713 %{$SubProblems{"Added_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3714 "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
3715 "Type_Name"=>$Type1_Pure{"Name"},
3716 "Type_Type"=>$Type1_Pure{"Type"},
3717 "Header"=>$Type2_Pure{"Header"},
3718 "Line"=>$Type2_Pure{"Line"} );
3723 my $MemberType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
3724 my $MemberType_DId = $Tid_TDid{2}{$MemberType_Id};
3725 my %MemberType_Pure = get_PureType
($MemberType_DId, $MemberType_Id, 2);
3727 my $MemberStraightPairType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3728 my %MemberStraightPairType_Pure = get_PureType
($Tid_TDid{1}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 1);
3730 if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName
($Type1_Pure{"Memb"}{$Member_Pos}{"name"}, \
%Type2_Pure) eq "lost")
3732 next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
3733 %{$SubProblems{"Member_Rename"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3734 "Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3735 "Type_Name"=>$Type1_Pure{"Name"},
3736 "Type_Type"=>$Type1_Pure{"Type"},
3737 "Header"=>$Type2_Pure{"Header"},
3738 "Line"=>$Type2_Pure{"Line"},
3739 "Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3740 "New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
3744 if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3746 if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3748 my $BitfieldSum = getBitfieldSum
($Member_Pos-1, \
%Type2_Pure)%($POINTER_SIZE*8);
3749 next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
3751 %{$SubProblems{"Added_Middle_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3752 "Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
3753 "Type_Name"=>$Type1_Pure{"Name"},
3754 "Type_Type"=>$Type1_Pure{"Type"},
3755 "Header"=>$Type2_Pure{"Header"},
3756 "Line"=>$Type2_Pure{"Line"} );
3763 %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}} = %SubProblems;
3765 return %SubProblems;
3768 sub get_TypeName
($$)
3770 my ($TypeId, $LibVersion) = @_;
3771 return $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$TypeId}}{$TypeId}{"Name"};
3776 my ($TypeDId, $TypeId, $LibVersion, $Type_Type) = @_;
3777 if(defined $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type})
3779 return %{$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type}};
3781 return () if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3782 my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3783 return () if(not $Type{"Type"});
3784 if($Type{"Type"} ne $Type_Type)
3786 return () if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3787 %Type = goToFirst
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
3789 $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type} = \
%Type;
3793 my %TypeSpecAttributes = (
3801 sub get_PureType
($$$)
3803 my ($TypeDId, $TypeId, $LibVersion) = @_;
3804 return "" if(not $TypeId);
3805 if(defined $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion})
3807 return %{$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion}};
3809 return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3810 my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3811 if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
3813 $CheckedTypes{$Type{"Name"}} = 1;
3815 return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3816 if($TypeSpecAttributes{$Type{"Type"}})
3818 %Type = get_PureType
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3820 $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion} = \
%Type;
3824 sub get_PointerLevel
($$$)
3826 my ($TypeDId, $TypeId, $LibVersion) = @_;
3827 return "" if(not $TypeId);
3828 if(defined $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion})
3830 return $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion};
3832 return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3833 my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3834 return 0 if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3835 my $PointerLevel = 0;
3836 if($Type{"Type"} eq "Pointer")
3840 $PointerLevel += get_PointerLevel
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3841 $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion} = $PointerLevel;
3842 return $PointerLevel;
3845 sub get_BaseType
($$$)
3847 my ($TypeDId, $TypeId, $LibVersion) = @_;
3848 return "" if(not $TypeId);
3849 if(defined $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion})
3851 return %{$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion}};
3853 return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3854 my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3855 if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
3857 $CheckedTypes{$Type{"Name"}} = 1;
3859 return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3860 %Type = get_BaseType
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3861 $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion} = \
%Type;
3865 sub get_OneStep_BaseType
($$$)
3867 my ($TypeDId, $TypeId, $LibVersion) = @_;
3868 return "" if(not $TypeId);
3869 return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3870 my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3871 return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3872 return get_Type
($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3877 my ($TypeDId, $TypeId, $LibVersion) = @_;
3878 return "" if(not $TypeId);
3879 return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3880 return %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3885 foreach my $Interface (sort keys(%AddedInt))
3886 {#checking added interfaces
3887 next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
3888 next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
3889 next if(defined $AppPath and not $InterfacesList_App{$Interface});
3890 next if($FuncAttr{2}{$Interface}{"Private"});
3891 next if(not $FuncAttr{2}{$Interface}{"Header"});
3892 %{$CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}}=(
3893 "Header"=>$FuncAttr{2}{$Interface}{"Header"},
3894 "Line"=>$FuncAttr{2}{$Interface}{"Line"},
3895 "Signature"=>$FuncAttr{2}{$Interface}{"Signature"},
3896 "New_SoName"=>$Interface_Library{2}{$Interface} );
3898 foreach my $Interface (sort keys(%WithdrawnInt))
3899 {#checking withdrawn interfaces
3900 next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
3901 next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
3902 next if(defined $AppPath and not $InterfacesList_App{$Interface});
3903 next if($FuncAttr{1}{$Interface}{"Private"});
3904 next if(not $FuncAttr{1}{$Interface}{"Header"});
3905 %{$CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}}=(
3906 "Header"=>$FuncAttr{1}{$Interface}{"Header"},
3907 "Line"=>$FuncAttr{1}{$Interface}{"Line"},
3908 "Signature"=>$FuncAttr{1}{$Interface}{"Signature"},
3909 "Old_SoName"=>$Interface_Library{1}{$Interface} );
3913 sub mergeSignatures
()
3915 my %SubProblems = ();
3917 prepareInterfaces
(1);
3918 prepareInterfaces
(2);
3921 initializeClassVirtFunc
(1);
3922 initializeClassVirtFunc
(2);
3924 checkVirtFuncRedefinitions
(1);
3925 checkVirtFuncRedefinitions
(2);
3927 setVirtFuncPositions
(1);
3928 setVirtFuncPositions
(2);
3930 foreach my $Interface (sort keys(%AddedInt))
3931 {#collecting the attributes of added interfaces
3932 next if($CheckedInterfaces{$Interface});
3933 if($CompleteSignature{2}{$Interface})
3935 if($CompleteSignature{2}{$Interface}{"Private"})
3937 $FuncAttr{2}{$Interface}{"Private"} = 1;
3939 if($CompleteSignature{2}{$Interface}{"Protected"})
3941 $FuncAttr{2}{$Interface}{"Protected"} = 1;
3943 if($CompleteSignature{2}{$Interface}{"Header"})
3945 $FuncAttr{2}{$Interface}{"Header"} = $CompleteSignature{2}{$Interface}{"Header"};
3947 if($CompleteSignature{2}{$Interface}{"Line"})
3949 $FuncAttr{2}{$Interface}{"Line"} = $CompleteSignature{2}{$Interface}{"Line"};
3951 $FuncAttr{2}{$Interface}{"Signature"} = get_Signature
($Interface, 2);
3952 foreach my $ParamPos (keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
3954 my $ParamType_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
3955 my $ParamType_DId = $Tid_TDid{2}{$ParamType_Id};
3956 my %ParamType = get_Type
($ParamType_DId, $ParamType_Id, 2);
3958 #checking virtual table
3959 check_VirtualTable
($Interface, 2);
3960 $CheckedInterfaces{$Interface} = 1;
3963 foreach my $Interface (sort keys(%WithdrawnInt))
3964 {#collecting the attributes of withdrawn interfaces
3965 next if($CheckedInterfaces{$Interface});
3966 if($CompleteSignature{1}{$Interface})
3968 if($CompleteSignature{1}{$Interface}{"Private"})
3970 $FuncAttr{1}{$Interface}{"Private"} = 1;
3972 if($CompleteSignature{1}{$Interface}{"Protected"})
3974 $FuncAttr{1}{$Interface}{"Protected"} = 1;
3976 if($CompleteSignature{1}{$Interface}{"Header"})
3978 $FuncAttr{1}{$Interface}{"Header"} = $CompleteSignature{1}{$Interface}{"Header"};
3980 if($CompleteSignature{1}{$Interface}{"Line"})
3982 $FuncAttr{1}{$Interface}{"Line"} = $CompleteSignature{1}{$Interface}{"Line"};
3984 $FuncAttr{1}{$Interface}{"Signature"} = get_Signature
($Interface, 1);
3985 foreach my $ParamPos (keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
3987 my $ParamType_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
3988 my $ParamType_DId = $Tid_TDid{1}{$ParamType_Id};
3989 my %ParamType = get_Type
($ParamType_DId, $ParamType_Id, 1);
3991 #checking virtual table
3992 check_VirtualTable
($Interface, 1);
3993 $CheckedInterfaces{$Interface} = 1;
3997 foreach my $Interface (sort keys(%{$CompleteSignature{1}}))
3998 {#checking interfaces
3999 if(($Interface !~ /\@/) and ($SymVer{1}{$Interface} =~ /\A(.*)[\@]+/))
4001 next if($1 eq $Interface);
4003 my ($MnglName, $SymbolVersion) = ($Interface, "");
4004 if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
4006 ($MnglName, $SymbolVersion) = ($1, $2);
4008 next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
4009 next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
4010 next if(defined $AppPath and not $InterfacesList_App{$Interface});
4011 next if($CheckedInterfaces{$Interface});
4012 next if($CompleteSignature{1}{$Interface}{"Private"});
4013 next if(not $CompleteSignature{1}{$Interface}{"Header"} or not $CompleteSignature{2}{$Interface}{"Header"});
4014 next if(not $CompleteSignature{1}{$Interface}{"MnglName"} or not $CompleteSignature{2}{$Interface}{"MnglName"});
4015 next if((not $CompleteSignature{1}{$Interface}{"PureVirt"} and $CompleteSignature{2}{$Interface}{"PureVirt"}) or ($CompleteSignature{1}{$Interface}{"PureVirt"} and not $CompleteSignature{2}{$Interface}{"PureVirt"}));
4016 $CheckedInterfaces{$Interface} = 1;
4017 #checking virtual table
4018 check_VirtualTable
($Interface, 1);
4019 #checking attributes
4020 if($CompleteSignature{2}{$Interface}{"Static"} and not $CompleteSignature{1}{$Interface}{"Static"})
4022 %{$CompatProblems{$Interface}{"Function_Become_Static"}{"Attributes"}}=(
4023 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4024 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4025 "Signature"=>get_Signature
($Interface, 1),
4026 "Old_SoName"=>$Interface_Library{1}{$Interface},
4027 "New_SoName"=>$Interface_Library{2}{$Interface} );
4029 elsif(not $CompleteSignature{2}{$Interface}{"Static"} and $CompleteSignature{1}{$Interface}{"Static"})
4031 %{$CompatProblems{$Interface}{"Function_Become_NonStatic"}{"Attributes"}}=(
4032 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4033 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4034 "Signature"=>get_Signature
($Interface, 1),
4035 "Old_SoName"=>$Interface_Library{1}{$Interface},
4036 "New_SoName"=>$Interface_Library{2}{$Interface} );
4038 if($CompleteSignature{1}{$Interface}{"Virt"} and $CompleteSignature{2}{$Interface}{"Virt"})
4040 if($CompleteSignature{1}{$Interface}{"Position"}!=$CompleteSignature{2}{$Interface}{"Position"})
4042 my $Class_Id = $CompleteSignature{1}{$Interface}{"Class"};
4043 my $Class_DId = $Tid_TDid{1}{$Class_Id};
4044 my %Class_Type = get_Type
($Class_DId, $Class_Id, 1);
4045 %{$CompatProblems{$Interface}{"Virtual_Function_Position"}{$tr_name{$MnglName}}}=(
4046 "Type_Name"=>$Class_Type{"Name"},
4047 "Type_Type"=>$Class_Type{"Type"},
4048 "Header"=>$Class_Type{"Header"},
4049 "Line"=>$Class_Type{"Line"},
4050 "Old_Value"=>$CompleteSignature{1}{$Interface}{"Position"},
4051 "New_Value"=>$CompleteSignature{2}{$Interface}{"Position"},
4052 "Signature"=>get_Signature
($Interface, 1),
4053 "Target"=>$tr_name{$MnglName},
4054 "Old_SoName"=>$Interface_Library{1}{$Interface},
4055 "New_SoName"=>$Interface_Library{2}{$Interface} );
4058 foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
4059 {#checking added parameters
4060 last if($Interface=~/\A_Z/);
4061 if(not defined $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos})
4062 {#checking withdrawn parameters
4063 my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
4064 my $Parameter_Name = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"name"};
4065 last if(get_TypeName
($ParamType2_Id, 2) eq "...");
4066 %{$CompatProblems{$Interface}{"Added_Parameter"}{num_to_str
($ParamPos+1)." Parameter"}}=(
4067 "Target"=>$Parameter_Name,
4068 "Parameter_Position"=>$ParamPos,
4069 "Signature"=>get_Signature
($Interface, 1),
4070 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4071 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4072 "Old_SoName"=>$Interface_Library{1}{$Interface},
4073 "New_SoName"=>$Interface_Library{2}{$Interface});
4076 foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
4077 {#checking parameters
4078 my $ParamType1_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
4079 my $Parameter_Name = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"name"};
4080 if(not defined $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos} and get_TypeName
($ParamType1_Id, 1) ne "..." and $Interface!~/\A_Z
/)
4081 {#checking withdrawn parameters
4082 %{$CompatProblems{$Interface}{"Withdrawn_Parameter"}{num_to_str
($ParamPos+1)." Parameter"}}=(
4083 "Target"=>$Parameter_Name,
4084 "Parameter_Position"=>$ParamPos,
4085 "Signature"=>get_Signature
($Interface, 1),
4086 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4087 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4088 "Old_SoName"=>$Interface_Library{1}{$Interface},
4089 "New_SoName"=>$Interface_Library{2}{$Interface});
4092 my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
4093 next if(not $ParamType1_Id or not $ParamType2_Id);
4094 my $Parameter_Location = ($Parameter_Name)?$Parameter_Name:num_to_str
($ParamPos+1)." Parameter";
4096 #checking type change(replace)
4097 %SubProblems = detectTypeChange
($ParamType1_Id, $ParamType2_Id, "Parameter");
4098 foreach my $SubProblemType (keys(%SubProblems))
4100 %{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}=(
4101 "Target"=>$Parameter_Name,
4102 "Parameter_Position"=>$ParamPos,
4103 "Signature"=>get_Signature
($Interface, 1),
4104 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4105 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4106 "Old_SoName"=>$Interface_Library{1}{$Interface},
4107 "New_SoName"=>$Interface_Library{2}{$Interface});
4108 @{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
4111 #checking type definition changes
4112 %SubProblems = mergeTypes
($ParamType1_Id, $Tid_TDid{1}{$ParamType1_Id}, $ParamType2_Id, $Tid_TDid{2}{$ParamType2_Id});
4113 foreach my $SubProblemType (keys(%SubProblems))
4115 foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4117 my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
4118 %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4119 "Signature"=>get_Signature
($Interface, 1),
4120 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4121 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4122 "Old_SoName"=>$Interface_Library{1}{$Interface},
4123 "New_SoName"=>$Interface_Library{2}{$Interface},
4124 "Parameter_Type_Name"=>get_TypeName
($ParamType1_Id, 1),
4125 "Parameter_Position"=>$ParamPos,
4126 "Parameter_Name"=>$Parameter_Name);
4127 @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4128 if($SubLocation !~ /\-\>/)
4130 $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName
($ParamType1_Id, 1);
4135 #checking return type
4136 my $ReturnType1_Id = $CompleteSignature{1}{$Interface}{"Return"};
4137 my $ReturnType2_Id = $CompleteSignature{2}{$Interface}{"Return"};
4138 %SubProblems = detectTypeChange
($ReturnType1_Id, $ReturnType2_Id, "Return");
4139 foreach my $SubProblemType (keys(%SubProblems))
4141 %{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}=(
4142 "Signature"=>get_Signature
($Interface, 1),
4143 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4144 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4145 "Old_SoName"=>$Interface_Library{1}{$Interface},
4146 "New_SoName"=>$Interface_Library{2}{$Interface});
4147 @{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
4149 if($ReturnType1_Id and $ReturnType2_Id)
4152 %SubProblems = mergeTypes
($ReturnType1_Id, $Tid_TDid{1}{$ReturnType1_Id}, $ReturnType2_Id, $Tid_TDid{2}{$ReturnType2_Id});
4153 foreach my $SubProblemType (keys(%SubProblems))
4155 foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4157 my $NewLocation = ($SubLocation)?"RetVal->".$SubLocation:"RetVal";
4158 %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4159 "Signature"=>get_Signature
($Interface, 1),
4160 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4161 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4162 "Old_SoName"=>$Interface_Library{1}{$Interface},
4163 "New_SoName"=>$Interface_Library{2}{$Interface},
4164 "Return_Type_Name"=>get_TypeName
($ReturnType1_Id, 1) );
4165 @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4166 if($SubLocation !~ /\-\>/)
4168 $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName
($ReturnType1_Id, 1);
4174 #checking object type
4175 my $ObjectType1_Id = $CompleteSignature{1}{$Interface}{"Class"};
4176 my $ObjectType2_Id = $CompleteSignature{2}{$Interface}{"Class"};
4177 if($ObjectType1_Id and $ObjectType2_Id)
4179 my $ThisType1_Id = getTypeIdByName
(get_TypeName
($ObjectType1_Id, 1)."*const", 1);
4180 my $ThisType2_Id = getTypeIdByName
(get_TypeName
($ObjectType2_Id, 2)."*const", 2);
4181 if($ThisType1_Id and $ThisType2_Id)
4184 %SubProblems = mergeTypes
($ThisType1_Id, $Tid_TDid{1}{$ThisType1_Id}, $ThisType2_Id, $Tid_TDid{2}{$ThisType2_Id});
4185 foreach my $SubProblemType (keys(%SubProblems))
4187 foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4189 my $NewLocation = ($SubLocation)?"Obj->".$SubLocation:"Obj";
4190 %{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4191 "Signature"=>get_Signature
($Interface, 1),
4192 "Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4193 "Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4194 "Old_SoName"=>$Interface_Library{1}{$Interface},
4195 "New_SoName"=>$Interface_Library{2}{$Interface},
4196 "Object_Type_Name"=>get_TypeName
($ObjectType1_Id, 1) );
4197 @{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4198 if($SubLocation !~ /\-\>/)
4200 $CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName
($ObjectType1_Id, 1);
4207 set_Problems_Priority
();
4210 sub getTypeIdByName
($$)
4212 my ($TypeName, $Version) = @_;
4213 return $TName_Tid{$Version}{correctName
($TypeName)};
4216 sub detectTypeChange
($$$)
4218 my ($Type1_Id, $Type2_Id, $Prefix) = @_;
4219 my %LocalProblems = ();
4220 my $Type1_DId = $Tid_TDid{1}{$Type1_Id};
4221 my $Type2_DId = $Tid_TDid{2}{$Type2_Id};
4222 my %Type1 = get_Type
($Type1_DId, $Type1_Id, 1);
4223 my %Type2 = get_Type
($Type2_DId, $Type2_Id, 2);
4224 my %Type1_Base = get_BaseType
($Type1_DId, $Type1_Id, 1);
4225 my %Type2_Base = get_BaseType
($Type2_DId, $Type2_Id, 2);
4226 my %Type1_Pure = get_PureType
($Type1_DId, $Type1_Id, 1);
4227 my %Type2_Pure = get_PureType
($Type2_DId, $Type2_Id, 2);
4228 my $Type1_PointerLevel = get_PointerLevel
($Type1_DId, $Type1_Id, 1);
4229 my $Type2_PointerLevel = get_PointerLevel
($Type2_DId, $Type2_Id, 2);
4230 return () if(not $Type1{"Name"} or not $Type2{"Name"} or not $Type1{"Size"} or not $Type2{"Size"} or not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"} or not $Type1_Base{"Name"} or not $Type2_Base{"Name"} or not $Type1_Base{"Size"} or not $Type2_Base{"Size"} or $Type1_PointerLevel eq "" or $Type2_PointerLevel eq "");
4231 if($Type1_Base{"Name"} ne $Type2_Base{"Name"})
4233 if($Type1_Base{"Name"}!~/anon\-/ and $Type2_Base{"Name"}!~/anon\-/)
4235 if($Type1_Base{"Size"}!=$Type2_Base{"Size"})
4237 %{$LocalProblems{$Prefix."_BaseType_And_Size"}}=(
4238 "Old_Value"=>$Type1_Base{"Name"},
4239 "New_Value"=>$Type2_Base{"Name"},
4240 "Old_Size"=>$Type1_Base{"Size"},
4241 "New_Size"=>$Type2_Base{"Size"},
4242 "InitialType_Type"=>$Type1_Pure{"Type"});
4246 %{$LocalProblems{$Prefix."_BaseType"}}=(
4247 "Old_Value"=>$Type1_Base{"Name"},
4248 "New_Value"=>$Type2_Base{"Name"},
4249 "InitialType_Type"=>$Type1_Pure{"Type"});
4253 elsif($Type1{"Name"} ne $Type2{"Name"})
4255 if($Type1{"Name"}!~/anon\-/ and $Type2{"Name"}!~/anon\-/)
4257 if($Type1{"Size"}!=$Type2{"Size"})
4259 %{$LocalProblems{$Prefix."_Type_And_Size"}}=(
4260 "Old_Value"=>$Type1{"Name"},
4261 "New_Value"=>$Type2{"Name"},
4262 "Old_Size"=>($Type1{"Type"} eq "Array")?$Type1{"Size"}*$Type1_Base{"Size"}:$Type1{"Size"},
4263 "New_Size"=>($Type2{"Type"} eq "Array")?$Type2{"Size"}*$Type2_Base{"Size"}:$Type2{"Size"},
4264 "InitialType_Type"=>$Type1_Pure{"Type"});
4268 %{$LocalProblems{$Prefix."_Type"}}=(
4269 "Old_Value"=>$Type1{"Name"},
4270 "New_Value"=>$Type2{"Name"},
4271 "InitialType_Type"=>$Type1_Pure{"Type"});
4276 if($Type1_PointerLevel!=$Type2_PointerLevel)
4278 %{$LocalProblems{$Prefix."_PointerLevel"}}=(
4279 "Old_Value"=>$Type1_PointerLevel,
4280 "New_Value"=>$Type2_PointerLevel);
4282 return %LocalProblems;
4285 sub htmlSpecChars
($)
4288 $Str =~ s/\&([^#])/&$1/g;
4291 $Str =~ s/([^ ])( )([^ ])/$1\@ALONE_SP\@$3/g;
4292 $Str =~ s/ / /g;
4293 $Str =~ s/\@ALONE_SP\@/ /g;
4294 $Str =~ s/\n/<br\/>/g
;
4298 sub highLight_Signature
($)
4300 my $Signature = $_[0];
4301 return highLight_Signature_PPos_Italic
($Signature, "", 0, 0);
4304 sub highLight_Signature_Italic
($)
4306 my $Signature = $_[0];
4307 return highLight_Signature_PPos_Italic
($Signature, "", 1, 0);
4310 sub highLight_Signature_Italic_Color
($)
4312 my $Signature = $_[0];
4313 return highLight_Signature_PPos_Italic
($Signature, "", 1, 1);
4316 sub highLight_Signature_PPos_Italic
($$$$)
4318 my ($FullSignature, $Parameter_Position, $ItalicParams, $ColorParams) = @_;
4319 my ($Signature, $SymbolVersion) = ($FullSignature, "");
4320 if($FullSignature =~ /\A(.+)[\@]+(.+)\Z/)
4322 ($Signature, $SymbolVersion) = ($1, $2);
4324 if($Signature=~/\Atypeinfo\W/)
4326 return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4328 if($Signature!~/\
)(| const
)\Z
/)
4330 return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4332 $Signature =~ /(.+?)\(.*\)(| const)\Z/;
4333 my ($Begin, $End) = ($1, $2);
4336 foreach my $Part (get_Signature_Parts
($Signature, 1))
4338 $Part =~ s/\A\s+|\s+\Z//g;
4339 my ($Part_Styled, $ParamName) = ($Part, "");
4340 if($Part=~/\([\*]+(\w+)\)/i)
4344 elsif($Part=~/(\w+)[\,\)]*\Z/i)
4350 push(@Parts, $Part);
4353 if($ItalicParams and not $TName_Tid{1}{$Part} and not $TName_Tid{2}{$Part})
4355 if(($Parameter_Position ne "") and ($Part_Num == $Parameter_Position))
4357 $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='focus_param'>$ParamName</span>$2!ig;
4361 $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='color_param'>$ParamName</span>$2!ig;
4365 $Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span style='font-style:italic;'>$ParamName</span>$2!ig;
4368 $Part_Styled = "<span style='white-space:nowrap;'>".$Part_Styled."</span>";
4369 push(@Parts, $Part_Styled);
4372 $Signature = $Begin."<span class='int_p'>"."(".join(" ", @Parts).")"."</span>".$End;
4373 $Signature =~ s!\[\]![<span style='padding-left:2px;'>]</span>!g;
4374 $Signature =~ s!operator=!operator<span style='padding-left:2px'>=</span>!g;
4375 $Signature =~ s!(\[in-charge\]|\[not-in-charge\]|\[in-charge-deleting\])!<span style='color:Black;font-weight:normal;'>$1</span>!g;
4376 return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4379 sub get_Signature_Parts
($$)
4381 my ($Signature, $Comma) = @_;
4383 my $Bracket_Num = 0;
4384 my $Bracket2_Num = 0;
4385 my $Parameters = $Signature;
4386 if($Signature=~/>|</)
4388 $Parameters=~s/>/>/g;
4389 $Parameters=~s/</</g;
4392 if($Parameters =~ s/.+?\((.*)\)(| const)\Z/$1/)
4394 foreach my $Pos (0 .. length($Parameters) - 1)
4396 my $Symbol = substr($Parameters, $Pos, 1);
4397 $Bracket_Num += 1 if($Symbol eq "(");
4398 $Bracket_Num -= 1 if($Symbol eq ")");
4399 $Bracket2_Num += 1 if($Symbol eq "<");
4400 $Bracket2_Num -= 1 if($Symbol eq ">");
4401 if($Symbol eq "," and $Bracket_Num==0 and $Bracket2_Num==0)
4403 $Parts[$Part_Num] .= $Symbol if($Comma);
4408 $Parts[$Part_Num] .= $Symbol;
4411 if($Signature=~/>|</)
4413 foreach my $Part (@Parts)
4427 my %TypeProblems_Kind=(
4428 "Added_Virtual_Function"=>1,
4429 "Withdrawn_Virtual_Function"=>1,
4430 "Virtual_Function_Position"=>1,
4431 "Virtual_Function_Redefinition"=>1,
4432 "Virtual_Function_Redefinition_B"=>1,
4434 "Added_Member_And_Size"=>1,
4435 "Added_Middle_Member_And_Size"=>1,
4436 "Withdrawn_Member_And_Size"=>1,
4437 "Withdrawn_Member"=>1,
4438 "Withdrawn_Middle_Member_And_Size"=>1,
4440 "Enum_Member_Value"=>1,
4441 "Enum_Member_Name"=>1,
4442 "Member_Type_And_Size"=>1,
4444 "Member_BaseType_And_Size"=>1,
4445 "Member_BaseType"=>1,
4446 "Member_PointerLevel"=>1,
4450 my %InterfaceProblems_Kind=(
4451 "Added_Interface"=>1,
4452 "Withdrawn_Interface"=>1,
4453 "Function_Become_Static"=>1,
4454 "Function_Become_NonStatic"=>1,
4455 "Parameter_Type_And_Size"=>1,
4456 "Parameter_Type"=>1,
4457 "Parameter_BaseType_And_Size"=>1,
4458 "Parameter_BaseType"=>1,
4459 "Parameter_PointerLevel"=>1,
4460 "Return_Type_And_Size"=>1,
4462 "Return_BaseType_And_Size"=>1,
4463 "Return_BaseType"=>1,
4464 "Return_PointerLevel"=>1,
4465 "Withdrawn_Parameter"=>1,
4466 "Added_Parameter"=>1
4469 sub testSystem_cpp
()
4471 print "testing for C++ library changes\n";
4472 my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
4474 #Withdrawn_Parameter
4475 @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
4476 @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
4478 @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
4479 @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
4482 @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
4483 @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
4485 @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
4486 @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
4488 #Added_Virtual_Function
4489 @DataDefs_v1 = (@DataDefs_v1, "class type_test_added_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
4490 @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
4491 @Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
4493 @DataDefs_v2 = (@DataDefs_v2, "class type_test_added_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4494 @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
4495 @Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
4497 #added simple function
4498 @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_funcptr(FUNCPTR_TYPE*const** f);");
4499 @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
4501 #Withdrawn_Virtual_Function
4502 @DataDefs_v1 = (@DataDefs_v1, "class type_test_withdrawn_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4503 @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
4504 @Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
4506 @DataDefs_v2 = (@DataDefs_v2, "class type_test_withdrawn_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
4507 @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
4508 @Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
4510 #Virtual_Function_Position
4511 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4512 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
4513 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
4515 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4516 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
4517 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
4519 #virtual functions safe replace
4520 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4521 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
4522 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
4524 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4525 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
4526 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
4528 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4529 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
4530 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
4532 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4533 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
4534 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
4536 #virtual table changes
4537 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4538 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4539 @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
4540 @Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
4541 @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
4542 @Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
4544 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4545 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4546 @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
4547 @Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
4548 @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
4549 @Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
4551 #Virtual_Function_Redefinition
4552 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4553 @DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func3(int param);\n};");
4554 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func1(int param)\n{\n return param;\n}");
4555 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func2(int param)\n{\n return param;\n}");
4556 @Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
4558 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4559 @DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func2(int param);\n virtual int func3(int param);\n};");
4560 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func1(int param){\n return param;\n}");
4561 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func2(int param){\n return param;\n}");
4562 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func2(int param)\n{\n return param;\n}");
4563 @Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
4566 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n};");
4567 @Sources_v1 = (@Sources_v1, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
4569 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n int added_member;\n};");
4570 @Sources_v2 = (@Sources_v2, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
4572 #Added_Member_And_Size
4573 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
4574 @Sources_v1 = (@Sources_v1, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
4576 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
4577 @Sources_v2 = (@Sources_v2, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
4579 #Method object changes
4580 @DataDefs_v1 = (@DataDefs_v1, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
4581 @Sources_v1 = (@Sources_v1, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
4583 @DataDefs_v2 = (@DataDefs_v2, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
4584 @Sources_v2 = (@Sources_v2, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
4587 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_added_bitfield* p;\n};");
4588 @Sources_v1 = (@Sources_v1, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
4590 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int added_bitfield : 1;\n type_test_added_bitfield* p;\n};");
4591 @Sources_v2 = (@Sources_v2, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
4594 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int withdrawn_bitfield : 1;\n type_test_withdrawn_bitfield* p;\n};");
4595 @Sources_v1 = (@Sources_v1, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
4597 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_withdrawn_bitfield* p;\n};");
4598 @Sources_v2 = (@Sources_v2, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
4600 #Added_Middle_Member_And_Size
4601 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
4602 @Sources_v1 = (@Sources_v1, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
4604 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n int added_middle_member;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
4605 @Sources_v2 = (@Sources_v2, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
4608 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long i;\n long j;\n double k;\n type_test_member_rename* p;\n};");
4609 @Sources_v1 = (@Sources_v1, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
4611 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long renamed_member;\n long j;\n double k;\n type_test_member_rename* p;\n};");
4612 @Sources_v2 = (@Sources_v2, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
4614 #Withdrawn_Member_And_Size
4615 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
4616 @Sources_v1 = (@Sources_v1, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
4618 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n};");
4619 @Sources_v2 = (@Sources_v2, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
4621 #Withdrawn_Middle_Member_And_Size
4622 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
4623 @Sources_v1 = (@Sources_v1, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
4625 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
4626 @Sources_v2 = (@Sources_v2, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
4629 @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
4630 @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
4631 @Sources_v1 = (@Sources_v1,
4632 "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
4644 @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
4645 @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
4646 @Sources_v2 = (@Sources_v2,
4647 "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
4660 @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
4661 @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
4662 @Sources_v1 = (@Sources_v1,
4663 "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
4675 @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
4676 @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
4677 @Sources_v2 = (@Sources_v2,
4678 "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
4690 #Member_Type_And_Size
4691 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n int i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
4692 @Sources_v1 = (@Sources_v1, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
4694 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
4695 @Sources_v2 = (@Sources_v2, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
4698 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n int i;\n long j;\n double k;\n type_test_member_type* p;\n};");
4699 @Sources_v1 = (@Sources_v1, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
4701 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n float i;\n long j;\n double k;\n type_test_member_type* p;\n};");
4702 @Sources_v2 = (@Sources_v2, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
4705 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n int *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
4706 @Sources_v1 = (@Sources_v1, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
4708 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n long long *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
4709 @Sources_v2 = (@Sources_v2, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
4711 #Member_PointerLevel_And_Size
4712 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
4713 @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
4715 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long *i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
4716 @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
4718 #Member_PointerLevel
4719 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int **i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
4720 @Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
4722 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int *i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
4723 @Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
4725 #Added_Interface (function)
4726 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
4727 @Sources_v1 = (@Sources_v1, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
4729 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n type_test_added_interface added_func(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
4730 @DataDefs_v2 = (@DataDefs_v2, "int added_func_2(void *** param);");
4731 @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
4732 @Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::added_func(type_test_added_interface param)\n{\n return param;\n}");
4733 @Sources_v2 = (@Sources_v2, "int added_func_2(void *** param)\n{\n return 0;\n}");
4735 #Added_Interface (global variable)
4736 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
4737 @Sources_v1 = (@Sources_v1, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return i;\n}");
4739 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n static int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
4740 @Sources_v2 = (@Sources_v2, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return type_test_added_variable::i;\n}");
4741 @Sources_v2 = (@Sources_v2, "int type_test_added_variable::i=0;");
4743 #Withdrawn_Interface
4744 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n type_test_withdrawn_interface withdrawn_func(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
4745 @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func_2(void *** param);");
4746 @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
4747 @Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::withdrawn_func(type_test_withdrawn_interface param)\n{\n return param;\n}");
4748 @Sources_v1 = (@Sources_v1, "int withdrawn_func_2(void *** param)\n{\n return 0;\n}");
4750 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
4751 @Sources_v2 = (@Sources_v2, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
4753 #Function_Become_Static
4754 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_static\n{\npublic:\n type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
4755 @Sources_v1 = (@Sources_v1, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
4757 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_static\n{\npublic:\n static type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
4758 @Sources_v2 = (@Sources_v2, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
4760 #Function_Become_NonStatic
4761 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_nonstatic\n{\npublic:\n static type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
4762 @Sources_v1 = (@Sources_v1, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
4764 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_nonstatic\n{\npublic:\n type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
4765 @Sources_v2 = (@Sources_v2, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
4767 #Parameter_Type_And_Size
4768 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
4769 @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
4771 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
4772 @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
4775 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
4776 @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
4778 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
4779 @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
4782 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
4783 @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
4785 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
4786 @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
4788 #Parameter_PointerLevel_And_Size
4789 @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
4790 @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
4792 @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
4793 @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
4795 #Parameter_PointerLevel
4796 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
4797 @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
4799 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
4800 @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
4802 #Return_Type_And_Size
4803 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
4804 @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4806 @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
4807 @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
4810 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
4811 @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4813 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
4814 @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
4817 @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetype(int param);");
4818 @Sources_v1 = (@Sources_v1, "int *func_return_basetype(int param)\n{\n int *x = new int[10];\n return x;\n}");
4820 @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetype(int param);");
4821 @Sources_v2 = (@Sources_v2, "long long *func_return_basetype(int param)\n{\n long long *x = new long long[10];\n return x;\n}");
4823 #Return_PointerLevel_And_Size
4824 @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
4825 @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
4827 @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
4828 @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long* x = new long long[10];\n return x;\n}");
4830 #Return_PointerLevel
4831 @DataDefs_v1 = (@DataDefs_v1, "int* func_return_pointerlevel(int param);");
4832 @Sources_v1 = (@Sources_v1, "int* func_return_pointerlevel(int param)\n{\n int* x = new int[10];\n return x;\n}");
4834 @DataDefs_v2 = (@DataDefs_v2, "int **func_return_pointerlevel(int param);");
4835 @Sources_v2 = (@Sources_v2, "int **func_return_pointerlevel(int param)\n{\n int** x = new int*[10];\n return x;\n}");
4837 #typedef to anon struct
4838 @DataDefs_v1 = (@DataDefs_v1, "
4845 } type_test_anon_typedef;
4846 int func_test_anon_typedef(type_test_anon_typedef param);");
4847 @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
4849 @DataDefs_v2 = (@DataDefs_v2, "
4859 char q_skiptable[256];
4864 } type_test_anon_typedef;
4865 int func_test_anon_typedef(type_test_anon_typedef param);");
4866 @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
4869 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n};");
4870 @Sources_v1 = (@Sources_v1, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
4872 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n int added_member;\n};");
4873 @Sources_v2 = (@Sources_v2, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
4876 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n};");
4877 @Sources_v1 = (@Sources_v1, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
4879 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n int added_member;\n};");
4880 @Sources_v2 = (@Sources_v2, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
4882 #starting versioning
4883 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
4884 @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4886 @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
4887 @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z37func_return_type_and_start_versioningi,_Z37func_return_type_and_start_versioningi\@TEST_2.0\");");
4889 #Return_Type And Good Versioning
4890 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
4891 @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
4893 @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
4894 @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z40func_return_type_and_good_versioning_oldi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
4896 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
4897 @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_2.0\");");
4899 #Return_Type and bad versioning
4900 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
4901 @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
4903 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
4904 @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z39func_return_type_and_bad_versioning_oldi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
4906 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
4907 @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_2.0\");");
4909 #unnamed struct fields within structs
4910 @DataDefs_v1 = (@DataDefs_v1, "
4918 } type_test_unnamed;
4919 int func_test_unnamed(type_test_unnamed param);");
4920 @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
4922 @DataDefs_v2 = (@DataDefs_v2, "
4930 } type_test_unnamed;
4931 int func_test_unnamed(type_test_unnamed param);");
4932 @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
4935 @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
4936 @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
4938 @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
4939 @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
4942 @DataDefs_v1 = (@DataDefs_v1, "
4943 union type_test_union {
4951 int func_test_union(type_test_union param);");
4952 @Sources_v1 = (@Sources_v1, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
4954 @DataDefs_v2 = (@DataDefs_v2, "
4955 union type_test_union {
4957 long double new_member;
4964 int func_test_union(type_test_union param);");
4965 @Sources_v2 = (@Sources_v2, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
4968 @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
4969 @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
4971 @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
4972 @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
4974 #typedefs in member type
4975 @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
4976 @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
4978 @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
4979 @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
4981 create_TestSuite
("abi_changes_test_cpp", "C++", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "_ZN18type_test_internal5func1ES_");
4986 print "\ntesting for C library changes\n";
4987 my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
4989 #Withdrawn_Parameter
4990 @DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
4991 @Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
4993 @DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
4994 @Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
4997 @DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
4998 @Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
5000 @DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
5001 @Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
5003 #added function with typedef funcptr parameter
5004 @DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f);");
5005 @Sources_v2 = (@Sources_v2, "int added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
5007 #added function with funcptr parameter
5008 @DataDefs_v2 = (@DataDefs_v2, "int added_function_param_funcptr(int(*func)(int, int));");
5009 @Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(int(*func)(int, int))\n{\n return 0;\n}");
5011 #added function with no limited parameters
5012 @DataDefs_v2 = (@DataDefs_v2, "int added_function_nolimit_param(float p1, ...);");
5013 @Sources_v2 = (@Sources_v2, "int added_function_nolimit_param(float p1, ...)\n{\n return 0;\n}");
5016 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\n long long i[5];\n long j;\n double k;\n struct type_test_size* p;\n};");
5017 @DataDefs_v1 = (@DataDefs_v1, "int func_test_type_size(struct type_test_size param, int param_2);");
5018 @Sources_v1 = (@Sources_v1, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
5020 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_size* p;\n};");
5021 @DataDefs_v2 = (@DataDefs_v2, "int func_test_type_size(struct type_test_size param, int param_2);");
5022 @Sources_v2 = (@Sources_v2, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
5024 #Added_Member_And_Size
5025 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5026 @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_member(struct type_test_added_member param, int param_2);");
5027 @Sources_v1 = (@Sources_v1, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
5029 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n int added_member;\n};");
5030 @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_member(struct type_test_added_member param, int param_2);");
5031 @Sources_v2 = (@Sources_v2, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
5033 #Added_Middle_Member_And_Size
5034 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5035 @DataDefs_v1 = (@DataDefs_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
5036 @Sources_v1 = (@Sources_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
5038 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\n int i;\n int added_middle_member;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5039 @DataDefs_v2 = (@DataDefs_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
5040 @Sources_v2 = (@Sources_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
5043 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\n long i;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
5044 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
5045 @Sources_v1 = (@Sources_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
5047 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\n long renamed_member;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
5048 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
5049 @Sources_v2 = (@Sources_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
5051 #Withdrawn_Member_And_Size
5052 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
5053 @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
5054 @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
5056 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n};");
5057 @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
5058 @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
5060 #Withdrawn_Middle_Member
5061 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
5062 @DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
5063 @Sources_v1 = (@Sources_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
5065 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
5066 @DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
5067 @Sources_v2 = (@Sources_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
5070 @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
5071 @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
5072 @Sources_v1 = (@Sources_v1,
5073 "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
5085 @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
5086 @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
5087 @Sources_v2 = (@Sources_v2,
5088 "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
5101 @DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
5102 @DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
5103 @Sources_v1 = (@Sources_v1,
5104 "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
5116 @DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
5117 @DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
5118 @Sources_v2 = (@Sources_v2,
5119 "int func_test_enum_member_rename(enum type_test_enum_member_rename param)
5131 #Member_Type_And_Size
5132 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n double k;\n struct type_test_member_type_and_size* p;\n};");
5133 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
5134 @Sources_v1 = (@Sources_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
5136 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n long double k;\n struct type_test_member_type_and_size* p;\n};");
5137 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
5138 @Sources_v2 = (@Sources_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
5141 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\n int i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
5142 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type(struct type_test_member_type param, int param_2);");
5143 @Sources_v1 = (@Sources_v1, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
5145 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\n float i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
5146 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type(struct type_test_member_type param, int param_2);");
5147 @Sources_v2 = (@Sources_v2, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
5150 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\n int i;\n long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
5151 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
5152 @Sources_v1 = (@Sources_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
5154 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
5155 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
5156 @Sources_v2 = (@Sources_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
5158 #Member_PointerLevel_And_Size
5159 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
5160 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
5161 @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
5163 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
5164 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
5165 @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
5167 #Member_PointerLevel
5168 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\n int i;\n long *j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
5169 @DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
5170 @Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
5172 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\n int i;\n long **j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
5173 @DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
5174 @Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
5177 @DataDefs_v2 = (@DataDefs_v2, "int added_func(int param);");
5178 @Sources_v2 = (@Sources_v2, "int added_func(int param)\n{\n return param;\n}");
5180 #Withdrawn_Interface
5181 @DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func(int param);");
5182 @Sources_v1 = (@Sources_v1, "int withdrawn_func(int param)\n{\n return param;\n}");
5184 #Parameter_Type_And_Size
5185 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
5186 @Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
5188 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
5189 @Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
5192 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
5193 @Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
5195 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
5196 @Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
5198 #Parameter_BaseType (Typedef)
5199 @DataDefs_v1 = (@DataDefs_v1, "typedef int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
5200 @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
5202 @DataDefs_v2 = (@DataDefs_v2, "typedef const int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
5203 @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
5206 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
5207 @Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
5209 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
5210 @Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
5212 #Parameter_PointerLevel_And_Size
5213 @DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
5214 @Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
5216 @DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
5217 @Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
5219 #Parameter_PointerLevel
5220 @DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
5221 @Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
5223 @DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
5224 @Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
5226 #Return_Type_And_Size
5227 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
5228 @Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5230 @DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
5231 @Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
5234 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
5235 @Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5237 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
5238 @Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
5241 @DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetypechange(int param);");
5242 @Sources_v1 = (@Sources_v1, "int *func_return_basetypechange(int param)\n{\n int *x = (int*)malloc(10*sizeof(int));\n *x = 2^(sizeof(int)*8-1)-1;\n return x;\n}");
5244 @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetypechange(int param);");
5245 @Sources_v2 = (@Sources_v2, "long long *func_return_basetypechange(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5247 #Return_PointerLevel_And_Size
5248 @DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
5249 @Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
5251 @DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
5252 @Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5254 #Return_PointerLevel
5255 @DataDefs_v1 = (@DataDefs_v1, "long long *func_return_pointerlevel(int param);");
5256 @Sources_v1 = (@Sources_v1, "long long *func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5258 @DataDefs_v2 = (@DataDefs_v2, "long long **func_return_pointerlevel(int param);");
5259 @Sources_v2 = (@Sources_v2, "long long **func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n long *y = (long*)malloc(sizeof(long long));\n *y=(long)&x;\n return (long long **)y;\n}");
5261 #typedef to anon struct
5262 @DataDefs_v1 = (@DataDefs_v1, "
5268 } type_test_anon_typedef;
5269 int func_test_anon_typedef(type_test_anon_typedef param);");
5270 @Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
5272 @DataDefs_v2 = (@DataDefs_v2, "
5281 char q_skiptable[256];
5286 } type_test_anon_typedef;
5287 int func_test_anon_typedef(type_test_anon_typedef param);");
5288 @Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
5291 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\n long long i[5];\n long j;\n double k;\n struct type_test_opaque* p;\n};");
5292 @DataDefs_v1 = (@DataDefs_v1, "int func_test_opaque(struct type_test_opaque param, int param_2);");
5293 @Sources_v1 = (@Sources_v1, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
5295 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_opaque* p;\n};");
5296 @DataDefs_v2 = (@DataDefs_v2, "int func_test_opaque(struct type_test_opaque param, int param_2);");
5297 @Sources_v2 = (@Sources_v2, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
5300 @DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\n long long i[5];\n long j;\n double k;\n struct type_test_internal* p;\n};");
5301 @DataDefs_v1 = (@DataDefs_v1, "int func_test_internal(struct type_test_internal param, int param_2);");
5302 @Sources_v1 = (@Sources_v1, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
5304 @DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_internal* p;\n};");
5305 @DataDefs_v2 = (@DataDefs_v2, "int func_test_internal(struct type_test_internal param, int param_2);");
5306 @Sources_v2 = (@Sources_v2, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
5308 #starting versioning
5309 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
5310 @Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5312 @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
5313 @Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_start_versioning,func_return_type_and_start_versioning\@TEST_2.0\");");
5315 #Return_Type and good versioning
5316 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
5317 @Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_1.0\");");
5319 @DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
5320 @Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning_old,func_return_type_and_good_versioning\@TEST_1.0\");");
5322 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
5323 @Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_2.0\");");
5325 #Return_Type and bad versioning
5326 @DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
5327 @Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_1.0\");");
5329 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
5330 @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning_old,func_return_type_and_bad_versioning\@TEST_1.0\");");
5332 @DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
5333 @Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_2.0\");");
5335 #unnamed struct/union fields within structs/unions
5336 @DataDefs_v1 = (@DataDefs_v1, "
5344 } type_test_unnamed;
5345 int func_test_unnamed(type_test_unnamed param);");
5346 @Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
5348 @DataDefs_v2 = (@DataDefs_v2, "
5356 } type_test_unnamed;
5357 int func_test_unnamed(type_test_unnamed param);");
5358 @Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
5361 @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
5362 @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
5364 @DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
5365 @DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
5368 @DataDefs_v1 = (@DataDefs_v1, "
5374 } *type_test_anonptr_typedef;
5375 extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
5379 @Sources_v1 = (@Sources_v1, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
5381 @DataDefs_v2 = (@DataDefs_v2, "
5387 } *type_test_anonptr_typedef;
5388 extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
5392 @Sources_v2 = (@Sources_v2, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
5395 @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
5396 @Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1.0;\n}");
5398 @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
5399 @Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
5401 #typedefs in member type
5402 @DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
5403 @Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
5405 @DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
5406 @Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
5408 create_TestSuite
("abi_changes_test_c", "C", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "func_test_internal");
5411 sub create_TestSuite
($$$$$$$$)
5413 my ($Dir, $Lang, $DataDefs_v1, $Sources_v1, $DataDefs_v2, $Sources_v2, $Opaque, $Private) = @_;
5414 my $Ext = ($Lang eq "C++")?"cpp":"c";
5415 my $Gcc = ($Lang eq "C++")?"g++":"gcc";
5416 #creating test suite
5417 my $Path_v1 = "$Dir/lib_abi_changes_test.v1";
5418 my $Path_v2 = "$Dir/lib_abi_changes_test.v2";
5420 system("rm", "-fr", $Path_v1, $Path_v2);
5421 system("mkdir", "-p", $Path_v1, $Path_v2);
5423 writeFile
("$Path_v1/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
5424 writeFile
("$Path_v1/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v1."\n");
5425 writeFile
("$Path_v1/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v1."\n");
5426 writeFile
("$Dir/descriptor.v1", "<version>\n 1.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v1/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v1/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v1\n</include_paths>\n");
5428 writeFile
("$Path_v2/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
5429 writeFile
("$Path_v2/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v2."\n");
5430 writeFile
("$Path_v2/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v2."\n");
5431 writeFile
("$Dir/descriptor.v2", "<version>\n 2.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v2/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v2/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v2\n</include_paths>\n");
5433 system("$Gcc $Path_v1/lib_abi_changes_test.h");
5436 print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.h\'\n";
5439 system("$Gcc -Wl,--version-script $Path_v1/version -shared $Path_v1/lib_abi_changes_test.$Ext -o $Path_v1/lib_abi_changes_test.so");
5442 print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.$Ext\'\n";
5445 system("$Gcc $Path_v2/lib_abi_changes_test.h");
5448 print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.h\'\n";
5451 system("$Gcc -Wl,--version-script $Path_v2/version -shared $Path_v2/lib_abi_changes_test.$Ext -o $Path_v2/lib_abi_changes_test.so");
5454 print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.$Ext\'\n";
5458 #running abi-compliance-checker
5459 system("$0 -l lib_$Dir -d1 $Dir/descriptor.v1 -d2 $Dir/descriptor.v2");
5464 my ($Path, $Content) = @_;
5465 return if(not $Path);
5466 open (FILE
, ">".$Path) || die ("Can't open file $Path\n");
5467 print FILE
$Content;
5474 return "" if(not $Path or not -f
$Path);
5476 my $Content = join("\n", <FILE
>);
5478 return toUnix
($Content);
5490 my $Arch = $ENV{"CPU"};
5501 $Arch = "x86" if($Arch =~ /i[3-7]86/);
5505 sub get_Report_Header
()
5507 my $Report_Header = "<h1>ABI compliance report for the library <span style='color:Blue;white-space:nowrap;'>$TargetLibraryName </span> from version <span style='color:Red;white-space:nowrap;'>".$Descriptor{1}{"Version"}."</span> to <span style='color:Red;white-space:nowrap;'>".$Descriptor{2}{"Version"}."</span> on <span style='color:Blue;'>".getArch
()."</span> ".(($AppPath)?"relating to the portability of application <span style='color:Blue;'>".get_FileName
($AppPath)."</span>":"")."</h1>\n";
5508 return "<!--Header-->\n".$Report_Header."<!--Header_End-->\n";
5511 sub get_SourceInfo
()
5513 my $CheckedHeaders = "<!--Checked_Headers-->\n<a name='Checked_Headers'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked header files (".keys(%{$Headers{1}}).")</h2><hr/>\n";
5514 foreach my $Header_Dest (sort {lc($Headers{1}{$a}{"Name"}) cmp lc($Headers{1}{$b}{"Name"})} keys(%{$Headers{1}}))
5516 my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
5517 my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
5518 my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
5519 my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
5520 $CheckedHeaders .= "<span class='header_list_elem'>$Header_Name"."$Dest_Comment</span><br/>\n";
5522 $CheckedHeaders .= "<!--Checked_Headers_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5523 my $CheckedLibs = "<!--Checked_Libs-->\n<a name='Checked_Libs'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked shared objects (".keys(%{$SoNames_All{1}}).")</h2><hr/>\n";
5524 foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$SoNames_All{1}}))
5526 $CheckedLibs .= "<span class='solib_list_elem'>$Library</span><br/>\n";
5528 $CheckedLibs .= "<!--Checked_Libs_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5529 return $CheckedHeaders.$CheckedLibs;
5532 sub get_TypeProblems_Count
($$)
5534 my ($TypeChanges, $TargetPriority) = @_;
5535 my $Type_Problems_Count = 0;
5536 foreach my $TypeName (sort keys(%{$TypeChanges}))
5538 my %Kinds_Target = ();
5539 foreach my $Kind (keys(%{$TypeChanges->{$TypeName}}))
5541 foreach my $Location (keys(%{$TypeChanges->{$TypeName}{$Kind}}))
5543 my $Priority = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Priority"};
5544 next if($Priority ne $TargetPriority);
5545 my $Target = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Target"};
5546 next if($Kinds_Target{$Kind}{$Target});
5547 $Kinds_Target{$Kind}{$Target} = 1;
5548 $Type_Problems_Count += 1;
5552 return $Type_Problems_Count;
5557 my ($Added, $Withdrawn, $I_Problems_High, $I_Problems_Medium, $I_Problems_Low, $T_Problems_High, $T_Problems_Medium, $T_Problems_Low) = (0,0,0,0,0,0,0,0);
5558 foreach my $Interface (sort keys(%CompatProblems))
5560 foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5562 if($InterfaceProblems_Kind{$Kind})
5564 foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5566 if($Kind eq "Added_Interface")
5570 elsif($Kind eq "Withdrawn_Interface")
5576 if($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "High")
5578 $I_Problems_High += 1;
5580 elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Medium")
5582 $I_Problems_Medium += 1;
5584 elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Low")
5586 $I_Problems_Low += 1;
5594 my (%TypeChanges, %Type_MaxPriority);
5595 foreach my $Interface (sort keys(%CompatProblems))
5597 foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
5599 if($TypeProblems_Kind{$Kind})
5601 foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
5603 my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
5604 my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
5605 %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
5606 $Type_MaxPriority{$Type_Name}{$Kind} = max_priority
($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
5612 foreach my $Type_Name (keys(%TypeChanges))
5614 foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
5616 foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
5618 my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
5619 if(cmp_priority
($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
5621 delete($TypeChanges{$Type_Name}{$Kind}{$Location});
5627 $T_Problems_High = get_TypeProblems_Count
(\
%TypeChanges, "High");
5628 $T_Problems_Medium = get_TypeProblems_Count
(\
%TypeChanges, "Medium");
5629 $T_Problems_Low = get_TypeProblems_Count
(\
%TypeChanges, "Low");
5632 my $Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Summary</h2><hr/>";
5633 $Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
5636 my $Checked_Headers_Link = "0";
5637 $Checked_Headers_Link = "<a href='#Checked_Headers' style='color:Blue;'>".keys(%{$Headers{1}})."</a>" if(keys(%{$Headers{1}})>0);
5638 $Summary .= "<tr><td class='table_header summary_item'>Total header files checked</td><td class='summary_item_value'>$Checked_Headers_Link</td></tr>";
5640 my $Checked_Libs_Link = "0";
5641 $Checked_Libs_Link = "<a href='#Checked_Libs' style='color:Blue;'>".keys(%{$SoNames_All{1}})."</a>" if(keys(%{$SoNames_All{1}})>0);
5642 $Summary .= "<tr><td class='table_header summary_item'>Total shared objects checked</td><td class='summary_item_value'>$Checked_Libs_Link</td></tr>";
5643 $Summary .= "<tr><td class='table_header summary_item'>Total interfaces / types checked</td><td class='summary_item_value'>".keys(%CheckedInterfaces)." / ".keys(%CheckedTypes)."</td></tr>";
5645 my $Verdict = "<span style='color:Green;'><b>Compatible</b></span>";
5646 $Verdict = "<span style='color:Red;'><b>Incompatible</b></span>" if(($Withdrawn>0) or ($I_Problems_High>0) or ($T_Problems_High>0));
5647 $Summary .= "<tr><td class='table_header summary_item'>Verdict</td><td class='summary_item_value'>$Verdict</td></tr>";
5649 $Summary .= "</table>\n";
5652 my $Problem_Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problem Summary</h2><hr/>";
5653 $Problem_Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
5655 my $Added_Link = "0";
5656 $Added_Link = "<a href='#Added' style='color:Blue;'>$Added</a>" if($Added>0);
5657 $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Added interfaces</td><td class='summary_item_value'>$Added_Link</td></tr>";
5659 my $WIthdrawn_Link = "0";
5660 $WIthdrawn_Link = "<a href='#Withdrawn' style='color:Blue;'>$Withdrawn</a>" if($Withdrawn>0);
5661 $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Withdrawn interfaces</td><td class='summary_item_value'>$WIthdrawn_Link</td></tr>";
5664 $TH_Link = "<a href='#Type_Problems_High' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
5665 $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Problems in<br/>Data Types</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td align='right' class='summary_item_value'>$TH_Link</td></tr>";
5668 $TM_Link = "<a href='#Type_Problems_Medium' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
5669 $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$TM_Link</td></tr>";
5672 $TL_Link = "<a href='#Type_Problems_Low' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
5673 $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$TL_Link</td></tr>";
5676 $IH_Link = "<a href='#Interface_Problems_High' style='color:Blue;'>$I_Problems_High</a>" if($I_Problems_High>0);
5677 $Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Interface<br/>problems</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td class='summary_item_value'>$IH_Link</td></tr>";
5680 $IM_Link = "<a href='#Interface_Problems_Medium' style='color:Blue;'>$I_Problems_Medium</a>" if($I_Problems_Medium>0);
5681 $Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$IM_Link</td></tr>";
5684 $IL_Link = "<a href='#Interface_Problems_Low' style='color:Blue;'>$I_Problems_Low</a>" if($I_Problems_Low>0);
5685 $Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$IL_Link</td></tr>";
5687 my $ChangedConstants_Link = "0";
5688 $ChangedConstants_Link = "<a href='#Constants' style='color:Blue;'>".keys(%ConstantProblems)."</a>" if(keys(%ConstantProblems)>0);
5689 $Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Constants Problems</td><td class='summary_item_value'>$ChangedConstants_Link</td></tr>";
5691 $Problem_Summary .= "</table>\n";
5692 return "<!--Summary-->\n".$Summary.$Problem_Summary."<!--Summary_End-->\n";
5695 sub get_Report_ChangedConstants
()
5697 my ($CHANGED_CONSTANTS, %HeaderConstant);
5698 foreach my $Name (keys(%ConstantProblems))
5700 $HeaderConstant{$ConstantProblems{$Name}{"Header"}}{$Name} = 1;
5702 my $Constants_Number = 0;
5703 foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%HeaderConstant))
5705 $CHANGED_CONSTANTS .= "<span class='header_name'>$HeaderName</span><br/>\n";
5706 foreach my $Name (sort {lc($a) cmp lc($b)} keys(%{$HeaderConstant{$HeaderName}}))
5708 $Constants_Number += 1;
5709 my $Old_Value = htmlSpecChars
($ConstantProblems{$Name}{"Old_Value"});
5710 my $New_Value = htmlSpecChars
($ConstantProblems{$Name}{"New_Value"});
5711 my $Incompatibility = "The value of constant <b>$Name</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
5712 my $Effect = "If application uses this constant as a parameter of some interface than its execution may change.";
5713 my $ConstantProblemsReport = "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>1</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
5714 $CHANGED_CONSTANTS .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Name.$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$ConstantProblemsReport</table><br/>$ContentDivEnd\n";
5715 $CHANGED_CONSTANTS = insertIDs
($CHANGED_CONSTANTS);
5717 $CHANGED_CONSTANTS .= "<br/>\n";
5719 if($CHANGED_CONSTANTS)
5721 $CHANGED_CONSTANTS = "<a name='Constants'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Constants Problems ($Constants_Number)</h2><hr/>\n"."<!--Changed_Constants-->\n".$CHANGED_CONSTANTS."<!--Changed_Constants_End-->\n"."<input id='Changed_Constants_Count' type='hidden' value=\'$Constants_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5723 return $CHANGED_CONSTANTS;
5726 sub get_Report_Added
()
5728 my $ADDED_INTERFACES;
5730 my %FuncAddedInHeaderLib;
5731 foreach my $Interface (sort keys(%CompatProblems))
5733 foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5735 foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5737 if($Kind eq "Added_Interface")
5739 $FuncAddedInHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"New_SoName"}}{$Interface} = 1;
5745 my $Added_Number = 0;
5746 foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncAddedInHeaderLib))
5748 foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncAddedInHeaderLib{$HeaderName}}))
5752 $ADDED_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
5756 $ADDED_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
5758 foreach my $Interface (sort {lc($CompatProblems{$a}{"Added_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Added_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncAddedInHeaderLib{$HeaderName}{$SoName}}))
5762 my $Signature = $CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}{"Signature"};
5763 if($Interface =~ /\A_Z/)
5767 $SubReport = insertIDs
($ContentSpanStart.highLight_Signature_Italic_Color
(htmlSpecChars
($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
5771 $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5778 $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color
($Signature)."</span>"."<br/>\n";
5782 $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5785 $ADDED_INTERFACES .= $SubReport;
5787 $ADDED_INTERFACES .= "<br/>\n";
5790 if($ADDED_INTERFACES)
5792 $ADDED_INTERFACES = "<a name='Added'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Added Interfaces ($Added_Number)</h2><hr/>\n"."<!--Added_Interfaces-->\n".$ADDED_INTERFACES."<!--Added_Interfaces_End-->\n"."<input id='Added_Interfaces_Count' type='hidden' value=\'$Added_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5794 return $ADDED_INTERFACES;
5797 sub get_Report_Withdrawn
()
5799 my $WITHDRAWN_INTERFACES;
5800 #withdrawn interfaces
5801 my %FuncWithdrawnFromHeaderLib;
5802 foreach my $Interface (sort keys(%CompatProblems))
5804 foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5806 foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5808 if($Kind eq "Withdrawn_Interface")
5810 $FuncWithdrawnFromHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"}}{$Interface} = 1;
5816 my $Withdrawn_Number = 0;
5817 foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncWithdrawnFromHeaderLib))
5819 foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}}))
5823 $WITHDRAWN_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
5827 $WITHDRAWN_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
5829 foreach my $Interface (sort {lc($CompatProblems{$a}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}{$SoName}}))
5831 $Withdrawn_Number += 1;
5833 my $Signature = $CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"};
5834 if($Interface =~ /\A_Z/)
5838 $SubReport = insertIDs
($ContentSpanStart.highLight_Signature_Italic_Color
(htmlSpecChars
($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
5842 $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5849 $SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color
($Signature)."</span>"."<br/>\n";
5853 $SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5856 $WITHDRAWN_INTERFACES .= $SubReport;
5858 $WITHDRAWN_INTERFACES .= "<br/>\n";
5861 if($WITHDRAWN_INTERFACES)
5863 $WITHDRAWN_INTERFACES = "<a name='Withdrawn'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Withdrawn Interfaces ($Withdrawn_Number)</h2><hr/>\n"."<!--Withdrawn_Interfaces-->\n".$WITHDRAWN_INTERFACES."<!--Withdrawn_Interfaces_End-->\n"."<input id='Withdrawn_Interfaces_Count' type='hidden' value=\'$Withdrawn_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5865 return $WITHDRAWN_INTERFACES;
5868 sub get_Report_InterfaceProblems
($)
5870 my $TargetPriority = $_[0];
5871 my ($INTERFACE_PROBLEMS, %FuncHeaderLib);
5872 foreach my $Interface (sort keys(%CompatProblems))
5874 foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5876 if($InterfaceProblems_Kind{$Kind} and ($Kind ne "Added_Interface") and ($Kind ne "Withdrawn_Interface"))
5878 foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5880 my $SoName = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"};
5881 my $HeaderName = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
5882 $FuncHeaderLib{$HeaderName}{$SoName}{$Interface} = 1;
5888 my $Problems_Number = 0;
5890 foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncHeaderLib))
5892 foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncHeaderLib{$HeaderName}}))
5894 my $HEADER_LIB_REPORT = "";
5895 foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$FuncHeaderLib{$HeaderName}{$SoName}}))
5898 my $InterfaceProblemsReport = "";
5900 foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
5902 foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
5904 my $Incompatibility = "";
5906 my $Old_Value = htmlSpecChars
($CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"});
5907 my $New_Value = htmlSpecChars
($CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"});
5908 my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
5909 my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
5910 my $Old_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Size"};
5911 my $New_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Size"};
5912 my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
5913 my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
5914 my $Parameter_Position_Str = num_to_str
($Parameter_Position + 1);
5915 $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"} if(not $Signature);
5916 next if($Priority ne $TargetPriority);
5917 if($Kind eq "Function_Become_Static")
5919 $Incompatibility = "Function become <b>static</b>.\n";
5920 $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5922 elsif($Kind eq "Function_Become_NonStatic")
5924 $Incompatibility = "Function become <b>non-static</b>.\n";
5925 $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5927 elsif($Kind eq "Parameter_Type_And_Size")
5929 $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5930 $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5932 elsif($Kind eq "Parameter_Type")
5934 $Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5935 $Effect = "Replacement of parameter data type may indicate a change in the semantic meaning of this parameter.";
5937 elsif($Kind eq "Withdrawn_Parameter")
5939 $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been withdrawn from the interface signature.\n";
5940 $Effect = "This parameter will be ignored by the interface.";
5942 elsif($Kind eq "Added_Parameter")
5944 $Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been added to the interface signature.\n";
5945 $Effect = "This parameter will not be initialized by applications.";
5947 elsif($Kind eq "Parameter_BaseType_And_Size")
5949 if($InitialType_Type eq "Pointer")
5951 $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5952 $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
5956 $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5957 $Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5960 elsif($Kind eq "Parameter_BaseType")
5962 if($InitialType_Type eq "Pointer")
5964 $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5965 $Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
5969 $Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5970 $Effect = "Replacement of parameter base type may indicate a change in the semantic meaning of this parameter.";
5973 elsif($Kind eq "Parameter_PointerLevel")
5975 $Incompatibility = "Type pointer level of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
5976 $Effect = "Possible incorrect initialization of $Parameter_Position_Str parameter <b>$Target</b> by applications.";
5978 elsif($Kind eq "Return_Type_And_Size")
5980 $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5981 $Effect = "Applications will get a different return value and execution may change.";
5983 elsif($Kind eq "Return_Type")
5985 $Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5986 $Effect = "Replacement of return type may indicate a change in its semantic meaning.";
5988 elsif($Kind eq "Return_BaseType_And_Size")
5990 $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5991 $Effect = "Applications will get a different return value and execution may change.";
5993 elsif($Kind eq "Return_BaseType")
5995 $Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5996 $Effect = "Replacement of return base type may indicate a change in its semantic meaning.";
5998 elsif($Kind eq "Return_PointerLevel")
6000 $Incompatibility = "Type pointer level of return value has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
6001 $Effect = "Applications will get a different return value and execution may change.";
6003 if($Incompatibility)
6005 $InterfaceProblemsReport .= "<tr><td align='center' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>".$Effect."</span></td></tr>\n";
6007 $Problems_Number += 1;
6012 if($InterfaceProblemsReport)
6014 if($Interface =~ /\A_Z/)
6018 $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color
(htmlSpecChars
($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/>\n";
6022 $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6029 $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color
(htmlSpecChars
($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6033 $HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6036 $HEADER_LIB_REPORT .= "<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$InterfaceProblemsReport</table><br/>$ContentDivEnd\n";
6037 $HEADER_LIB_REPORT = insertIDs
($HEADER_LIB_REPORT);
6040 if($HEADER_LIB_REPORT)
6042 $INTERFACE_PROBLEMS .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n".$HEADER_LIB_REPORT."<br/>";
6046 if($INTERFACE_PROBLEMS)
6048 $INTERFACE_PROBLEMS = "<a name=\'Interface_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Interface problems, $TargetPriority risk ($Problems_Number)</h2><hr/>\n"."<!--Interface_Problems_".$TargetPriority."-->\n".$INTERFACE_PROBLEMS."<!--Interface_Problems_".$TargetPriority."_End-->\n"."<input id=\'Interface_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
6050 return $INTERFACE_PROBLEMS;
6053 sub get_Report_TypeProblems
($)
6055 my $TargetPriority = $_[0];
6056 my ($TYPE_PROBLEMS, %TypeHeader, %TypeChanges, %Type_MaxPriority) = ();
6057 foreach my $Interface (sort keys(%CompatProblems))
6059 foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
6061 if($TypeProblems_Kind{$Kind})
6063 foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
6065 my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6066 my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
6067 my $Type_Header = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
6068 %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
6069 $TypeHeader{$Type_Header}{$Type_Name} = 1;
6070 $Type_MaxPriority{$Type_Name}{$Kind} = max_priority
($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
6075 foreach my $Type_Name (keys(%TypeChanges))
6077 foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
6079 foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
6081 my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
6082 if(cmp_priority
($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
6084 delete($TypeChanges{$Type_Name}{$Kind}{$Location});
6089 my $Problems_Number = 0;
6090 foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%TypeHeader))
6092 my $HEADER_REPORT = "";
6093 foreach my $TypeName (sort {lc($a) cmp lc($b)} keys(%{$TypeHeader{$HeaderName}}))
6096 my $TypeProblemsReport = "";
6097 my %Kinds_Locations = ();
6098 my %Kinds_Target = ();
6099 foreach my $Kind (keys(%{$TypeChanges{$TypeName}}))
6101 foreach my $Location (keys(%{$TypeChanges{$TypeName}{$Kind}}))
6103 my $Priority = $TypeChanges{$TypeName}{$Kind}{$Location}{"Priority"};
6104 next if($Priority ne $TargetPriority);
6105 $Kinds_Locations{$Kind}{$Location} = 1;
6106 my $Incompatibility = "";
6108 my $Target = $TypeChanges{$TypeName}{$Kind}{$Location}{"Target"};
6109 next if($Kinds_Target{$Kind}{$Target});
6110 $Kinds_Target{$Kind}{$Target} = 1;
6111 my $Old_Value = htmlSpecChars
($TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Value"});
6112 my $New_Value = htmlSpecChars
($TypeChanges{$TypeName}{$Kind}{$Location}{"New_Value"});
6113 my $Old_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Size"};
6114 my $New_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"New_Size"};
6115 my $Type_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"Type_Type"};
6116 my $InitialType_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"InitialType_Type"};
6118 if($Kind eq "Added_Virtual_Function")
6120 $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Target))."</span>"." has been added to this class and therefore the layout of virtual table has been changed.";
6121 $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
6123 elsif($Kind eq "Withdrawn_Virtual_Function")
6125 $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Target))."</span>"." has been withdrawn from this class and therefore the layout of virtual table has been changed.";
6126 $Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
6128 elsif($Kind eq "Virtual_Function_Position")
6130 $Incompatibility = "The relative position of virtual method "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Target))."</span>"." has been changed from <b>$Old_Value</b> to <b>$New_Value</b> and therefore the layout of virtual table has been changed.";
6131 $Effect = "Call of this virtual method will result in crash of application.";
6133 elsif($Kind eq "Virtual_Function_Redefinition")
6135 $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Old_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($New_Value))."</span>";
6136 $Effect = "Method <span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($New_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Old_Value))."</span>";
6138 elsif($Kind eq "Virtual_Function_Redefinition_B")
6140 $Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($New_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Old_Value))."</span>";
6141 $Effect = "Method <span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($Old_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature
(htmlSpecChars
($New_Value))."</span>";
6143 elsif($Kind eq "Size")
6145 $Incompatibility = "Size of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b> bytes.";
6146 $Effect = "Change of type size may lead to different effects in different contexts. $ContentSpanStart"."<span style='color:Black'>[+] ...</span>"."$ContentSpanEnd <label id=\"CONTENT_ID\" style=\"display:none;\"> In the context of function parameters, this change affects the parameter's stack layout and may lead to incorrect initialization of parameters in higher positions in the stack. In the context of structure members, this change affects the member's layout and may lead to incorrect attempts to access members in higher positions. Other effects are possible.</label>";
6148 elsif($Kind eq "BaseType")
6150 $Incompatibility = "Base of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6151 $Effect = "Possible incorrect initialization of interface parameters by applications.";
6153 elsif($Kind eq "Added_Member_And_Size")
6155 $Incompatibility = "Member <b>$Target</b> has been added to this type.";
6156 $Effect = "The size of the inclusive type has been changed.";
6158 elsif($Kind eq "Added_Middle_Member_And_Size")
6160 $Incompatibility = "Member <b>$Target</b> has been added between the first member and the last member of this structural type.";
6161 $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) The size of the inclusive type will also be affected.";
6163 elsif($Kind eq "Member_Rename")
6165 $Incompatibility = "Member <b>$Target</b> has been renamed to <b>$New_Value</b>.";
6166 $Effect = "Renaming of a member in a structural data type may indicate a change in the semantic meaning of the member.";
6168 elsif($Kind eq "Withdrawn_Member_And_Size")
6170 $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
6171 $Effect = "1) Applications will access incorrect memory when attempting to access this member.<br/>2) The size of the inclusive type will also be affected.";
6173 elsif($Kind eq "Withdrawn_Member")
6175 $Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
6176 $Effect = "Applications will access incorrect memory when attempting to access this member.";
6178 elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
6180 $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
6181 $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Previous accesses of applications to the withdrawn member will be incorrect.";
6183 elsif($Kind eq "Withdrawn_Middle_Member")
6185 $Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
6186 $Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Applications will access incorrect memory when attempting to access this member.";
6188 elsif($Kind eq "Enum_Member_Value")
6190 $Incompatibility = "Value of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6191 $Effect = "Applications may execute another branch of library code.";
6193 elsif($Kind eq "Enum_Member_Name")
6195 $Incompatibility = "Name of member with value <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6196 $Effect = "Applications may execute another branch of library code.";
6198 elsif($Kind eq "Member_Type_And_Size")
6200 $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6201 $Effect = "Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.";
6203 elsif($Kind eq "Member_Type")
6205 $Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6206 $Effect = "Replacement of the member data type may indicate a change in the semantic meaning of the member.";
6208 elsif($Kind eq "Member_BaseType_And_Size")
6210 if($InitialType_Type eq "Pointer")
6212 $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6213 $Effect = "Possible access of applications to incorrect memory via member pointer.";
6217 $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6218 $Effect = "Layout of structure members has been changed and therefore members in higher positions in structure definition may be incorrectly accessed by applications.";
6221 elsif($Kind eq "Member_BaseType")
6223 if($InitialType_Type eq "Pointer")
6225 $Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6226 $Effect = "Possible access of applications to incorrect memory via member pointer.";
6230 $Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6231 $Effect = "Replacement of member base type may indicate a change in the semantic meaning of this member.";
6234 elsif($Kind eq "Member_PointerLevel")
6236 $Incompatibility = "Type pointer level of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6237 $Effect = "Possible incorrect initialization of member <b>$Target</b> by applications.";
6239 if($Incompatibility)
6241 $TypeProblemsReport .= "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
6243 $Problems_Number += 1;
6244 $Kinds_Locations{$Kind}{$Location} = 1;
6249 if($TypeProblemsReport)
6251 my ($Affected_Interfaces_Header, $Affected_Interfaces) = getAffectedInterfaces
($TypeName, \
%Kinds_Locations);
6252 $HEADER_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".htmlSpecChars
($TypeName)." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$TypeProblemsReport</table>"."<span style='padding-left:10px'>$Affected_Interfaces_Header</span>$Affected_Interfaces<br/><br/>$ContentDivEnd\n";
6253 $HEADER_REPORT = insertIDs
($HEADER_REPORT);
6258 $TYPE_PROBLEMS .= "<span class='header_name'>$HeaderName</span><br/>\n".$HEADER_REPORT."<br/>";
6264 if($TYPE_PROBLEMS =~ /'RetVal|'Obj/)
6266 my @Notations_Array = ();
6267 if($TYPE_PROBLEMS =~ /'RetVal/)
6269 @Notations_Array = (@Notations_Array, "<span style='color:#444444;padding-left:5px;'><b>RetVal</b></span> - function's return value");
6271 if($TYPE_PROBLEMS =~ /'Obj/)
6273 @Notations_Array = (@Notations_Array, "<span style='color:#444444;'><b>Obj</b></span> - method's object (C++)");
6275 $Notations = "Shorthand notations: ".join("; ", @Notations_Array).".<br/>\n";
6277 $TYPE_PROBLEMS = "<a name=\'Type_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problems in Data Types, $TargetPriority risk ($Problems_Number)</h2><hr/>\n".$Notations."<!--Type_Problems_".$TargetPriority."-->\n".$TYPE_PROBLEMS."<!--Type_Problems_".$TargetPriority."_End-->\n"."<input id=\'Type_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
6279 return $TYPE_PROBLEMS;
6282 my $ContentSpanStart_2 = "<span style='line-height:25px;' class=\"section_2\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
6284 sub getAffectedInterfaces
($$)
6286 my ($Target_TypeName, $Kinds_Locations) = @_;
6287 my ($Affected_Interfaces_Header, $Affected_Interfaces, %FunctionNumber) = ();
6288 foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%CompatProblems))
6290 next if(($Interface =~ /C2/) or ($Interface =~ /D2/) or ($Interface =~ /D0/));
6291 next if(keys(%FunctionNumber)>1000);
6292 my $FunctionProblem = "";
6293 my $MinPath_Length = "";
6294 my $MaxPriority = 0;
6295 my $Location_Last = "";
6296 foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
6298 foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
6300 next if(not $Kinds_Locations->{$Kind}{$Location});
6301 my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6302 my $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"};
6303 my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
6304 my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
6305 if($Type_Name eq $Target_TypeName)
6307 $FunctionNumber{$Interface} = 1;
6308 my $Path_Length = 0;
6309 while($Location =~ /\-\>/g){$Path_Length += 1;}
6310 if(($MinPath_Length eq "") or ($Path_Length<$MinPath_Length and $Priority_Value{$Priority}>$MaxPriority) or (($Location_Last =~ /RetVal/ or $Location_Last =~ /Obj/) and $Location !~ /RetVal|Obj/ and $Location !~ /\-\>/) or ($Location_Last =~ /RetVal|Obj/ and $Location_Last =~ /\-\>/ and $Location !~ /RetVal|Obj/ and $Location =~ /\-\>/))
6312 $MinPath_Length = $Path_Length;
6313 $MaxPriority = $Priority_Value{$Priority};
6314 $Location_Last = $Location;
6315 my $Description = get_AffectDescription
($Interface, $Kind, $Location);
6316 $FunctionProblem = "<span class='interface_name_black' style='padding-left:20px;'>".highLight_Signature_PPos_Italic
(htmlSpecChars
($Signature), $Parameter_Position, 1, 0)."</span>:<br/>"."<span class='affect_description'>".addArrows
($Description)."</span><br/><div style='height:4px;'> </div>\n";
6321 $Affected_Interfaces .= $FunctionProblem;
6323 $Affected_Interfaces .= "and other...<br/>" if(keys(%FunctionNumber)>5000);
6324 if($Affected_Interfaces)
6326 $Affected_Interfaces_Header = $ContentSpanStart_2."[+] affected interfaces (".keys(%FunctionNumber).")".$ContentSpanEnd;
6327 $Affected_Interfaces = $ContentDivStart.$Affected_Interfaces.$ContentDivEnd;
6329 return ($Affected_Interfaces_Header, $Affected_Interfaces);
6332 my %Kind_TypeStructureChanged=(
6334 "Added_Member_And_Size"=>1,
6335 "Added_Middle_Member_And_Size"=>1,
6337 "Withdrawn_Member_And_Size"=>1,
6338 "Withdrawn_Member"=>1,
6339 "Withdrawn_Middle_Member_And_Size"=>1,
6340 "Enum_Member_Value"=>1,
6341 "Enum_Member_Name"=>1,
6342 "Member_Type_And_Size"=>1,
6344 "Member_BaseType_And_Size"=>1,
6345 "Member_BaseType"=>1,
6346 "Member_PointerLevel"=>1,
6350 my %Kind_VirtualTableChanged=(
6351 "Added_Virtual_Function"=>1,
6352 "Withdrawn_Virtual_Function"=>1,
6353 "Virtual_Function_Position"=>1,
6354 "Virtual_Function_Redefinition"=>1,
6355 "Virtual_Function_Redefinition_B"=>1
6358 sub get_AffectDescription
($$$)
6360 my ($Interface, $Kind, $Location) = @_;
6361 my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
6362 my $Old_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"};
6363 my $New_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"};
6364 my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6365 my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
6366 my $Parameter_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Name"};
6367 my $Parameter_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Type_Name"};
6368 my $Member_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Member_Type_Name"};
6369 my $Object_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Object_Type_Name"};
6370 my $Return_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Return_Type_Name"};
6371 my $Start_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Start_Type_Name"};
6372 my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
6373 my $Parameter_Position_Str = num_to_str
($Parameter_Position + 1);
6374 my @Sentence_Parts = ();
6375 my $Location_To_Type = $Location;
6376 $Location_To_Type =~ s/\-\>[^>]+?\Z//;
6377 if($Kind_VirtualTableChanged{$Kind})
6379 if($Kind eq "Virtual_Function_Redefinition")
6381 @Sentence_Parts = (@Sentence_Parts, "This method become virtual and will be called instead of redefined method '".highLight_Signature
(htmlSpecChars
($Old_Value))."'.");
6383 elsif($Kind eq "Virtual_Function_Redefinition_B")
6385 @Sentence_Parts = (@Sentence_Parts, "This method become non-virtual and redefined method '".highLight_Signature
(htmlSpecChars
($Old_Value))."' will be called instead of it.");
6389 @Sentence_Parts = (@Sentence_Parts, "Call of this virtual method will result in crash of application because the layout of virtual table has been changed.");
6392 elsif($Kind_TypeStructureChanged{$Kind})
6394 if($Location_To_Type =~ /RetVal/)
6396 if($Location_To_Type =~ /\-\>/)
6398 @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in return value");
6402 @Sentence_Parts = (@Sentence_Parts, "Return value");
6405 elsif($Location_To_Type =~ /Obj/)
6407 if($Location_To_Type =~ /\-\>/)
6409 @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in the object of this method");
6413 @Sentence_Parts = (@Sentence_Parts, "Object");
6418 if($Location_To_Type =~ /\-\>/)
6420 @Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' of $Parameter_Position_Str parameter");
6424 @Sentence_Parts = (@Sentence_Parts, "$Parameter_Position_Str parameter");
6428 @Sentence_Parts = (@Sentence_Parts, "\'$Parameter_Name\'");
6430 if($InitialType_Type eq "Pointer")
6432 @Sentence_Parts = (@Sentence_Parts, "(pointer)");
6435 if($Start_Type_Name eq $Type_Name)
6437 @Sentence_Parts = (@Sentence_Parts, "has type \'$Type_Name\'.");
6441 @Sentence_Parts = (@Sentence_Parts, "has base type \'$Type_Name\'.");
6444 return join(" ", @Sentence_Parts);
6447 sub create_HtmlReport
()
6449 my $CssStyles = "<style type=\"text/css\">
6450 body{font-family:Arial;}
6451 hr{color:Black;background-color:Black;height:1px;border:0;}
6452 span.section{font-weight:bold;cursor:pointer;margin-left:7px;font-size:16px;font-family:Arial;color:#003E69;}
6453 span:hover.section{color:#336699;}
6454 span.section_2{cursor:pointer;margin-left:7px;font-size:14px;font-family:Arial;color:#cc3300;}
6455 span.extension{font-weight:100;font-size:16px;}
6456 span.problem_exact_location{color:Red;font-size:14px;}
6457 span.header_name{color:#cc3300;font-size:14px;font-family:Arial;font-weight:bold;}
6458 span.header_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
6459 span.solib_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
6460 span.solib_name{color:Green;font-size:14px;font-family:Arial;font-weight:bold;}
6461 span.interface_name{font-weight:bold;font-size:16px;font-family:Arial;color:#003E69;margin-left:7px;}
6462 span.interface_name_black{font-weight:bold;font-size:15px;font-family:Arial;color:#333333;}
6463 span.problem_title{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
6464 span.problem_sub_title{color:#333333;text-decoration:none;font-weight:bold;font-size:13px;font-family:Verdana;}
6465 span.problem_body{color:Black;font-size:14px;}
6466 span.int_p{font-weight:normal;}
6467 span.affect_description{padding-left:30px;font-size:14px;font-style:italic;line-height:13px;}
6468 table.problems_table{line-height:16px;margin-left:15px;margin-top:3px;border-collapse:collapse;}
6469 table.problems_table td{border-style:solid;border-color:Gray;border-width:1px;}
6470 td.table_header{background-color:#eeeeee;}
6471 td.summary_item{font-size:15px;font-family:Arial;text-align:left;}
6472 td.summary_item_value{padding-left:5px;padding-right:5px;width:35px;text-align:right;}
6473 span.problem_num{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
6474 span.mangled{padding-left:15px;font-size:13px;cursor:text;color:#444444;}
6475 span.symver{color:#555555;font-size:13px;white-space:nowrap;}
6476 span.color_param{font-style:italic;color:Brown;}
6477 span.focus_param{font-style:italic;color:Red;}</style>";
6479 my $JScripts = "<script type=\"text/javascript\" language=\"JavaScript\">
6480 function showContent(header, id) {
6481 e = document.getElementById(id);
6482 if(e.style.display == 'none')
6484 e.style.display = '';
6485 e.style.visibility = 'visible';
6486 header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[−]\");
6490 e.style.display = 'none';
6491 e.style.visibility = 'hidden';
6492 header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[+]\");
6496 writeFile
("$REPORT_PATH/abi_compat_report.html", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
6497 <title>ABI compliance report for the library $TargetLibraryName from version ".$Descriptor{1}{"Version"}." to ".$Descriptor{2}{"Version"}." on ".getArch
()."\n</title>\n<!--Styles-->\n".$CssStyles."\n<!--Styles_End-->\n"."<!--JScripts-->\n".$JScripts."\n<!--JScripts_End-->\n</head>\n<body>\n<div><a name='Top'></a>\n".get_Report_Header
()."<br/>\n".get_Summary
()."<br/>\n".get_Report_Added
().get_Report_Withdrawn
().get_Report_TypeProblems
("High").get_Report_TypeProblems
("Medium").get_Report_TypeProblems
("Low").get_Report_InterfaceProblems
("High").get_Report_InterfaceProblems
("Medium").get_Report_InterfaceProblems
("Low").get_Report_ChangedConstants
().get_SourceInfo
()."</div>\n"."<br/><br/><br/><hr/><div style='width:100%;font-family:Arial;font-size:11px;' align='right'><i>Generated on ".(localtime time)." for <span style='font-weight:bold'>$TargetLibraryName</span> by <a href='http://ispras.linux-foundation.org/index.php/ABI_compliance_checker'>ABI-compliance-checker</a> $ABI_COMPLIANCE_CHECKER_VERSION </i></div>\n<div style='height:999px;'></div>\n</body></html>");
6502 if(int($_[0]) > int($_[1]))
6506 elsif($_[0] eq $_[1])
6519 #$Text =~ s/\-\>/→/g;
6520 $Text =~ s/\-\>/−>/g;
6527 while($Text =~ /CONTENT_ID/)
6529 if(int($Content_Counter)%2)
6533 $Text =~ s/CONTENT_ID/c_$ContentID/;
6535 $Content_Counter += 1;
6540 sub restrict_num_decimal_digits
6543 my $digs_to_cut=shift;
6545 if ($num=~/\d+\.(\d){$digs_to_cut,}/)
6547 $num=sprintf("%.".($digs_to_cut-1)."f", $num);
6552 sub parse_constants
()
6555 foreach my $String (split("\n", $ConstantsSrc{$Version}))
6556 {#detecting public and private constants using sources
6557 if($String=~/#[ \t]+\d+[ \t]+\"(.+)\"/)
6561 if($String=~/\#[ \t]*define[ \t]+([_A-Z]+)[ \t]+(.*)[ \t]*\Z/)
6563 my ($Name, $Value) = ($1, $2);
6564 if(not $Constants{$Version}{$Name}{"Access"})
6566 $Constants{$Version}{$Name}{"Access"} = "public";
6567 $Constants{$Version}{$Name}{"Value"} = $Value;
6568 $Constants{$Version}{$Name}{"Header"} = get_FileName
($CurHeader);
6571 elsif($String=~/\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/)
6574 $Constants{$Version}{$Name}{"Access"} = "private";
6577 foreach my $Constant (keys(%{$Constants{$Version}}))
6579 if(($Constants{$Version}{$Constant}{"Access"} eq "private") or not $Constants{$Version}{$Constant}{"Value"}
6580 or $Constant=~/_h\Z/i)
6582 delete($Constants{$Version}{$Constant});
6586 delete($Constants{$Version}{$Constant}{"Access"});
6591 sub mergeConstants
()
6593 return if(defined $AppPath);
6594 foreach my $Constant (keys(%{$Constants{1}}))
6596 my $Old_Value = $Constants{1}{$Constant}{"Value"};
6597 my $New_Value = $Constants{2}{$Constant}{"Value"};
6598 my $Header = $Constants{1}{$Constant}{"Header"};
6599 if($New_Value and $Old_Value and ($New_Value ne $Old_Value))
6601 %{$ConstantProblems{$Constant}} = (
6602 "Old_Value"=>$Old_Value,
6603 "New_Value"=>$New_Value,
6610 sub mergeHeaders_Separately
()
6612 system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
6613 system("rm", "-fr", $ERR_PATH{1}, $ERR_PATH{2});
6614 my ($Header_Num, $Prev_Header_Length) = (0, 0);
6615 my $All_Count = keys(%{$Headers{1}});
6616 foreach my $Header_Dest (sort {int($Headers{1}{$a}{"Position"})<=>int($Headers{1}{$b}{"Position"})} keys(%{$Headers{1}}))
6618 my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
6619 my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
6620 my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
6621 my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
6622 print get_one_step_title
($Header_Name.$Dest_Comment, $Header_Num, $All_Count, $Prev_Header_Length, 1)."\r";
6626 %ClassVirtFunc = ();
6628 %CompleteSignature = ();
6631 parseHeader
($Header_Dest);
6633 my $PairHeaderDest = find_pair_header
($Header_Dest);
6634 if(not $PairHeaderDest)
6639 parseHeader
($PairHeaderDest);
6643 $Prev_Header_Length = length($Header_Name.$Dest_Comment);
6645 print get_one_step_title
("", $All_Count, $All_Count, $Prev_Header_Length, 0)."\n";
6648 sub get_one_step_title
($$$$$)
6650 my ($Header_Name, $Num, $All_Count, $SpacesAtTheEnd, $ShowCurrent) = @_;
6651 my ($Spaces_1, $Spaces_2, $Title) = ();
6652 my $Title_1 = "checking headers: $Num/$All_Count [".restrict_num_decimal_digits
($Num*100/$All_Count, 3)."%]".(($ShowCurrent)?",":"");
6653 foreach (0 .. length("checking headers: ")+length($All_Count)*2+11 - length($Title_1))
6657 $Title .= $Title_1.$Spaces_1;
6660 my $Title_2 = "current: $Header_Name";
6661 foreach (0 .. $SpacesAtTheEnd - length($Header_Name)-1)
6665 $Title .= $Title_2.$Spaces_2;
6669 foreach (0 .. $SpacesAtTheEnd + length(" current: ") - 1)
6677 sub find_pair_header
($)
6679 my $Header_Dest = $_[0];
6680 my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
6681 my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
6682 my @Pair_Dest = keys(%{$HeaderName_Destinations{2}{$Header_Name}});
6685 return $Pair_Dest[0];
6687 elsif($#Pair_Dest==-1)
6693 foreach my $Pair_Dest (@Pair_Dest)
6695 my $Pair_Identity = $Headers{2}{$Pair_Dest}{"Identity"};
6696 if($Identity eq $Pair_Identity)
6707 my $LibVersion = $_[0];
6708 my @SoLibPaths = getSoPaths
($LibVersion);
6709 if($#SoLibPaths eq -1 and not $CheckHeadersOnly)
6711 print "ERROR: shared objects were not found\n";
6714 foreach my $SoLibPath (@SoLibPaths)
6716 getSymbols_Lib
($LibVersion, $SoLibPath, 0);
6722 return ("", $_[0])if($_[0] !~ /\//);
6723 if($_[0] =~ /\A(.*\/)([^\
/]*)\Z/)
6733 sub translateSymbols
($)
6735 my $LibVersion = $_[0];
6736 my (@MnglNames, @UnMnglNames) = ();
6737 foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
6739 if($Interface =~ /\A_Z/)
6741 $Interface =~ s/[\@]+(.*)\Z//;
6742 push(@MnglNames, $Interface);
6746 $tr_name{$Interface} = $Interface;
6747 $mangled_name{$tr_name{$Interface}} = $Interface;
6750 if($#MnglNames > -1)
6752 @UnMnglNames = reverse(unmangleArray
(@MnglNames));
6753 foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
6755 if($Interface =~ /\A_Z/)
6757 $Interface =~ s/[\@]+(.*)\Z//;
6758 $tr_name{$Interface} = pop(@UnMnglNames);
6759 $mangled_name{correctName
($tr_name{$Interface})} = $Interface;
6768 foreach my $Interface (keys(%{$Interface_Library{2}}))
6770 if(not $Interface_Library{1}{$Interface})
6772 $AddedInt{$Interface} = 1;
6773 my ($MnglName, $SymbolVersion) = ($Interface, "");
6774 if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
6776 ($MnglName, $SymbolVersion) = ($1, $2);
6778 $FuncAttr{2}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
6783 sub detectWithdrawn
()
6785 #detecting withdrawn
6786 foreach my $Interface (keys(%{$Interface_Library{1}}))
6788 if(not $Interface_Library{2}{$Interface} and not $Interface_Library{2}{$SymVer{2}{$Interface}})
6790 next if($DepInterfaces{2}{$Interface});
6791 $WithdrawnInt{$Interface} = 1;
6792 my ($MnglName, $SymbolVersion) = ($Interface, "");
6793 if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
6795 ($MnglName, $SymbolVersion) = ($1, $2);
6797 $FuncAttr{1}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
6804 my $LibName = $_[0];
6805 foreach my $LibNameInStack (@RecurLib)
6807 if($LibName eq $LibNameInStack)
6815 sub getSymbols_App
($)
6818 return () if(not $Path or not -f
$Path);
6820 open(APP
, "readelf -WhlSsdA $Path |");
6821 my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
6825 #do nothing with symtab (but there are some plans for the future)
6831 elsif( /'.symtab'/ ) {
6834 elsif(my ($fullname, $idx, $Ndx) = readlile_ELF
($_)) {
6835 if( $Ndx eq "UND" ) {
6836 #only exported interfaces
6837 push(@Ints, $fullname);
6847 if($_[0]=~/\s*\d+:\s+(\w*)\s+\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s((\w|@|\.)+)/)
6848 {#the line of 'readelf' output corresponding to the interface
6849 my ($value, $type, $bind, $vis, $Ndx, $fullname)=($1, $2, $3, $4, $5, $6);
6850 if(($bind ne "WEAK") and ($bind ne "GLOBAL")) {
6853 if(($type ne "FUNC") and ($type ne "OBJECT") and ($type ne "COMMON")) {
6856 if($vis ne "DEFAULT") {
6859 if(($Ndx eq "ABS") and ($value !~ /\D|1|2|3|4|5|6|7|8|9/)) {
6862 return ($fullname, $value, $Ndx);
6870 sub getSymbols_Lib
($$$)
6872 my ($LibVersion, $Lib_Path, $IsNeededLib) = @_;
6873 return if(not $Lib_Path or not -f
$Lib_Path);
6874 my ($Lib_Dir, $Lib_SoName) = separatePath
($Lib_Path);
6875 return if($CheckedSoLib{$LibVersion}{$Lib_SoName} and $IsNeededLib);
6876 return if(isRecurLib
($Lib_SoName) or $#RecurLib>=1);
6877 $CheckedSoLib{$LibVersion}{$Lib_SoName} = 1;
6878 push(@RecurLib, $Lib_SoName);
6879 my (%Value_Interface, %Interface_Value, %NeededLib) = ();
6880 if(not $IsNeededLib)
6882 $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
6884 open(SOLIB
, "readelf -WhlSsdA $Lib_Path |");
6885 my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
6889 #do nothing with symtab (but there are some plans for the future)
6895 elsif(/'.symtab'/) {
6898 elsif(/NEEDED.+\[([^\[\]]+)\]/)
6902 elsif(my ($fullname, $idx, $Ndx) = readlile_ELF
($_)) {
6903 if( $Ndx eq "UND" ) {
6904 #ignore interfaces that are exported form somewhere else
6907 my ($realname, $version) = ($fullname, "");
6908 if($fullname =~ /\A([^@]+)[\@]+([^@]+)\Z/)
6910 ($realname, $version) = ($1, $2);
6912 next if(defined $InterfacesListPath and not $InterfacesList{$realname});
6913 next if(defined $AppPath and not $InterfacesList_App{$realname});
6916 $DepInterfaces{$LibVersion}{$fullname} = 1;
6918 if(not $IsNeededLib or (defined $InterfacesListPath and $InterfacesList{$realname}) or (defined $AppPath and $InterfacesList_App{$realname}))
6920 $Interface_Library{$LibVersion}{$fullname} = $Lib_SoName;
6921 $Library_Interface{$LibVersion}{$Lib_SoName}{$fullname} = 1;
6922 $Interface_Value{$LibVersion}{$fullname} = $idx;
6923 $Value_Interface{$LibVersion}{$idx}{$fullname} = 1;
6924 if(not $Language{$LibVersion}{$Lib_SoName})
6926 if($fullname =~ /\A_Z[A-Z]*[0-9]+/)
6928 $Language{$LibVersion}{$Lib_SoName} = "C++";
6935 if(not $IsNeededLib)
6937 foreach my $Interface_Name (keys(%{$Interface_Library{$LibVersion}}))
6939 next if($Interface_Name !~ /\@/);
6940 my $Interface_SymName = "";
6941 foreach my $InterfaceName_SameValue (keys(%{$Value_Interface{$LibVersion}{$Interface_Value{$LibVersion}{$Interface_Name}}}))
6943 if($InterfaceName_SameValue ne $Interface_Name)
6945 $SymVer{$LibVersion}{$InterfaceName_SameValue} = $Interface_Name;
6946 $Interface_SymName = $InterfaceName_SameValue;
6950 if(not $Interface_SymName)
6952 if($Interface_Name =~ /\A([^@]*)[\@]+([^@]*)\Z/ and not $SymVer{$LibVersion}{$1})
6954 $SymVer{$LibVersion}{$1} = $Interface_Name;
6959 foreach my $SoLib (keys(%NeededLib))
6961 getSymbols_Lib
($LibVersion, find_solib_path
($Lib_Dir, $SoLib), 1);
6966 sub find_solib_path
($$)
6968 my ($Dir, $SoName) = @_;
6970 if(-f
$Dir."/".$SoName)
6972 return $Dir."/".$SoName;
6976 return $SoLib_DefaultPath{$SoName};
6980 sub symbols_Preparation
($)
6981 {#recreate %SoNames and %Language using info from *.abi file
6982 my $LibVersion = $_[0];
6983 foreach my $Lib_SoName (keys(%{$Library_Interface{$LibVersion}}))
6985 foreach my $Interface_Name (keys(%{$Library_Interface{$LibVersion}{$Lib_SoName}}))
6987 $Interface_Library{$LibVersion}{$Interface_Name} = $Lib_SoName;
6988 $SoNames_All{$LibVersion}{$Lib_SoName} = 1;
6989 if(not $Language{$LibVersion}{$Lib_SoName})
6991 if($Interface_Name =~ /\A_Z[A-Z]*[0-9]+/)
6993 $Language{$LibVersion}{$Lib_SoName} = "C++";
7002 my $LibVersion = $_[0];
7004 foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Libs"}))
7006 $Dest =~ s/\A\s+|\s+\Z//g;
7010 print "ERROR: can't access \'$Dest\'\n";
7012 my @SoPaths_Dest = getSOPaths_Dest
($Dest);
7013 foreach (@SoPaths_Dest)
7021 sub getSOPaths_Dest
($)
7028 my @AllObjects = cmd_find
($Dest,"f","*\.so*");
7030 foreach my $SharedObject (@AllObjects)
7032 if(cmd_file
($SharedObject) =~ /shared object/)
7034 @SOPaths = (@SOPaths, $SharedObject);
7040 sub genDescriptorTemplate
()
7042 writeFile
("library-descriptor.xml", $Descriptor_Template."\n");
7043 print "descriptor template named 'library-descriptor.xml' has been generated in the current directory\n";
7046 sub detectPointerSize
()
7049 writeFile
("temp/get_pointer_size.c", "#include <stdio.h>
7052 printf(\"\%d\", sizeof(int*));
7055 system("gcc temp/get_pointer_size.c -o temp/get_pointer_size");
7056 $POINTER_SIZE = `./temp/get_pointer_size`;
7060 sub data_Preparation
($)
7062 my $LibVersion = $_[0];
7063 if($Descriptor{$LibVersion}{"Path"} =~ /\.abi\.tar\.gz/)
7065 my $FileName = cmd_tar
($Descriptor{$LibVersion}{"Path"});
7066 if($FileName =~ /\.abi/)
7069 my $LibraryABI = eval readFile
($FileName);
7070 system("rm", "-f", $FileName);
7071 $TypeDescr{$LibVersion} = $LibraryABI->{"TypeDescr"};
7072 $FuncDescr{$LibVersion} = $LibraryABI->{"FuncDescr"};
7073 $Library_Interface{$LibVersion} = $LibraryABI->{"Interfaces"};
7074 $SymVer{$LibVersion} = $LibraryABI->{"SymVer"};
7075 $Tid_TDid{$LibVersion} = $LibraryABI->{"Tid_TDid"};
7076 $Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
7077 $OpaqueTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
7078 $InternalInterfaces{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
7079 $Headers{$LibVersion} = $LibraryABI->{"Headers"};
7080 $SoNames_All{$LibVersion} = $LibraryABI->{"SharedObjects"};
7081 $Constants{$LibVersion} = $LibraryABI->{"Constants"};
7082 if($LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"} ne $ABI_COMPLIANCE_CHECKER_VERSION)
7084 print "ERROR: incompatible version of specified ABI dump (allowed only $ABI_COMPLIANCE_CHECKER_VERSION)\n";
7087 foreach my $Destination (keys(%{$Headers{$LibVersion}}))
7089 my $Header = get_FileName
($Destination);
7090 $HeaderName_Destinations{$LibVersion}{$Header}{$Destination} = 1;
7092 symbols_Preparation
($LibVersion);
7095 elsif($Descriptor{$LibVersion}{"Path"} =~ /\.tar\.gz\Z/)
7097 print "ERROR: descriptor must be an XML file or '*.abi.tar.gz' ABI dump\n";
7102 readDescriptor
($LibVersion);
7103 if(not $CheckHeadersOnly)
7105 getSymbols
($LibVersion);
7107 headerSearch
($LibVersion);
7114 if((keys(%{$hash}))[0] =~ /\A[0-9]+\Z/)
7116 return [sort {int($a) <=> int($b)} keys %{$hash}];
7120 return [sort {$a cmp $b} keys %{$hash}];
7124 sub get_solib_default_paths
()
7126 foreach my $Line (split("\n", `ldconfig -p`))
7128 if($Line=~/\A[ \t]*([^ \t]+) .* \=\> (.+)\Z/)
7130 $SoLib_DefaultPath{$1} = $2;
7142 if(defined $ShowVersion)
7144 print "ABI Compliance Checker $ABI_COMPLIANCE_CHECKER_VERSION\nCopyright (C) The Linux Foundation\nCopyright (C) Institute for System Programming, RAS\nLicense GPLv2: GNU GPL version 2 <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.\n";
7147 $Data::Dumper
::Sortkeys
= \
&dump_sorting
;
7148 if(defined $TestSystem)
7154 if($GenerateDescriptor)
7156 genDescriptorTemplate
();
7159 if(not defined $TargetLibraryName)
7161 print "select library name (option -l <name>)\n";
7164 if(defined $InterfacesListPath)
7166 if(not -f
$InterfacesListPath)
7168 print "ERROR: can't access file $InterfacesListPath\n";
7171 foreach my $Interface (split("\n", readFile
($InterfacesListPath)))
7173 $InterfacesList{$Interface} = 1;
7180 foreach my $Interface (getSymbols_App
($AppPath))
7182 $InterfacesList_App{$Interface} = 1;
7187 print "ERROR: can't access file \'$AppPath\'\n";
7191 get_solib_default_paths
();
7192 if($DumpInfo_DescriptorPath)
7194 if(not -f
$DumpInfo_DescriptorPath)
7196 print "ERROR: can't access file \'$DumpInfo_DescriptorPath\'\n";
7199 $Descriptor{1}{"Path"} = $DumpInfo_DescriptorPath;
7201 detectPointerSize
();
7203 translateSymbols
(1);
7205 parseHeaders_AllInOne
(1);
7207 my %LibraryABI = ();
7208 print "creating library ABI info dump ...\n";
7209 $LibraryABI{"TypeDescr"} = $TypeDescr{1};
7210 $LibraryABI{"FuncDescr"} = $FuncDescr{1};
7211 $LibraryABI{"Interfaces"} = $Library_Interface{1};
7212 $LibraryABI{"SymVer"} = $SymVer{1};
7213 $LibraryABI{"LibraryVersion"} = $Descriptor{1}{"Version"};
7214 $LibraryABI{"Library"} = $TargetLibraryName;
7215 $LibraryABI{"SharedObjects"} = $SoNames_All{1};
7216 $LibraryABI{"Tid_TDid"} = $Tid_TDid{1};
7217 $LibraryABI{"OpaqueTypes"} = $OpaqueTypes{1};
7218 $LibraryABI{"InternalInterfaces"} = $InternalInterfaces{1};
7219 $LibraryABI{"Headers"} = $Headers{1};
7220 $LibraryABI{"Constants"} = $Constants{1};
7221 $LibraryABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $ABI_COMPLIANCE_CHECKER_VERSION;
7222 my $InfoDump_FilePath = "abi_dumps/$TargetLibraryName";
7223 my $InfoDump_FileName = $TargetLibraryName."_".$Descriptor{1}{"Version"}.".abi";
7224 system("mkdir", "-p", $InfoDump_FilePath);
7225 system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName.".tar.gz");
7226 writeFile
("$InfoDump_FilePath/$InfoDump_FileName", Dumper
(\
%LibraryABI));
7227 system("cd ".esc
($InfoDump_FilePath)." && tar -cf ".esc
($InfoDump_FileName).".tar ".esc
($InfoDump_FileName));
7228 system("cd ".esc
($InfoDump_FilePath)." && gzip ".esc
($InfoDump_FileName).".tar --best");
7229 system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName);
7232 print "ERROR: can't create library ABI info dump\n";
7237 print "see library ABI info dump in \'$InfoDump_FilePath/$InfoDump_FileName\.tar\.gz\': use it instead of library version descriptor on other machine\n";
7241 if(not $Descriptor{1}{"Path"})
7243 print "select 1st library descriptor (option -d1 <path>)\n";
7246 if(not -f
$Descriptor{1}{"Path"})
7248 print "ERROR: descriptor d1 does not exist, incorrect file path '".$Descriptor{1}{"Path"}."'\n";
7251 if(not $Descriptor{2}{"Path"})
7253 print "select 2nd library descriptor (option -d2 <path>)\n";
7256 if(not -f
$Descriptor{2}{"Path"})
7258 print "ERROR: descriptor d2 does not exist, incorrect file path '".$Descriptor{2}{"Path"}."'\n";
7261 $StartTime = localtime time;
7262 print "preparation...\n";
7263 data_Preparation
(1);
7264 data_Preparation
(2);
7265 if($AppPath and not keys(%{$Interface_Library{1}}))
7267 print "WARNING: symbols from the specified application were not found in the specified library shared objects\n";
7269 $REPORT_PATH = "compat_reports/$TargetLibraryName/".$Descriptor{1}{"Version"}."_to_".$Descriptor{2}{"Version"};
7270 system("mkdir", "-p", $REPORT_PATH);
7271 system("rm", "-f", $REPORT_PATH."/abi_compat_report.html");
7272 detectPointerSize
();
7273 translateSymbols
(1);
7274 translateSymbols
(2);
7275 if(not $CheckHeadersOnly)
7281 if($HeaderCheckingMode_Separately and $Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/ and $Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
7283 mergeHeaders_Separately
();
7287 if($Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/)
7289 parseHeaders_AllInOne
(1);
7291 if($Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
7293 parseHeaders_AllInOne
(2);
7295 print "comparing headers ...\n";
7300 if(not $CheckHeadersOnly)
7302 print "comparing shared objects ...\n";
7305 print "creating ABI compliance report ...\n";
7306 create_HtmlReport
();
7307 if($HeaderCheckingMode_Separately)
7309 if(keys(%HeaderCompileError))
7311 print "\nWARNING: compilation errors in following headers:\n";
7312 foreach my $Header (keys(%HeaderCompileError))
7316 print "\nyou can see compilation errors in the following files:\n '$ERR_PATH{1}'\n '$ERR_PATH{2}'\n";
7320 print "\nstarted: $StartTime, finished: ".(localtime time)."\n" if($ShowExpendTime);
7321 print "see the ABI compliance report in the file '$REPORT_PATH/abi_compat_report.html'\n";